Daily bump.
[official-gcc.git] / gcc / config / i386 / i386.md
blobc4c4cd859340f38d19d197d3992fc0b5484d5278
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2016 Free Software Foundation, Inc.
3 ;; Mostly by William Schelter.
4 ;; x86_64 support added by Jan Hubicka
5 ;;
6 ;; This file is part of GCC.
7 ;;
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
11 ;; any later version.
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3.  If not see
20 ;; <http://www.gnu.org/licenses/>.  */
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;; The special asm out single letter directives following a '%' are:
28 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
29 ;; C -- print opcode suffix for set/cmov insn.
30 ;; c -- like C, but print reversed condition
31 ;; F,f -- likewise, but for floating-point.
32 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
33 ;;      otherwise nothing
34 ;; R -- print the prefix for register names.
35 ;; z -- print the opcode suffix for the size of the current operand.
36 ;; Z -- likewise, with special suffixes for x87 instructions.
37 ;; * -- print a star (in certain assembler syntax)
38 ;; A -- print an absolute memory reference.
39 ;; E -- print address with DImode register names if TARGET_64BIT.
40 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
41 ;; s -- print a shift double count, followed by the assemblers argument
42 ;;      delimiter.
43 ;; b -- print the QImode name of the register for the indicated operand.
44 ;;      %b0 would print %al if operands[0] is reg 0.
45 ;; w --  likewise, print the HImode name of the register.
46 ;; k --  likewise, print the SImode name of the register.
47 ;; q --  likewise, print the DImode name of the register.
48 ;; x --  likewise, print the V4SFmode name of the register.
49 ;; t --  likewise, print the V8SFmode name of the register.
50 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
51 ;; y -- print "st(0)" instead of "st" as a register.
52 ;; d -- print duplicated register operand for AVX instruction.
53 ;; D -- print condition for SSE cmp instruction.
54 ;; P -- if PIC, print an @PLT suffix.
55 ;; p -- print raw symbol name.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; K -- print HLE lock prefix
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
64 ;; @ -- print a segment register of thread base pointer load
65 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
66 ;; ! -- print MPX prefix for jxx/call/ret instructions if required.
68 (define_c_enum "unspec" [
69   ;; Relocation specifiers
70   UNSPEC_GOT
71   UNSPEC_GOTOFF
72   UNSPEC_GOTPCREL
73   UNSPEC_GOTTPOFF
74   UNSPEC_TPOFF
75   UNSPEC_NTPOFF
76   UNSPEC_DTPOFF
77   UNSPEC_GOTNTPOFF
78   UNSPEC_INDNTPOFF
79   UNSPEC_PLTOFF
80   UNSPEC_MACHOPIC_OFFSET
81   UNSPEC_PCREL
82   UNSPEC_SIZEOF
84   ;; Prologue support
85   UNSPEC_STACK_ALLOC
86   UNSPEC_SET_GOT
87   UNSPEC_SET_RIP
88   UNSPEC_SET_GOT_OFFSET
89   UNSPEC_MEMORY_BLOCKAGE
90   UNSPEC_STACK_CHECK
92   ;; TLS support
93   UNSPEC_TP
94   UNSPEC_TLS_GD
95   UNSPEC_TLS_LD_BASE
96   UNSPEC_TLSDESC
97   UNSPEC_TLS_IE_SUN
99   ;; Other random patterns
100   UNSPEC_SCAS
101   UNSPEC_FNSTSW
102   UNSPEC_SAHF
103   UNSPEC_PARITY
104   UNSPEC_FSTCW
105   UNSPEC_FLDCW
106   UNSPEC_REP
107   UNSPEC_LD_MPIC        ; load_macho_picbase
108   UNSPEC_TRUNC_NOOP
109   UNSPEC_DIV_ALREADY_SPLIT
110   UNSPEC_PAUSE
111   UNSPEC_LEA_ADDR
112   UNSPEC_XBEGIN_ABORT
113   UNSPEC_STOS
114   UNSPEC_PEEPSIB
115   UNSPEC_INSN_FALSE_DEP
117   ;; For SSE/MMX support:
118   UNSPEC_FIX_NOTRUNC
119   UNSPEC_MASKMOV
120   UNSPEC_MOVMSK
121   UNSPEC_RCP
122   UNSPEC_RSQRT
123   UNSPEC_PSADBW
125   ;; Generic math support
126   UNSPEC_COPYSIGN
127   UNSPEC_IEEE_MIN       ; not commutative
128   UNSPEC_IEEE_MAX       ; not commutative
130   ;; x87 Floating point
131   UNSPEC_SIN
132   UNSPEC_COS
133   UNSPEC_FPATAN
134   UNSPEC_FYL2X
135   UNSPEC_FYL2XP1
136   UNSPEC_FRNDINT
137   UNSPEC_FIST
138   UNSPEC_F2XM1
139   UNSPEC_TAN
140   UNSPEC_FXAM
142   ;; x87 Rounding
143   UNSPEC_FRNDINT_FLOOR
144   UNSPEC_FRNDINT_CEIL
145   UNSPEC_FRNDINT_TRUNC
146   UNSPEC_FRNDINT_MASK_PM
147   UNSPEC_FIST_FLOOR
148   UNSPEC_FIST_CEIL
150   ;; x87 Double output FP
151   UNSPEC_SINCOS_COS
152   UNSPEC_SINCOS_SIN
153   UNSPEC_XTRACT_FRACT
154   UNSPEC_XTRACT_EXP
155   UNSPEC_FSCALE_FRACT
156   UNSPEC_FSCALE_EXP
157   UNSPEC_FPREM_F
158   UNSPEC_FPREM_U
159   UNSPEC_FPREM1_F
160   UNSPEC_FPREM1_U
162   UNSPEC_C2_FLAG
163   UNSPEC_FXAM_MEM
165   ;; SSP patterns
166   UNSPEC_SP_SET
167   UNSPEC_SP_TEST
168   UNSPEC_SP_TLS_SET
169   UNSPEC_SP_TLS_TEST
171   ;; For ROUND support
172   UNSPEC_ROUND
174   ;; For CRC32 support
175   UNSPEC_CRC32
177   ;; For BMI support
178   UNSPEC_BEXTR
180   ;; For BMI2 support
181   UNSPEC_PDEP
182   UNSPEC_PEXT
184   ;; For AVX512F support
185   UNSPEC_KMOV
187   UNSPEC_BNDMK
188   UNSPEC_BNDMK_ADDR
189   UNSPEC_BNDSTX
190   UNSPEC_BNDLDX
191   UNSPEC_BNDLDX_ADDR
192   UNSPEC_BNDCL
193   UNSPEC_BNDCU
194   UNSPEC_BNDCN
195   UNSPEC_MPX_FENCE
198 (define_c_enum "unspecv" [
199   UNSPECV_BLOCKAGE
200   UNSPECV_STACK_PROBE
201   UNSPECV_PROBE_STACK_RANGE
202   UNSPECV_ALIGN
203   UNSPECV_PROLOGUE_USE
204   UNSPECV_SPLIT_STACK_RETURN
205   UNSPECV_CLD
206   UNSPECV_NOPS
207   UNSPECV_RDTSC
208   UNSPECV_RDTSCP
209   UNSPECV_RDPMC
210   UNSPECV_LLWP_INTRINSIC
211   UNSPECV_SLWP_INTRINSIC
212   UNSPECV_LWPVAL_INTRINSIC
213   UNSPECV_LWPINS_INTRINSIC
214   UNSPECV_RDFSBASE
215   UNSPECV_RDGSBASE
216   UNSPECV_WRFSBASE
217   UNSPECV_WRGSBASE
218   UNSPECV_FXSAVE
219   UNSPECV_FXRSTOR
220   UNSPECV_FXSAVE64
221   UNSPECV_FXRSTOR64
222   UNSPECV_XSAVE
223   UNSPECV_XRSTOR
224   UNSPECV_XSAVE64
225   UNSPECV_XRSTOR64
226   UNSPECV_XSAVEOPT
227   UNSPECV_XSAVEOPT64
228   UNSPECV_XSAVES
229   UNSPECV_XRSTORS
230   UNSPECV_XSAVES64
231   UNSPECV_XRSTORS64
232   UNSPECV_XSAVEC
233   UNSPECV_XSAVEC64
235   ;; For atomic compound assignments.
236   UNSPECV_FNSTENV
237   UNSPECV_FLDENV
238   UNSPECV_FNSTSW
239   UNSPECV_FNCLEX
241   ;; For RDRAND support
242   UNSPECV_RDRAND
244   ;; For RDSEED support
245   UNSPECV_RDSEED
247   ;; For RTM support
248   UNSPECV_XBEGIN
249   UNSPECV_XEND
250   UNSPECV_XABORT
251   UNSPECV_XTEST
253   UNSPECV_NLGR
255   ;; For CLWB support
256   UNSPECV_CLWB
258   ;; For PCOMMIT support
259   UNSPECV_PCOMMIT
261   ;; For CLFLUSHOPT support
262   UNSPECV_CLFLUSHOPT
264   ;; For MONITORX and MWAITX support 
265   UNSPECV_MONITORX
266   UNSPECV_MWAITX
268   ;; For CLZERO support
269   UNSPECV_CLZERO
271   ;; For RDPKRU and WRPKRU support
272   UNSPECV_PKU
275 ;; Constants to represent rounding modes in the ROUND instruction
276 (define_constants
277   [(ROUND_FLOOR                 0x1)
278    (ROUND_CEIL                  0x2)
279    (ROUND_TRUNC                 0x3)
280    (ROUND_MXCSR                 0x4)
281    (ROUND_NO_EXC                0x8)
282   ])
284 ;; Constants to represent AVX512F embeded rounding
285 (define_constants
286   [(ROUND_NEAREST_INT                   0)
287    (ROUND_NEG_INF                       1)
288    (ROUND_POS_INF                       2)
289    (ROUND_ZERO                          3)
290    (NO_ROUND                            4)
291    (ROUND_SAE                           8)
292   ])
294 ;; Constants to represent pcomtrue/pcomfalse variants
295 (define_constants
296   [(PCOM_FALSE                  0)
297    (PCOM_TRUE                   1)
298    (COM_FALSE_S                 2)
299    (COM_FALSE_P                 3)
300    (COM_TRUE_S                  4)
301    (COM_TRUE_P                  5)
302   ])
304 ;; Constants used in the XOP pperm instruction
305 (define_constants
306   [(PPERM_SRC                   0x00)   /* copy source */
307    (PPERM_INVERT                0x20)   /* invert source */
308    (PPERM_REVERSE               0x40)   /* bit reverse source */
309    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
310    (PPERM_ZERO                  0x80)   /* all 0's */
311    (PPERM_ONES                  0xa0)   /* all 1's */
312    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
313    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
314    (PPERM_SRC1                  0x00)   /* use first source byte */
315    (PPERM_SRC2                  0x10)   /* use second source byte */
316    ])
318 ;; Registers by name.
319 (define_constants
320   [(AX_REG                       0)
321    (DX_REG                       1)
322    (CX_REG                       2)
323    (BX_REG                       3)
324    (SI_REG                       4)
325    (DI_REG                       5)
326    (BP_REG                       6)
327    (SP_REG                       7)
328    (ST0_REG                      8)
329    (ST1_REG                      9)
330    (ST2_REG                     10)
331    (ST3_REG                     11)
332    (ST4_REG                     12)
333    (ST5_REG                     13)
334    (ST6_REG                     14)
335    (ST7_REG                     15)
336    (ARGP_REG                    16)
337    (FLAGS_REG                   17)
338    (FPSR_REG                    18)
339    (FPCR_REG                    19)
340    (FRAME_REG                   20)
341    (XMM0_REG                    21)
342    (XMM1_REG                    22)
343    (XMM2_REG                    23)
344    (XMM3_REG                    24)
345    (XMM4_REG                    25)
346    (XMM5_REG                    26)
347    (XMM6_REG                    27)
348    (XMM7_REG                    28)
349    (MM0_REG                     29)
350    (MM1_REG                     30)
351    (MM2_REG                     31)
352    (MM3_REG                     32)
353    (MM4_REG                     33)
354    (MM5_REG                     34)
355    (MM6_REG                     35)
356    (MM7_REG                     36)
357    (R8_REG                      37)
358    (R9_REG                      38)
359    (R10_REG                     39)
360    (R11_REG                     40)
361    (R12_REG                     41)
362    (R13_REG                     42)
363    (R14_REG                     43)
364    (R15_REG                     44)
365    (XMM8_REG                    45)
366    (XMM9_REG                    46)
367    (XMM10_REG                   47)
368    (XMM11_REG                   48)
369    (XMM12_REG                   49)
370    (XMM13_REG                   50)
371    (XMM14_REG                   51)
372    (XMM15_REG                   52)
373    (XMM16_REG                   53)
374    (XMM17_REG                   54)
375    (XMM18_REG                   55)
376    (XMM19_REG                   56)
377    (XMM20_REG                   57)
378    (XMM21_REG                   58)
379    (XMM22_REG                   59)
380    (XMM23_REG                   60)
381    (XMM24_REG                   61)
382    (XMM25_REG                   62)
383    (XMM26_REG                   63)
384    (XMM27_REG                   64)
385    (XMM28_REG                   65)
386    (XMM29_REG                   66)
387    (XMM30_REG                   67)
388    (XMM31_REG                   68)
389    (MASK0_REG                   69)
390    (MASK1_REG                   70)
391    (MASK2_REG                   71)
392    (MASK3_REG                   72)
393    (MASK4_REG                   73)
394    (MASK5_REG                   74)
395    (MASK6_REG                   75)
396    (MASK7_REG                   76)
397    (BND0_REG                    77)
398    (BND1_REG                    78)
399    (BND2_REG                    79)
400    (BND3_REG                    80)
401    (FIRST_PSEUDO_REG            81)
402   ])
404 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
405 ;; from i386.c.
407 ;; In C guard expressions, put expressions which may be compile-time
408 ;; constants first.  This allows for better optimization.  For
409 ;; example, write "TARGET_64BIT && reload_completed", not
410 ;; "reload_completed && TARGET_64BIT".
413 ;; Processor type.
414 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
415                     atom,slm,haswell,generic,amdfam10,bdver1,bdver2,bdver3,
416                     bdver4,btver2,znver1"
417   (const (symbol_ref "ix86_schedule")))
419 ;; A basic instruction type.  Refinements due to arguments to be
420 ;; provided in other attributes.
421 (define_attr "type"
422   "other,multi,
423    alu,alu1,negnot,imov,imovx,lea,
424    incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
425    imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
426    push,pop,call,callv,leave,
427    str,bitmanip,
428    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
429    fxch,fistp,fisttp,frndint,
430    sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
431    ssemul,sseimul,ssediv,sselog,sselog1,
432    sseishft,sseishft1,ssecmp,ssecomi,
433    ssecvt,ssecvt1,sseicvt,sseins,
434    sseshuf,sseshuf1,ssemuladd,sse4arg,
435    lwp,mskmov,msklog,
436    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
437    mpxmov,mpxmk,mpxchk,mpxld,mpxst"
438   (const_string "other"))
440 ;; Main data type used by the insn
441 (define_attr "mode"
442   "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
443   V2DF,V2SF,V1DF,V8DF"
444   (const_string "unknown"))
446 ;; The CPU unit operations uses.
447 (define_attr "unit" "integer,i387,sse,mmx,unknown"
448   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
449                           fxch,fistp,fisttp,frndint")
450            (const_string "i387")
451          (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
452                           ssemul,sseimul,ssediv,sselog,sselog1,
453                           sseishft,sseishft1,ssecmp,ssecomi,
454                           ssecvt,ssecvt1,sseicvt,sseins,
455                           sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
456            (const_string "sse")
457          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
458            (const_string "mmx")
459          (eq_attr "type" "other")
460            (const_string "unknown")]
461          (const_string "integer")))
463 ;; The minimum required alignment of vector mode memory operands of the SSE
464 ;; (non-VEX/EVEX) instruction in bits, if it is different from
465 ;; GET_MODE_ALIGNMENT of the operand, otherwise 0.  If an instruction has
466 ;; multiple alternatives, this should be conservative maximum of those minimum
467 ;; required alignments.
468 (define_attr "ssememalign" "" (const_int 0))
470 ;; The (bounding maximum) length of an instruction immediate.
471 (define_attr "length_immediate" ""
472   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
473                           bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
474                           mpxld,mpxst")
475            (const_int 0)
476          (eq_attr "unit" "i387,sse,mmx")
477            (const_int 0)
478          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
479                           rotate,rotatex,rotate1,imul,icmp,push,pop")
480            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
481          (eq_attr "type" "imov,test")
482            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
483          (eq_attr "type" "call")
484            (if_then_else (match_operand 0 "constant_call_address_operand")
485              (const_int 4)
486              (const_int 0))
487          (eq_attr "type" "callv")
488            (if_then_else (match_operand 1 "constant_call_address_operand")
489              (const_int 4)
490              (const_int 0))
491          ;; We don't know the size before shorten_branches.  Expect
492          ;; the instruction to fit for better scheduling.
493          (eq_attr "type" "ibr")
494            (const_int 1)
495          ]
496          (symbol_ref "/* Update immediate_length and other attributes! */
497                       gcc_unreachable (),1")))
499 ;; The (bounding maximum) length of an instruction address.
500 (define_attr "length_address" ""
501   (cond [(eq_attr "type" "str,other,multi,fxch")
502            (const_int 0)
503          (and (eq_attr "type" "call")
504               (match_operand 0 "constant_call_address_operand"))
505              (const_int 0)
506          (and (eq_attr "type" "callv")
507               (match_operand 1 "constant_call_address_operand"))
508              (const_int 0)
509          ]
510          (symbol_ref "ix86_attr_length_address_default (insn)")))
512 ;; Set when length prefix is used.
513 (define_attr "prefix_data16" ""
514   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
515            (const_int 0)
516          (eq_attr "mode" "HI")
517            (const_int 1)
518          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
519            (const_int 1)
520         ]
521         (const_int 0)))
523 ;; Set when string REP prefix is used.
524 (define_attr "prefix_rep" ""
525   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
526            (const_int 0)
527          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
528            (const_int 1)
529          (and (eq_attr "type" "ibr,call,callv")
530               (match_test "ix86_bnd_prefixed_insn_p (insn)"))
531            (const_int 1)
532         ]
533         (const_int 0)))
535 ;; Set when 0f opcode prefix is used.
536 (define_attr "prefix_0f" ""
537   (if_then_else
538     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
539                           mpxmk,mpxmov,mpxchk,mpxld,mpxst")
540          (eq_attr "unit" "sse,mmx"))
541     (const_int 1)
542     (const_int 0)))
544 ;; Set when REX opcode prefix is used.
545 (define_attr "prefix_rex" ""
546   (cond [(not (match_test "TARGET_64BIT"))
547            (const_int 0)
548          (and (eq_attr "mode" "DI")
549               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
550                    (eq_attr "unit" "!mmx")))
551            (const_int 1)
552          (and (eq_attr "mode" "QI")
553               (match_test "x86_extended_QIreg_mentioned_p (insn)"))
554            (const_int 1)
555          (match_test "x86_extended_reg_mentioned_p (insn)")
556            (const_int 1)
557          (and (eq_attr "type" "imovx")
558               (match_operand:QI 1 "ext_QIreg_operand"))
559            (const_int 1)
560         ]
561         (const_int 0)))
563 ;; There are also additional prefixes in 3DNOW, SSSE3.
564 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
565 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
566 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
567 (define_attr "prefix_extra" ""
568   (cond [(eq_attr "type" "ssemuladd,sse4arg")
569            (const_int 2)
570          (eq_attr "type" "sseiadd1,ssecvt1")
571            (const_int 1)
572         ]
573         (const_int 0)))
575 ;; Set when BND opcode prefix may be used.
576 (define_attr "maybe_prefix_bnd" "" (const_int 0))
578 ;; Prefix used: original, VEX or maybe VEX.
579 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
580   (cond [(eq_attr "mode" "OI,V8SF,V4DF")
581            (const_string "vex")
582          (eq_attr "mode" "XI,V16SF,V8DF")
583            (const_string "evex")
584         ]
585         (const_string "orig")))
587 ;; VEX W bit is used.
588 (define_attr "prefix_vex_w" "" (const_int 0))
590 ;; The length of VEX prefix
591 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
592 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
593 ;; still prefix_0f 1, with prefix_extra 1.
594 (define_attr "length_vex" ""
595   (if_then_else (and (eq_attr "prefix_0f" "1")
596                      (eq_attr "prefix_extra" "0"))
597     (if_then_else (eq_attr "prefix_vex_w" "1")
598       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
599       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
600     (if_then_else (eq_attr "prefix_vex_w" "1")
601       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
602       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
604 ;; 4-bytes evex prefix and 1 byte opcode.
605 (define_attr "length_evex" "" (const_int 5))
607 ;; Set when modrm byte is used.
608 (define_attr "modrm" ""
609   (cond [(eq_attr "type" "str,leave")
610            (const_int 0)
611          (eq_attr "unit" "i387")
612            (const_int 0)
613          (and (eq_attr "type" "incdec")
614               (and (not (match_test "TARGET_64BIT"))
615                    (ior (match_operand:SI 1 "register_operand")
616                         (match_operand:HI 1 "register_operand"))))
617            (const_int 0)
618          (and (eq_attr "type" "push")
619               (not (match_operand 1 "memory_operand")))
620            (const_int 0)
621          (and (eq_attr "type" "pop")
622               (not (match_operand 0 "memory_operand")))
623            (const_int 0)
624          (and (eq_attr "type" "imov")
625               (and (not (eq_attr "mode" "DI"))
626                    (ior (and (match_operand 0 "register_operand")
627                              (match_operand 1 "immediate_operand"))
628                         (ior (and (match_operand 0 "ax_reg_operand")
629                                   (match_operand 1 "memory_displacement_only_operand"))
630                              (and (match_operand 0 "memory_displacement_only_operand")
631                                   (match_operand 1 "ax_reg_operand"))))))
632            (const_int 0)
633          (and (eq_attr "type" "call")
634               (match_operand 0 "constant_call_address_operand"))
635              (const_int 0)
636          (and (eq_attr "type" "callv")
637               (match_operand 1 "constant_call_address_operand"))
638              (const_int 0)
639          (and (eq_attr "type" "alu,alu1,icmp,test")
640               (match_operand 0 "ax_reg_operand"))
641              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
642          ]
643          (const_int 1)))
645 (define_attr "modrm_class" "none,incdec,op0,op01,op02,pushpop,unknown"
646   (cond [(eq_attr "modrm" "0")
647            (const_string "none")
648          (eq_attr "type" "alu,imul,ishift")
649            (const_string "op02")
650          (eq_attr "type" "imov,imovx,lea,alu1,icmp")
651            (const_string "op01")
652          (eq_attr "type" "incdec")
653            (const_string "incdec")
654          (eq_attr "type" "push,pop")
655            (const_string "pushpop")]
656          (const_string "unknown")))
658 ;; The (bounding maximum) length of an instruction in bytes.
659 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
660 ;; Later we may want to split them and compute proper length as for
661 ;; other insns.
662 (define_attr "length" ""
663   (cond [(eq_attr "type" "other,multi,fistp,frndint")
664            (const_int 16)
665          (eq_attr "type" "fcmp")
666            (const_int 4)
667          (eq_attr "unit" "i387")
668            (plus (const_int 2)
669                  (plus (attr "prefix_data16")
670                        (attr "length_address")))
671          (ior (eq_attr "prefix" "evex")
672               (and (ior (eq_attr "prefix" "maybe_evex")
673                         (eq_attr "prefix" "maybe_vex"))
674                    (match_test "TARGET_AVX512F")))
675            (plus (attr "length_evex")
676                  (plus (attr "length_immediate")
677                        (plus (attr "modrm")
678                              (attr "length_address"))))
679          (ior (eq_attr "prefix" "vex")
680               (and (ior (eq_attr "prefix" "maybe_vex")
681                         (eq_attr "prefix" "maybe_evex"))
682                    (match_test "TARGET_AVX")))
683            (plus (attr "length_vex")
684                  (plus (attr "length_immediate")
685                        (plus (attr "modrm")
686                              (attr "length_address"))))]
687          (plus (plus (attr "modrm")
688                      (plus (attr "prefix_0f")
689                            (plus (attr "prefix_rex")
690                                  (plus (attr "prefix_extra")
691                                        (const_int 1)))))
692                (plus (attr "prefix_rep")
693                      (plus (attr "prefix_data16")
694                            (plus (attr "length_immediate")
695                                  (attr "length_address")))))))
697 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
698 ;; `store' if there is a simple memory reference therein, or `unknown'
699 ;; if the instruction is complex.
701 (define_attr "memory" "none,load,store,both,unknown"
702   (cond [(eq_attr "type" "other,multi,str,lwp")
703            (const_string "unknown")
704          (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
705            (const_string "none")
706          (eq_attr "type" "fistp,leave")
707            (const_string "both")
708          (eq_attr "type" "frndint")
709            (const_string "load")
710          (eq_attr "type" "mpxld")
711            (const_string "load")
712          (eq_attr "type" "mpxst")
713            (const_string "store")
714          (eq_attr "type" "push")
715            (if_then_else (match_operand 1 "memory_operand")
716              (const_string "both")
717              (const_string "store"))
718          (eq_attr "type" "pop")
719            (if_then_else (match_operand 0 "memory_operand")
720              (const_string "both")
721              (const_string "load"))
722          (eq_attr "type" "setcc")
723            (if_then_else (match_operand 0 "memory_operand")
724              (const_string "store")
725              (const_string "none"))
726          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
727            (if_then_else (ior (match_operand 0 "memory_operand")
728                               (match_operand 1 "memory_operand"))
729              (const_string "load")
730              (const_string "none"))
731          (eq_attr "type" "ibr")
732            (if_then_else (match_operand 0 "memory_operand")
733              (const_string "load")
734              (const_string "none"))
735          (eq_attr "type" "call")
736            (if_then_else (match_operand 0 "constant_call_address_operand")
737              (const_string "none")
738              (const_string "load"))
739          (eq_attr "type" "callv")
740            (if_then_else (match_operand 1 "constant_call_address_operand")
741              (const_string "none")
742              (const_string "load"))
743          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
744               (match_operand 1 "memory_operand"))
745            (const_string "both")
746          (and (match_operand 0 "memory_operand")
747               (match_operand 1 "memory_operand"))
748            (const_string "both")
749          (match_operand 0 "memory_operand")
750            (const_string "store")
751          (match_operand 1 "memory_operand")
752            (const_string "load")
753          (and (eq_attr "type"
754                  "!alu1,negnot,ishift1,
755                    imov,imovx,icmp,test,bitmanip,
756                    fmov,fcmp,fsgn,
757                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
758                    sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
759                    mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
760               (match_operand 2 "memory_operand"))
761            (const_string "load")
762          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
763               (match_operand 3 "memory_operand"))
764            (const_string "load")
765         ]
766         (const_string "none")))
768 ;; Indicates if an instruction has both an immediate and a displacement.
770 (define_attr "imm_disp" "false,true,unknown"
771   (cond [(eq_attr "type" "other,multi")
772            (const_string "unknown")
773          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
774               (and (match_operand 0 "memory_displacement_operand")
775                    (match_operand 1 "immediate_operand")))
776            (const_string "true")
777          (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
778               (and (match_operand 0 "memory_displacement_operand")
779                    (match_operand 2 "immediate_operand")))
780            (const_string "true")
781         ]
782         (const_string "false")))
784 ;; Indicates if an FP operation has an integer source.
786 (define_attr "fp_int_src" "false,true"
787   (const_string "false"))
789 ;; Defines rounding mode of an FP operation.
791 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
792   (const_string "any"))
794 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
795 (define_attr "use_carry" "0,1" (const_string "0"))
797 ;; Define attribute to indicate unaligned ssemov insns
798 (define_attr "movu" "0,1" (const_string "0"))
800 ;; Used to control the "enabled" attribute on a per-instruction basis.
801 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
802                     sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
803                     avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
804                     fma_avx512f,avx512bw,noavx512bw,avx512dq,noavx512dq,
805                     avx512vl,noavx512vl"
806   (const_string "base"))
808 (define_attr "enabled" ""
809   (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
810          (eq_attr "isa" "x64_sse4")
811            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
812          (eq_attr "isa" "x64_sse4_noavx")
813            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
814          (eq_attr "isa" "x64_avx")
815            (symbol_ref "TARGET_64BIT && TARGET_AVX")
816          (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
817          (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
818          (eq_attr "isa" "sse2_noavx")
819            (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
820          (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
821          (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
822          (eq_attr "isa" "sse4_noavx")
823            (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
824          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
825          (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
826          (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
827          (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
828          (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
829          (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
830          (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
831          (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
832          (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
833          (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
834          (eq_attr "isa" "fma_avx512f")
835            (symbol_ref "TARGET_FMA || TARGET_AVX512F")
836          (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
837          (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
838          (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
839          (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
840          (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
841          (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
842         ]
843         (const_int 1)))
845 (define_attr "preferred_for_size" "" (const_int 1))
846 (define_attr "preferred_for_speed" "" (const_int 1))
848 ;; Describe a user's asm statement.
849 (define_asm_attributes
850   [(set_attr "length" "128")
851    (set_attr "type" "multi")])
853 (define_code_iterator plusminus [plus minus])
855 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
857 (define_code_iterator multdiv [mult div])
859 ;; Base name for define_insn
860 (define_code_attr plusminus_insn
861   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
862    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
864 ;; Base name for insn mnemonic.
865 (define_code_attr plusminus_mnemonic
866   [(plus "add") (ss_plus "adds") (us_plus "addus")
867    (minus "sub") (ss_minus "subs") (us_minus "subus")])
868 (define_code_attr multdiv_mnemonic
869   [(mult "mul") (div "div")])
871 ;; Mark commutative operators as such in constraints.
872 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
873                         (minus "") (ss_minus "") (us_minus "")])
875 ;; Mapping of max and min
876 (define_code_iterator maxmin [smax smin umax umin])
878 ;; Mapping of signed max and min
879 (define_code_iterator smaxmin [smax smin])
881 ;; Mapping of unsigned max and min
882 (define_code_iterator umaxmin [umax umin])
884 ;; Base name for integer and FP insn mnemonic
885 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
886                               (umax "maxu") (umin "minu")])
887 (define_code_attr maxmin_float [(smax "max") (smin "min")])
889 ;; Mapping of logic operators
890 (define_code_iterator any_logic [and ior xor])
891 (define_code_iterator any_or [ior xor])
892 (define_code_iterator fpint_logic [and xor])
894 ;; Base name for insn mnemonic.
895 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
897 ;; Mapping of logic-shift operators
898 (define_code_iterator any_lshift [ashift lshiftrt])
900 ;; Mapping of shift-right operators
901 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
903 ;; Mapping of all shift operators
904 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
906 ;; Base name for define_insn
907 (define_code_attr shift_insn
908   [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
910 ;; Base name for insn mnemonic.
911 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
912 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
914 ;; Mask variant left right mnemonics
915 (define_code_attr mshift [(ashift "shiftl") (lshiftrt "shiftr")])
917 ;; Mapping of rotate operators
918 (define_code_iterator any_rotate [rotate rotatert])
920 ;; Base name for define_insn
921 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
923 ;; Base name for insn mnemonic.
924 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
926 ;; Mapping of abs neg operators
927 (define_code_iterator absneg [abs neg])
929 ;; Base name for x87 insn mnemonic.
930 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
932 ;; Used in signed and unsigned widening multiplications.
933 (define_code_iterator any_extend [sign_extend zero_extend])
935 ;; Prefix for insn menmonic.
936 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
938 ;; Prefix for define_insn
939 (define_code_attr u [(sign_extend "") (zero_extend "u")])
940 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
941 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
943 ;; Used in signed and unsigned truncations.
944 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
945 ;; Instruction suffix for truncations.
946 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
948 ;; Used in signed and unsigned fix.
949 (define_code_iterator any_fix [fix unsigned_fix])
950 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
952 ;; Used in signed and unsigned float.
953 (define_code_iterator any_float [float unsigned_float])
954 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
956 ;; All integer modes.
957 (define_mode_iterator SWI1248x [QI HI SI DI])
959 ;; All integer modes with AVX512BW/DQ.
960 (define_mode_iterator SWI1248_AVX512BWDQ
961   [(QI "TARGET_AVX512DQ") HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
963 ;; All integer modes without QImode.
964 (define_mode_iterator SWI248x [HI SI DI])
966 ;; All integer modes without QImode and HImode.
967 (define_mode_iterator SWI48x [SI DI])
969 ;; All integer modes without SImode and DImode.
970 (define_mode_iterator SWI12 [QI HI])
972 ;; All integer modes without DImode.
973 (define_mode_iterator SWI124 [QI HI SI])
975 ;; All integer modes without QImode and DImode.
976 (define_mode_iterator SWI24 [HI SI])
978 ;; Single word integer modes.
979 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
981 ;; Single word integer modes without QImode.
982 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
984 ;; Single word integer modes without QImode and HImode.
985 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
987 ;; All math-dependant single and double word integer modes.
988 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
989                              (HI "TARGET_HIMODE_MATH")
990                              SI DI (TI "TARGET_64BIT")])
992 ;; Math-dependant single word integer modes.
993 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
994                             (HI "TARGET_HIMODE_MATH")
995                             SI (DI "TARGET_64BIT")])
997 ;; Math-dependant integer modes without DImode.
998 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
999                                (HI "TARGET_HIMODE_MATH")
1000                                SI])
1002 ;; Math-dependant integer modes with DImode.
1003 (define_mode_iterator SWIM1248x [(QI "TARGET_QIMODE_MATH")
1004                                  (HI "TARGET_HIMODE_MATH")
1005                                  SI (DI "(TARGET_STV && TARGET_SSE2) || TARGET_64BIT")])
1007 ;; Math-dependant single word integer modes without QImode.
1008 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1009                                SI (DI "TARGET_64BIT")])
1011 ;; Double word integer modes.
1012 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1013                            (TI "TARGET_64BIT")])
1015 ;; GET_MODE_SIZE for selected modes.  As GET_MODE_SIZE is not
1016 ;; compile time constant, it is faster to use <MODE_SIZE> than
1017 ;; GET_MODE_SIZE (<MODE>mode).  For XFmode which depends on
1018 ;; command line options just use GET_MODE_SIZE macro.
1019 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
1020                              (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
1021                              (V16QI "16") (V32QI "32") (V64QI "64")
1022                              (V8HI "16") (V16HI "32") (V32HI "64")
1023                              (V4SI "16") (V8SI "32") (V16SI "64")
1024                              (V2DI "16") (V4DI "32") (V8DI "64")
1025                              (V1TI "16") (V2TI "32") (V4TI "64")
1026                              (V2DF "16") (V4DF "32") (V8DF "64")
1027                              (V4SF "16") (V8SF "32") (V16SF "64")])
1029 ;; Double word integer modes as mode attribute.
1030 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1031 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1033 ;; Half mode for double word integer modes.
1034 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1035                             (DI "TARGET_64BIT")])
1037 ;; Bound modes.
1038 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1039                            (BND64 "TARGET_LP64")])
1041 ;; Pointer mode corresponding to bound mode.
1042 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
1044 ;; MPX check types
1045 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
1047 ;; Check name
1048 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
1049                            (UNSPEC_BNDCU "cu")
1050                            (UNSPEC_BNDCN "cn")])
1052 ;; Instruction suffix for integer modes.
1053 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1055 ;; Instruction suffix for masks.
1056 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1058 ;; Pointer size prefix for integer modes (Intel asm dialect)
1059 (define_mode_attr iptrsize [(QI "BYTE")
1060                             (HI "WORD")
1061                             (SI "DWORD")
1062                             (DI "QWORD")])
1064 ;; Register class for integer modes.
1065 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1067 ;; Immediate operand constraint for integer modes.
1068 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1070 ;; General operand constraint for word modes.
1071 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1073 ;; Immediate operand constraint for double integer modes.
1074 (define_mode_attr di [(SI "nF") (DI "e")])
1076 ;; Immediate operand constraint for shifts.
1077 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1079 ;; General operand predicate for integer modes.
1080 (define_mode_attr general_operand
1081         [(QI "general_operand")
1082          (HI "general_operand")
1083          (SI "x86_64_general_operand")
1084          (DI "x86_64_general_operand")
1085          (TI "x86_64_general_operand")])
1087 ;; General sign extend operand predicate for integer modes,
1088 ;; which disallows VOIDmode operands and thus it is suitable
1089 ;; for use inside sign_extend.
1090 (define_mode_attr general_sext_operand
1091         [(QI "sext_operand")
1092          (HI "sext_operand")
1093          (SI "x86_64_sext_operand")
1094          (DI "x86_64_sext_operand")])
1096 ;; General sign/zero extend operand predicate for integer modes.
1097 (define_mode_attr general_szext_operand
1098         [(QI "general_operand")
1099          (HI "general_operand")
1100          (SI "x86_64_szext_general_operand")
1101          (DI "x86_64_szext_general_operand")])
1103 ;; Immediate operand predicate for integer modes.
1104 (define_mode_attr immediate_operand
1105         [(QI "immediate_operand")
1106          (HI "immediate_operand")
1107          (SI "x86_64_immediate_operand")
1108          (DI "x86_64_immediate_operand")])
1110 ;; Nonmemory operand predicate for integer modes.
1111 (define_mode_attr nonmemory_operand
1112         [(QI "nonmemory_operand")
1113          (HI "nonmemory_operand")
1114          (SI "x86_64_nonmemory_operand")
1115          (DI "x86_64_nonmemory_operand")])
1117 ;; Operand predicate for shifts.
1118 (define_mode_attr shift_operand
1119         [(QI "nonimmediate_operand")
1120          (HI "nonimmediate_operand")
1121          (SI "nonimmediate_operand")
1122          (DI "shiftdi_operand")
1123          (TI "register_operand")])
1125 ;; Operand predicate for shift argument.
1126 (define_mode_attr shift_immediate_operand
1127         [(QI "const_1_to_31_operand")
1128          (HI "const_1_to_31_operand")
1129          (SI "const_1_to_31_operand")
1130          (DI "const_1_to_63_operand")])
1132 ;; Input operand predicate for arithmetic left shifts.
1133 (define_mode_attr ashl_input_operand
1134         [(QI "nonimmediate_operand")
1135          (HI "nonimmediate_operand")
1136          (SI "nonimmediate_operand")
1137          (DI "ashldi_input_operand")
1138          (TI "reg_or_pm1_operand")])
1140 ;; SSE and x87 SFmode and DFmode floating point modes
1141 (define_mode_iterator MODEF [SF DF])
1143 ;; All x87 floating point modes
1144 (define_mode_iterator X87MODEF [SF DF XF])
1146 ;; SSE instruction suffix for various modes
1147 (define_mode_attr ssemodesuffix
1148   [(SF "ss") (DF "sd")
1149    (V16SF "ps") (V8DF "pd")
1150    (V8SF "ps") (V4DF "pd")
1151    (V4SF "ps") (V2DF "pd")
1152    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1153    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1154    (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1156 ;; SSE vector suffix for floating point modes
1157 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1159 ;; SSE vector mode corresponding to a scalar mode
1160 (define_mode_attr ssevecmode
1161   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1162 (define_mode_attr ssevecmodelower
1163   [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1165 ;; Instruction suffix for REX 64bit operators.
1166 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1168 ;; This mode iterator allows :P to be used for patterns that operate on
1169 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
1170 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1172 ;; This mode iterator allows :W to be used for patterns that operate on
1173 ;; word_mode sized quantities.
1174 (define_mode_iterator W
1175   [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1177 ;; This mode iterator allows :PTR to be used for patterns that operate on
1178 ;; ptr_mode sized quantities.
1179 (define_mode_iterator PTR
1180   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1182 ;; Scheduling descriptions
1184 (include "pentium.md")
1185 (include "ppro.md")
1186 (include "k6.md")
1187 (include "athlon.md")
1188 (include "bdver1.md")
1189 (include "bdver3.md")
1190 (include "btver2.md")
1191 (include "znver1.md")
1192 (include "geode.md")
1193 (include "atom.md")
1194 (include "slm.md")
1195 (include "core2.md")
1196 (include "haswell.md")
1199 ;; Operand and operator predicates and constraints
1201 (include "predicates.md")
1202 (include "constraints.md")
1205 ;; Compare and branch/compare and store instructions.
1207 (define_expand "cbranch<mode>4"
1208   [(set (reg:CC FLAGS_REG)
1209         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1210                     (match_operand:SDWIM 2 "<general_operand>")))
1211    (set (pc) (if_then_else
1212                (match_operator 0 "ordered_comparison_operator"
1213                 [(reg:CC FLAGS_REG) (const_int 0)])
1214                (label_ref (match_operand 3))
1215                (pc)))]
1216   ""
1218   if (MEM_P (operands[1]) && MEM_P (operands[2]))
1219     operands[1] = force_reg (<MODE>mode, operands[1]);
1220   ix86_expand_branch (GET_CODE (operands[0]),
1221                       operands[1], operands[2], operands[3]);
1222   DONE;
1225 (define_expand "cstore<mode>4"
1226   [(set (reg:CC FLAGS_REG)
1227         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1228                     (match_operand:SWIM 3 "<general_operand>")))
1229    (set (match_operand:QI 0 "register_operand")
1230         (match_operator 1 "ordered_comparison_operator"
1231           [(reg:CC FLAGS_REG) (const_int 0)]))]
1232   ""
1234   if (MEM_P (operands[2]) && MEM_P (operands[3]))
1235     operands[2] = force_reg (<MODE>mode, operands[2]);
1236   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1237                      operands[2], operands[3]);
1238   DONE;
1241 (define_expand "cmp<mode>_1"
1242   [(set (reg:CC FLAGS_REG)
1243         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1244                     (match_operand:SWI48 1 "<general_operand>")))])
1246 (define_insn "*cmp<mode>_ccno_1"
1247   [(set (reg FLAGS_REG)
1248         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1249                  (match_operand:SWI 1 "const0_operand")))]
1250   "ix86_match_ccmode (insn, CCNOmode)"
1251   "@
1252    test{<imodesuffix>}\t%0, %0
1253    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1254   [(set_attr "type" "test,icmp")
1255    (set_attr "length_immediate" "0,1")
1256    (set_attr "modrm_class" "op0,unknown")
1257    (set_attr "mode" "<MODE>")])
1259 (define_insn "*cmp<mode>_1"
1260   [(set (reg FLAGS_REG)
1261         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1262                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1263   "ix86_match_ccmode (insn, CCmode)"
1264   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1265   [(set_attr "type" "icmp")
1266    (set_attr "mode" "<MODE>")])
1268 (define_insn "*cmp<mode>_minus_1"
1269   [(set (reg FLAGS_REG)
1270         (compare
1271           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1272                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1273           (const_int 0)))]
1274   "ix86_match_ccmode (insn, CCGOCmode)"
1275   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1276   [(set_attr "type" "icmp")
1277    (set_attr "mode" "<MODE>")])
1279 (define_insn "*cmpqi_ext_1"
1280   [(set (reg FLAGS_REG)
1281         (compare
1282           (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1283           (subreg:QI
1284             (zero_extract:SI
1285               (match_operand 1 "ext_register_operand" "Q,Q")
1286               (const_int 8)
1287               (const_int 8)) 0)))]
1288   "ix86_match_ccmode (insn, CCmode)"
1289   "cmp{b}\t{%h1, %0|%0, %h1}"
1290   [(set_attr "isa" "*,nox64")
1291    (set_attr "type" "icmp")
1292    (set_attr "mode" "QI")])
1294 (define_insn "*cmpqi_ext_2"
1295   [(set (reg FLAGS_REG)
1296         (compare
1297           (subreg:QI
1298             (zero_extract:SI
1299               (match_operand 0 "ext_register_operand" "Q")
1300               (const_int 8)
1301               (const_int 8)) 0)
1302           (match_operand:QI 1 "const0_operand")))]
1303   "ix86_match_ccmode (insn, CCNOmode)"
1304   "test{b}\t%h0, %h0"
1305   [(set_attr "type" "test")
1306    (set_attr "length_immediate" "0")
1307    (set_attr "mode" "QI")])
1309 (define_expand "cmpqi_ext_3"
1310   [(set (reg:CC FLAGS_REG)
1311         (compare:CC
1312           (subreg:QI
1313             (zero_extract:SI
1314               (match_operand 0 "ext_register_operand")
1315               (const_int 8)
1316               (const_int 8)) 0)
1317           (match_operand:QI 1 "const_int_operand")))])
1319 (define_insn "*cmpqi_ext_3"
1320   [(set (reg FLAGS_REG)
1321         (compare
1322           (subreg:QI
1323             (zero_extract:SI
1324               (match_operand 0 "ext_register_operand" "Q,Q")
1325               (const_int 8)
1326               (const_int 8)) 0)
1327           (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1328   "ix86_match_ccmode (insn, CCmode)"
1329   "cmp{b}\t{%1, %h0|%h0, %1}"
1330   [(set_attr "isa" "*,nox64")
1331    (set_attr "type" "icmp")
1332    (set_attr "modrm" "1")
1333    (set_attr "mode" "QI")])
1335 (define_insn "*cmpqi_ext_4"
1336   [(set (reg FLAGS_REG)
1337         (compare
1338           (subreg:QI
1339             (zero_extract:SI
1340               (match_operand 0 "ext_register_operand" "Q")
1341               (const_int 8)
1342               (const_int 8)) 0)
1343           (subreg:QI
1344             (zero_extract:SI
1345               (match_operand 1 "ext_register_operand" "Q")
1346               (const_int 8)
1347               (const_int 8)) 0)))]
1348   "ix86_match_ccmode (insn, CCmode)"
1349   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1350   [(set_attr "type" "icmp")
1351    (set_attr "mode" "QI")])
1353 ;; These implement float point compares.
1354 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1355 ;; which would allow mix and match FP modes on the compares.  Which is what
1356 ;; the old patterns did, but with many more of them.
1358 (define_expand "cbranchxf4"
1359   [(set (reg:CC FLAGS_REG)
1360         (compare:CC (match_operand:XF 1 "nonmemory_operand")
1361                     (match_operand:XF 2 "nonmemory_operand")))
1362    (set (pc) (if_then_else
1363               (match_operator 0 "ix86_fp_comparison_operator"
1364                [(reg:CC FLAGS_REG)
1365                 (const_int 0)])
1366               (label_ref (match_operand 3))
1367               (pc)))]
1368   "TARGET_80387"
1370   ix86_expand_branch (GET_CODE (operands[0]),
1371                       operands[1], operands[2], operands[3]);
1372   DONE;
1375 (define_expand "cstorexf4"
1376   [(set (reg:CC FLAGS_REG)
1377         (compare:CC (match_operand:XF 2 "nonmemory_operand")
1378                     (match_operand:XF 3 "nonmemory_operand")))
1379    (set (match_operand:QI 0 "register_operand")
1380               (match_operator 1 "ix86_fp_comparison_operator"
1381                [(reg:CC FLAGS_REG)
1382                 (const_int 0)]))]
1383   "TARGET_80387"
1385   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1386                      operands[2], operands[3]);
1387   DONE;
1390 (define_expand "cbranch<mode>4"
1391   [(set (reg:CC FLAGS_REG)
1392         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1393                     (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1394    (set (pc) (if_then_else
1395               (match_operator 0 "ix86_fp_comparison_operator"
1396                [(reg:CC FLAGS_REG)
1397                 (const_int 0)])
1398               (label_ref (match_operand 3))
1399               (pc)))]
1400   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1402   ix86_expand_branch (GET_CODE (operands[0]),
1403                       operands[1], operands[2], operands[3]);
1404   DONE;
1407 (define_expand "cstore<mode>4"
1408   [(set (reg:CC FLAGS_REG)
1409         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1410                     (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1411    (set (match_operand:QI 0 "register_operand")
1412               (match_operator 1 "ix86_fp_comparison_operator"
1413                [(reg:CC FLAGS_REG)
1414                 (const_int 0)]))]
1415   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1417   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1418                      operands[2], operands[3]);
1419   DONE;
1422 (define_expand "cbranchcc4"
1423   [(set (pc) (if_then_else
1424               (match_operator 0 "comparison_operator"
1425                [(match_operand 1 "flags_reg_operand")
1426                 (match_operand 2 "const0_operand")])
1427               (label_ref (match_operand 3))
1428               (pc)))]
1429   ""
1431   ix86_expand_branch (GET_CODE (operands[0]),
1432                       operands[1], operands[2], operands[3]);
1433   DONE;
1436 (define_expand "cstorecc4"
1437   [(set (match_operand:QI 0 "register_operand")
1438               (match_operator 1 "comparison_operator"
1439                [(match_operand 2 "flags_reg_operand")
1440                 (match_operand 3 "const0_operand")]))]
1441   ""
1443   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1444                      operands[2], operands[3]);
1445   DONE;
1449 ;; FP compares, step 1:
1450 ;; Set the FP condition codes.
1452 ;; CCFPmode     compare with exceptions
1453 ;; CCFPUmode    compare with no exceptions
1455 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1456 ;; used to manage the reg stack popping would not be preserved.
1458 (define_insn "*cmp<mode>_0_i387"
1459   [(set (match_operand:HI 0 "register_operand" "=a")
1460         (unspec:HI
1461           [(compare:CCFP
1462              (match_operand:X87MODEF 1 "register_operand" "f")
1463              (match_operand:X87MODEF 2 "const0_operand"))]
1464         UNSPEC_FNSTSW))]
1465   "TARGET_80387"
1466   "* return output_fp_compare (insn, operands, false, false);"
1467   [(set_attr "type" "multi")
1468    (set_attr "unit" "i387")
1469    (set_attr "mode" "<MODE>")])
1471 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1472   [(set (reg:CCFP FLAGS_REG)
1473         (compare:CCFP
1474           (match_operand:X87MODEF 1 "register_operand" "f")
1475           (match_operand:X87MODEF 2 "const0_operand")))
1476    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1477   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1478   "#"
1479   "&& reload_completed"
1480   [(set (match_dup 0)
1481         (unspec:HI
1482           [(compare:CCFP (match_dup 1)(match_dup 2))]
1483         UNSPEC_FNSTSW))
1484    (set (reg:CC FLAGS_REG)
1485         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1486   ""
1487   [(set_attr "type" "multi")
1488    (set_attr "unit" "i387")
1489    (set_attr "mode" "<MODE>")])
1491 (define_insn "*cmpxf_i387"
1492   [(set (match_operand:HI 0 "register_operand" "=a")
1493         (unspec:HI
1494           [(compare:CCFP
1495              (match_operand:XF 1 "register_operand" "f")
1496              (match_operand:XF 2 "register_operand" "f"))]
1497           UNSPEC_FNSTSW))]
1498   "TARGET_80387"
1499   "* return output_fp_compare (insn, operands, false, false);"
1500   [(set_attr "type" "multi")
1501    (set_attr "unit" "i387")
1502    (set_attr "mode" "XF")])
1504 (define_insn_and_split "*cmpxf_cc_i387"
1505   [(set (reg:CCFP FLAGS_REG)
1506         (compare:CCFP
1507           (match_operand:XF 1 "register_operand" "f")
1508           (match_operand:XF 2 "register_operand" "f")))
1509    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1510   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1511   "#"
1512   "&& reload_completed"
1513   [(set (match_dup 0)
1514         (unspec:HI
1515           [(compare:CCFP (match_dup 1)(match_dup 2))]
1516         UNSPEC_FNSTSW))
1517    (set (reg:CC FLAGS_REG)
1518         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1519   ""
1520   [(set_attr "type" "multi")
1521    (set_attr "unit" "i387")
1522    (set_attr "mode" "XF")])
1524 (define_insn "*cmp<mode>_i387"
1525   [(set (match_operand:HI 0 "register_operand" "=a")
1526         (unspec:HI
1527           [(compare:CCFP
1528              (match_operand:MODEF 1 "register_operand" "f")
1529              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1530           UNSPEC_FNSTSW))]
1531   "TARGET_80387"
1532   "* return output_fp_compare (insn, operands, false, false);"
1533   [(set_attr "type" "multi")
1534    (set_attr "unit" "i387")
1535    (set_attr "mode" "<MODE>")])
1537 (define_insn_and_split "*cmp<mode>_cc_i387"
1538   [(set (reg:CCFP FLAGS_REG)
1539         (compare:CCFP
1540           (match_operand:MODEF 1 "register_operand" "f")
1541           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1542    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1543   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1544   "#"
1545   "&& reload_completed"
1546   [(set (match_dup 0)
1547         (unspec:HI
1548           [(compare:CCFP (match_dup 1)(match_dup 2))]
1549         UNSPEC_FNSTSW))
1550    (set (reg:CC FLAGS_REG)
1551         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1552   ""
1553   [(set_attr "type" "multi")
1554    (set_attr "unit" "i387")
1555    (set_attr "mode" "<MODE>")])
1557 (define_insn "*cmpu<mode>_i387"
1558   [(set (match_operand:HI 0 "register_operand" "=a")
1559         (unspec:HI
1560           [(compare:CCFPU
1561              (match_operand:X87MODEF 1 "register_operand" "f")
1562              (match_operand:X87MODEF 2 "register_operand" "f"))]
1563           UNSPEC_FNSTSW))]
1564   "TARGET_80387"
1565   "* return output_fp_compare (insn, operands, false, true);"
1566   [(set_attr "type" "multi")
1567    (set_attr "unit" "i387")
1568    (set_attr "mode" "<MODE>")])
1570 (define_insn_and_split "*cmpu<mode>_cc_i387"
1571   [(set (reg:CCFPU FLAGS_REG)
1572         (compare:CCFPU
1573           (match_operand:X87MODEF 1 "register_operand" "f")
1574           (match_operand:X87MODEF 2 "register_operand" "f")))
1575    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1576   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1577   "#"
1578   "&& reload_completed"
1579   [(set (match_dup 0)
1580         (unspec:HI
1581           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1582         UNSPEC_FNSTSW))
1583    (set (reg:CC FLAGS_REG)
1584         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1585   ""
1586   [(set_attr "type" "multi")
1587    (set_attr "unit" "i387")
1588    (set_attr "mode" "<MODE>")])
1590 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1591   [(set (match_operand:HI 0 "register_operand" "=a")
1592         (unspec:HI
1593           [(compare:CCFP
1594              (match_operand:X87MODEF 1 "register_operand" "f")
1595              (match_operator:X87MODEF 3 "float_operator"
1596                [(match_operand:SWI24 2 "memory_operand" "m")]))]
1597           UNSPEC_FNSTSW))]
1598   "TARGET_80387
1599    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1600        || optimize_function_for_size_p (cfun))"
1601   "* return output_fp_compare (insn, operands, false, false);"
1602   [(set_attr "type" "multi")
1603    (set_attr "unit" "i387")
1604    (set_attr "fp_int_src" "true")
1605    (set_attr "mode" "<SWI24:MODE>")])
1607 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1608   [(set (reg:CCFP FLAGS_REG)
1609         (compare:CCFP
1610           (match_operand:X87MODEF 1 "register_operand" "f")
1611           (match_operator:X87MODEF 3 "float_operator"
1612             [(match_operand:SWI24 2 "memory_operand" "m")])))
1613    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1614   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1615    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1616        || optimize_function_for_size_p (cfun))"
1617   "#"
1618   "&& reload_completed"
1619   [(set (match_dup 0)
1620         (unspec:HI
1621           [(compare:CCFP
1622              (match_dup 1)
1623              (match_op_dup 3 [(match_dup 2)]))]
1624         UNSPEC_FNSTSW))
1625    (set (reg:CC FLAGS_REG)
1626         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1627   ""
1628   [(set_attr "type" "multi")
1629    (set_attr "unit" "i387")
1630    (set_attr "fp_int_src" "true")
1631    (set_attr "mode" "<SWI24:MODE>")])
1633 ;; FP compares, step 2
1634 ;; Move the fpsw to ax.
1636 (define_insn "x86_fnstsw_1"
1637   [(set (match_operand:HI 0 "register_operand" "=a")
1638         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1639   "TARGET_80387"
1640   "fnstsw\t%0"
1641   [(set_attr "length" "2")
1642    (set_attr "mode" "SI")
1643    (set_attr "unit" "i387")])
1645 ;; FP compares, step 3
1646 ;; Get ax into flags, general case.
1648 (define_insn "x86_sahf_1"
1649   [(set (reg:CC FLAGS_REG)
1650         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1651                    UNSPEC_SAHF))]
1652   "TARGET_SAHF"
1654 #ifndef HAVE_AS_IX86_SAHF
1655   if (TARGET_64BIT)
1656     return ASM_BYTE "0x9e";
1657   else
1658 #endif
1659   return "sahf";
1661   [(set_attr "length" "1")
1662    (set_attr "athlon_decode" "vector")
1663    (set_attr "amdfam10_decode" "direct")
1664    (set_attr "bdver1_decode" "direct")
1665    (set_attr "mode" "SI")])
1667 ;; Pentium Pro can do steps 1 through 3 in one go.
1668 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1669 ;; (these i387 instructions set flags directly)
1671 (define_mode_iterator FPCMP [CCFP CCFPU])
1672 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1674 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1675   [(set (reg:FPCMP FLAGS_REG)
1676         (compare:FPCMP
1677           (match_operand:MODEF 0 "register_operand" "f,v")
1678           (match_operand:MODEF 1 "nonimmediate_operand" "f,vm")))]
1679   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
1680   "* return output_fp_compare (insn, operands, true,
1681                                <FPCMP:MODE>mode == CCFPUmode);"
1682   [(set_attr "type" "fcmp,ssecomi")
1683    (set_attr "prefix" "orig,maybe_vex")
1684    (set_attr "mode" "<MODEF:MODE>")
1685    (set_attr "prefix_rep" "*,0")
1686    (set (attr "prefix_data16")
1687         (cond [(eq_attr "alternative" "0")
1688                  (const_string "*")
1689                (eq_attr "mode" "DF")
1690                  (const_string "1")
1691               ]
1692               (const_string "0")))
1693    (set_attr "athlon_decode" "vector")
1694    (set_attr "amdfam10_decode" "direct")
1695    (set_attr "bdver1_decode" "double")
1696    (set_attr "znver1_decode" "double")
1697    (set (attr "enabled")
1698      (cond [(eq_attr "alternative" "0")
1699               (symbol_ref "TARGET_MIX_SSE_I387")
1700            ]
1701            (symbol_ref "true")))])
1703 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1704   [(set (reg:FPCMP FLAGS_REG)
1705         (compare:FPCMP
1706           (match_operand:X87MODEF 0 "register_operand" "f")
1707           (match_operand:X87MODEF 1 "register_operand" "f")))]
1708   "TARGET_80387 && TARGET_CMOVE
1709    && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1710   "* return output_fp_compare (insn, operands, true,
1711                                <FPCMP:MODE>mode == CCFPUmode);"
1712   [(set_attr "type" "fcmp")
1713    (set_attr "mode" "<X87MODEF:MODE>")
1714    (set_attr "athlon_decode" "vector")
1715    (set_attr "amdfam10_decode" "direct")
1716    (set_attr "bdver1_decode" "double")
1717    (set_attr "znver1_decode" "double")])
1719 ;; Push/pop instructions.
1721 (define_insn "*push<mode>2"
1722   [(set (match_operand:DWI 0 "push_operand" "=<")
1723         (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1724   ""
1725   "#"
1726   [(set_attr "type" "multi")
1727    (set_attr "mode" "<MODE>")])
1729 (define_split
1730   [(set (match_operand:TI 0 "push_operand")
1731         (match_operand:TI 1 "general_operand"))]
1732   "TARGET_64BIT && reload_completed
1733    && !SSE_REG_P (operands[1])"
1734   [(const_int 0)]
1735   "ix86_split_long_move (operands); DONE;")
1737 (define_insn "*pushdi2_rex64"
1738   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1739         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1740   "TARGET_64BIT"
1741   "@
1742    push{q}\t%1
1743    #"
1744   [(set_attr "type" "push,multi")
1745    (set_attr "mode" "DI")])
1747 ;; Convert impossible pushes of immediate to existing instructions.
1748 ;; First try to get scratch register and go through it.  In case this
1749 ;; fails, push sign extended lower part first and then overwrite
1750 ;; upper part by 32bit move.
1751 (define_peephole2
1752   [(match_scratch:DI 2 "r")
1753    (set (match_operand:DI 0 "push_operand")
1754         (match_operand:DI 1 "immediate_operand"))]
1755   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1756    && !x86_64_immediate_operand (operands[1], DImode)"
1757   [(set (match_dup 2) (match_dup 1))
1758    (set (match_dup 0) (match_dup 2))])
1760 ;; We need to define this as both peepholer and splitter for case
1761 ;; peephole2 pass is not run.
1762 ;; "&& 1" is needed to keep it from matching the previous pattern.
1763 (define_peephole2
1764   [(set (match_operand:DI 0 "push_operand")
1765         (match_operand:DI 1 "immediate_operand"))]
1766   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1767    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1768   [(set (match_dup 0) (match_dup 1))
1769    (set (match_dup 2) (match_dup 3))]
1771   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1773   operands[1] = gen_lowpart (DImode, operands[2]);
1774   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1775                                                    GEN_INT (4)));
1778 (define_split
1779   [(set (match_operand:DI 0 "push_operand")
1780         (match_operand:DI 1 "immediate_operand"))]
1781   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1782                     ? epilogue_completed : reload_completed)
1783    && !symbolic_operand (operands[1], DImode)
1784    && !x86_64_immediate_operand (operands[1], DImode)"
1785   [(set (match_dup 0) (match_dup 1))
1786    (set (match_dup 2) (match_dup 3))]
1788   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1790   operands[1] = gen_lowpart (DImode, operands[2]);
1791   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1792                                                    GEN_INT (4)));
1795 (define_split
1796   [(set (match_operand:DI 0 "push_operand")
1797         (match_operand:DI 1 "general_operand"))]
1798   "!TARGET_64BIT && reload_completed
1799    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1800   [(const_int 0)]
1801   "ix86_split_long_move (operands); DONE;")
1803 (define_insn "*pushsi2"
1804   [(set (match_operand:SI 0 "push_operand" "=<")
1805         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1806   "!TARGET_64BIT"
1807   "push{l}\t%1"
1808   [(set_attr "type" "push")
1809    (set_attr "mode" "SI")])
1811 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1812 ;; "push a byte/word".  But actually we use pushl, which has the effect
1813 ;; of rounding the amount pushed up to a word.
1815 ;; For TARGET_64BIT we always round up to 8 bytes.
1816 (define_insn "*push<mode>2_rex64"
1817   [(set (match_operand:SWI124 0 "push_operand" "=X")
1818         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1819   "TARGET_64BIT"
1820   "push{q}\t%q1"
1821   [(set_attr "type" "push")
1822    (set_attr "mode" "DI")])
1824 (define_insn "*push<mode>2"
1825   [(set (match_operand:SWI12 0 "push_operand" "=X")
1826         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1827   "!TARGET_64BIT"
1828   "push{l}\t%k1"
1829   [(set_attr "type" "push")
1830    (set_attr "mode" "SI")])
1832 (define_insn "*push<mode>2_prologue"
1833   [(set (match_operand:W 0 "push_operand" "=<")
1834         (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1835    (clobber (mem:BLK (scratch)))]
1836   ""
1837   "push{<imodesuffix>}\t%1"
1838   [(set_attr "type" "push")
1839    (set_attr "mode" "<MODE>")])
1841 (define_insn "*pop<mode>1"
1842   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1843         (match_operand:W 1 "pop_operand" ">"))]
1844   ""
1845   "pop{<imodesuffix>}\t%0"
1846   [(set_attr "type" "pop")
1847    (set_attr "mode" "<MODE>")])
1849 (define_insn "*pop<mode>1_epilogue"
1850   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1851         (match_operand:W 1 "pop_operand" ">"))
1852    (clobber (mem:BLK (scratch)))]
1853   ""
1854   "pop{<imodesuffix>}\t%0"
1855   [(set_attr "type" "pop")
1856    (set_attr "mode" "<MODE>")])
1858 (define_insn "*pushfl<mode>2"
1859   [(set (match_operand:W 0 "push_operand" "=<")
1860         (match_operand:W 1 "flags_reg_operand"))]
1861   ""
1862   "pushf{<imodesuffix>}"
1863   [(set_attr "type" "push")
1864    (set_attr "mode" "<MODE>")])
1866 (define_insn "*popfl<mode>1"
1867   [(set (match_operand:W 0 "flags_reg_operand")
1868         (match_operand:W 1 "pop_operand" ">"))]
1869   ""
1870   "popf{<imodesuffix>}"
1871   [(set_attr "type" "pop")
1872    (set_attr "mode" "<MODE>")])
1875 ;; Reload patterns to support multi-word load/store
1876 ;; with non-offsetable address.
1877 (define_expand "reload_noff_store"
1878   [(parallel [(match_operand 0 "memory_operand" "=m")
1879               (match_operand 1 "register_operand" "r")
1880               (match_operand:DI 2 "register_operand" "=&r")])]
1881   "TARGET_64BIT"
1883   rtx mem = operands[0];
1884   rtx addr = XEXP (mem, 0);
1886   emit_move_insn (operands[2], addr);
1887   mem = replace_equiv_address_nv (mem, operands[2]);
1889   emit_insn (gen_rtx_SET (mem, operands[1]));
1890   DONE;
1893 (define_expand "reload_noff_load"
1894   [(parallel [(match_operand 0 "register_operand" "=r")
1895               (match_operand 1 "memory_operand" "m")
1896               (match_operand:DI 2 "register_operand" "=r")])]
1897   "TARGET_64BIT"
1899   rtx mem = operands[1];
1900   rtx addr = XEXP (mem, 0);
1902   emit_move_insn (operands[2], addr);
1903   mem = replace_equiv_address_nv (mem, operands[2]);
1905   emit_insn (gen_rtx_SET (operands[0], mem));
1906   DONE;
1909 ;; Move instructions.
1911 (define_expand "movxi"
1912   [(set (match_operand:XI 0 "nonimmediate_operand")
1913         (match_operand:XI 1 "general_operand"))]
1914   "TARGET_AVX512F"
1915   "ix86_expand_vector_move (XImode, operands); DONE;")
1917 (define_expand "movoi"
1918   [(set (match_operand:OI 0 "nonimmediate_operand")
1919         (match_operand:OI 1 "general_operand"))]
1920   "TARGET_AVX"
1921   "ix86_expand_vector_move (OImode, operands); DONE;")
1923 (define_expand "movti"
1924   [(set (match_operand:TI 0 "nonimmediate_operand")
1925         (match_operand:TI 1 "general_operand"))]
1926   "TARGET_64BIT || TARGET_SSE"
1928   if (TARGET_64BIT)
1929     ix86_expand_move (TImode, operands);
1930   else
1931     ix86_expand_vector_move (TImode, operands);
1932   DONE;
1935 ;; This expands to what emit_move_complex would generate if we didn't
1936 ;; have a movti pattern.  Having this avoids problems with reload on
1937 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1938 ;; to have around all the time.
1939 (define_expand "movcdi"
1940   [(set (match_operand:CDI 0 "nonimmediate_operand")
1941         (match_operand:CDI 1 "general_operand"))]
1942   ""
1944   if (push_operand (operands[0], CDImode))
1945     emit_move_complex_push (CDImode, operands[0], operands[1]);
1946   else
1947     emit_move_complex_parts (operands[0], operands[1]);
1948   DONE;
1951 (define_expand "mov<mode>"
1952   [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1953         (match_operand:SWI1248x 1 "general_operand"))]
1954   ""
1955   "ix86_expand_move (<MODE>mode, operands); DONE;")
1957 (define_insn "*mov<mode>_xor"
1958   [(set (match_operand:SWI48 0 "register_operand" "=r")
1959         (match_operand:SWI48 1 "const0_operand"))
1960    (clobber (reg:CC FLAGS_REG))]
1961   "reload_completed"
1962   "xor{l}\t%k0, %k0"
1963   [(set_attr "type" "alu1")
1964    (set_attr "modrm_class" "op0")
1965    (set_attr "mode" "SI")
1966    (set_attr "length_immediate" "0")])
1968 (define_insn "*mov<mode>_or"
1969   [(set (match_operand:SWI48 0 "register_operand" "=r")
1970         (match_operand:SWI48 1 "const_int_operand"))
1971    (clobber (reg:CC FLAGS_REG))]
1972   "reload_completed
1973    && operands[1] == constm1_rtx"
1974   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1975   [(set_attr "type" "alu1")
1976    (set_attr "mode" "<MODE>")
1977    (set_attr "length_immediate" "1")])
1979 (define_insn "*movxi_internal_avx512f"
1980   [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,m")
1981         (match_operand:XI 1 "vector_move_operand"  "C ,vm,v"))]
1982   "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1984   switch (which_alternative)
1985     {
1986     case 0:
1987       return standard_sse_constant_opcode (insn, operands[1]);
1988     case 1:
1989     case 2:
1990       if (misaligned_operand (operands[0], XImode)
1991           || misaligned_operand (operands[1], XImode))
1992         return "vmovdqu32\t{%1, %0|%0, %1}";
1993       else
1994         return "vmovdqa32\t{%1, %0|%0, %1}";
1995     default:
1996       gcc_unreachable ();
1997     }
1999   [(set_attr "type" "sselog1,ssemov,ssemov")
2000    (set_attr "prefix" "evex")
2001    (set_attr "mode" "XI")])
2003 (define_insn "*movoi_internal_avx"
2004   [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,m")
2005         (match_operand:OI 1 "vector_move_operand"  "C ,vm,v"))]
2006   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2008   switch (get_attr_type (insn))
2009     {
2010     case TYPE_SSELOG1:
2011       return standard_sse_constant_opcode (insn, operands[1]);
2013     case TYPE_SSEMOV:
2014       if (misaligned_operand (operands[0], OImode)
2015           || misaligned_operand (operands[1], OImode))
2016         {
2017           if (get_attr_mode (insn) == MODE_V8SF)
2018             return "vmovups\t{%1, %0|%0, %1}";
2019           else if (get_attr_mode (insn) == MODE_XI)
2020             return "vmovdqu32\t{%1, %0|%0, %1}";
2021           else
2022             return "vmovdqu\t{%1, %0|%0, %1}";
2023         }
2024       else
2025         {
2026           if (get_attr_mode (insn) == MODE_V8SF)
2027             return "vmovaps\t{%1, %0|%0, %1}";
2028           else if (get_attr_mode (insn) == MODE_XI)
2029             return "vmovdqa32\t{%1, %0|%0, %1}";
2030           else
2031             return "vmovdqa\t{%1, %0|%0, %1}";
2032         }
2034     default:
2035       gcc_unreachable ();
2036     }
2038   [(set_attr "type" "sselog1,ssemov,ssemov")
2039    (set_attr "prefix" "vex")
2040    (set (attr "mode")
2041         (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2042                     (match_operand 1 "ext_sse_reg_operand"))
2043                  (const_string "XI")
2044                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2045                  (const_string "V8SF")
2046                (and (eq_attr "alternative" "2")
2047                     (match_test "TARGET_SSE_TYPELESS_STORES"))
2048                  (const_string "V8SF")
2049               ]
2050               (const_string "OI")))])
2052 (define_insn "*movti_internal"
2053   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,m")
2054         (match_operand:TI 1 "general_operand"      "riFo,re,C,vm,v"))]
2055   "(TARGET_64BIT || TARGET_SSE)
2056    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2058   switch (get_attr_type (insn))
2059     {
2060     case TYPE_MULTI:
2061       return "#";
2063     case TYPE_SSELOG1:
2064       return standard_sse_constant_opcode (insn, operands[1]);
2066     case TYPE_SSEMOV:
2067       /* TDmode values are passed as TImode on the stack.  Moving them
2068          to stack may result in unaligned memory access.  */
2069       if (misaligned_operand (operands[0], TImode)
2070           || misaligned_operand (operands[1], TImode))
2071         {
2072           if (get_attr_mode (insn) == MODE_V4SF)
2073             return "%vmovups\t{%1, %0|%0, %1}";
2074           else if (get_attr_mode (insn) == MODE_XI)
2075             return "vmovdqu32\t{%1, %0|%0, %1}";
2076           else
2077             return "%vmovdqu\t{%1, %0|%0, %1}";
2078         }
2079       else
2080         {
2081           if (get_attr_mode (insn) == MODE_V4SF)
2082             return "%vmovaps\t{%1, %0|%0, %1}";
2083           else if (get_attr_mode (insn) == MODE_XI)
2084             return "vmovdqa32\t{%1, %0|%0, %1}";
2085           else
2086             return "%vmovdqa\t{%1, %0|%0, %1}";
2087         }
2089     default:
2090       gcc_unreachable ();
2091     }
2093   [(set_attr "isa" "x64,x64,*,*,*")
2094    (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
2095    (set (attr "prefix")
2096      (if_then_else (eq_attr "type" "sselog1,ssemov")
2097        (const_string "maybe_vex")
2098        (const_string "orig")))
2099    (set (attr "mode")
2100         (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2101                     (match_operand 1 "ext_sse_reg_operand"))
2102                  (const_string "XI")
2103                (eq_attr "alternative" "0,1")
2104                  (const_string "DI")
2105                (ior (not (match_test "TARGET_SSE2"))
2106                     (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2107                  (const_string "V4SF")
2108                (and (eq_attr "alternative" "4")
2109                     (match_test "TARGET_SSE_TYPELESS_STORES"))
2110                  (const_string "V4SF")
2111                (match_test "TARGET_AVX")
2112                  (const_string "TI")
2113                (match_test "optimize_function_for_size_p (cfun)")
2114                  (const_string "V4SF")
2115                ]
2116                (const_string "TI")))])
2118 (define_split
2119   [(set (match_operand:TI 0 "nonimmediate_operand")
2120         (match_operand:TI 1 "general_operand"))]
2121   "reload_completed
2122    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
2123   [(const_int 0)]
2124   "ix86_split_long_move (operands); DONE;")
2126 (define_insn "*movdi_internal"
2127   [(set (match_operand:DI 0 "nonimmediate_operand"
2128     "=r  ,o  ,r,r  ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,m,?r ,?r,?*Yi,?*Ym,?*Yi,*k,*k ,*r ,*m")
2129         (match_operand:DI 1 "general_operand"
2130     "riFo,riF,Z,rem,i,re,C ,*y,m  ,*y,*Yn,r   ,C ,*v,m ,*v,v,*Yj,*v,r   ,*Yj ,*Yn ,*r ,*km,*k,*k"))]
2131   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2133   switch (get_attr_type (insn))
2134     {
2135     case TYPE_MSKMOV:
2136       return "kmovq\t{%1, %0|%0, %1}";
2138     case TYPE_MULTI:
2139       return "#";
2141     case TYPE_MMX:
2142       return "pxor\t%0, %0";
2144     case TYPE_MMXMOV:
2145       /* Handle broken assemblers that require movd instead of movq.  */
2146       if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2147           && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2148         return "movd\t{%1, %0|%0, %1}";
2149       return "movq\t{%1, %0|%0, %1}";
2151     case TYPE_SSELOG1:
2152       if (GENERAL_REG_P (operands[0]))
2153         return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2155       return standard_sse_constant_opcode (insn, operands[1]);
2157     case TYPE_SSEMOV:
2158       switch (get_attr_mode (insn))
2159         {
2160         case MODE_DI:
2161           /* Handle broken assemblers that require movd instead of movq.  */
2162           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2163               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2164             return "%vmovd\t{%1, %0|%0, %1}";
2165           return "%vmovq\t{%1, %0|%0, %1}";
2166         case MODE_TI:
2167           return "%vmovdqa\t{%1, %0|%0, %1}";
2168         case MODE_XI:
2169           return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2171         case MODE_V2SF:
2172           gcc_assert (!TARGET_AVX);
2173           return "movlps\t{%1, %0|%0, %1}";
2174         case MODE_V4SF:
2175           return "%vmovaps\t{%1, %0|%0, %1}";
2177         default:
2178           gcc_unreachable ();
2179         }
2181     case TYPE_SSECVT:
2182       if (SSE_REG_P (operands[0]))
2183         return "movq2dq\t{%1, %0|%0, %1}";
2184       else
2185         return "movdq2q\t{%1, %0|%0, %1}";
2187     case TYPE_LEA:
2188       return "lea{q}\t{%E1, %0|%0, %E1}";
2190     case TYPE_IMOV:
2191       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2192       if (get_attr_mode (insn) == MODE_SI)
2193         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2194       else if (which_alternative == 4)
2195         return "movabs{q}\t{%1, %0|%0, %1}";
2196       else if (ix86_use_lea_for_mov (insn, operands))
2197         return "lea{q}\t{%E1, %0|%0, %E1}";
2198       else
2199         return "mov{q}\t{%1, %0|%0, %1}";
2201     default:
2202       gcc_unreachable ();
2203     }
2205   [(set (attr "isa")
2206      (cond [(eq_attr "alternative" "0,1")
2207               (const_string "nox64")
2208             (eq_attr "alternative" "2,3,4,5,10,11,17,19,22,24")
2209               (const_string "x64")
2210             (eq_attr "alternative" "18")
2211               (const_string "x64_sse4")
2212            ]
2213            (const_string "*")))
2214    (set (attr "type")
2215      (cond [(eq_attr "alternative" "0,1")
2216               (const_string "multi")
2217             (eq_attr "alternative" "6")
2218               (const_string "mmx")
2219             (eq_attr "alternative" "7,8,9,10,11")
2220               (const_string "mmxmov")
2221             (eq_attr "alternative" "12,18")
2222               (const_string "sselog1")
2223             (eq_attr "alternative" "13,14,15,16,17,19")
2224               (const_string "ssemov")
2225             (eq_attr "alternative" "20,21")
2226               (const_string "ssecvt")
2227             (eq_attr "alternative" "22,23,24,25")
2228               (const_string "mskmov")
2229             (and (match_operand 0 "register_operand")
2230                  (match_operand 1 "pic_32bit_operand"))
2231               (const_string "lea")
2232            ]
2233            (const_string "imov")))
2234    (set (attr "modrm")
2235      (if_then_else
2236        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2237          (const_string "0")
2238          (const_string "*")))
2239    (set (attr "length_immediate")
2240      (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2241               (const_string "8")
2242             (eq_attr "alternative" "18")
2243               (const_string "1")
2244            ]
2245            (const_string "*")))
2246    (set (attr "prefix_rex")
2247      (if_then_else (eq_attr "alternative" "10,11,17,18,19")
2248        (const_string "1")
2249        (const_string "*")))
2250    (set (attr "prefix_extra")
2251      (if_then_else (eq_attr "alternative" "18")
2252        (const_string "1")
2253        (const_string "*")))
2254    (set (attr "prefix")
2255      (if_then_else (eq_attr "type" "sselog1,ssemov")
2256        (const_string "maybe_vex")
2257        (const_string "orig")))
2258    (set (attr "prefix_data16")
2259      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2260        (const_string "1")
2261        (const_string "*")))
2262    (set (attr "mode")
2263      (cond [(eq_attr "alternative" "2")
2264               (const_string "SI")
2265             (eq_attr "alternative" "12,13")
2266               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2267                           (match_operand 1 "ext_sse_reg_operand"))
2268                        (const_string "XI")
2269                      (ior (not (match_test "TARGET_SSE2"))
2270                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2271                        (const_string "V4SF")
2272                      (match_test "TARGET_AVX")
2273                        (const_string "TI")
2274                      (match_test "optimize_function_for_size_p (cfun)")
2275                        (const_string "V4SF")
2276                     ]
2277                     (const_string "TI"))
2279             (and (eq_attr "alternative" "14,15,16")
2280                  (not (match_test "TARGET_SSE2")))
2281               (const_string "V2SF")
2282             (eq_attr "alternative" "18")
2283               (const_string "TI")
2284            ]
2285            (const_string "DI")))
2286    (set (attr "enabled")
2287      (cond [(eq_attr "alternative" "15")
2288               (if_then_else
2289                 (match_test "TARGET_STV && TARGET_SSE2")
2290                 (symbol_ref "false")
2291                 (const_string "*"))
2292             (eq_attr "alternative" "16")
2293               (if_then_else
2294                 (match_test "TARGET_STV && TARGET_SSE2")
2295                 (symbol_ref "true")
2296                 (symbol_ref "false"))
2297            ]
2298            (const_string "*")))])
2300 (define_split
2301   [(set (match_operand:DI 0 "nonimmediate_operand")
2302         (match_operand:DI 1 "general_operand"))]
2303   "!TARGET_64BIT && reload_completed
2304    && !(MMX_REG_P (operands[0])
2305         || SSE_REG_P (operands[0])
2306         || MASK_REG_P (operands[0]))
2307    && !(MMX_REG_P (operands[1])
2308         || SSE_REG_P (operands[1])
2309         || MASK_REG_P (operands[1]))"
2310   [(const_int 0)]
2311   "ix86_split_long_move (operands); DONE;")
2313 (define_insn "*movsi_internal"
2314   [(set (match_operand:SI 0 "nonimmediate_operand"
2315                         "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi,*k  ,*rm")
2316         (match_operand:SI 1 "general_operand"
2317                         "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r   ,*krm,*k"))]
2318   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2320   switch (get_attr_type (insn))
2321     {
2322     case TYPE_SSELOG1:
2323       if (GENERAL_REG_P (operands[0]))
2324         return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2326       return standard_sse_constant_opcode (insn, operands[1]);
2328     case TYPE_MSKMOV:
2329       return "kmovd\t{%1, %0|%0, %1}";
2331     case TYPE_SSEMOV:
2332       switch (get_attr_mode (insn))
2333         {
2334         case MODE_SI:
2335           return "%vmovd\t{%1, %0|%0, %1}";
2336         case MODE_TI:
2337           return "%vmovdqa\t{%1, %0|%0, %1}";
2338         case MODE_XI:
2339           return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2341         case MODE_V4SF:
2342           return "%vmovaps\t{%1, %0|%0, %1}";
2344         case MODE_SF:
2345           gcc_assert (!TARGET_AVX);
2346           return "movss\t{%1, %0|%0, %1}";
2348         default:
2349           gcc_unreachable ();
2350         }
2352     case TYPE_MMX:
2353       return "pxor\t%0, %0";
2355     case TYPE_MMXMOV:
2356       switch (get_attr_mode (insn))
2357         {
2358         case MODE_DI:
2359           return "movq\t{%1, %0|%0, %1}";
2360         case MODE_SI:
2361           return "movd\t{%1, %0|%0, %1}";
2363         default:
2364           gcc_unreachable ();
2365         }
2367     case TYPE_LEA:
2368       return "lea{l}\t{%E1, %0|%0, %E1}";
2370     case TYPE_IMOV:
2371       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2372       if (ix86_use_lea_for_mov (insn, operands))
2373         return "lea{l}\t{%E1, %0|%0, %E1}";
2374       else
2375         return "mov{l}\t{%1, %0|%0, %1}";
2377     default:
2378       gcc_unreachable ();
2379     }
2381   [(set (attr "isa")
2382      (if_then_else (eq_attr "alternative" "11")
2383        (const_string "sse4")
2384        (const_string "*")))
2385    (set (attr "type")
2386      (cond [(eq_attr "alternative" "2")
2387               (const_string "mmx")
2388             (eq_attr "alternative" "3,4,5")
2389               (const_string "mmxmov")
2390             (eq_attr "alternative" "6,11")
2391               (const_string "sselog1")
2392             (eq_attr "alternative" "7,8,9,10,12")
2393               (const_string "ssemov")
2394             (eq_attr "alternative" "13,14")
2395               (const_string "mskmov")
2396             (and (match_operand 0 "register_operand")
2397                  (match_operand 1 "pic_32bit_operand"))
2398               (const_string "lea")
2399            ]
2400            (const_string "imov")))
2401    (set (attr "length_immediate")
2402      (if_then_else (eq_attr "alternative" "11")
2403        (const_string "1")
2404        (const_string "*")))
2405    (set (attr "prefix_extra")
2406      (if_then_else (eq_attr "alternative" "11")
2407        (const_string "1")
2408        (const_string "*")))
2409    (set (attr "prefix")
2410      (if_then_else (eq_attr "type" "sselog1,ssemov")
2411        (const_string "maybe_vex")
2412        (const_string "orig")))
2413    (set (attr "prefix_data16")
2414      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2415        (const_string "1")
2416        (const_string "*")))
2417    (set (attr "mode")
2418      (cond [(eq_attr "alternative" "2,3")
2419               (const_string "DI")
2420             (eq_attr "alternative" "6,7")
2421               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2422                           (match_operand 1 "ext_sse_reg_operand"))
2423                        (const_string "XI")
2424                      (ior (not (match_test "TARGET_SSE2"))
2425                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2426                        (const_string "V4SF")
2427                      (match_test "TARGET_AVX")
2428                        (const_string "TI")
2429                      (match_test "optimize_function_for_size_p (cfun)")
2430                        (const_string "V4SF")
2431                     ]
2432                     (const_string "TI"))
2434             (and (eq_attr "alternative" "8,9")
2435                  (not (match_test "TARGET_SSE2")))
2436               (const_string "SF")
2437             (eq_attr "alternative" "11")
2438               (const_string "TI")
2439            ]
2440            (const_string "SI")))])
2442 (define_insn "kmovw"
2443   [(set (match_operand:HI 0 "nonimmediate_operand" "=k,k")
2444         (unspec:HI
2445           [(match_operand:HI 1 "nonimmediate_operand" "r,km")]
2446           UNSPEC_KMOV))]
2447   "!(MEM_P (operands[0]) && MEM_P (operands[1])) && TARGET_AVX512F"
2448   "@
2449    kmovw\t{%k1, %0|%0, %k1}
2450    kmovw\t{%1, %0|%0, %1}";
2451   [(set_attr "mode" "HI")
2452    (set_attr "type" "mskmov")
2453    (set_attr "prefix" "vex")])
2456 (define_insn "*movhi_internal"
2457   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k, r,m")
2458         (match_operand:HI 1 "general_operand"      "r ,rn,rm,rn,r,km,k,k"))]
2459   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2461   switch (get_attr_type (insn))
2462     {
2463     case TYPE_IMOVX:
2464       /* movzwl is faster than movw on p2 due to partial word stalls,
2465          though not as fast as an aligned movl.  */
2466       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2468     case TYPE_MSKMOV:
2469       switch (which_alternative)
2470         {
2471         case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2472         case 5: /* FALLTHRU */
2473         case 7: return "kmovw\t{%1, %0|%0, %1}";
2474         case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2475         default: gcc_unreachable ();
2476         }
2478     default:
2479       if (get_attr_mode (insn) == MODE_SI)
2480         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2481       else
2482         return "mov{w}\t{%1, %0|%0, %1}";
2483     }
2485   [(set (attr "type")
2486      (cond [(eq_attr "alternative" "4,5,6,7")
2487               (const_string "mskmov")
2488             (match_test "optimize_function_for_size_p (cfun)")
2489               (const_string "imov")
2490             (and (eq_attr "alternative" "0")
2491                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2492                       (not (match_test "TARGET_HIMODE_MATH"))))
2493               (const_string "imov")
2494             (and (eq_attr "alternative" "1,2")
2495                  (match_operand:HI 1 "aligned_operand"))
2496               (const_string "imov")
2497             (and (match_test "TARGET_MOVX")
2498                  (eq_attr "alternative" "0,2"))
2499               (const_string "imovx")
2500            ]
2501            (const_string "imov")))
2502     (set (attr "prefix")
2503       (if_then_else (eq_attr "alternative" "4,5,6,7")
2504         (const_string "vex")
2505         (const_string "orig")))
2506     (set (attr "mode")
2507       (cond [(eq_attr "type" "imovx")
2508                (const_string "SI")
2509              (and (eq_attr "alternative" "1,2")
2510                   (match_operand:HI 1 "aligned_operand"))
2511                (const_string "SI")
2512              (and (eq_attr "alternative" "0")
2513                   (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2514                        (not (match_test "TARGET_HIMODE_MATH"))))
2515                (const_string "SI")
2516             ]
2517             (const_string "HI")))])
2519 ;; Situation is quite tricky about when to choose full sized (SImode) move
2520 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2521 ;; partial register dependency machines (such as AMD Athlon), where QImode
2522 ;; moves issue extra dependency and for partial register stalls machines
2523 ;; that don't use QImode patterns (and QImode move cause stall on the next
2524 ;; instruction).
2526 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2527 ;; register stall machines with, where we use QImode instructions, since
2528 ;; partial register stall can be caused there.  Then we use movzx.
2530 (define_insn "*movqi_internal"
2531   [(set (match_operand:QI 0 "nonimmediate_operand"
2532                         "=q,q ,q ,r,r ,?r,m ,k,k,r ,m,k")
2533         (match_operand:QI 1 "general_operand"
2534                         "q ,qn,qm,q,rn,qm,qn,r ,k,k,k,m"))]
2535   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2537   switch (get_attr_type (insn))
2538     {
2539     case TYPE_IMOVX:
2540       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2541       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2543     case TYPE_MSKMOV:
2544       switch (which_alternative)
2545         {
2546         case 7: return TARGET_AVX512DQ ? "kmovb\t{%k1, %0|%0, %k1}"
2547                                        : "kmovw\t{%k1, %0|%0, %k1}";
2548         case 8: return TARGET_AVX512DQ ? "kmovb\t{%1, %0|%0, %1}"
2549                                        : "kmovw\t{%1, %0|%0, %1}";
2550         case 9: return TARGET_AVX512DQ ? "kmovb\t{%1, %k0|%k0, %1}"
2551                                        : "kmovw\t{%1, %k0|%k0, %1}";
2552         case 10:
2553         case 11:
2554           gcc_assert (TARGET_AVX512DQ);
2555           return "kmovb\t{%1, %0|%0, %1}";
2556         default: gcc_unreachable ();
2557         }
2559     default:
2560       if (get_attr_mode (insn) == MODE_SI)
2561         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2562       else
2563         return "mov{b}\t{%1, %0|%0, %1}";
2564     }
2566   [(set_attr "isa" "*,*,*,*,*,*,*,*,*,*,avx512dq,avx512dq")
2567    (set (attr "type")
2568      (cond [(eq_attr "alternative" "7,8,9,10,11")
2569               (const_string "mskmov")
2570             (and (eq_attr "alternative" "5")
2571                  (not (match_operand:QI 1 "aligned_operand")))
2572               (const_string "imovx")
2573             (match_test "optimize_function_for_size_p (cfun)")
2574               (const_string "imov")
2575             (and (eq_attr "alternative" "3")
2576                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2577                       (not (match_test "TARGET_QIMODE_MATH"))))
2578               (const_string "imov")
2579             (eq_attr "alternative" "3,5")
2580               (const_string "imovx")
2581             (and (match_test "TARGET_MOVX")
2582                  (eq_attr "alternative" "2"))
2583               (const_string "imovx")
2584            ]
2585            (const_string "imov")))
2586    (set (attr "prefix")
2587      (if_then_else (eq_attr "alternative" "7,8,9")
2588        (const_string "vex")
2589        (const_string "orig")))
2590    (set (attr "mode")
2591       (cond [(eq_attr "alternative" "3,4,5")
2592                (const_string "SI")
2593              (eq_attr "alternative" "6")
2594                (const_string "QI")
2595              (eq_attr "type" "imovx")
2596                (const_string "SI")
2597              (and (eq_attr "type" "imov")
2598                   (and (eq_attr "alternative" "0,1")
2599                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2600                             (and (not (match_test "optimize_function_for_size_p (cfun)"))
2601                                  (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2602                (const_string "SI")
2603              ;; Avoid partial register stalls when not using QImode arithmetic
2604              (and (eq_attr "type" "imov")
2605                   (and (eq_attr "alternative" "0,1")
2606                        (and (match_test "TARGET_PARTIAL_REG_STALL")
2607                             (not (match_test "TARGET_QIMODE_MATH")))))
2608                (const_string "SI")
2609            ]
2610            (const_string "QI")))])
2612 ;; Stores and loads of ax to arbitrary constant address.
2613 ;; We fake an second form of instruction to force reload to load address
2614 ;; into register when rax is not available
2615 (define_insn "*movabs<mode>_1"
2616   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2617         (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2618   "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2620   /* Recover the full memory rtx.  */
2621   operands[0] = SET_DEST (PATTERN (insn));
2622   switch (which_alternative)
2623     {
2624     case 0:
2625       return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
2626     case 1:
2627       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2628     default:
2629       gcc_unreachable ();
2630     }
2632   [(set_attr "type" "imov")
2633    (set_attr "modrm" "0,*")
2634    (set_attr "length_address" "8,0")
2635    (set_attr "length_immediate" "0,*")
2636    (set_attr "memory" "store")
2637    (set_attr "mode" "<MODE>")])
2639 (define_insn "*movabs<mode>_2"
2640   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2641         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2642   "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2644   /* Recover the full memory rtx.  */
2645   operands[1] = SET_SRC (PATTERN (insn));
2646   switch (which_alternative)
2647     {
2648     case 0:
2649       return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
2650     case 1:
2651       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2652     default:
2653       gcc_unreachable ();
2654     }
2656   [(set_attr "type" "imov")
2657    (set_attr "modrm" "0,*")
2658    (set_attr "length_address" "8,0")
2659    (set_attr "length_immediate" "0")
2660    (set_attr "memory" "load")
2661    (set_attr "mode" "<MODE>")])
2663 (define_insn "*swap<mode>"
2664   [(set (match_operand:SWI48 0 "register_operand" "+r")
2665         (match_operand:SWI48 1 "register_operand" "+r"))
2666    (set (match_dup 1)
2667         (match_dup 0))]
2668   ""
2669   "xchg{<imodesuffix>}\t%1, %0"
2670   [(set_attr "type" "imov")
2671    (set_attr "mode" "<MODE>")
2672    (set_attr "pent_pair" "np")
2673    (set_attr "athlon_decode" "vector")
2674    (set_attr "amdfam10_decode" "double")
2675    (set_attr "bdver1_decode" "double")])
2677 (define_insn "*swap<mode>_1"
2678   [(set (match_operand:SWI12 0 "register_operand" "+r")
2679         (match_operand:SWI12 1 "register_operand" "+r"))
2680    (set (match_dup 1)
2681         (match_dup 0))]
2682   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2683   "xchg{l}\t%k1, %k0"
2684   [(set_attr "type" "imov")
2685    (set_attr "mode" "SI")
2686    (set_attr "pent_pair" "np")
2687    (set_attr "athlon_decode" "vector")
2688    (set_attr "amdfam10_decode" "double")
2689    (set_attr "bdver1_decode" "double")])
2691 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2692 ;; is disabled for AMDFAM10
2693 (define_insn "*swap<mode>_2"
2694   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2695         (match_operand:SWI12 1 "register_operand" "+<r>"))
2696    (set (match_dup 1)
2697         (match_dup 0))]
2698   "TARGET_PARTIAL_REG_STALL"
2699   "xchg{<imodesuffix>}\t%1, %0"
2700   [(set_attr "type" "imov")
2701    (set_attr "mode" "<MODE>")
2702    (set_attr "pent_pair" "np")
2703    (set_attr "athlon_decode" "vector")])
2705 (define_expand "movstrict<mode>"
2706   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2707         (match_operand:SWI12 1 "general_operand"))]
2708   ""
2710   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2711     FAIL;
2712   if (SUBREG_P (operands[0])
2713       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2714     FAIL;
2715   /* Don't generate memory->memory moves, go through a register */
2716   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2717     operands[1] = force_reg (<MODE>mode, operands[1]);
2720 (define_insn "*movstrict<mode>_1"
2721   [(set (strict_low_part
2722           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2723         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2724   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2725    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2726   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2727   [(set_attr "type" "imov")
2728    (set_attr "mode" "<MODE>")])
2730 (define_insn "*movstrict<mode>_xor"
2731   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2732         (match_operand:SWI12 1 "const0_operand"))
2733    (clobber (reg:CC FLAGS_REG))]
2734   "reload_completed"
2735   "xor{<imodesuffix>}\t%0, %0"
2736   [(set_attr "type" "alu1")
2737    (set_attr "modrm_class" "op0")
2738    (set_attr "mode" "<MODE>")
2739    (set_attr "length_immediate" "0")])
2741 (define_expand "extv<mode>"
2742   [(set (match_operand:SWI24 0 "register_operand")
2743         (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2744                             (match_operand:SI 2 "const_int_operand")
2745                             (match_operand:SI 3 "const_int_operand")))]
2746   ""
2748   /* Handle extractions from %ah et al.  */
2749   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2750     FAIL;
2752   if (! ext_register_operand (operands[1], VOIDmode))
2753     operands[1] = copy_to_reg (operands[1]);
2756 (define_insn "*extv<mode>"
2757   [(set (match_operand:SWI24 0 "register_operand" "=R")
2758         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2759                             (const_int 8)
2760                             (const_int 8)))]
2761   ""
2762   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2763   [(set_attr "type" "imovx")
2764    (set_attr "mode" "SI")])
2766 (define_insn "*extvqi"
2767   [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2768         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2769                          (const_int 8)
2770                          (const_int 8)))]
2771   ""
2773   switch (get_attr_type (insn))
2774     {
2775     case TYPE_IMOVX:
2776       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2777     default:
2778       return "mov{b}\t{%h1, %0|%0, %h1}";
2779     }
2781   [(set_attr "isa" "*,*,nox64")
2782    (set (attr "type")
2783      (if_then_else (and (match_operand:QI 0 "register_operand")
2784                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2785                              (match_test "TARGET_MOVX")))
2786         (const_string "imovx")
2787         (const_string "imov")))
2788    (set (attr "mode")
2789      (if_then_else (eq_attr "type" "imovx")
2790         (const_string "SI")
2791         (const_string "QI")))])
2793 (define_expand "extzv<mode>"
2794   [(set (match_operand:SWI248 0 "register_operand")
2795         (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2796                              (match_operand:SI 2 "const_int_operand")
2797                              (match_operand:SI 3 "const_int_operand")))]
2798   ""
2800   if (ix86_expand_pextr (operands))
2801     DONE;
2803   /* Handle extractions from %ah et al.  */
2804   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2805     FAIL;
2807   if (! ext_register_operand (operands[1], VOIDmode))
2808     operands[1] = copy_to_reg (operands[1]);
2811 (define_insn "*extzv<mode>"
2812   [(set (match_operand:SWI248 0 "register_operand" "=R")
2813         (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
2814                              (const_int 8)
2815                              (const_int 8)))]
2816   ""
2817   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2818   [(set_attr "type" "imovx")
2819    (set_attr "mode" "SI")])
2821 (define_insn "*extzvqi"
2822   [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2823         (subreg:QI
2824           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2825                            (const_int 8)
2826                            (const_int 8)) 0))]
2827   ""
2829   switch (get_attr_type (insn))
2830     {
2831     case TYPE_IMOVX:
2832       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2833     default:
2834       return "mov{b}\t{%h1, %0|%0, %h1}";
2835     }
2837   [(set_attr "isa" "*,*,nox64")
2838    (set (attr "type")
2839      (if_then_else (and (match_operand:QI 0 "register_operand")
2840                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2841                              (match_test "TARGET_MOVX")))
2842         (const_string "imovx")
2843         (const_string "imov")))
2844    (set (attr "mode")
2845      (if_then_else (eq_attr "type" "imovx")
2846         (const_string "SI")
2847         (const_string "QI")))])
2849 (define_expand "insv<mode>"
2850   [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
2851                              (match_operand:SI 1 "const_int_operand")
2852                              (match_operand:SI 2 "const_int_operand"))
2853         (match_operand:SWI248 3 "register_operand"))]
2854   ""
2856   rtx dst;
2858   if (ix86_expand_pinsr (operands))
2859     DONE;
2861   /* Handle insertions to %ah et al.  */
2862   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
2863     FAIL;
2865   dst = operands[0];
2866   
2867   if (!ext_register_operand (dst, VOIDmode))
2868     dst = copy_to_reg (dst);
2870   emit_insn (gen_insv<mode>_1 (dst, operands[3]));
2872   /* Fix up the destination if needed.  */
2873   if (dst != operands[0])
2874     emit_move_insn (operands[0], dst);
2876   DONE;
2879 (define_insn "insv<mode>_1"
2880   [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
2881                              (const_int 8)
2882                              (const_int 8))
2883         (match_operand:SWI248 1 "general_x64nomem_operand" "Qn,m"))]
2884   ""
2886   if (CONST_INT_P (operands[1]))
2887     operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
2888   return "mov{b}\t{%b1, %h0|%h0, %b1}";
2890   [(set_attr "isa" "*,nox64")
2891    (set_attr "type" "imov")
2892    (set_attr "mode" "QI")])
2894 (define_insn "*insvqi"
2895   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2896                          (const_int 8)
2897                          (const_int 8))
2898         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2899                      (const_int 8)))]
2900   ""
2901   "mov{b}\t{%h1, %h0|%h0, %h1}"
2902   [(set_attr "type" "imov")
2903    (set_attr "mode" "QI")])
2905 ;; Floating point push instructions.
2907 (define_insn "*pushtf"
2908   [(set (match_operand:TF 0 "push_operand" "=<,<")
2909         (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2910   "TARGET_64BIT || TARGET_SSE"
2912   /* This insn should be already split before reg-stack.  */
2913   gcc_unreachable ();
2915   [(set_attr "isa" "*,x64")
2916    (set_attr "type" "multi")
2917    (set_attr "unit" "sse,*")
2918    (set_attr "mode" "TF,DI")])
2920 ;; %%% Kill this when call knows how to work this out.
2921 (define_split
2922   [(set (match_operand:TF 0 "push_operand")
2923         (match_operand:TF 1 "sse_reg_operand"))]
2924   "TARGET_SSE && reload_completed"
2925   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2926    (set (match_dup 0) (match_dup 1))]
2928   /* Preserve memory attributes. */
2929   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2932 (define_insn "*pushxf"
2933   [(set (match_operand:XF 0 "push_operand" "=<,<,<,<")
2934         (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF"))]
2935   ""
2937   /* This insn should be already split before reg-stack.  */
2938   gcc_unreachable ();
2940   [(set_attr "type" "multi")
2941    (set_attr "unit" "i387,*,*,*")
2942    (set (attr "mode")
2943         (cond [(eq_attr "alternative" "1,2,3")
2944                  (if_then_else (match_test "TARGET_64BIT")
2945                    (const_string "DI")
2946                    (const_string "SI"))
2947               ]
2948               (const_string "XF")))
2949    (set (attr "preferred_for_size")
2950      (cond [(eq_attr "alternative" "1")
2951               (symbol_ref "false")]
2952            (symbol_ref "true")))])
2954 ;; %%% Kill this when call knows how to work this out.
2955 (define_split
2956   [(set (match_operand:XF 0 "push_operand")
2957         (match_operand:XF 1 "fp_register_operand"))]
2958   "reload_completed"
2959   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2960    (set (match_dup 0) (match_dup 1))]
2962   operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
2963   /* Preserve memory attributes. */
2964   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2967 (define_insn "*pushdf"
2968   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
2969         (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmF,x"))]
2970   ""
2972   /* This insn should be already split before reg-stack.  */
2973   gcc_unreachable ();
2975   [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
2976    (set_attr "type" "multi")
2977    (set_attr "unit" "i387,*,*,*,*,sse")
2978    (set_attr "mode" "DF,SI,SI,SI,DI,DF")
2979    (set (attr "preferred_for_size")
2980      (cond [(eq_attr "alternative" "1")
2981               (symbol_ref "false")]
2982            (symbol_ref "true")))
2983    (set (attr "preferred_for_speed")
2984      (cond [(eq_attr "alternative" "1")
2985               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
2986            (symbol_ref "true")))])
2987    
2988 ;; %%% Kill this when call knows how to work this out.
2989 (define_split
2990   [(set (match_operand:DF 0 "push_operand")
2991         (match_operand:DF 1 "any_fp_register_operand"))]
2992   "reload_completed"
2993   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2994    (set (match_dup 0) (match_dup 1))]
2996   /* Preserve memory attributes. */
2997   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3000 (define_insn "*pushsf_rex64"
3001   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3002         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3003   "TARGET_64BIT"
3005   /* Anything else should be already split before reg-stack.  */
3006   gcc_assert (which_alternative == 1);
3007   return "push{q}\t%q1";
3009   [(set_attr "type" "multi,push,multi")
3010    (set_attr "unit" "i387,*,*")
3011    (set_attr "mode" "SF,DI,SF")])
3013 (define_insn "*pushsf"
3014   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3015         (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
3016   "!TARGET_64BIT"
3018   /* Anything else should be already split before reg-stack.  */
3019   gcc_assert (which_alternative == 1);
3020   return "push{l}\t%1";
3022   [(set_attr "type" "multi,push,multi")
3023    (set_attr "unit" "i387,*,*")
3024    (set_attr "mode" "SF,SI,SF")])
3026 ;; %%% Kill this when call knows how to work this out.
3027 (define_split
3028   [(set (match_operand:SF 0 "push_operand")
3029         (match_operand:SF 1 "any_fp_register_operand"))]
3030   "reload_completed"
3031   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3032    (set (match_dup 0) (match_dup 1))]
3034   rtx op = XEXP (operands[0], 0);
3035   if (GET_CODE (op) == PRE_DEC)
3036     {
3037       gcc_assert (!TARGET_64BIT);
3038       op = GEN_INT (-4);
3039     }
3040   else
3041     {
3042       op = XEXP (XEXP (op, 1), 1);
3043       gcc_assert (CONST_INT_P (op));
3044     }
3045   operands[2] = op;
3046   /* Preserve memory attributes. */
3047   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3050 (define_split
3051   [(set (match_operand:SF 0 "push_operand")
3052         (match_operand:SF 1 "memory_operand"))]
3053   "reload_completed"
3054   [(set (match_dup 0) (match_dup 2))]
3056   operands[2] = find_constant_src (curr_insn);
3058   if (operands[2] == NULL_RTX)
3059     FAIL;
3062 (define_split
3063   [(set (match_operand 0 "push_operand")
3064         (match_operand 1 "general_operand"))]
3065   "reload_completed
3066    && (GET_MODE (operands[0]) == TFmode
3067        || GET_MODE (operands[0]) == XFmode
3068        || GET_MODE (operands[0]) == DFmode)
3069    && !ANY_FP_REG_P (operands[1])"
3070   [(const_int 0)]
3071   "ix86_split_long_move (operands); DONE;")
3073 ;; Floating point move instructions.
3075 (define_expand "movtf"
3076   [(set (match_operand:TF 0 "nonimmediate_operand")
3077         (match_operand:TF 1 "nonimmediate_operand"))]
3078   "TARGET_64BIT || TARGET_SSE"
3079   "ix86_expand_move (TFmode, operands); DONE;")
3081 (define_expand "mov<mode>"
3082   [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3083         (match_operand:X87MODEF 1 "general_operand"))]
3084   ""
3085   "ix86_expand_move (<MODE>mode, operands); DONE;")
3087 (define_insn "*movtf_internal"
3088   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
3089         (match_operand:TF 1 "general_operand"      "C ,xm,x,*roF,*rC"))]
3090   "(TARGET_64BIT || TARGET_SSE)
3091    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3092    && (!can_create_pseudo_p ()
3093        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3094        || !CONST_DOUBLE_P (operands[1])
3095        || (optimize_function_for_size_p (cfun)
3096            && standard_sse_constant_p (operands[1])
3097            && !memory_operand (operands[0], TFmode))
3098        || (!TARGET_MEMORY_MISMATCH_STALL
3099            && memory_operand (operands[0], TFmode)))"
3101   switch (get_attr_type (insn))
3102     {
3103     case TYPE_SSELOG1:
3104       return standard_sse_constant_opcode (insn, operands[1]);
3106     case TYPE_SSEMOV:
3107       /* Handle misaligned load/store since we
3108          don't have movmisaligntf pattern. */
3109       if (misaligned_operand (operands[0], TFmode)
3110           || misaligned_operand (operands[1], TFmode))
3111         {
3112           if (get_attr_mode (insn) == MODE_V4SF)
3113             return "%vmovups\t{%1, %0|%0, %1}";
3114           else
3115             return "%vmovdqu\t{%1, %0|%0, %1}";
3116         }
3117       else
3118         {
3119           if (get_attr_mode (insn) == MODE_V4SF)
3120             return "%vmovaps\t{%1, %0|%0, %1}";
3121           else
3122             return "%vmovdqa\t{%1, %0|%0, %1}";
3123         }
3125     case TYPE_MULTI:
3126         return "#";
3128     default:
3129       gcc_unreachable ();
3130     }
3132   [(set_attr "isa" "*,*,*,x64,x64")
3133    (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3134    (set (attr "prefix")
3135      (if_then_else (eq_attr "type" "sselog1,ssemov")
3136        (const_string "maybe_vex")
3137        (const_string "orig")))
3138    (set (attr "mode")
3139         (cond [(eq_attr "alternative" "3,4")
3140                  (const_string "DI")
3141                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3142                  (const_string "V4SF")
3143                (and (eq_attr "alternative" "2")
3144                     (match_test "TARGET_SSE_TYPELESS_STORES"))
3145                  (const_string "V4SF")
3146                (match_test "TARGET_AVX")
3147                  (const_string "TI")
3148                (ior (not (match_test "TARGET_SSE2"))
3149                     (match_test "optimize_function_for_size_p (cfun)"))
3150                  (const_string "V4SF")
3151                ]
3152                (const_string "TI")))])
3154 (define_split
3155   [(set (match_operand:TF 0 "nonimmediate_operand")
3156         (match_operand:TF 1 "general_operand"))]
3157   "reload_completed
3158    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3159   [(const_int 0)]
3160   "ix86_split_long_move (operands); DONE;")
3162 ;; Possible store forwarding (partial memory) stall
3163 ;; in alternatives 4, 6, 7 and 8.
3164 (define_insn "*movxf_internal"
3165   [(set (match_operand:XF 0 "nonimmediate_operand"
3166          "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r  ,o")
3167         (match_operand:XF 1 "general_operand"
3168          "fm,f,G,roF,r , *roF,*r,F ,C,roF,rF"))]
3169   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3170    && (!can_create_pseudo_p ()
3171        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3172        || !CONST_DOUBLE_P (operands[1])
3173        || (optimize_function_for_size_p (cfun)
3174            && standard_80387_constant_p (operands[1]) > 0
3175            && !memory_operand (operands[0], XFmode))
3176        || (!TARGET_MEMORY_MISMATCH_STALL
3177            && memory_operand (operands[0], XFmode))
3178        || !TARGET_HARD_XF_REGS)"
3180   switch (get_attr_type (insn))
3181     {
3182     case TYPE_FMOV:
3183       if (which_alternative == 2)
3184         return standard_80387_constant_opcode (operands[1]);
3185       return output_387_reg_move (insn, operands);
3187     case TYPE_MULTI:
3188       return "#";
3190     default:
3191       gcc_unreachable ();
3192     }
3194   [(set (attr "isa")
3195         (cond [(eq_attr "alternative" "7")
3196                  (const_string "nox64")
3197                (eq_attr "alternative" "8")
3198                  (const_string "x64")
3199               ]
3200               (const_string "*")))
3201    (set (attr "type")
3202         (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10")
3203                  (const_string "multi")
3204               ]
3205               (const_string "fmov")))
3206    (set (attr "mode")
3207         (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10")
3208                  (if_then_else (match_test "TARGET_64BIT")
3209                    (const_string "DI")
3210                    (const_string "SI"))
3211               ]
3212               (const_string "XF")))
3213    (set (attr "preferred_for_size")
3214      (cond [(eq_attr "alternative" "3,4")
3215               (symbol_ref "false")]
3216            (symbol_ref "true")))
3217    (set (attr "enabled")
3218      (cond [(eq_attr "alternative" "9,10")
3219               (if_then_else
3220                 (match_test "TARGET_HARD_XF_REGS")
3221                 (symbol_ref "false")
3222                 (const_string "*"))
3223             (not (match_test "TARGET_HARD_XF_REGS"))
3224               (symbol_ref "false")
3225            ]
3226            (const_string "*")))])
3227    
3228 (define_split
3229   [(set (match_operand:XF 0 "nonimmediate_operand")
3230         (match_operand:XF 1 "general_operand"))]
3231   "reload_completed
3232    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3233   [(const_int 0)]
3234   "ix86_split_long_move (operands); DONE;")
3236 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3237 (define_insn "*movdf_internal"
3238   [(set (match_operand:DF 0 "nonimmediate_operand"
3239     "=Yf*f,m   ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi,r  ,o ,r  ,m")
3240         (match_operand:DF 1 "general_operand"
3241     "Yf*fm,Yf*f,G   ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r ,roF,rF,rmF,rC"))]
3242   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3243    && (!can_create_pseudo_p ()
3244        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3245        || !CONST_DOUBLE_P (operands[1])
3246        || (optimize_function_for_size_p (cfun)
3247            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3248                 && standard_80387_constant_p (operands[1]) > 0)
3249                || (TARGET_SSE2 && TARGET_SSE_MATH
3250                    && standard_sse_constant_p (operands[1])))
3251            && !memory_operand (operands[0], DFmode))
3252        || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3253            && memory_operand (operands[0], DFmode))
3254        || !TARGET_HARD_DF_REGS)"
3256   switch (get_attr_type (insn))
3257     {
3258     case TYPE_FMOV:
3259       if (which_alternative == 2)
3260         return standard_80387_constant_opcode (operands[1]);
3261       return output_387_reg_move (insn, operands);
3263     case TYPE_MULTI:
3264       return "#";
3266     case TYPE_IMOV:
3267       if (get_attr_mode (insn) == MODE_SI)
3268         return "mov{l}\t{%1, %k0|%k0, %1}";
3269       else if (which_alternative == 11)
3270         return "movabs{q}\t{%1, %0|%0, %1}";
3271       else
3272         return "mov{q}\t{%1, %0|%0, %1}";
3274     case TYPE_SSELOG1:
3275       return standard_sse_constant_opcode (insn, operands[1]);
3277     case TYPE_SSEMOV:
3278       switch (get_attr_mode (insn))
3279         {
3280         case MODE_DF:
3281           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3282             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3283           return "%vmovsd\t{%1, %0|%0, %1}";
3285         case MODE_V4SF:
3286           return "%vmovaps\t{%1, %0|%0, %1}";
3287         case MODE_V8DF:
3288           return "vmovapd\t{%g1, %g0|%g0, %g1}";
3289         case MODE_V2DF:
3290           return "%vmovapd\t{%1, %0|%0, %1}";
3292         case MODE_V2SF:
3293           gcc_assert (!TARGET_AVX);
3294           return "movlps\t{%1, %0|%0, %1}";
3295         case MODE_V1DF:
3296           gcc_assert (!TARGET_AVX);
3297           return "movlpd\t{%1, %0|%0, %1}";
3299         case MODE_DI:
3300           /* Handle broken assemblers that require movd instead of movq.  */
3301           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3302               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3303             return "%vmovd\t{%1, %0|%0, %1}";
3304           return "%vmovq\t{%1, %0|%0, %1}";
3306         default:
3307           gcc_unreachable ();
3308         }
3310     default:
3311       gcc_unreachable ();
3312     }
3314   [(set (attr "isa")
3315         (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3316                  (const_string "nox64")
3317                (eq_attr "alternative" "8,9,10,11,20,21,24,25")
3318                  (const_string "x64")
3319                (eq_attr "alternative" "12,13,14,15")
3320                  (const_string "sse2")
3321               ]
3322               (const_string "*")))
3323    (set (attr "type")
3324         (cond [(eq_attr "alternative" "0,1,2")
3325                  (const_string "fmov")
3326                (eq_attr "alternative" "3,4,5,6,7,22,23")
3327                  (const_string "multi")
3328                (eq_attr "alternative" "8,9,10,11,24,25")
3329                  (const_string "imov")
3330                (eq_attr "alternative" "12,16")
3331                  (const_string "sselog1")
3332               ]
3333               (const_string "ssemov")))
3334    (set (attr "modrm")
3335      (if_then_else (eq_attr "alternative" "11")
3336        (const_string "0")
3337        (const_string "*")))
3338    (set (attr "length_immediate")
3339      (if_then_else (eq_attr "alternative" "11")
3340        (const_string "8")
3341        (const_string "*")))
3342    (set (attr "prefix")
3343      (if_then_else (eq_attr "type" "sselog1,ssemov")
3344        (const_string "maybe_vex")
3345        (const_string "orig")))
3346    (set (attr "prefix_data16")
3347      (if_then_else
3348        (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3349             (eq_attr "mode" "V1DF"))
3350        (const_string "1")
3351        (const_string "*")))
3352    (set (attr "mode")
3353         (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3354                  (const_string "SI")
3355                (eq_attr "alternative" "8,9,11,20,21,24,25")
3356                  (const_string "DI")
3358                /* xorps is one byte shorter for non-AVX targets.  */
3359                (eq_attr "alternative" "12,16")
3360                  (cond [(not (match_test "TARGET_SSE2"))
3361                           (const_string "V4SF")
3362                         (match_test "TARGET_AVX512F")
3363                           (const_string "XI")
3364                         (match_test "TARGET_AVX")
3365                           (const_string "V2DF")
3366                         (match_test "optimize_function_for_size_p (cfun)")
3367                           (const_string "V4SF")
3368                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3369                           (const_string "TI")
3370                        ]
3371                        (const_string "V2DF"))
3373                /* For architectures resolving dependencies on
3374                   whole SSE registers use movapd to break dependency
3375                   chains, otherwise use short move to avoid extra work.  */
3377                /* movaps is one byte shorter for non-AVX targets.  */
3378                (eq_attr "alternative" "13,17")
3379                  (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3380                              (match_operand 1 "ext_sse_reg_operand"))
3381                           (const_string "V8DF")
3382                         (ior (not (match_test "TARGET_SSE2"))
3383                              (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3384                           (const_string "V4SF")
3385                         (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3386                           (const_string "V2DF")
3387                         (match_test "TARGET_AVX")
3388                           (const_string "DF")
3389                         (match_test "optimize_function_for_size_p (cfun)")
3390                           (const_string "V4SF")
3391                        ]
3392                        (const_string "DF"))
3394                /* For architectures resolving dependencies on register
3395                   parts we may avoid extra work to zero out upper part
3396                   of register.  */
3397                (eq_attr "alternative" "14,18")
3398                  (cond [(not (match_test "TARGET_SSE2"))
3399                           (const_string "V2SF")
3400                         (match_test "TARGET_AVX")
3401                           (const_string "DF")
3402                         (match_test "TARGET_SSE_SPLIT_REGS")
3403                           (const_string "V1DF")
3404                        ]
3405                        (const_string "DF"))
3407                (and (eq_attr "alternative" "15,19")
3408                     (not (match_test "TARGET_SSE2")))
3409                  (const_string "V2SF")
3410               ]
3411               (const_string "DF")))
3412    (set (attr "preferred_for_size")
3413      (cond [(eq_attr "alternative" "3,4")
3414               (symbol_ref "false")]
3415            (symbol_ref "true")))
3416    (set (attr "preferred_for_speed")
3417      (cond [(eq_attr "alternative" "3,4")
3418               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3419            (symbol_ref "true")))
3420    (set (attr "enabled")
3421      (cond [(eq_attr "alternative" "22,23,24,25")
3422               (if_then_else
3423                 (match_test "TARGET_HARD_DF_REGS")
3424                 (symbol_ref "false")
3425                 (const_string "*"))
3426             (not (match_test "TARGET_HARD_DF_REGS"))
3427               (symbol_ref "false")
3428            ]
3429            (const_string "*")))])
3431 (define_split
3432   [(set (match_operand:DF 0 "nonimmediate_operand")
3433         (match_operand:DF 1 "general_operand"))]
3434   "!TARGET_64BIT && reload_completed
3435    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3436   [(const_int 0)]
3437   "ix86_split_long_move (operands); DONE;")
3439 (define_insn "*movsf_internal"
3440   [(set (match_operand:SF 0 "nonimmediate_operand"
3441           "=Yf*f,m   ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym,r  ,m")
3442         (match_operand:SF 1 "general_operand"
3443           "Yf*fm,Yf*f,G   ,rmF,rF,C,v,m,v,Yj,r  ,*y ,m  ,*y,*Yn,r   ,rmF,rF"))]
3444   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3445    && (!can_create_pseudo_p ()
3446        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3447        || !CONST_DOUBLE_P (operands[1])
3448        || (optimize_function_for_size_p (cfun)
3449            && ((!TARGET_SSE_MATH
3450                 && standard_80387_constant_p (operands[1]) > 0)
3451                || (TARGET_SSE_MATH
3452                    && standard_sse_constant_p (operands[1]))))
3453        || memory_operand (operands[0], SFmode)
3454        || !TARGET_HARD_SF_REGS)"
3456   switch (get_attr_type (insn))
3457     {
3458     case TYPE_FMOV:
3459       if (which_alternative == 2)
3460         return standard_80387_constant_opcode (operands[1]);
3461       return output_387_reg_move (insn, operands);
3463     case TYPE_IMOV:
3464       return "mov{l}\t{%1, %0|%0, %1}";
3466     case TYPE_SSELOG1:
3467       return standard_sse_constant_opcode (insn, operands[1]);
3469     case TYPE_SSEMOV:
3470       switch (get_attr_mode (insn))
3471         {
3472         case MODE_SF:
3473           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3474             return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3475           return "%vmovss\t{%1, %0|%0, %1}";
3477         case MODE_V16SF:
3478           return "vmovaps\t{%g1, %g0|%g0, %g1}";
3479         case MODE_V4SF:
3480           return "%vmovaps\t{%1, %0|%0, %1}";
3482         case MODE_SI:
3483           return "%vmovd\t{%1, %0|%0, %1}";
3485         default:
3486           gcc_unreachable ();
3487         }
3489     case TYPE_MMXMOV:
3490       switch (get_attr_mode (insn))
3491         {
3492         case MODE_DI:
3493           return "movq\t{%1, %0|%0, %1}";
3494         case MODE_SI:
3495           return "movd\t{%1, %0|%0, %1}";
3497         default:
3498           gcc_unreachable ();
3499         }
3501     default:
3502       gcc_unreachable ();
3503     }
3505   [(set (attr "type")
3506         (cond [(eq_attr "alternative" "0,1,2")
3507                  (const_string "fmov")
3508                (eq_attr "alternative" "3,4,16,17")
3509                  (const_string "imov")
3510                (eq_attr "alternative" "5")
3511                  (const_string "sselog1")
3512                (eq_attr "alternative" "11,12,13,14,15")
3513                  (const_string "mmxmov")
3514               ]
3515               (const_string "ssemov")))
3516    (set (attr "prefix")
3517      (if_then_else (eq_attr "type" "sselog1,ssemov")
3518        (const_string "maybe_vex")
3519        (const_string "orig")))
3520    (set (attr "prefix_data16")
3521      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3522        (const_string "1")
3523        (const_string "*")))
3524    (set (attr "mode")
3525         (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3526                  (const_string "SI")
3527                (eq_attr "alternative" "11")
3528                  (const_string "DI")
3529                (eq_attr "alternative" "5")
3530                  (cond [(not (match_test "TARGET_SSE2"))
3531                           (const_string "V4SF")
3532                         (match_test "TARGET_AVX512F")
3533                           (const_string "V16SF")
3534                         (match_test "TARGET_AVX")
3535                           (const_string "V4SF")
3536                         (match_test "optimize_function_for_size_p (cfun)")
3537                           (const_string "V4SF")
3538                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3539                           (const_string "TI")
3540                        ]
3541                        (const_string "V4SF"))
3543                /* For architectures resolving dependencies on
3544                   whole SSE registers use APS move to break dependency
3545                   chains, otherwise use short move to avoid extra work.
3547                   Do the same for architectures resolving dependencies on
3548                   the parts.  While in DF mode it is better to always handle
3549                   just register parts, the SF mode is different due to lack
3550                   of instructions to load just part of the register.  It is
3551                   better to maintain the whole registers in single format
3552                   to avoid problems on using packed logical operations.  */
3553                (eq_attr "alternative" "6")
3554                  (cond [(ior  (match_operand 0 "ext_sse_reg_operand")
3555                               (match_operand 1 "ext_sse_reg_operand"))
3556                           (const_string "V16SF")
3557                         (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3558                              (match_test "TARGET_SSE_SPLIT_REGS"))
3559                           (const_string "V4SF")
3560                        ]
3561                        (const_string "SF"))
3562               ]
3563               (const_string "SF")))
3564    (set (attr "enabled")
3565      (cond [(eq_attr "alternative" "16,17")
3566               (if_then_else
3567                 (match_test "TARGET_HARD_SF_REGS")
3568                 (symbol_ref "false")
3569                 (const_string "*"))
3570             (not (match_test "TARGET_HARD_SF_REGS"))
3571               (symbol_ref "false")
3572            ]
3573            (const_string "*")))])
3575 (define_split
3576   [(set (match_operand 0 "any_fp_register_operand")
3577         (match_operand 1 "memory_operand"))]
3578   "reload_completed
3579    && (GET_MODE (operands[0]) == TFmode
3580        || GET_MODE (operands[0]) == XFmode
3581        || GET_MODE (operands[0]) == DFmode
3582        || GET_MODE (operands[0]) == SFmode)"
3583   [(set (match_dup 0) (match_dup 2))]
3585   operands[2] = find_constant_src (curr_insn);
3587   if (operands[2] == NULL_RTX
3588       || (SSE_REGNO_P (REGNO (operands[0]))
3589           && !standard_sse_constant_p (operands[2]))
3590       || (STACK_REGNO_P (REGNO (operands[0]))
3591            && standard_80387_constant_p (operands[2]) < 1))
3592     FAIL;
3595 (define_split
3596   [(set (match_operand 0 "any_fp_register_operand")
3597         (float_extend (match_operand 1 "memory_operand")))]
3598   "reload_completed
3599    && (GET_MODE (operands[0]) == TFmode
3600        || GET_MODE (operands[0]) == XFmode
3601        || GET_MODE (operands[0]) == DFmode)"
3602   [(set (match_dup 0) (match_dup 2))]
3604   operands[2] = find_constant_src (curr_insn);
3606   if (operands[2] == NULL_RTX
3607       || (SSE_REGNO_P (REGNO (operands[0]))
3608           && !standard_sse_constant_p (operands[2]))
3609       || (STACK_REGNO_P (REGNO (operands[0]))
3610            && standard_80387_constant_p (operands[2]) < 1))
3611     FAIL;
3614 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3615 (define_split
3616   [(set (match_operand:X87MODEF 0 "fp_register_operand")
3617         (match_operand:X87MODEF 1 "immediate_operand"))]
3618   "reload_completed
3619    && (standard_80387_constant_p (operands[1]) == 8
3620        || standard_80387_constant_p (operands[1]) == 9)"
3621   [(set (match_dup 0)(match_dup 1))
3622    (set (match_dup 0)
3623         (neg:X87MODEF (match_dup 0)))]
3625   if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3626     operands[1] = CONST0_RTX (<MODE>mode);
3627   else
3628     operands[1] = CONST1_RTX (<MODE>mode);
3631 (define_insn "swapxf"
3632   [(set (match_operand:XF 0 "register_operand" "+f")
3633         (match_operand:XF 1 "register_operand" "+f"))
3634    (set (match_dup 1)
3635         (match_dup 0))]
3636   "TARGET_80387"
3638   if (STACK_TOP_P (operands[0]))
3639     return "fxch\t%1";
3640   else
3641     return "fxch\t%0";
3643   [(set_attr "type" "fxch")
3644    (set_attr "mode" "XF")])
3646 (define_insn "*swap<mode>"
3647   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3648         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3649    (set (match_dup 1)
3650         (match_dup 0))]
3651   "TARGET_80387 || reload_completed"
3653   if (STACK_TOP_P (operands[0]))
3654     return "fxch\t%1";
3655   else
3656     return "fxch\t%0";
3658   [(set_attr "type" "fxch")
3659    (set_attr "mode" "<MODE>")])
3661 ;; Zero extension instructions
3663 (define_expand "zero_extendsidi2"
3664   [(set (match_operand:DI 0 "nonimmediate_operand")
3665         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3667 (define_insn "*zero_extendsidi2"
3668   [(set (match_operand:DI 0 "nonimmediate_operand"
3669                         "=r,?r,?o,r   ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3670         (zero_extend:DI
3671          (match_operand:SI 1 "x86_64_zext_operand"
3672                         "0 ,rm,r ,rmWz,0,r   ,m   ,*Yj,*x,r   ,m")))]
3673   ""
3675   switch (get_attr_type (insn))
3676     {
3677     case TYPE_IMOVX:
3678       if (ix86_use_lea_for_mov (insn, operands))
3679         return "lea{l}\t{%E1, %k0|%k0, %E1}";
3680       else
3681         return "mov{l}\t{%1, %k0|%k0, %1}";
3683     case TYPE_MULTI:
3684       return "#";
3686     case TYPE_MMXMOV:
3687       return "movd\t{%1, %0|%0, %1}";
3689     case TYPE_SSELOG1:
3690       return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3692     case TYPE_SSEMOV:
3693       if (GENERAL_REG_P (operands[0]))
3694         return "%vmovd\t{%1, %k0|%k0, %1}";
3696       return "%vmovd\t{%1, %0|%0, %1}";
3698     default:
3699       gcc_unreachable ();
3700     }
3702   [(set (attr "isa")
3703      (cond [(eq_attr "alternative" "0,1,2")
3704               (const_string "nox64")
3705             (eq_attr "alternative" "3,7")
3706               (const_string "x64")
3707             (eq_attr "alternative" "8")
3708               (const_string "x64_sse4")
3709             (eq_attr "alternative" "10")
3710               (const_string "sse2")
3711            ]
3712            (const_string "*")))
3713    (set (attr "type")
3714      (cond [(eq_attr "alternative" "0,1,2,4")
3715               (const_string "multi")
3716             (eq_attr "alternative" "5,6")
3717               (const_string "mmxmov")
3718             (eq_attr "alternative" "7,9,10")
3719               (const_string "ssemov")
3720             (eq_attr "alternative" "8")
3721               (const_string "sselog1")
3722            ]
3723            (const_string "imovx")))
3724    (set (attr "prefix_extra")
3725      (if_then_else (eq_attr "alternative" "8")
3726        (const_string "1")
3727        (const_string "*")))
3728    (set (attr "length_immediate")
3729      (if_then_else (eq_attr "alternative" "8")
3730        (const_string "1")
3731        (const_string "*")))
3732    (set (attr "prefix")
3733      (if_then_else (eq_attr "type" "ssemov,sselog1")
3734        (const_string "maybe_vex")
3735        (const_string "orig")))
3736    (set (attr "prefix_0f")
3737      (if_then_else (eq_attr "type" "imovx")
3738        (const_string "0")
3739        (const_string "*")))
3740    (set (attr "mode")
3741      (cond [(eq_attr "alternative" "5,6")
3742               (const_string "DI")
3743             (eq_attr "alternative" "7,8,9")
3744               (const_string "TI")
3745            ]
3746            (const_string "SI")))])
3748 (define_split
3749   [(set (match_operand:DI 0 "memory_operand")
3750         (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3751   "reload_completed"
3752   [(set (match_dup 4) (const_int 0))]
3753   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3755 (define_split
3756   [(set (match_operand:DI 0 "register_operand")
3757         (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3758   "!TARGET_64BIT && reload_completed
3759    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3760    && true_regnum (operands[0]) == true_regnum (operands[1])"
3761   [(set (match_dup 4) (const_int 0))]
3762   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3764 (define_split
3765   [(set (match_operand:DI 0 "nonimmediate_operand")
3766         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3767   "!TARGET_64BIT && reload_completed
3768    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3769    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3770   [(set (match_dup 3) (match_dup 1))
3771    (set (match_dup 4) (const_int 0))]
3772   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3774 (define_insn "zero_extend<mode>di2"
3775   [(set (match_operand:DI 0 "register_operand" "=r")
3776         (zero_extend:DI
3777          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3778   "TARGET_64BIT"
3779   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3780   [(set_attr "type" "imovx")
3781    (set_attr "mode" "SI")])
3783 (define_expand "zero_extend<mode>si2"
3784   [(set (match_operand:SI 0 "register_operand")
3785         (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3786   ""
3788   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3789     {
3790       operands[1] = force_reg (<MODE>mode, operands[1]);
3791       emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3792       DONE;
3793     }
3796 (define_insn_and_split "zero_extend<mode>si2_and"
3797   [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3798         (zero_extend:SI
3799           (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3800    (clobber (reg:CC FLAGS_REG))]
3801   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3802   "#"
3803   "&& reload_completed"
3804   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3805               (clobber (reg:CC FLAGS_REG))])]
3807   if (true_regnum (operands[0]) != true_regnum (operands[1]))
3808     {
3809       ix86_expand_clear (operands[0]);
3811       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3812       emit_insn (gen_movstrict<mode>
3813                   (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3814       DONE;
3815     }
3817   operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3819   [(set_attr "type" "alu1")
3820    (set_attr "mode" "SI")])
3822 (define_insn "*zero_extend<mode>si2"
3823   [(set (match_operand:SI 0 "register_operand" "=r")
3824         (zero_extend:SI
3825           (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3826   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3827   "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3828   [(set_attr "type" "imovx")
3829    (set_attr "mode" "SI")])
3831 (define_expand "zero_extendqihi2"
3832   [(set (match_operand:HI 0 "register_operand")
3833         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3834   ""
3836   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3837     {
3838       operands[1] = force_reg (QImode, operands[1]);
3839       emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3840       DONE;
3841     }
3844 (define_insn_and_split "zero_extendqihi2_and"
3845   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3846         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3847    (clobber (reg:CC FLAGS_REG))]
3848   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3849   "#"
3850   "&& reload_completed"
3851   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3852               (clobber (reg:CC FLAGS_REG))])]
3854   if (true_regnum (operands[0]) != true_regnum (operands[1]))
3855     {
3856       ix86_expand_clear (operands[0]);
3858       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3859       emit_insn (gen_movstrictqi
3860                   (gen_lowpart (QImode, operands[0]), operands[1]));
3861       DONE;
3862     }
3864   operands[0] = gen_lowpart (SImode, operands[0]);
3866   [(set_attr "type" "alu1")
3867    (set_attr "mode" "SI")])
3869 ; zero extend to SImode to avoid partial register stalls
3870 (define_insn "*zero_extendqihi2"
3871   [(set (match_operand:HI 0 "register_operand" "=r")
3872         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3873   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3874   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3875   [(set_attr "type" "imovx")
3876    (set_attr "mode" "SI")])
3878 (define_insn_and_split "*zext<mode>_doubleword_and"
3879   [(set (match_operand:DI 0 "register_operand" "=&<r>")
3880         (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3881   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
3882    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3883   "#"
3884   "&& reload_completed && GENERAL_REG_P (operands[0])"
3885   [(set (match_dup 2) (const_int 0))]
3887   split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);
3889   emit_move_insn (operands[0], const0_rtx);
3891   gcc_assert (!TARGET_PARTIAL_REG_STALL);
3892   emit_insn (gen_movstrict<mode>
3893              (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3896 (define_insn_and_split "*zext<mode>_doubleword"
3897   [(set (match_operand:DI 0 "register_operand" "=r")
3898         (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3899   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
3900    && !(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3901   "#"
3902   "&& reload_completed && GENERAL_REG_P (operands[0])"
3903   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
3904    (set (match_dup 2) (const_int 0))]
3905   "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
3907 (define_insn_and_split "*zextsi_doubleword"
3908   [(set (match_operand:DI 0 "register_operand" "=r")
3909         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3910   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
3911   "#"
3912   "&& reload_completed && GENERAL_REG_P (operands[0])"
3913   [(set (match_dup 0) (match_dup 1))
3914    (set (match_dup 2) (const_int 0))]
3915   "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
3917 ;; Sign extension instructions
3919 (define_expand "extendsidi2"
3920   [(set (match_operand:DI 0 "register_operand")
3921         (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3922   ""
3924   if (!TARGET_64BIT)
3925     {
3926       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3927       DONE;
3928     }
3931 (define_insn "*extendsidi2_rex64"
3932   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3933         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3934   "TARGET_64BIT"
3935   "@
3936    {cltq|cdqe}
3937    movs{lq|x}\t{%1, %0|%0, %1}"
3938   [(set_attr "type" "imovx")
3939    (set_attr "mode" "DI")
3940    (set_attr "prefix_0f" "0")
3941    (set_attr "modrm" "0,1")])
3943 (define_insn "extendsidi2_1"
3944   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3945         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3946    (clobber (reg:CC FLAGS_REG))
3947    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3948   "!TARGET_64BIT"
3949   "#")
3951 ;; Split the memory case.  If the source register doesn't die, it will stay
3952 ;; this way, if it does die, following peephole2s take care of it.
3953 (define_split
3954   [(set (match_operand:DI 0 "memory_operand")
3955         (sign_extend:DI (match_operand:SI 1 "register_operand")))
3956    (clobber (reg:CC FLAGS_REG))
3957    (clobber (match_operand:SI 2 "register_operand"))]
3958   "reload_completed"
3959   [(const_int 0)]
3961   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3963   emit_move_insn (operands[3], operands[1]);
3965   /* Generate a cltd if possible and doing so it profitable.  */
3966   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3967       && true_regnum (operands[1]) == AX_REG
3968       && true_regnum (operands[2]) == DX_REG)
3969     {
3970       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3971     }
3972   else
3973     {
3974       emit_move_insn (operands[2], operands[1]);
3975       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3976     }
3977   emit_move_insn (operands[4], operands[2]);
3978   DONE;
3981 ;; Peepholes for the case where the source register does die, after
3982 ;; being split with the above splitter.
3983 (define_peephole2
3984   [(set (match_operand:SI 0 "memory_operand")
3985         (match_operand:SI 1 "register_operand"))
3986    (set (match_operand:SI 2 "register_operand") (match_dup 1))
3987    (parallel [(set (match_dup 2)
3988                    (ashiftrt:SI (match_dup 2) (const_int 31)))
3989                (clobber (reg:CC FLAGS_REG))])
3990    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3991   "REGNO (operands[1]) != REGNO (operands[2])
3992    && peep2_reg_dead_p (2, operands[1])
3993    && peep2_reg_dead_p (4, operands[2])
3994    && !reg_mentioned_p (operands[2], operands[3])"
3995   [(set (match_dup 0) (match_dup 1))
3996    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3997               (clobber (reg:CC FLAGS_REG))])
3998    (set (match_dup 3) (match_dup 1))])
4000 (define_peephole2
4001   [(set (match_operand:SI 0 "memory_operand")
4002         (match_operand:SI 1 "register_operand"))
4003    (parallel [(set (match_operand:SI 2 "register_operand")
4004                    (ashiftrt:SI (match_dup 1) (const_int 31)))
4005                (clobber (reg:CC FLAGS_REG))])
4006    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4007   "/* cltd is shorter than sarl $31, %eax */
4008    !optimize_function_for_size_p (cfun)
4009    && true_regnum (operands[1]) == AX_REG
4010    && true_regnum (operands[2]) == DX_REG
4011    && peep2_reg_dead_p (2, operands[1])
4012    && peep2_reg_dead_p (3, operands[2])
4013    && !reg_mentioned_p (operands[2], operands[3])"
4014   [(set (match_dup 0) (match_dup 1))
4015    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4016               (clobber (reg:CC FLAGS_REG))])
4017    (set (match_dup 3) (match_dup 1))])
4019 ;; Extend to register case.  Optimize case where source and destination
4020 ;; registers match and cases where we can use cltd.
4021 (define_split
4022   [(set (match_operand:DI 0 "register_operand")
4023         (sign_extend:DI (match_operand:SI 1 "register_operand")))
4024    (clobber (reg:CC FLAGS_REG))
4025    (clobber (match_scratch:SI 2))]
4026   "reload_completed"
4027   [(const_int 0)]
4029   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4031   if (true_regnum (operands[3]) != true_regnum (operands[1]))
4032     emit_move_insn (operands[3], operands[1]);
4034   /* Generate a cltd if possible and doing so it profitable.  */
4035   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4036       && true_regnum (operands[3]) == AX_REG
4037       && true_regnum (operands[4]) == DX_REG)
4038     {
4039       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4040       DONE;
4041     }
4043   if (true_regnum (operands[4]) != true_regnum (operands[1]))
4044     emit_move_insn (operands[4], operands[1]);
4046   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4047   DONE;
4050 (define_insn "extend<mode>di2"
4051   [(set (match_operand:DI 0 "register_operand" "=r")
4052         (sign_extend:DI
4053          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4054   "TARGET_64BIT"
4055   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4056   [(set_attr "type" "imovx")
4057    (set_attr "mode" "DI")])
4059 (define_insn "extendhisi2"
4060   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4061         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4062   ""
4064   switch (get_attr_prefix_0f (insn))
4065     {
4066     case 0:
4067       return "{cwtl|cwde}";
4068     default:
4069       return "movs{wl|x}\t{%1, %0|%0, %1}";
4070     }
4072   [(set_attr "type" "imovx")
4073    (set_attr "mode" "SI")
4074    (set (attr "prefix_0f")
4075      ;; movsx is short decodable while cwtl is vector decoded.
4076      (if_then_else (and (eq_attr "cpu" "!k6")
4077                         (eq_attr "alternative" "0"))
4078         (const_string "0")
4079         (const_string "1")))
4080    (set (attr "znver1_decode")
4081      (if_then_else (eq_attr "prefix_0f" "0")
4082         (const_string "double")
4083         (const_string "direct")))
4084    (set (attr "modrm")
4085      (if_then_else (eq_attr "prefix_0f" "0")
4086         (const_string "0")
4087         (const_string "1")))])
4089 (define_insn "*extendhisi2_zext"
4090   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4091         (zero_extend:DI
4092          (sign_extend:SI
4093           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4094   "TARGET_64BIT"
4096   switch (get_attr_prefix_0f (insn))
4097     {
4098     case 0:
4099       return "{cwtl|cwde}";
4100     default:
4101       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4102     }
4104   [(set_attr "type" "imovx")
4105    (set_attr "mode" "SI")
4106    (set (attr "prefix_0f")
4107      ;; movsx is short decodable while cwtl is vector decoded.
4108      (if_then_else (and (eq_attr "cpu" "!k6")
4109                         (eq_attr "alternative" "0"))
4110         (const_string "0")
4111         (const_string "1")))
4112    (set (attr "modrm")
4113      (if_then_else (eq_attr "prefix_0f" "0")
4114         (const_string "0")
4115         (const_string "1")))])
4117 (define_insn "extendqisi2"
4118   [(set (match_operand:SI 0 "register_operand" "=r")
4119         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4120   ""
4121   "movs{bl|x}\t{%1, %0|%0, %1}"
4122    [(set_attr "type" "imovx")
4123     (set_attr "mode" "SI")])
4125 (define_insn "*extendqisi2_zext"
4126   [(set (match_operand:DI 0 "register_operand" "=r")
4127         (zero_extend:DI
4128           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4129   "TARGET_64BIT"
4130   "movs{bl|x}\t{%1, %k0|%k0, %1}"
4131    [(set_attr "type" "imovx")
4132     (set_attr "mode" "SI")])
4134 (define_insn "extendqihi2"
4135   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4136         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4137   ""
4139   switch (get_attr_prefix_0f (insn))
4140     {
4141     case 0:
4142       return "{cbtw|cbw}";
4143     default:
4144       return "movs{bw|x}\t{%1, %0|%0, %1}";
4145     }
4147   [(set_attr "type" "imovx")
4148    (set_attr "mode" "HI")
4149    (set (attr "prefix_0f")
4150      ;; movsx is short decodable while cwtl is vector decoded.
4151      (if_then_else (and (eq_attr "cpu" "!k6")
4152                         (eq_attr "alternative" "0"))
4153         (const_string "0")
4154         (const_string "1")))
4155    (set (attr "modrm")
4156      (if_then_else (eq_attr "prefix_0f" "0")
4157         (const_string "0")
4158         (const_string "1")))])
4160 ;; Conversions between float and double.
4162 ;; These are all no-ops in the model used for the 80387.
4163 ;; So just emit moves.
4165 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4166 (define_split
4167   [(set (match_operand:DF 0 "push_operand")
4168         (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4169   "reload_completed"
4170   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4171    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4173 (define_split
4174   [(set (match_operand:XF 0 "push_operand")
4175         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4176   "reload_completed"
4177   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4178    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4179   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4181 (define_expand "extendsfdf2"
4182   [(set (match_operand:DF 0 "nonimmediate_operand")
4183         (float_extend:DF (match_operand:SF 1 "general_operand")))]
4184   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4186   /* ??? Needed for compress_float_constant since all fp constants
4187      are TARGET_LEGITIMATE_CONSTANT_P.  */
4188   if (CONST_DOUBLE_P (operands[1]))
4189     {
4190       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4191           && standard_80387_constant_p (operands[1]) > 0)
4192         {
4193           operands[1] = simplify_const_unary_operation
4194             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4195           emit_move_insn_1 (operands[0], operands[1]);
4196           DONE;
4197         }
4198       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4199     }
4202 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4203    cvtss2sd:
4204       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4205       cvtps2pd xmm2,xmm1
4206    We do the conversion post reload to avoid producing of 128bit spills
4207    that might lead to ICE on 32bit target.  The sequence unlikely combine
4208    anyway.  */
4209 (define_split
4210   [(set (match_operand:DF 0 "register_operand")
4211         (float_extend:DF
4212           (match_operand:SF 1 "nonimmediate_operand")))]
4213   "TARGET_USE_VECTOR_FP_CONVERTS
4214    && optimize_insn_for_speed_p ()
4215    && reload_completed && SSE_REG_P (operands[0])
4216    && (!EXT_REX_SSE_REG_P (operands[0])
4217        || TARGET_AVX512VL)"
4218    [(set (match_dup 2)
4219          (float_extend:V2DF
4220            (vec_select:V2SF
4221              (match_dup 3)
4222              (parallel [(const_int 0) (const_int 1)]))))]
4224   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4225   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4226   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4227      Try to avoid move when unpacking can be done in source.  */
4228   if (REG_P (operands[1]))
4229     {
4230       /* If it is unsafe to overwrite upper half of source, we need
4231          to move to destination and unpack there.  */
4232       if (((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4233             || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4234            && true_regnum (operands[0]) != true_regnum (operands[1]))
4235           || (EXT_REX_SSE_REG_P (operands[1])
4236               && !TARGET_AVX512VL))
4237         {
4238           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4239           emit_move_insn (tmp, operands[1]);
4240         }
4241       else
4242         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4243       /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
4244          =v, v, then vbroadcastss will be only needed for AVX512F without
4245          AVX512VL.  */
4246       if (!EXT_REX_SSE_REGNO_P (true_regnum (operands[3])))
4247         emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4248                                                operands[3]));
4249       else
4250         {
4251           rtx tmp = simplify_gen_subreg (V16SFmode, operands[3], V4SFmode, 0);
4252           emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
4253         }
4254     }
4255   else
4256     emit_insn (gen_vec_setv4sf_0 (operands[3],
4257                                   CONST0_RTX (V4SFmode), operands[1]));
4260 ;; It's more profitable to split and then extend in the same register.
4261 (define_peephole2
4262   [(set (match_operand:DF 0 "register_operand")
4263         (float_extend:DF
4264           (match_operand:SF 1 "memory_operand")))]
4265   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4266    && optimize_insn_for_speed_p ()
4267    && SSE_REG_P (operands[0])"
4268   [(set (match_dup 2) (match_dup 1))
4269    (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4270   "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
4272 (define_insn "*extendsfdf2_mixed"
4273   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,v")
4274         (float_extend:DF
4275           (match_operand:SF 1 "nonimmediate_operand" "fm,f,vm")))]
4276   "TARGET_SSE2 && TARGET_SSE_MATH"
4278   switch (which_alternative)
4279     {
4280     case 0:
4281     case 1:
4282       return output_387_reg_move (insn, operands);
4284     case 2:
4285       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4287     default:
4288       gcc_unreachable ();
4289     }
4291   [(set_attr "type" "fmov,fmov,ssecvt")
4292    (set_attr "prefix" "orig,orig,maybe_vex")
4293    (set_attr "mode" "SF,XF,DF")
4294    (set (attr "enabled")
4295      (cond [(eq_attr "alternative" "0,1")
4296               (symbol_ref "TARGET_MIX_SSE_I387")
4297            ]
4298            (symbol_ref "true")))])
4300 (define_insn "*extendsfdf2_i387"
4301   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4302         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4303   "TARGET_80387"
4304   "* return output_387_reg_move (insn, operands);"
4305   [(set_attr "type" "fmov")
4306    (set_attr "mode" "SF,XF")])
4308 (define_expand "extend<mode>xf2"
4309   [(set (match_operand:XF 0 "nonimmediate_operand")
4310         (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4311   "TARGET_80387"
4313   /* ??? Needed for compress_float_constant since all fp constants
4314      are TARGET_LEGITIMATE_CONSTANT_P.  */
4315   if (CONST_DOUBLE_P (operands[1]))
4316     {
4317       if (standard_80387_constant_p (operands[1]) > 0)
4318         {
4319           operands[1] = simplify_const_unary_operation
4320             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4321           emit_move_insn_1 (operands[0], operands[1]);
4322           DONE;
4323         }
4324       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4325     }
4328 (define_insn "*extend<mode>xf2_i387"
4329   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4330         (float_extend:XF
4331           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4332   "TARGET_80387"
4333   "* return output_387_reg_move (insn, operands);"
4334   [(set_attr "type" "fmov")
4335    (set_attr "mode" "<MODE>,XF")])
4337 ;; %%% This seems like bad news.
4338 ;; This cannot output into an f-reg because there is no way to be sure
4339 ;; of truncating in that case.  Otherwise this is just like a simple move
4340 ;; insn.  So we pretend we can output to a reg in order to get better
4341 ;; register preferencing, but we really use a stack slot.
4343 ;; Conversion from DFmode to SFmode.
4345 (define_expand "truncdfsf2"
4346   [(set (match_operand:SF 0 "nonimmediate_operand")
4347         (float_truncate:SF
4348           (match_operand:DF 1 "nonimmediate_operand")))]
4349   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4351   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4352     ;
4353   else if (flag_unsafe_math_optimizations)
4354     ;
4355   else
4356     {
4357       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4358       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4359       DONE;
4360     }
4363 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4364    cvtsd2ss:
4365       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4366       cvtpd2ps xmm2,xmm1
4367    We do the conversion post reload to avoid producing of 128bit spills
4368    that might lead to ICE on 32bit target.  The sequence unlikely combine
4369    anyway.  */
4370 (define_split
4371   [(set (match_operand:SF 0 "register_operand")
4372         (float_truncate:SF
4373           (match_operand:DF 1 "nonimmediate_operand")))]
4374   "TARGET_USE_VECTOR_FP_CONVERTS
4375    && optimize_insn_for_speed_p ()
4376    && reload_completed && SSE_REG_P (operands[0])
4377    && (!EXT_REX_SSE_REG_P (operands[0])
4378        || TARGET_AVX512VL)"
4379    [(set (match_dup 2)
4380          (vec_concat:V4SF
4381            (float_truncate:V2SF
4382              (match_dup 4))
4383            (match_dup 3)))]
4385   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4386   operands[3] = CONST0_RTX (V2SFmode);
4387   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4388   /* Use movsd for loading from memory, unpcklpd for registers.
4389      Try to avoid move when unpacking can be done in source, or SSE3
4390      movddup is available.  */
4391   if (REG_P (operands[1]))
4392     {
4393       if (!TARGET_SSE3
4394           && true_regnum (operands[0]) != true_regnum (operands[1])
4395           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4396               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4397         {
4398           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4399           emit_move_insn (tmp, operands[1]);
4400           operands[1] = tmp;
4401         }
4402       else if (!TARGET_SSE3)
4403         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4404       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4405     }
4406   else
4407     emit_insn (gen_vec_concatv2df (operands[4], operands[1],
4408                                    CONST0_RTX (DFmode)));
4411 ;; It's more profitable to split and then extend in the same register.
4412 (define_peephole2
4413   [(set (match_operand:SF 0 "register_operand")
4414         (float_truncate:SF
4415           (match_operand:DF 1 "memory_operand")))]
4416   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4417    && optimize_insn_for_speed_p ()
4418    && SSE_REG_P (operands[0])"
4419   [(set (match_dup 2) (match_dup 1))
4420    (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4421   "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
4423 (define_expand "truncdfsf2_with_temp"
4424   [(parallel [(set (match_operand:SF 0)
4425                    (float_truncate:SF (match_operand:DF 1)))
4426               (clobber (match_operand:SF 2))])])
4428 ;; SSE alternative doesn't depend on flag_unsafe_math_optimizations,
4429 ;; because nothing we do there is unsafe.
4430 (define_insn "*truncdfsf_fast_mixed"
4431   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,v")
4432         (float_truncate:SF
4433           (match_operand:DF 1 "nonimmediate_operand" "f  ,vm")))]
4434   "TARGET_SSE2 && TARGET_SSE_MATH"
4436   switch (which_alternative)
4437     {
4438     case 0:
4439       return output_387_reg_move (insn, operands);
4440     case 1:
4441       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4442     default:
4443       gcc_unreachable ();
4444     }
4446   [(set_attr "type" "fmov,ssecvt")
4447    (set_attr "prefix" "orig,maybe_vex")
4448    (set_attr "mode" "SF")
4449    (set (attr "enabled")
4450      (cond [(eq_attr "alternative" "0")
4451               (symbol_ref "TARGET_MIX_SSE_I387
4452                            && flag_unsafe_math_optimizations")
4453            ]
4454            (symbol_ref "true")))])
4456 (define_insn "*truncdfsf_fast_i387"
4457   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4458         (float_truncate:SF
4459           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4460   "TARGET_80387 && flag_unsafe_math_optimizations"
4461   "* return output_387_reg_move (insn, operands);"
4462   [(set_attr "type" "fmov")
4463    (set_attr "mode" "SF")])
4465 (define_insn "*truncdfsf_mixed"
4466   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,x ,?f,?x,?*r")
4467         (float_truncate:SF
4468           (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4469    (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
4470   "TARGET_MIX_SSE_I387"
4472   switch (which_alternative)
4473     {
4474     case 0:
4475       return output_387_reg_move (insn, operands);
4476     case 1:
4477       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4479     default:
4480       return "#";
4481     }
4483   [(set_attr "isa" "*,sse2,*,*,*")
4484    (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4485    (set_attr "unit" "*,*,i387,i387,i387")
4486    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4487    (set_attr "mode" "SF")])
4489 (define_insn "*truncdfsf_i387"
4490   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4491         (float_truncate:SF
4492           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4493    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4494   "TARGET_80387"
4496   switch (which_alternative)
4497     {
4498     case 0:
4499       return output_387_reg_move (insn, operands);
4501     default:
4502       return "#";
4503     }
4505   [(set_attr "type" "fmov,multi,multi,multi")
4506    (set_attr "unit" "*,i387,i387,i387")
4507    (set_attr "mode" "SF")])
4509 (define_insn "*truncdfsf2_i387_1"
4510   [(set (match_operand:SF 0 "memory_operand" "=m")
4511         (float_truncate:SF
4512           (match_operand:DF 1 "register_operand" "f")))]
4513   "TARGET_80387
4514    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4515    && !TARGET_MIX_SSE_I387"
4516   "* return output_387_reg_move (insn, operands);"
4517   [(set_attr "type" "fmov")
4518    (set_attr "mode" "SF")])
4520 (define_split
4521   [(set (match_operand:SF 0 "register_operand")
4522         (float_truncate:SF
4523          (match_operand:DF 1 "fp_register_operand")))
4524    (clobber (match_operand 2))]
4525   "reload_completed"
4526   [(set (match_dup 2) (match_dup 1))
4527    (set (match_dup 0) (match_dup 2))]
4528   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4530 ;; Conversion from XFmode to {SF,DF}mode
4532 (define_expand "truncxf<mode>2"
4533   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4534                    (float_truncate:MODEF
4535                      (match_operand:XF 1 "register_operand")))
4536               (clobber (match_dup 2))])]
4537   "TARGET_80387"
4539   if (flag_unsafe_math_optimizations)
4540     {
4541       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4542       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4543       if (reg != operands[0])
4544         emit_move_insn (operands[0], reg);
4545       DONE;
4546     }
4547   else
4548     operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4551 (define_insn "*truncxfsf2_mixed"
4552   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4553         (float_truncate:SF
4554           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4555    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4556   "TARGET_80387"
4558   gcc_assert (!which_alternative);
4559   return output_387_reg_move (insn, operands);
4561   [(set_attr "type" "fmov,multi,multi,multi")
4562    (set_attr "unit" "*,i387,i387,i387")
4563    (set_attr "mode" "SF")])
4565 (define_insn "*truncxfdf2_mixed"
4566   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4567         (float_truncate:DF
4568           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4569    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4570   "TARGET_80387"
4572   gcc_assert (!which_alternative);
4573   return output_387_reg_move (insn, operands);
4575   [(set_attr "isa" "*,*,sse2,*")
4576    (set_attr "type" "fmov,multi,multi,multi")
4577    (set_attr "unit" "*,i387,i387,i387")
4578    (set_attr "mode" "DF")])
4580 (define_insn "truncxf<mode>2_i387_noop"
4581   [(set (match_operand:MODEF 0 "register_operand" "=f")
4582         (float_truncate:MODEF
4583           (match_operand:XF 1 "register_operand" "f")))]
4584   "TARGET_80387 && flag_unsafe_math_optimizations"
4585   "* return output_387_reg_move (insn, operands);"
4586   [(set_attr "type" "fmov")
4587    (set_attr "mode" "<MODE>")])
4589 (define_insn "*truncxf<mode>2_i387"
4590   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4591         (float_truncate:MODEF
4592           (match_operand:XF 1 "register_operand" "f")))]
4593   "TARGET_80387"
4594   "* return output_387_reg_move (insn, operands);"
4595   [(set_attr "type" "fmov")
4596    (set_attr "mode" "<MODE>")])
4598 (define_split
4599   [(set (match_operand:MODEF 0 "register_operand")
4600         (float_truncate:MODEF
4601           (match_operand:XF 1 "register_operand")))
4602    (clobber (match_operand:MODEF 2 "memory_operand"))]
4603   "TARGET_80387 && reload_completed"
4604   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4605    (set (match_dup 0) (match_dup 2))])
4607 (define_split
4608   [(set (match_operand:MODEF 0 "memory_operand")
4609         (float_truncate:MODEF
4610           (match_operand:XF 1 "register_operand")))
4611    (clobber (match_operand:MODEF 2 "memory_operand"))]
4612   "TARGET_80387"
4613   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4615 ;; Signed conversion to DImode.
4617 (define_expand "fix_truncxfdi2"
4618   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4619                    (fix:DI (match_operand:XF 1 "register_operand")))
4620               (clobber (reg:CC FLAGS_REG))])]
4621   "TARGET_80387"
4623   if (TARGET_FISTTP)
4624    {
4625      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4626      DONE;
4627    }
4630 (define_expand "fix_trunc<mode>di2"
4631   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4632                    (fix:DI (match_operand:MODEF 1 "register_operand")))
4633               (clobber (reg:CC FLAGS_REG))])]
4634   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4636   if (TARGET_FISTTP
4637       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4638    {
4639      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4640      DONE;
4641    }
4642   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4643    {
4644      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4645      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4646      if (out != operands[0])
4647         emit_move_insn (operands[0], out);
4648      DONE;
4649    }
4652 ;; Signed conversion to SImode.
4654 (define_expand "fix_truncxfsi2"
4655   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4656                    (fix:SI (match_operand:XF 1 "register_operand")))
4657               (clobber (reg:CC FLAGS_REG))])]
4658   "TARGET_80387"
4660   if (TARGET_FISTTP)
4661    {
4662      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4663      DONE;
4664    }
4667 (define_expand "fix_trunc<mode>si2"
4668   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4669                    (fix:SI (match_operand:MODEF 1 "register_operand")))
4670               (clobber (reg:CC FLAGS_REG))])]
4671   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4673   if (TARGET_FISTTP
4674       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4675    {
4676      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4677      DONE;
4678    }
4679   if (SSE_FLOAT_MODE_P (<MODE>mode))
4680    {
4681      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4682      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4683      if (out != operands[0])
4684         emit_move_insn (operands[0], out);
4685      DONE;
4686    }
4689 ;; Signed conversion to HImode.
4691 (define_expand "fix_trunc<mode>hi2"
4692   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4693                    (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4694               (clobber (reg:CC FLAGS_REG))])]
4695   "TARGET_80387
4696    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4698   if (TARGET_FISTTP)
4699    {
4700      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4701      DONE;
4702    }
4705 ;; Unsigned conversion to SImode.
4707 (define_expand "fixuns_trunc<mode>si2"
4708   [(parallel
4709     [(set (match_operand:SI 0 "register_operand")
4710           (unsigned_fix:SI
4711             (match_operand:MODEF 1 "nonimmediate_operand")))
4712      (use (match_dup 2))
4713      (clobber (match_scratch:<ssevecmode> 3))
4714      (clobber (match_scratch:<ssevecmode> 4))])]
4715   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4717   machine_mode mode = <MODE>mode;
4718   machine_mode vecmode = <ssevecmode>mode;
4719   REAL_VALUE_TYPE TWO31r;
4720   rtx two31;
4722   if (optimize_insn_for_size_p ())
4723     FAIL;
4725   real_ldexp (&TWO31r, &dconst1, 31);
4726   two31 = const_double_from_real_value (TWO31r, mode);
4727   two31 = ix86_build_const_vector (vecmode, true, two31);
4728   operands[2] = force_reg (vecmode, two31);
4731 (define_insn_and_split "*fixuns_trunc<mode>_1"
4732   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4733         (unsigned_fix:SI
4734           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4735    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4736    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4737    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4738   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4739    && optimize_function_for_speed_p (cfun)"
4740   "#"
4741   "&& reload_completed"
4742   [(const_int 0)]
4744   ix86_split_convert_uns_si_sse (operands);
4745   DONE;
4748 ;; Unsigned conversion to HImode.
4749 ;; Without these patterns, we'll try the unsigned SI conversion which
4750 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4752 (define_expand "fixuns_trunc<mode>hi2"
4753   [(set (match_dup 2)
4754         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4755    (set (match_operand:HI 0 "nonimmediate_operand")
4756         (subreg:HI (match_dup 2) 0))]
4757   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4758   "operands[2] = gen_reg_rtx (SImode);")
4760 ;; When SSE is available, it is always faster to use it!
4761 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4762   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4763         (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
4764   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4765    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4766   "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4767   [(set_attr "type" "sseicvt")
4768    (set_attr "prefix" "maybe_vex")
4769    (set (attr "prefix_rex")
4770         (if_then_else
4771           (match_test "<SWI48:MODE>mode == DImode")
4772           (const_string "1")
4773           (const_string "*")))
4774    (set_attr "mode" "<MODEF:MODE>")
4775    (set_attr "athlon_decode" "double,vector")
4776    (set_attr "amdfam10_decode" "double,double")
4777    (set_attr "bdver1_decode" "double,double")])
4779 ;; Avoid vector decoded forms of the instruction.
4780 (define_peephole2
4781   [(match_scratch:MODEF 2 "x")
4782    (set (match_operand:SWI48 0 "register_operand")
4783         (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4784   "TARGET_AVOID_VECTOR_DECODE
4785    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4786    && optimize_insn_for_speed_p ()"
4787   [(set (match_dup 2) (match_dup 1))
4788    (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4790 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4791   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4792         (fix:SWI248x (match_operand 1 "register_operand")))]
4793   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4794    && TARGET_FISTTP
4795    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4796          && (TARGET_64BIT || <MODE>mode != DImode))
4797         && TARGET_SSE_MATH)
4798    && can_create_pseudo_p ()"
4799   "#"
4800   "&& 1"
4801   [(const_int 0)]
4803   if (memory_operand (operands[0], VOIDmode))
4804     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4805   else
4806     {
4807       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4808       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4809                                                             operands[1],
4810                                                             operands[2]));
4811     }
4812   DONE;
4814   [(set_attr "type" "fisttp")
4815    (set_attr "mode" "<MODE>")])
4817 (define_insn "fix_trunc<mode>_i387_fisttp"
4818   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4819         (fix:SWI248x (match_operand 1 "register_operand" "f")))
4820    (clobber (match_scratch:XF 2 "=&1f"))]
4821   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4822    && TARGET_FISTTP
4823    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4824          && (TARGET_64BIT || <MODE>mode != DImode))
4825         && TARGET_SSE_MATH)"
4826   "* return output_fix_trunc (insn, operands, true);"
4827   [(set_attr "type" "fisttp")
4828    (set_attr "mode" "<MODE>")])
4830 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4831   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4832         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4833    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4834    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4835   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4836    && TARGET_FISTTP
4837    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4838         && (TARGET_64BIT || <MODE>mode != DImode))
4839         && TARGET_SSE_MATH)"
4840   "#"
4841   [(set_attr "type" "fisttp")
4842    (set_attr "mode" "<MODE>")])
4844 (define_split
4845   [(set (match_operand:SWI248x 0 "register_operand")
4846         (fix:SWI248x (match_operand 1 "register_operand")))
4847    (clobber (match_operand:SWI248x 2 "memory_operand"))
4848    (clobber (match_scratch 3))]
4849   "reload_completed"
4850   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4851               (clobber (match_dup 3))])
4852    (set (match_dup 0) (match_dup 2))])
4854 (define_split
4855   [(set (match_operand:SWI248x 0 "memory_operand")
4856         (fix:SWI248x (match_operand 1 "register_operand")))
4857    (clobber (match_operand:SWI248x 2 "memory_operand"))
4858    (clobber (match_scratch 3))]
4859   "reload_completed"
4860   [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4861               (clobber (match_dup 3))])])
4863 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4864 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4865 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4866 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4867 ;; function in i386.c.
4868 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4869   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4870         (fix:SWI248x (match_operand 1 "register_operand")))
4871    (clobber (reg:CC FLAGS_REG))]
4872   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4873    && !TARGET_FISTTP
4874    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4875          && (TARGET_64BIT || <MODE>mode != DImode))
4876    && can_create_pseudo_p ()"
4877   "#"
4878   "&& 1"
4879   [(const_int 0)]
4881   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4883   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4884   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4885   if (memory_operand (operands[0], VOIDmode))
4886     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4887                                          operands[2], operands[3]));
4888   else
4889     {
4890       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4891       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4892                                                      operands[2], operands[3],
4893                                                      operands[4]));
4894     }
4895   DONE;
4897   [(set_attr "type" "fistp")
4898    (set_attr "i387_cw" "trunc")
4899    (set_attr "mode" "<MODE>")])
4901 (define_insn "fix_truncdi_i387"
4902   [(set (match_operand:DI 0 "memory_operand" "=m")
4903         (fix:DI (match_operand 1 "register_operand" "f")))
4904    (use (match_operand:HI 2 "memory_operand" "m"))
4905    (use (match_operand:HI 3 "memory_operand" "m"))
4906    (clobber (match_scratch:XF 4 "=&1f"))]
4907   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4908    && !TARGET_FISTTP
4909    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4910   "* return output_fix_trunc (insn, operands, false);"
4911   [(set_attr "type" "fistp")
4912    (set_attr "i387_cw" "trunc")
4913    (set_attr "mode" "DI")])
4915 (define_insn "fix_truncdi_i387_with_temp"
4916   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4917         (fix:DI (match_operand 1 "register_operand" "f,f")))
4918    (use (match_operand:HI 2 "memory_operand" "m,m"))
4919    (use (match_operand:HI 3 "memory_operand" "m,m"))
4920    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4921    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4922   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4923    && !TARGET_FISTTP
4924    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4925   "#"
4926   [(set_attr "type" "fistp")
4927    (set_attr "i387_cw" "trunc")
4928    (set_attr "mode" "DI")])
4930 (define_split
4931   [(set (match_operand:DI 0 "register_operand")
4932         (fix:DI (match_operand 1 "register_operand")))
4933    (use (match_operand:HI 2 "memory_operand"))
4934    (use (match_operand:HI 3 "memory_operand"))
4935    (clobber (match_operand:DI 4 "memory_operand"))
4936    (clobber (match_scratch 5))]
4937   "reload_completed"
4938   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4939               (use (match_dup 2))
4940               (use (match_dup 3))
4941               (clobber (match_dup 5))])
4942    (set (match_dup 0) (match_dup 4))])
4944 (define_split
4945   [(set (match_operand:DI 0 "memory_operand")
4946         (fix:DI (match_operand 1 "register_operand")))
4947    (use (match_operand:HI 2 "memory_operand"))
4948    (use (match_operand:HI 3 "memory_operand"))
4949    (clobber (match_operand:DI 4 "memory_operand"))
4950    (clobber (match_scratch 5))]
4951   "reload_completed"
4952   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4953               (use (match_dup 2))
4954               (use (match_dup 3))
4955               (clobber (match_dup 5))])])
4957 (define_insn "fix_trunc<mode>_i387"
4958   [(set (match_operand:SWI24 0 "memory_operand" "=m")
4959         (fix:SWI24 (match_operand 1 "register_operand" "f")))
4960    (use (match_operand:HI 2 "memory_operand" "m"))
4961    (use (match_operand:HI 3 "memory_operand" "m"))]
4962   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4963    && !TARGET_FISTTP
4964    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4965   "* return output_fix_trunc (insn, operands, false);"
4966   [(set_attr "type" "fistp")
4967    (set_attr "i387_cw" "trunc")
4968    (set_attr "mode" "<MODE>")])
4970 (define_insn "fix_trunc<mode>_i387_with_temp"
4971   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4972         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4973    (use (match_operand:HI 2 "memory_operand" "m,m"))
4974    (use (match_operand:HI 3 "memory_operand" "m,m"))
4975    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4976   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4977    && !TARGET_FISTTP
4978    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4979   "#"
4980   [(set_attr "type" "fistp")
4981    (set_attr "i387_cw" "trunc")
4982    (set_attr "mode" "<MODE>")])
4984 (define_split
4985   [(set (match_operand:SWI24 0 "register_operand")
4986         (fix:SWI24 (match_operand 1 "register_operand")))
4987    (use (match_operand:HI 2 "memory_operand"))
4988    (use (match_operand:HI 3 "memory_operand"))
4989    (clobber (match_operand:SWI24 4 "memory_operand"))]
4990   "reload_completed"
4991   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4992               (use (match_dup 2))
4993               (use (match_dup 3))])
4994    (set (match_dup 0) (match_dup 4))])
4996 (define_split
4997   [(set (match_operand:SWI24 0 "memory_operand")
4998         (fix:SWI24 (match_operand 1 "register_operand")))
4999    (use (match_operand:HI 2 "memory_operand"))
5000    (use (match_operand:HI 3 "memory_operand"))
5001    (clobber (match_operand:SWI24 4 "memory_operand"))]
5002   "reload_completed"
5003   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
5004               (use (match_dup 2))
5005               (use (match_dup 3))])])
5007 (define_insn "x86_fnstcw_1"
5008   [(set (match_operand:HI 0 "memory_operand" "=m")
5009         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5010   "TARGET_80387"
5011   "fnstcw\t%0"
5012   [(set (attr "length")
5013         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5014    (set_attr "mode" "HI")
5015    (set_attr "unit" "i387")
5016    (set_attr "bdver1_decode" "vector")])
5018 (define_insn "x86_fldcw_1"
5019   [(set (reg:HI FPCR_REG)
5020         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5021   "TARGET_80387"
5022   "fldcw\t%0"
5023   [(set (attr "length")
5024         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5025    (set_attr "mode" "HI")
5026    (set_attr "unit" "i387")
5027    (set_attr "athlon_decode" "vector")
5028    (set_attr "amdfam10_decode" "vector")
5029    (set_attr "bdver1_decode" "vector")])
5031 ;; Conversion between fixed point and floating point.
5033 ;; Even though we only accept memory inputs, the backend _really_
5034 ;; wants to be able to do this between registers.  Thankfully, LRA
5035 ;; will fix this up for us during register allocation.
5037 (define_insn "floathi<mode>2"
5038   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5039         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5040   "TARGET_80387
5041    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5042        || TARGET_MIX_SSE_I387)"
5043   "fild%Z1\t%1"
5044   [(set_attr "type" "fmov")
5045    (set_attr "mode" "<MODE>")
5046    (set_attr "znver1_decode" "double")
5047    (set_attr "fp_int_src" "true")])
5049 (define_insn "float<SWI48x:mode>xf2"
5050   [(set (match_operand:XF 0 "register_operand" "=f")
5051         (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5052   "TARGET_80387"
5053   "fild%Z1\t%1"
5054   [(set_attr "type" "fmov")
5055    (set_attr "mode" "XF")
5056    (set_attr "znver1_decode" "double")
5057    (set_attr "fp_int_src" "true")])
5059 (define_expand "float<SWI48:mode><MODEF:mode>2"
5060   [(set (match_operand:MODEF 0 "register_operand")
5061         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5062   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5064   if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
5065       && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5066     {
5067       rtx reg = gen_reg_rtx (XFmode);
5068       rtx (*insn)(rtx, rtx);
5070       emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
5072       if (<MODEF:MODE>mode == SFmode)
5073         insn = gen_truncxfsf2;
5074       else if (<MODEF:MODE>mode == DFmode)
5075         insn = gen_truncxfdf2;
5076       else
5077         gcc_unreachable ();
5079       emit_insn (insn (operands[0], reg));
5080       DONE;
5081     }
5084 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed"
5085   [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5086         (float:MODEF
5087           (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5088   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5089   "@
5090    fild%Z1\t%1
5091    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5092    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5093   [(set_attr "type" "fmov,sseicvt,sseicvt")
5094    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5095    (set_attr "mode" "<MODEF:MODE>")
5096    (set (attr "prefix_rex")
5097      (if_then_else
5098        (and (eq_attr "prefix" "maybe_vex")
5099             (match_test "<SWI48:MODE>mode == DImode"))
5100        (const_string "1")
5101        (const_string "*")))
5102    (set_attr "unit" "i387,*,*")
5103    (set_attr "athlon_decode" "*,double,direct")
5104    (set_attr "amdfam10_decode" "*,vector,double")
5105    (set_attr "bdver1_decode" "*,double,direct")
5106    (set_attr "znver1_decode" "double,*,*")
5107    (set_attr "fp_int_src" "true")
5108    (set (attr "enabled")
5109      (cond [(eq_attr "alternative" "0")
5110               (symbol_ref "TARGET_MIX_SSE_I387
5111                            && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5112                                                 <SWI48:MODE>mode)")
5113            ]
5114            (symbol_ref "true")))
5115    (set (attr "preferred_for_speed")
5116      (cond [(eq_attr "alternative" "1")
5117               (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5118            (symbol_ref "true")))])
5120 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
5121   [(set (match_operand:MODEF 0 "register_operand" "=f")
5122         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5123   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
5124   "fild%Z1\t%1"
5125   [(set_attr "type" "fmov")
5126    (set_attr "mode" "<MODEF:MODE>")
5127    (set_attr "znver1_decode" "double")
5128    (set_attr "fp_int_src" "true")])
5130 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5131 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5132 ;; alternative in sse2_loadld.
5133 (define_split
5134   [(set (match_operand:MODEF 0 "register_operand")
5135         (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5136   "TARGET_SSE2 && TARGET_SSE_MATH
5137    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5138    && reload_completed && SSE_REG_P (operands[0])
5139    && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5140    && (!EXT_REX_SSE_REG_P (operands[0])
5141        || TARGET_AVX512VL)"
5142   [(const_int 0)]
5144   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5145                                      <MODE>mode, 0);
5146   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5148   emit_insn (gen_sse2_loadld (operands[4],
5149                               CONST0_RTX (V4SImode), operands[1]));
5151   if (<ssevecmode>mode == V4SFmode)
5152     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5153   else
5154     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5155   DONE;
5158 ;; Avoid partial SSE register dependency stalls
5159 (define_split
5160   [(set (match_operand:MODEF 0 "register_operand")
5161         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5162   "TARGET_SSE2 && TARGET_SSE_MATH
5163    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5164    && optimize_function_for_speed_p (cfun)
5165    && reload_completed && SSE_REG_P (operands[0])
5166    && (!EXT_REX_SSE_REG_P (operands[0])
5167        || TARGET_AVX512VL)"
5168   [(const_int 0)]
5170   const machine_mode vmode = <MODEF:ssevecmode>mode;
5171   const machine_mode mode = <MODEF:MODE>mode;
5172   rtx t, op0 = simplify_gen_subreg (vmode, operands[0], mode, 0);
5174   emit_move_insn (op0, CONST0_RTX (vmode));
5176   t = gen_rtx_FLOAT (mode, operands[1]);
5177   t = gen_rtx_VEC_DUPLICATE (vmode, t);
5178   t = gen_rtx_VEC_MERGE (vmode, t, op0, const1_rtx);
5179   emit_insn (gen_rtx_SET (op0, t));
5180   DONE;
5183 ;; Break partial reg stall for cvtsd2ss.
5185 (define_peephole2
5186   [(set (match_operand:SF 0 "register_operand")
5187         (float_truncate:SF
5188           (match_operand:DF 1 "nonimmediate_operand")))]
5189   "TARGET_SSE2 && TARGET_SSE_MATH
5190    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5191    && optimize_function_for_speed_p (cfun)
5192    && SSE_REG_P (operands[0])
5193    && (!SSE_REG_P (operands[1])
5194        || REGNO (operands[0]) != REGNO (operands[1]))
5195    && (!EXT_REX_SSE_REG_P (operands[0])
5196        || TARGET_AVX512VL)"
5197   [(set (match_dup 0)
5198         (vec_merge:V4SF
5199           (vec_duplicate:V4SF
5200             (float_truncate:V2SF
5201               (match_dup 1)))
5202           (match_dup 0)
5203           (const_int 1)))]
5205   operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
5206                                      SFmode, 0);
5207   operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
5208                                      DFmode, 0);
5209   emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5212 ;; Break partial reg stall for cvtss2sd.
5214 (define_peephole2
5215   [(set (match_operand:DF 0 "register_operand")
5216         (float_extend:DF
5217           (match_operand:SF 1 "nonimmediate_operand")))]
5218   "TARGET_SSE2 && TARGET_SSE_MATH
5219    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5220    && optimize_function_for_speed_p (cfun)
5221    && SSE_REG_P (operands[0])
5222    && (!SSE_REG_P (operands[1])
5223        || REGNO (operands[0]) != REGNO (operands[1]))
5224    && (!EXT_REX_SSE_REG_P (operands[0])
5225        || TARGET_AVX512VL)"
5226   [(set (match_dup 0)
5227         (vec_merge:V2DF
5228           (float_extend:V2DF
5229             (vec_select:V2SF
5230               (match_dup 1)
5231               (parallel [(const_int 0) (const_int 1)])))
5232           (match_dup 0)
5233           (const_int 1)))]
5235   operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
5236                                      DFmode, 0);
5237   operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
5238                                      SFmode, 0);
5239   emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5242 ;; Avoid store forwarding (partial memory) stall penalty
5243 ;; by passing DImode value through XMM registers.  */
5245 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5246   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5247         (float:X87MODEF
5248           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5249    (clobber (match_scratch:V4SI 3 "=X,x"))
5250    (clobber (match_scratch:V4SI 4 "=X,x"))
5251    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5252   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5253    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5254    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5255   "#"
5256   [(set_attr "type" "multi")
5257    (set_attr "mode" "<X87MODEF:MODE>")
5258    (set_attr "unit" "i387")
5259    (set_attr "fp_int_src" "true")])
5261 (define_split
5262   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5263         (float:X87MODEF (match_operand:DI 1 "register_operand")))
5264    (clobber (match_scratch:V4SI 3))
5265    (clobber (match_scratch:V4SI 4))
5266    (clobber (match_operand:DI 2 "memory_operand"))]
5267   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5268    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5269    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5270    && reload_completed"
5271   [(set (match_dup 2) (match_dup 3))
5272    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5274   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5275      Assemble the 64-bit DImode value in an xmm register.  */
5276   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5277                               gen_lowpart (SImode, operands[1])));
5278   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5279                               gen_highpart (SImode, operands[1])));
5280   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5281                                          operands[4]));
5283   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5286 (define_split
5287   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5288         (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5289    (clobber (match_scratch:V4SI 3))
5290    (clobber (match_scratch:V4SI 4))
5291    (clobber (match_operand:DI 2 "memory_operand"))]
5292   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5293    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5294    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5295    && reload_completed"
5296   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5298 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5299   [(set (match_operand:MODEF 0 "register_operand")
5300         (unsigned_float:MODEF
5301           (match_operand:SWI12 1 "nonimmediate_operand")))]
5302   "!TARGET_64BIT
5303    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5305   operands[1] = convert_to_mode (SImode, operands[1], 1);
5306   emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5307   DONE;
5310 ;; Avoid store forwarding (partial memory) stall penalty by extending
5311 ;; SImode value to DImode through XMM register instead of pushing two
5312 ;; SImode values to stack. Also note that fild loads from memory only.
5314 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5315   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5316         (unsigned_float:X87MODEF
5317           (match_operand:SI 1 "nonimmediate_operand" "rm")))
5318    (clobber (match_scratch:DI 3 "=x"))
5319    (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5320   "!TARGET_64BIT
5321    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5322    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5323   "#"
5324   "&& reload_completed"
5325   [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5326    (set (match_dup 2) (match_dup 3))
5327    (set (match_dup 0)
5328         (float:X87MODEF (match_dup 2)))]
5329   ""
5330   [(set_attr "type" "multi")
5331    (set_attr "mode" "<MODE>")])
5333 (define_expand "floatunssi<mode>2"
5334   [(parallel
5335      [(set (match_operand:X87MODEF 0 "register_operand")
5336            (unsigned_float:X87MODEF
5337              (match_operand:SI 1 "nonimmediate_operand")))
5338       (clobber (match_scratch:DI 3))
5339       (clobber (match_dup 2))])]
5340   "!TARGET_64BIT
5341    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5342         && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5343        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5345   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5346     {
5347       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5348       DONE;
5349     }
5350   else
5351     operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5354 (define_expand "floatunsdisf2"
5355   [(use (match_operand:SF 0 "register_operand"))
5356    (use (match_operand:DI 1 "nonimmediate_operand"))]
5357   "TARGET_64BIT && TARGET_SSE_MATH"
5358   "x86_emit_floatuns (operands); DONE;")
5360 (define_expand "floatunsdidf2"
5361   [(use (match_operand:DF 0 "register_operand"))
5362    (use (match_operand:DI 1 "nonimmediate_operand"))]
5363   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5364    && TARGET_SSE2 && TARGET_SSE_MATH"
5366   if (TARGET_64BIT)
5367     x86_emit_floatuns (operands);
5368   else
5369     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5370   DONE;
5373 ;; Load effective address instructions
5375 (define_insn_and_split "*lea<mode>"
5376   [(set (match_operand:SWI48 0 "register_operand" "=r")
5377         (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5378   ""
5380   if (SImode_address_operand (operands[1], VOIDmode))
5381     {
5382       gcc_assert (TARGET_64BIT);
5383       return "lea{l}\t{%E1, %k0|%k0, %E1}";
5384     }
5385   else 
5386     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5388   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5389   [(const_int 0)]
5391   machine_mode mode = <MODE>mode;
5392   rtx pat;
5394   /* ix86_avoid_lea_for_addr re-recognizes insn and may
5395      change operands[] array behind our back.  */
5396   pat = PATTERN (curr_insn);
5398   operands[0] = SET_DEST (pat);
5399   operands[1] = SET_SRC (pat);
5401   /* Emit all operations in SImode for zero-extended addresses.  */
5402   if (SImode_address_operand (operands[1], VOIDmode))
5403     mode = SImode;
5405   ix86_split_lea_for_addr (curr_insn, operands, mode);
5407   /* Zero-extend return register to DImode for zero-extended addresses.  */
5408   if (mode != <MODE>mode)
5409     emit_insn (gen_zero_extendsidi2
5410                (operands[0], gen_lowpart (mode, operands[0])));
5412   DONE;
5414   [(set_attr "type" "lea")
5415    (set (attr "mode")
5416      (if_then_else
5417        (match_operand 1 "SImode_address_operand")
5418        (const_string "SI")
5419        (const_string "<MODE>")))])
5421 ;; Add instructions
5423 (define_expand "add<mode>3"
5424   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5425         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5426                     (match_operand:SDWIM 2 "<general_operand>")))]
5427   ""
5428   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5430 (define_insn_and_split "*add<dwi>3_doubleword"
5431   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5432         (plus:<DWI>
5433           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5434           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5435    (clobber (reg:CC FLAGS_REG))]
5436   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5437   "#"
5438   "reload_completed"
5439   [(parallel [(set (reg:CCC FLAGS_REG)
5440                    (compare:CCC
5441                      (plus:DWIH (match_dup 1) (match_dup 2))
5442                      (match_dup 1)))
5443               (set (match_dup 0)
5444                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5445    (parallel [(set (match_dup 3)
5446                    (plus:DWIH
5447                      (plus:DWIH
5448                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5449                        (match_dup 4))
5450                      (match_dup 5)))
5451               (clobber (reg:CC FLAGS_REG))])]
5453   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
5454   if (operands[2] == const0_rtx)
5455     {
5456       ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
5457       DONE;
5458     }
5461 (define_insn "*add<mode>_1"
5462   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5463         (plus:SWI48
5464           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5465           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5466    (clobber (reg:CC FLAGS_REG))]
5467   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5469   switch (get_attr_type (insn))
5470     {
5471     case TYPE_LEA:
5472       return "#";
5474     case TYPE_INCDEC:
5475       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5476       if (operands[2] == const1_rtx)
5477         return "inc{<imodesuffix>}\t%0";
5478       else
5479         {
5480           gcc_assert (operands[2] == constm1_rtx);
5481           return "dec{<imodesuffix>}\t%0";
5482         }
5484     default:
5485       /* For most processors, ADD is faster than LEA.  This alternative
5486          was added to use ADD as much as possible.  */
5487       if (which_alternative == 2)
5488         std::swap (operands[1], operands[2]);
5489         
5490       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5491       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5492         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5494       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5495     }
5497   [(set (attr "type")
5498      (cond [(eq_attr "alternative" "3")
5499               (const_string "lea")
5500             (match_operand:SWI48 2 "incdec_operand")
5501               (const_string "incdec")
5502            ]
5503            (const_string "alu")))
5504    (set (attr "length_immediate")
5505       (if_then_else
5506         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5507         (const_string "1")
5508         (const_string "*")))
5509    (set_attr "mode" "<MODE>")])
5511 ;; It may seem that nonimmediate operand is proper one for operand 1.
5512 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5513 ;; we take care in ix86_binary_operator_ok to not allow two memory
5514 ;; operands so proper swapping will be done in reload.  This allow
5515 ;; patterns constructed from addsi_1 to match.
5517 (define_insn "addsi_1_zext"
5518   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5519         (zero_extend:DI
5520           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5521                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5522    (clobber (reg:CC FLAGS_REG))]
5523   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5525   switch (get_attr_type (insn))
5526     {
5527     case TYPE_LEA:
5528       return "#";
5530     case TYPE_INCDEC:
5531       if (operands[2] == const1_rtx)
5532         return "inc{l}\t%k0";
5533       else
5534         {
5535           gcc_assert (operands[2] == constm1_rtx);
5536           return "dec{l}\t%k0";
5537         }
5539     default:
5540       /* For most processors, ADD is faster than LEA.  This alternative
5541          was added to use ADD as much as possible.  */
5542       if (which_alternative == 1)
5543         std::swap (operands[1], operands[2]);
5545       if (x86_maybe_negate_const_int (&operands[2], SImode))
5546         return "sub{l}\t{%2, %k0|%k0, %2}";
5548       return "add{l}\t{%2, %k0|%k0, %2}";
5549     }
5551   [(set (attr "type")
5552      (cond [(eq_attr "alternative" "2")
5553               (const_string "lea")
5554             (match_operand:SI 2 "incdec_operand")
5555               (const_string "incdec")
5556            ]
5557            (const_string "alu")))
5558    (set (attr "length_immediate")
5559       (if_then_else
5560         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5561         (const_string "1")
5562         (const_string "*")))
5563    (set_attr "mode" "SI")])
5565 (define_insn "*addhi_1"
5566   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5567         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5568                  (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5569    (clobber (reg:CC FLAGS_REG))]
5570   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5572   switch (get_attr_type (insn))
5573     {
5574     case TYPE_LEA:
5575       return "#";
5577     case TYPE_INCDEC:
5578       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5579       if (operands[2] == const1_rtx)
5580         return "inc{w}\t%0";
5581       else
5582         {
5583           gcc_assert (operands[2] == constm1_rtx);
5584           return "dec{w}\t%0";
5585         }
5587     default:
5588       /* For most processors, ADD is faster than LEA.  This alternative
5589          was added to use ADD as much as possible.  */
5590       if (which_alternative == 2)
5591         std::swap (operands[1], operands[2]);
5593       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5594       if (x86_maybe_negate_const_int (&operands[2], HImode))
5595         return "sub{w}\t{%2, %0|%0, %2}";
5597       return "add{w}\t{%2, %0|%0, %2}";
5598     }
5600   [(set (attr "type")
5601      (cond [(eq_attr "alternative" "3")
5602               (const_string "lea")
5603             (match_operand:HI 2 "incdec_operand")
5604               (const_string "incdec")
5605            ]
5606            (const_string "alu")))
5607    (set (attr "length_immediate")
5608       (if_then_else
5609         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5610         (const_string "1")
5611         (const_string "*")))
5612    (set_attr "mode" "HI,HI,HI,SI")])
5614 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5615 (define_insn "*addqi_1"
5616   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5617         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5618                  (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5619    (clobber (reg:CC FLAGS_REG))]
5620   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5622   bool widen = (which_alternative == 3 || which_alternative == 4);
5624   switch (get_attr_type (insn))
5625     {
5626     case TYPE_LEA:
5627       return "#";
5629     case TYPE_INCDEC:
5630       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5631       if (operands[2] == const1_rtx)
5632         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5633       else
5634         {
5635           gcc_assert (operands[2] == constm1_rtx);
5636           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5637         }
5639     default:
5640       /* For most processors, ADD is faster than LEA.  These alternatives
5641          were added to use ADD as much as possible.  */
5642       if (which_alternative == 2 || which_alternative == 4)
5643         std::swap (operands[1], operands[2]);
5645       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5646       if (x86_maybe_negate_const_int (&operands[2], QImode))
5647         {
5648           if (widen)
5649             return "sub{l}\t{%2, %k0|%k0, %2}";
5650           else
5651             return "sub{b}\t{%2, %0|%0, %2}";
5652         }
5653       if (widen)
5654         return "add{l}\t{%k2, %k0|%k0, %k2}";
5655       else
5656         return "add{b}\t{%2, %0|%0, %2}";
5657     }
5659   [(set (attr "type")
5660      (cond [(eq_attr "alternative" "5")
5661               (const_string "lea")
5662             (match_operand:QI 2 "incdec_operand")
5663               (const_string "incdec")
5664            ]
5665            (const_string "alu")))
5666    (set (attr "length_immediate")
5667       (if_then_else
5668         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5669         (const_string "1")
5670         (const_string "*")))
5671    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5673 (define_insn "*addqi_1_slp"
5674   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5675         (plus:QI (match_dup 0)
5676                  (match_operand:QI 1 "general_operand" "qn,qm")))
5677    (clobber (reg:CC FLAGS_REG))]
5678   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5679    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5681   switch (get_attr_type (insn))
5682     {
5683     case TYPE_INCDEC:
5684       if (operands[1] == const1_rtx)
5685         return "inc{b}\t%0";
5686       else
5687         {
5688           gcc_assert (operands[1] == constm1_rtx);
5689           return "dec{b}\t%0";
5690         }
5692     default:
5693       if (x86_maybe_negate_const_int (&operands[1], QImode))
5694         return "sub{b}\t{%1, %0|%0, %1}";
5696       return "add{b}\t{%1, %0|%0, %1}";
5697     }
5699   [(set (attr "type")
5700      (if_then_else (match_operand:QI 1 "incdec_operand")
5701         (const_string "incdec")
5702         (const_string "alu1")))
5703    (set (attr "memory")
5704      (if_then_else (match_operand 1 "memory_operand")
5705         (const_string "load")
5706         (const_string "none")))
5707    (set_attr "mode" "QI")])
5709 ;; Split non destructive adds if we cannot use lea.
5710 (define_split
5711   [(set (match_operand:SWI48 0 "register_operand")
5712         (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5713                     (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5714    (clobber (reg:CC FLAGS_REG))]
5715   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5716   [(set (match_dup 0) (match_dup 1))
5717    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5718               (clobber (reg:CC FLAGS_REG))])])
5720 ;; Convert add to the lea pattern to avoid flags dependency.
5721 (define_split
5722   [(set (match_operand:SWI 0 "register_operand")
5723         (plus:SWI (match_operand:SWI 1 "register_operand")
5724                   (match_operand:SWI 2 "<nonmemory_operand>")))
5725    (clobber (reg:CC FLAGS_REG))]
5726   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5727   [(const_int 0)]
5729   machine_mode mode = <MODE>mode;
5730   rtx pat;
5732   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
5733     { 
5734       mode = SImode; 
5735       operands[0] = gen_lowpart (mode, operands[0]);
5736       operands[1] = gen_lowpart (mode, operands[1]);
5737       operands[2] = gen_lowpart (mode, operands[2]);
5738     }
5740   pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5742   emit_insn (gen_rtx_SET (operands[0], pat));
5743   DONE;
5746 ;; Split non destructive adds if we cannot use lea.
5747 (define_split
5748   [(set (match_operand:DI 0 "register_operand")
5749         (zero_extend:DI
5750           (plus:SI (match_operand:SI 1 "register_operand")
5751                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5752    (clobber (reg:CC FLAGS_REG))]
5753   "TARGET_64BIT
5754    && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5755   [(set (match_dup 3) (match_dup 1))
5756    (parallel [(set (match_dup 0)
5757                    (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5758               (clobber (reg:CC FLAGS_REG))])]
5759   "operands[3] = gen_lowpart (SImode, operands[0]);")
5761 ;; Convert add to the lea pattern to avoid flags dependency.
5762 (define_split
5763   [(set (match_operand:DI 0 "register_operand")
5764         (zero_extend:DI
5765           (plus:SI (match_operand:SI 1 "register_operand")
5766                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5767    (clobber (reg:CC FLAGS_REG))]
5768   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5769   [(set (match_dup 0)
5770         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5772 (define_insn "*add<mode>_2"
5773   [(set (reg FLAGS_REG)
5774         (compare
5775           (plus:SWI
5776             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5777             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5778           (const_int 0)))
5779    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5780         (plus:SWI (match_dup 1) (match_dup 2)))]
5781   "ix86_match_ccmode (insn, CCGOCmode)
5782    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5784   switch (get_attr_type (insn))
5785     {
5786     case TYPE_INCDEC:
5787       if (operands[2] == const1_rtx)
5788         return "inc{<imodesuffix>}\t%0";
5789       else
5790         {
5791           gcc_assert (operands[2] == constm1_rtx);
5792           return "dec{<imodesuffix>}\t%0";
5793         }
5795     default:
5796       if (which_alternative == 2)
5797         std::swap (operands[1], operands[2]);
5798         
5799       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5800       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5801         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5803       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5804     }
5806   [(set (attr "type")
5807      (if_then_else (match_operand:SWI 2 "incdec_operand")
5808         (const_string "incdec")
5809         (const_string "alu")))
5810    (set (attr "length_immediate")
5811       (if_then_else
5812         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5813         (const_string "1")
5814         (const_string "*")))
5815    (set_attr "mode" "<MODE>")])
5817 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5818 (define_insn "*addsi_2_zext"
5819   [(set (reg FLAGS_REG)
5820         (compare
5821           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5822                    (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5823           (const_int 0)))
5824    (set (match_operand:DI 0 "register_operand" "=r,r")
5825         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5826   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5827    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5829   switch (get_attr_type (insn))
5830     {
5831     case TYPE_INCDEC:
5832       if (operands[2] == const1_rtx)
5833         return "inc{l}\t%k0";
5834       else
5835         {
5836           gcc_assert (operands[2] == constm1_rtx);
5837           return "dec{l}\t%k0";
5838         }
5840     default:
5841       if (which_alternative == 1)
5842         std::swap (operands[1], operands[2]);
5844       if (x86_maybe_negate_const_int (&operands[2], SImode))
5845         return "sub{l}\t{%2, %k0|%k0, %2}";
5847       return "add{l}\t{%2, %k0|%k0, %2}";
5848     }
5850   [(set (attr "type")
5851      (if_then_else (match_operand:SI 2 "incdec_operand")
5852         (const_string "incdec")
5853         (const_string "alu")))
5854    (set (attr "length_immediate")
5855       (if_then_else
5856         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5857         (const_string "1")
5858         (const_string "*")))
5859    (set_attr "mode" "SI")])
5861 (define_insn "*add<mode>_3"
5862   [(set (reg FLAGS_REG)
5863         (compare
5864           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5865           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5866    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5867   "ix86_match_ccmode (insn, CCZmode)
5868    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5870   switch (get_attr_type (insn))
5871     {
5872     case TYPE_INCDEC:
5873       if (operands[2] == const1_rtx)
5874         return "inc{<imodesuffix>}\t%0";
5875       else
5876         {
5877           gcc_assert (operands[2] == constm1_rtx);
5878           return "dec{<imodesuffix>}\t%0";
5879         }
5881     default:
5882       if (which_alternative == 1)
5883         std::swap (operands[1], operands[2]);
5885       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5886       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5887         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5889       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5890     }
5892   [(set (attr "type")
5893      (if_then_else (match_operand:SWI 2 "incdec_operand")
5894         (const_string "incdec")
5895         (const_string "alu")))
5896    (set (attr "length_immediate")
5897       (if_then_else
5898         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5899         (const_string "1")
5900         (const_string "*")))
5901    (set_attr "mode" "<MODE>")])
5903 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5904 (define_insn "*addsi_3_zext"
5905   [(set (reg FLAGS_REG)
5906         (compare
5907           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5908           (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5909    (set (match_operand:DI 0 "register_operand" "=r,r")
5910         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5911   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5912    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5914   switch (get_attr_type (insn))
5915     {
5916     case TYPE_INCDEC:
5917       if (operands[2] == const1_rtx)
5918         return "inc{l}\t%k0";
5919       else
5920         {
5921           gcc_assert (operands[2] == constm1_rtx);
5922           return "dec{l}\t%k0";
5923         }
5925     default:
5926       if (which_alternative == 1)
5927         std::swap (operands[1], operands[2]);
5929       if (x86_maybe_negate_const_int (&operands[2], SImode))
5930         return "sub{l}\t{%2, %k0|%k0, %2}";
5932       return "add{l}\t{%2, %k0|%k0, %2}";
5933     }
5935   [(set (attr "type")
5936      (if_then_else (match_operand:SI 2 "incdec_operand")
5937         (const_string "incdec")
5938         (const_string "alu")))
5939    (set (attr "length_immediate")
5940       (if_then_else
5941         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5942         (const_string "1")
5943         (const_string "*")))
5944    (set_attr "mode" "SI")])
5946 ; For comparisons against 1, -1 and 128, we may generate better code
5947 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5948 ; is matched then.  We can't accept general immediate, because for
5949 ; case of overflows,  the result is messed up.
5950 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5951 ; only for comparisons not depending on it.
5953 (define_insn "*adddi_4"
5954   [(set (reg FLAGS_REG)
5955         (compare
5956           (match_operand:DI 1 "nonimmediate_operand" "0")
5957           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5958    (clobber (match_scratch:DI 0 "=rm"))]
5959   "TARGET_64BIT
5960    && ix86_match_ccmode (insn, CCGCmode)"
5962   switch (get_attr_type (insn))
5963     {
5964     case TYPE_INCDEC:
5965       if (operands[2] == constm1_rtx)
5966         return "inc{q}\t%0";
5967       else
5968         {
5969           gcc_assert (operands[2] == const1_rtx);
5970           return "dec{q}\t%0";
5971         }
5973     default:
5974       if (x86_maybe_negate_const_int (&operands[2], DImode))
5975         return "add{q}\t{%2, %0|%0, %2}";
5977       return "sub{q}\t{%2, %0|%0, %2}";
5978     }
5980   [(set (attr "type")
5981      (if_then_else (match_operand:DI 2 "incdec_operand")
5982         (const_string "incdec")
5983         (const_string "alu")))
5984    (set (attr "length_immediate")
5985       (if_then_else
5986         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5987         (const_string "1")
5988         (const_string "*")))
5989    (set_attr "mode" "DI")])
5991 ; For comparisons against 1, -1 and 128, we may generate better code
5992 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5993 ; is matched then.  We can't accept general immediate, because for
5994 ; case of overflows,  the result is messed up.
5995 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5996 ; only for comparisons not depending on it.
5998 (define_insn "*add<mode>_4"
5999   [(set (reg FLAGS_REG)
6000         (compare
6001           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6002           (match_operand:SWI124 2 "const_int_operand" "n")))
6003    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6004   "ix86_match_ccmode (insn, CCGCmode)"
6006   switch (get_attr_type (insn))
6007     {
6008     case TYPE_INCDEC:
6009       if (operands[2] == constm1_rtx)
6010         return "inc{<imodesuffix>}\t%0";
6011       else
6012         {
6013           gcc_assert (operands[2] == const1_rtx);
6014           return "dec{<imodesuffix>}\t%0";
6015         }
6017     default:
6018       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6019         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6021       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6022     }
6024   [(set (attr "type")
6025      (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6026         (const_string "incdec")
6027         (const_string "alu")))
6028    (set (attr "length_immediate")
6029       (if_then_else
6030         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6031         (const_string "1")
6032         (const_string "*")))
6033    (set_attr "mode" "<MODE>")])
6035 (define_insn "*add<mode>_5"
6036   [(set (reg FLAGS_REG)
6037         (compare
6038           (plus:SWI
6039             (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6040             (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6041           (const_int 0)))
6042    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6043   "ix86_match_ccmode (insn, CCGOCmode)
6044    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6046   switch (get_attr_type (insn))
6047     {
6048     case TYPE_INCDEC:
6049       if (operands[2] == const1_rtx)
6050         return "inc{<imodesuffix>}\t%0";
6051       else
6052         {
6053           gcc_assert (operands[2] == constm1_rtx);
6054           return "dec{<imodesuffix>}\t%0";
6055         }
6057     default:
6058       if (which_alternative == 1)
6059         std::swap (operands[1], operands[2]);
6061       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6062       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6063         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6065       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6066     }
6068   [(set (attr "type")
6069      (if_then_else (match_operand:SWI 2 "incdec_operand")
6070         (const_string "incdec")
6071         (const_string "alu")))
6072    (set (attr "length_immediate")
6073       (if_then_else
6074         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6075         (const_string "1")
6076         (const_string "*")))
6077    (set_attr "mode" "<MODE>")])
6079 (define_insn "addqi_ext_1"
6080   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
6081                          (const_int 8)
6082                          (const_int 8))
6083         (plus:SI
6084           (zero_extract:SI
6085             (match_operand 1 "ext_register_operand" "0,0")
6086             (const_int 8)
6087             (const_int 8))
6088           (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
6089    (clobber (reg:CC FLAGS_REG))]
6090   ""
6092   switch (get_attr_type (insn))
6093     {
6094     case TYPE_INCDEC:
6095       if (operands[2] == const1_rtx)
6096         return "inc{b}\t%h0";
6097       else
6098         {
6099           gcc_assert (operands[2] == constm1_rtx);
6100           return "dec{b}\t%h0";
6101         }
6103     default:
6104       return "add{b}\t{%2, %h0|%h0, %2}";
6105     }
6107   [(set_attr "isa" "*,nox64")
6108    (set (attr "type")
6109      (if_then_else (match_operand:QI 2 "incdec_operand")
6110         (const_string "incdec")
6111         (const_string "alu")))
6112    (set_attr "modrm" "1")
6113    (set_attr "mode" "QI")])
6115 (define_insn "*addqi_ext_2"
6116   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6117                          (const_int 8)
6118                          (const_int 8))
6119         (plus:SI
6120           (zero_extract:SI
6121             (match_operand 1 "ext_register_operand" "%0")
6122             (const_int 8)
6123             (const_int 8))
6124           (zero_extract:SI
6125             (match_operand 2 "ext_register_operand" "Q")
6126             (const_int 8)
6127             (const_int 8))))
6128    (clobber (reg:CC FLAGS_REG))]
6129   ""
6130   "add{b}\t{%h2, %h0|%h0, %h2}"
6131   [(set_attr "type" "alu")
6132    (set_attr "mode" "QI")])
6134 ;; Add with jump on overflow.
6135 (define_expand "addv<mode>4"
6136   [(parallel [(set (reg:CCO FLAGS_REG)
6137                    (eq:CCO (plus:<DWI>
6138                               (sign_extend:<DWI>
6139                                  (match_operand:SWI 1 "nonimmediate_operand"))
6140                               (match_dup 4))
6141                            (sign_extend:<DWI>
6142                               (plus:SWI (match_dup 1)
6143                                         (match_operand:SWI 2
6144                                            "<general_operand>")))))
6145               (set (match_operand:SWI 0 "register_operand")
6146                    (plus:SWI (match_dup 1) (match_dup 2)))])
6147    (set (pc) (if_then_else
6148                (eq (reg:CCO FLAGS_REG) (const_int 0))
6149                (label_ref (match_operand 3))
6150                (pc)))]
6151   ""
6153   ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
6154   if (CONST_INT_P (operands[2]))
6155     operands[4] = operands[2];
6156   else
6157     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6160 (define_insn "*addv<mode>4"
6161   [(set (reg:CCO FLAGS_REG)
6162         (eq:CCO (plus:<DWI>
6163                    (sign_extend:<DWI>
6164                       (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6165                    (sign_extend:<DWI>
6166                       (match_operand:SWI 2 "<general_sext_operand>"
6167                                            "<r>mWe,<r>We")))
6168                 (sign_extend:<DWI>
6169                    (plus:SWI (match_dup 1) (match_dup 2)))))
6170    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6171         (plus:SWI (match_dup 1) (match_dup 2)))]
6172   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6173   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6174   [(set_attr "type" "alu")
6175    (set_attr "mode" "<MODE>")])
6177 (define_insn "*addv<mode>4_1"
6178   [(set (reg:CCO FLAGS_REG)
6179         (eq:CCO (plus:<DWI>
6180                    (sign_extend:<DWI>
6181                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
6182                    (match_operand:<DWI> 3 "const_int_operand" "i"))
6183                 (sign_extend:<DWI>
6184                    (plus:SWI (match_dup 1)
6185                              (match_operand:SWI 2 "x86_64_immediate_operand"
6186                                                   "<i>")))))
6187    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6188         (plus:SWI (match_dup 1) (match_dup 2)))]
6189   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6190    && CONST_INT_P (operands[2])
6191    && INTVAL (operands[2]) == INTVAL (operands[3])"
6192   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6193   [(set_attr "type" "alu")
6194    (set_attr "mode" "<MODE>")
6195    (set (attr "length_immediate")
6196         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6197                   (const_string "1")
6198                (match_test "<MODE_SIZE> == 8")
6199                   (const_string "4")]
6200               (const_string "<MODE_SIZE>")))])
6202 (define_expand "uaddv<mode>4"
6203   [(parallel [(set (reg:CCC FLAGS_REG)
6204                    (compare:CCC
6205                      (plus:SWI
6206                        (match_operand:SWI 1 "nonimmediate_operand")
6207                        (match_operand:SWI 2 "<general_operand>"))
6208                      (match_dup 1)))
6209               (set (match_operand:SWI 0 "register_operand")
6210                    (plus:SWI (match_dup 1) (match_dup 2)))])
6211    (set (pc) (if_then_else
6212                (ltu (reg:CCC FLAGS_REG) (const_int 0))
6213                (label_ref (match_operand 3))
6214                (pc)))]
6215   ""
6216   "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6218 ;; The lea patterns for modes less than 32 bits need to be matched by
6219 ;; several insns converted to real lea by splitters.
6221 (define_insn_and_split "*lea_general_1"
6222   [(set (match_operand 0 "register_operand" "=r")
6223         (plus (plus (match_operand 1 "index_register_operand" "l")
6224                     (match_operand 2 "register_operand" "r"))
6225               (match_operand 3 "immediate_operand" "i")))]
6226   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6227    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6228    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6229    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6230    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6231        || GET_MODE (operands[3]) == VOIDmode)"
6232   "#"
6233   "&& reload_completed"
6234   [(const_int 0)]
6236   machine_mode mode = SImode;
6237   rtx pat;
6239   operands[0] = gen_lowpart (mode, operands[0]);
6240   operands[1] = gen_lowpart (mode, operands[1]);
6241   operands[2] = gen_lowpart (mode, operands[2]);
6242   operands[3] = gen_lowpart (mode, operands[3]);
6244   pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6245                       operands[3]);
6247   emit_insn (gen_rtx_SET (operands[0], pat));
6248   DONE;
6250   [(set_attr "type" "lea")
6251    (set_attr "mode" "SI")])
6253 (define_insn_and_split "*lea_general_2"
6254   [(set (match_operand 0 "register_operand" "=r")
6255         (plus (mult (match_operand 1 "index_register_operand" "l")
6256                     (match_operand 2 "const248_operand" "n"))
6257               (match_operand 3 "nonmemory_operand" "ri")))]
6258   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6259    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6260    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6261    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6262        || GET_MODE (operands[3]) == VOIDmode)"
6263   "#"
6264   "&& reload_completed"
6265   [(const_int 0)]
6267   machine_mode mode = SImode;
6268   rtx pat;
6270   operands[0] = gen_lowpart (mode, operands[0]);
6271   operands[1] = gen_lowpart (mode, operands[1]);
6272   operands[3] = gen_lowpart (mode, operands[3]);
6274   pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6275                       operands[3]);
6277   emit_insn (gen_rtx_SET (operands[0], pat));
6278   DONE;
6280   [(set_attr "type" "lea")
6281    (set_attr "mode" "SI")])
6283 (define_insn_and_split "*lea_general_3"
6284   [(set (match_operand 0 "register_operand" "=r")
6285         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6286                           (match_operand 2 "const248_operand" "n"))
6287                     (match_operand 3 "register_operand" "r"))
6288               (match_operand 4 "immediate_operand" "i")))]
6289   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6290    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6291    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6292    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6293   "#"
6294   "&& reload_completed"
6295   [(const_int 0)]
6297   machine_mode mode = SImode;
6298   rtx pat;
6300   operands[0] = gen_lowpart (mode, operands[0]);
6301   operands[1] = gen_lowpart (mode, operands[1]);
6302   operands[3] = gen_lowpart (mode, operands[3]);
6303   operands[4] = gen_lowpart (mode, operands[4]);
6305   pat = gen_rtx_PLUS (mode,
6306                       gen_rtx_PLUS (mode,
6307                                     gen_rtx_MULT (mode, operands[1],
6308                                                         operands[2]),
6309                                     operands[3]),
6310                       operands[4]);
6312   emit_insn (gen_rtx_SET (operands[0], pat));
6313   DONE;
6315   [(set_attr "type" "lea")
6316    (set_attr "mode" "SI")])
6318 (define_insn_and_split "*lea_general_4"
6319   [(set (match_operand 0 "register_operand" "=r")
6320         (any_or (ashift
6321                   (match_operand 1 "index_register_operand" "l")
6322                   (match_operand 2 "const_int_operand" "n"))
6323                 (match_operand 3 "const_int_operand" "n")))]
6324   "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6325       && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6326     || GET_MODE (operands[0]) == SImode
6327     || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6328    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6329    && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6330    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6331        < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6332   "#"
6333   "&& reload_completed"
6334   [(const_int 0)]
6336   machine_mode mode = GET_MODE (operands[0]);
6337   rtx pat;
6339   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6340     { 
6341       mode = SImode; 
6342       operands[0] = gen_lowpart (mode, operands[0]);
6343       operands[1] = gen_lowpart (mode, operands[1]);
6344     }
6346   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6348   pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6349                        INTVAL (operands[3]));
6351   emit_insn (gen_rtx_SET (operands[0], pat));
6352   DONE;
6354   [(set_attr "type" "lea")
6355    (set (attr "mode")
6356       (if_then_else (match_operand:DI 0)
6357         (const_string "DI")
6358         (const_string "SI")))])
6360 ;; Subtract instructions
6362 (define_expand "sub<mode>3"
6363   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6364         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6365                      (match_operand:SDWIM 2 "<general_operand>")))]
6366   ""
6367   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6369 (define_insn_and_split "*sub<dwi>3_doubleword"
6370   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6371         (minus:<DWI>
6372           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6373           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6374    (clobber (reg:CC FLAGS_REG))]
6375   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6376   "#"
6377   "reload_completed"
6378   [(parallel [(set (reg:CC FLAGS_REG)
6379                    (compare:CC (match_dup 1) (match_dup 2)))
6380               (set (match_dup 0)
6381                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6382    (parallel [(set (match_dup 3)
6383                    (minus:DWIH
6384                      (minus:DWIH
6385                        (match_dup 4)
6386                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6387                      (match_dup 5)))
6388               (clobber (reg:CC FLAGS_REG))])]
6390   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6391   if (operands[2] == const0_rtx)
6392     {
6393       ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
6394       DONE;
6395     }
6398 (define_insn "*sub<mode>_1"
6399   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6400         (minus:SWI
6401           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6402           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6403    (clobber (reg:CC FLAGS_REG))]
6404   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6405   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6406   [(set_attr "type" "alu")
6407    (set_attr "mode" "<MODE>")])
6409 (define_insn "*subsi_1_zext"
6410   [(set (match_operand:DI 0 "register_operand" "=r")
6411         (zero_extend:DI
6412           (minus:SI (match_operand:SI 1 "register_operand" "0")
6413                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6414    (clobber (reg:CC FLAGS_REG))]
6415   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6416   "sub{l}\t{%2, %k0|%k0, %2}"
6417   [(set_attr "type" "alu")
6418    (set_attr "mode" "SI")])
6420 (define_insn "*subqi_1_slp"
6421   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6422         (minus:QI (match_dup 0)
6423                   (match_operand:QI 1 "general_operand" "qn,qm")))
6424    (clobber (reg:CC FLAGS_REG))]
6425   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6426    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6427   "sub{b}\t{%1, %0|%0, %1}"
6428   [(set_attr "type" "alu1")
6429    (set_attr "mode" "QI")])
6431 (define_insn "*sub<mode>_2"
6432   [(set (reg FLAGS_REG)
6433         (compare
6434           (minus:SWI
6435             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6436             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6437           (const_int 0)))
6438    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6439         (minus:SWI (match_dup 1) (match_dup 2)))]
6440   "ix86_match_ccmode (insn, CCGOCmode)
6441    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6442   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6443   [(set_attr "type" "alu")
6444    (set_attr "mode" "<MODE>")])
6446 (define_insn "*subsi_2_zext"
6447   [(set (reg FLAGS_REG)
6448         (compare
6449           (minus:SI (match_operand:SI 1 "register_operand" "0")
6450                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6451           (const_int 0)))
6452    (set (match_operand:DI 0 "register_operand" "=r")
6453         (zero_extend:DI
6454           (minus:SI (match_dup 1)
6455                     (match_dup 2))))]
6456   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6457    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6458   "sub{l}\t{%2, %k0|%k0, %2}"
6459   [(set_attr "type" "alu")
6460    (set_attr "mode" "SI")])
6462 ;; Subtract with jump on overflow.
6463 (define_expand "subv<mode>4"
6464   [(parallel [(set (reg:CCO FLAGS_REG)
6465                    (eq:CCO (minus:<DWI>
6466                               (sign_extend:<DWI>
6467                                  (match_operand:SWI 1 "nonimmediate_operand"))
6468                               (match_dup 4))
6469                            (sign_extend:<DWI>
6470                               (minus:SWI (match_dup 1)
6471                                          (match_operand:SWI 2
6472                                             "<general_operand>")))))
6473               (set (match_operand:SWI 0 "register_operand")
6474                    (minus:SWI (match_dup 1) (match_dup 2)))])
6475    (set (pc) (if_then_else
6476                (eq (reg:CCO FLAGS_REG) (const_int 0))
6477                (label_ref (match_operand 3))
6478                (pc)))]
6479   ""
6481   ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6482   if (CONST_INT_P (operands[2]))
6483     operands[4] = operands[2];
6484   else
6485     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6488 (define_insn "*subv<mode>4"
6489   [(set (reg:CCO FLAGS_REG)
6490         (eq:CCO (minus:<DWI>
6491                    (sign_extend:<DWI>
6492                       (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6493                    (sign_extend:<DWI>
6494                       (match_operand:SWI 2 "<general_sext_operand>"
6495                                            "<r>We,<r>m")))
6496                 (sign_extend:<DWI>
6497                    (minus:SWI (match_dup 1) (match_dup 2)))))
6498    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6499         (minus:SWI (match_dup 1) (match_dup 2)))]
6500   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6501   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6502   [(set_attr "type" "alu")
6503    (set_attr "mode" "<MODE>")])
6505 (define_insn "*subv<mode>4_1"
6506   [(set (reg:CCO FLAGS_REG)
6507         (eq:CCO (minus:<DWI>
6508                    (sign_extend:<DWI>
6509                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
6510                    (match_operand:<DWI> 3 "const_int_operand" "i"))
6511                 (sign_extend:<DWI>
6512                    (minus:SWI (match_dup 1)
6513                               (match_operand:SWI 2 "x86_64_immediate_operand"
6514                                                    "<i>")))))
6515    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6516         (minus:SWI (match_dup 1) (match_dup 2)))]
6517   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6518    && CONST_INT_P (operands[2])
6519    && INTVAL (operands[2]) == INTVAL (operands[3])"
6520   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6521   [(set_attr "type" "alu")
6522    (set_attr "mode" "<MODE>")
6523    (set (attr "length_immediate")
6524         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6525                   (const_string "1")
6526                (match_test "<MODE_SIZE> == 8")
6527                   (const_string "4")]
6528               (const_string "<MODE_SIZE>")))])
6530 (define_expand "usubv<mode>4"
6531   [(parallel [(set (reg:CC FLAGS_REG)
6532                    (compare:CC
6533                      (match_operand:SWI 1 "nonimmediate_operand")
6534                      (match_operand:SWI 2 "<general_operand>")))
6535               (set (match_operand:SWI 0 "register_operand")
6536                    (minus:SWI (match_dup 1) (match_dup 2)))])
6537    (set (pc) (if_then_else
6538                (ltu (reg:CC FLAGS_REG) (const_int 0))
6539                (label_ref (match_operand 3))
6540                (pc)))]
6541   ""
6542   "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6544 (define_insn "*sub<mode>_3"
6545   [(set (reg FLAGS_REG)
6546         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6547                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6548    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6549         (minus:SWI (match_dup 1) (match_dup 2)))]
6550   "ix86_match_ccmode (insn, CCmode)
6551    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6552   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6553   [(set_attr "type" "alu")
6554    (set_attr "mode" "<MODE>")])
6556 (define_insn "*subsi_3_zext"
6557   [(set (reg FLAGS_REG)
6558         (compare (match_operand:SI 1 "register_operand" "0")
6559                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6560    (set (match_operand:DI 0 "register_operand" "=r")
6561         (zero_extend:DI
6562           (minus:SI (match_dup 1)
6563                     (match_dup 2))))]
6564   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6565    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6566   "sub{l}\t{%2, %1|%1, %2}"
6567   [(set_attr "type" "alu")
6568    (set_attr "mode" "SI")])
6570 ;; Add with carry and subtract with borrow
6572 (define_insn "add<mode>3_carry"
6573   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6574         (plus:SWI
6575           (plus:SWI
6576             (match_operator:SWI 4 "ix86_carry_flag_operator"
6577              [(match_operand 3 "flags_reg_operand") (const_int 0)])
6578             (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6579           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6580    (clobber (reg:CC FLAGS_REG))]
6581   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6582   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6583   [(set_attr "type" "alu")
6584    (set_attr "use_carry" "1")
6585    (set_attr "pent_pair" "pu")
6586    (set_attr "mode" "<MODE>")])
6588 (define_insn "*addsi3_carry_zext"
6589   [(set (match_operand:DI 0 "register_operand" "=r")
6590         (zero_extend:DI
6591           (plus:SI
6592             (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6593                       [(reg FLAGS_REG) (const_int 0)])
6594                      (match_operand:SI 1 "register_operand" "%0"))
6595             (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6596    (clobber (reg:CC FLAGS_REG))]
6597   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6598   "adc{l}\t{%2, %k0|%k0, %2}"
6599   [(set_attr "type" "alu")
6600    (set_attr "use_carry" "1")
6601    (set_attr "pent_pair" "pu")
6602    (set_attr "mode" "SI")])
6604 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6606 (define_insn "addcarry<mode>"
6607   [(set (reg:CCC FLAGS_REG)
6608         (compare:CCC
6609           (plus:SWI48
6610             (plus:SWI48
6611               (match_operator:SWI48 4 "ix86_carry_flag_operator"
6612                [(match_operand 3 "flags_reg_operand") (const_int 0)])
6613               (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6614             (match_operand:SWI48 2 "nonimmediate_operand" "rm"))
6615           (match_dup 1)))
6616    (set (match_operand:SWI48 0 "register_operand" "=r")
6617         (plus:SWI48 (plus:SWI48 (match_op_dup 4
6618                                  [(match_dup 3) (const_int 0)])
6619                                 (match_dup 1))
6620                     (match_dup 2)))]
6621   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6622   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6623   [(set_attr "type" "alu")
6624    (set_attr "use_carry" "1")
6625    (set_attr "pent_pair" "pu")
6626    (set_attr "mode" "<MODE>")])
6628 (define_insn "sub<mode>3_carry"
6629   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6630         (minus:SWI
6631           (minus:SWI
6632             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6633             (match_operator:SWI 4 "ix86_carry_flag_operator"
6634              [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6635           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6636    (clobber (reg:CC FLAGS_REG))]
6637   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6638   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6639   [(set_attr "type" "alu")
6640    (set_attr "use_carry" "1")
6641    (set_attr "pent_pair" "pu")
6642    (set_attr "mode" "<MODE>")])
6644 (define_insn "*subsi3_carry_zext"
6645   [(set (match_operand:DI 0 "register_operand" "=r")
6646         (zero_extend:DI
6647           (minus:SI
6648             (minus:SI
6649               (match_operand:SI 1 "register_operand" "0")
6650               (match_operator:SI 3 "ix86_carry_flag_operator"
6651                [(reg FLAGS_REG) (const_int 0)]))
6652             (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6653    (clobber (reg:CC FLAGS_REG))]
6654   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6655   "sbb{l}\t{%2, %k0|%k0, %2}"
6656   [(set_attr "type" "alu")
6657    (set_attr "use_carry" "1")
6658    (set_attr "pent_pair" "pu")
6659    (set_attr "mode" "SI")])
6661 (define_insn "subborrow<mode>"
6662   [(set (reg:CCC FLAGS_REG)
6663         (compare:CCC
6664           (match_operand:SWI48 1 "nonimmediate_operand" "0")
6665           (plus:SWI48
6666             (match_operator:SWI48 4 "ix86_carry_flag_operator"
6667              [(match_operand 3 "flags_reg_operand") (const_int 0)])
6668             (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
6669    (set (match_operand:SWI48 0 "register_operand" "=r")
6670         (minus:SWI48 (minus:SWI48 (match_dup 1)
6671                                   (match_op_dup 4
6672                                    [(match_dup 3) (const_int 0)]))
6673                      (match_dup 2)))]
6674   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6675   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6676   [(set_attr "type" "alu")
6677    (set_attr "use_carry" "1")
6678    (set_attr "pent_pair" "pu")
6679    (set_attr "mode" "<MODE>")])
6681 ;; Overflow setting add instructions
6683 (define_expand "addqi3_cconly_overflow"
6684   [(parallel
6685      [(set (reg:CCC FLAGS_REG)
6686            (compare:CCC
6687              (plus:QI
6688                (match_operand:QI 0 "nonimmediate_operand")
6689                (match_operand:QI 1 "general_operand"))
6690              (match_dup 0)))
6691       (clobber (match_scratch:QI 2))])]
6692   "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
6694 (define_insn "*add<mode>3_cconly_overflow_1"
6695   [(set (reg:CCC FLAGS_REG)
6696         (compare:CCC
6697           (plus:SWI
6698             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6699             (match_operand:SWI 2 "<general_operand>" "<g>"))
6700           (match_dup 1)))
6701    (clobber (match_scratch:SWI 0 "=<r>"))]
6702   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6703   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6704   [(set_attr "type" "alu")
6705    (set_attr "mode" "<MODE>")])
6707 (define_insn "*add<mode>3_cconly_overflow_2"
6708   [(set (reg:CCC FLAGS_REG)
6709         (compare:CCC
6710           (plus:SWI
6711             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6712             (match_operand:SWI 2 "<general_operand>" "<g>"))
6713           (match_dup 2)))
6714    (clobber (match_scratch:SWI 0 "=<r>"))]
6715   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6716   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6717   [(set_attr "type" "alu")
6718    (set_attr "mode" "<MODE>")])
6720 (define_insn "*add<mode>3_cc_overflow_1"
6721   [(set (reg:CCC FLAGS_REG)
6722         (compare:CCC
6723             (plus:SWI
6724                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6725                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6726             (match_dup 1)))
6727    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6728         (plus:SWI (match_dup 1) (match_dup 2)))]
6729   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6730   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6731   [(set_attr "type" "alu")
6732    (set_attr "mode" "<MODE>")])
6734 (define_insn "*add<mode>3_cc_overflow_2"
6735   [(set (reg:CCC FLAGS_REG)
6736         (compare:CCC
6737             (plus:SWI
6738                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6739                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6740             (match_dup 2)))
6741    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6742         (plus:SWI (match_dup 1) (match_dup 2)))]
6743   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6744   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6745   [(set_attr "type" "alu")
6746    (set_attr "mode" "<MODE>")])
6748 (define_insn "*addsi3_zext_cc_overflow_1"
6749   [(set (reg:CCC FLAGS_REG)
6750         (compare:CCC
6751           (plus:SI
6752             (match_operand:SI 1 "nonimmediate_operand" "%0")
6753             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6754           (match_dup 1)))
6755    (set (match_operand:DI 0 "register_operand" "=r")
6756         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6757   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6758   "add{l}\t{%2, %k0|%k0, %2}"
6759   [(set_attr "type" "alu")
6760    (set_attr "mode" "SI")])
6762 (define_insn "*addsi3_zext_cc_overflow_2"
6763   [(set (reg:CCC FLAGS_REG)
6764         (compare:CCC
6765           (plus:SI
6766             (match_operand:SI 1 "nonimmediate_operand" "%0")
6767             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6768           (match_dup 2)))
6769    (set (match_operand:DI 0 "register_operand" "=r")
6770         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6771   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6772   "add{l}\t{%2, %k0|%k0, %2}"
6773   [(set_attr "type" "alu")
6774    (set_attr "mode" "SI")])
6776 ;; The patterns that match these are at the end of this file.
6778 (define_expand "<plusminus_insn>xf3"
6779   [(set (match_operand:XF 0 "register_operand")
6780         (plusminus:XF
6781           (match_operand:XF 1 "register_operand")
6782           (match_operand:XF 2 "register_operand")))]
6783   "TARGET_80387")
6785 (define_expand "<plusminus_insn><mode>3"
6786   [(set (match_operand:MODEF 0 "register_operand")
6787         (plusminus:MODEF
6788           (match_operand:MODEF 1 "register_operand")
6789           (match_operand:MODEF 2 "nonimmediate_operand")))]
6790   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6791     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6793 ;; Multiply instructions
6795 (define_expand "mul<mode>3"
6796   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6797                    (mult:SWIM248
6798                      (match_operand:SWIM248 1 "register_operand")
6799                      (match_operand:SWIM248 2 "<general_operand>")))
6800               (clobber (reg:CC FLAGS_REG))])])
6802 (define_expand "mulqi3"
6803   [(parallel [(set (match_operand:QI 0 "register_operand")
6804                    (mult:QI
6805                      (match_operand:QI 1 "register_operand")
6806                      (match_operand:QI 2 "nonimmediate_operand")))
6807               (clobber (reg:CC FLAGS_REG))])]
6808   "TARGET_QIMODE_MATH")
6810 ;; On AMDFAM10
6811 ;; IMUL reg32/64, reg32/64, imm8        Direct
6812 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6813 ;; IMUL reg32/64, reg32/64, imm32       Direct
6814 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6815 ;; IMUL reg32/64, reg32/64              Direct
6816 ;; IMUL reg32/64, mem32/64              Direct
6818 ;; On BDVER1, all above IMULs use DirectPath
6820 ;; On AMDFAM10
6821 ;; IMUL reg16, reg16, imm8      VectorPath
6822 ;; IMUL reg16, mem16, imm8      VectorPath
6823 ;; IMUL reg16, reg16, imm16     VectorPath
6824 ;; IMUL reg16, mem16, imm16     VectorPath
6825 ;; IMUL reg16, reg16            Direct
6826 ;; IMUL reg16, mem16            Direct
6828 ;; On BDVER1, all HI MULs use DoublePath
6830 (define_insn "*mul<mode>3_1"
6831   [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
6832         (mult:SWIM248
6833           (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
6834           (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
6835    (clobber (reg:CC FLAGS_REG))]
6836   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6837   "@
6838    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6839    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6840    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6841   [(set_attr "type" "imul")
6842    (set_attr "prefix_0f" "0,0,1")
6843    (set (attr "athlon_decode")
6844         (cond [(eq_attr "cpu" "athlon")
6845                   (const_string "vector")
6846                (eq_attr "alternative" "1")
6847                   (const_string "vector")
6848                (and (eq_attr "alternative" "2")
6849                     (ior (match_test "<MODE>mode == HImode")
6850                          (match_operand 1 "memory_operand")))
6851                   (const_string "vector")]
6852               (const_string "direct")))
6853    (set (attr "amdfam10_decode")
6854         (cond [(and (eq_attr "alternative" "0,1")
6855                     (ior (match_test "<MODE>mode == HImode")
6856                          (match_operand 1 "memory_operand")))
6857                   (const_string "vector")]
6858               (const_string "direct")))
6859    (set (attr "bdver1_decode")
6860         (if_then_else
6861           (match_test "<MODE>mode == HImode")
6862             (const_string "double")
6863             (const_string "direct")))
6864    (set_attr "mode" "<MODE>")])
6866 (define_insn "*mulsi3_1_zext"
6867   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6868         (zero_extend:DI
6869           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6870                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6871    (clobber (reg:CC FLAGS_REG))]
6872   "TARGET_64BIT
6873    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6874   "@
6875    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6876    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6877    imul{l}\t{%2, %k0|%k0, %2}"
6878   [(set_attr "type" "imul")
6879    (set_attr "prefix_0f" "0,0,1")
6880    (set (attr "athlon_decode")
6881         (cond [(eq_attr "cpu" "athlon")
6882                   (const_string "vector")
6883                (eq_attr "alternative" "1")
6884                   (const_string "vector")
6885                (and (eq_attr "alternative" "2")
6886                     (match_operand 1 "memory_operand"))
6887                   (const_string "vector")]
6888               (const_string "direct")))
6889    (set (attr "amdfam10_decode")
6890         (cond [(and (eq_attr "alternative" "0,1")
6891                     (match_operand 1 "memory_operand"))
6892                   (const_string "vector")]
6893               (const_string "direct")))
6894    (set_attr "bdver1_decode" "direct")
6895    (set_attr "mode" "SI")])
6897 ;;On AMDFAM10 and BDVER1
6898 ;; MUL reg8     Direct
6899 ;; MUL mem8     Direct
6901 (define_insn "*mulqi3_1"
6902   [(set (match_operand:QI 0 "register_operand" "=a")
6903         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6904                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6905    (clobber (reg:CC FLAGS_REG))]
6906   "TARGET_QIMODE_MATH
6907    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6908   "mul{b}\t%2"
6909   [(set_attr "type" "imul")
6910    (set_attr "length_immediate" "0")
6911    (set (attr "athlon_decode")
6912      (if_then_else (eq_attr "cpu" "athlon")
6913         (const_string "vector")
6914         (const_string "direct")))
6915    (set_attr "amdfam10_decode" "direct")
6916    (set_attr "bdver1_decode" "direct")
6917    (set_attr "mode" "QI")])
6919 ;; Multiply with jump on overflow.
6920 (define_expand "mulv<mode>4"
6921   [(parallel [(set (reg:CCO FLAGS_REG)
6922                    (eq:CCO (mult:<DWI>
6923                               (sign_extend:<DWI>
6924                                  (match_operand:SWI248 1 "register_operand"))
6925                               (match_dup 4))
6926                            (sign_extend:<DWI>
6927                               (mult:SWI248 (match_dup 1)
6928                                            (match_operand:SWI248 2
6929                                               "<general_operand>")))))
6930               (set (match_operand:SWI248 0 "register_operand")
6931                    (mult:SWI248 (match_dup 1) (match_dup 2)))])
6932    (set (pc) (if_then_else
6933                (eq (reg:CCO FLAGS_REG) (const_int 0))
6934                (label_ref (match_operand 3))
6935                (pc)))]
6936   ""
6938   if (CONST_INT_P (operands[2]))
6939     operands[4] = operands[2];
6940   else
6941     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6944 (define_insn "*mulv<mode>4"
6945   [(set (reg:CCO FLAGS_REG)
6946         (eq:CCO (mult:<DWI>
6947                    (sign_extend:<DWI>
6948                       (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6949                    (sign_extend:<DWI>
6950                       (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
6951                 (sign_extend:<DWI>
6952                    (mult:SWI48 (match_dup 1) (match_dup 2)))))
6953    (set (match_operand:SWI48 0 "register_operand" "=r,r")
6954         (mult:SWI48 (match_dup 1) (match_dup 2)))]
6955   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6956   "@
6957    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6958    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6959   [(set_attr "type" "imul")
6960    (set_attr "prefix_0f" "0,1")
6961    (set (attr "athlon_decode")
6962         (cond [(eq_attr "cpu" "athlon")
6963                   (const_string "vector")
6964                (eq_attr "alternative" "0")
6965                   (const_string "vector")
6966                (and (eq_attr "alternative" "1")
6967                     (match_operand 1 "memory_operand"))
6968                   (const_string "vector")]
6969               (const_string "direct")))
6970    (set (attr "amdfam10_decode")
6971         (cond [(and (eq_attr "alternative" "1")
6972                     (match_operand 1 "memory_operand"))
6973                   (const_string "vector")]
6974               (const_string "direct")))
6975    (set_attr "bdver1_decode" "direct")
6976    (set_attr "mode" "<MODE>")])
6978 (define_insn "*mulvhi4"
6979   [(set (reg:CCO FLAGS_REG)
6980         (eq:CCO (mult:SI
6981                    (sign_extend:SI
6982                       (match_operand:HI 1 "nonimmediate_operand" "%0"))
6983                    (sign_extend:SI
6984                       (match_operand:HI 2 "nonimmediate_operand" "mr")))
6985                 (sign_extend:SI
6986                    (mult:HI (match_dup 1) (match_dup 2)))))
6987    (set (match_operand:HI 0 "register_operand" "=r")
6988         (mult:HI (match_dup 1) (match_dup 2)))]
6989   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6990   "imul{w}\t{%2, %0|%0, %2}"
6991   [(set_attr "type" "imul")
6992    (set_attr "prefix_0f" "1")
6993    (set_attr "athlon_decode" "vector")
6994    (set_attr "amdfam10_decode" "direct")
6995    (set_attr "bdver1_decode" "double")
6996    (set_attr "mode" "HI")])
6998 (define_insn "*mulv<mode>4_1"
6999   [(set (reg:CCO FLAGS_REG)
7000         (eq:CCO (mult:<DWI>
7001                    (sign_extend:<DWI>
7002                       (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
7003                    (match_operand:<DWI> 3 "const_int_operand" "K,i"))
7004                 (sign_extend:<DWI>
7005                    (mult:SWI248 (match_dup 1)
7006                                 (match_operand:SWI248 2
7007                                    "<immediate_operand>" "K,<i>")))))
7008    (set (match_operand:SWI248 0 "register_operand" "=r,r")
7009         (mult:SWI248 (match_dup 1) (match_dup 2)))]
7010   "!(MEM_P (operands[1]) && MEM_P (operands[2]))
7011    && CONST_INT_P (operands[2])
7012    && INTVAL (operands[2]) == INTVAL (operands[3])"
7013   "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7014   [(set_attr "type" "imul")
7015    (set (attr "prefix_0f")
7016         (if_then_else
7017           (match_test "<MODE>mode == HImode")
7018             (const_string "0")
7019             (const_string "*")))
7020    (set (attr "athlon_decode")
7021         (cond [(eq_attr "cpu" "athlon")
7022                   (const_string "vector")
7023                (eq_attr "alternative" "1")
7024                   (const_string "vector")]
7025               (const_string "direct")))
7026    (set (attr "amdfam10_decode")
7027         (cond [(ior (match_test "<MODE>mode == HImode")
7028                     (match_operand 1 "memory_operand"))
7029                   (const_string "vector")]
7030               (const_string "direct")))
7031    (set (attr "bdver1_decode")
7032         (if_then_else
7033           (match_test "<MODE>mode == HImode")
7034             (const_string "double")
7035             (const_string "direct")))
7036    (set_attr "mode" "<MODE>")
7037    (set (attr "length_immediate")
7038         (cond [(eq_attr "alternative" "0")
7039                   (const_string "1")
7040                (match_test "<MODE_SIZE> == 8")
7041                   (const_string "4")]
7042               (const_string "<MODE_SIZE>")))])
7044 (define_expand "umulv<mode>4"
7045   [(parallel [(set (reg:CCO FLAGS_REG)
7046                    (eq:CCO (mult:<DWI>
7047                               (zero_extend:<DWI>
7048                                  (match_operand:SWI248 1
7049                                                       "nonimmediate_operand"))
7050                               (zero_extend:<DWI>
7051                                  (match_operand:SWI248 2
7052                                                       "nonimmediate_operand")))
7053                            (zero_extend:<DWI>
7054                               (mult:SWI248 (match_dup 1) (match_dup 2)))))
7055               (set (match_operand:SWI248 0 "register_operand")
7056                    (mult:SWI248 (match_dup 1) (match_dup 2)))
7057               (clobber (match_scratch:SWI248 4))])
7058    (set (pc) (if_then_else
7059                (eq (reg:CCO FLAGS_REG) (const_int 0))
7060                (label_ref (match_operand 3))
7061                (pc)))]
7062   ""
7064   if (MEM_P (operands[1]) && MEM_P (operands[2]))
7065     operands[1] = force_reg (<MODE>mode, operands[1]);
7068 (define_insn "*umulv<mode>4"
7069   [(set (reg:CCO FLAGS_REG)
7070         (eq:CCO (mult:<DWI>
7071                    (zero_extend:<DWI>
7072                       (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7073                    (zero_extend:<DWI>
7074                       (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7075                 (zero_extend:<DWI>
7076                    (mult:SWI248 (match_dup 1) (match_dup 2)))))
7077    (set (match_operand:SWI248 0 "register_operand" "=a")
7078         (mult:SWI248 (match_dup 1) (match_dup 2)))
7079    (clobber (match_scratch:SWI248 3 "=d"))]
7080   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7081   "mul{<imodesuffix>}\t%2"
7082   [(set_attr "type" "imul")
7083    (set_attr "length_immediate" "0")
7084    (set (attr "athlon_decode")
7085      (if_then_else (eq_attr "cpu" "athlon")
7086        (const_string "vector")
7087        (const_string "double")))
7088    (set_attr "amdfam10_decode" "double")
7089    (set_attr "bdver1_decode" "direct")
7090    (set_attr "mode" "<MODE>")])
7092 (define_expand "<u>mulvqi4"
7093   [(parallel [(set (reg:CCO FLAGS_REG)
7094                    (eq:CCO (mult:HI
7095                               (any_extend:HI
7096                                  (match_operand:QI 1 "nonimmediate_operand"))
7097                               (any_extend:HI
7098                                  (match_operand:QI 2 "nonimmediate_operand")))
7099                            (any_extend:HI
7100                               (mult:QI (match_dup 1) (match_dup 2)))))
7101               (set (match_operand:QI 0 "register_operand")
7102                    (mult:QI (match_dup 1) (match_dup 2)))])
7103    (set (pc) (if_then_else
7104                (eq (reg:CCO FLAGS_REG) (const_int 0))
7105                (label_ref (match_operand 3))
7106                (pc)))]
7107   "TARGET_QIMODE_MATH"
7109   if (MEM_P (operands[1]) && MEM_P (operands[2]))
7110     operands[1] = force_reg (QImode, operands[1]);
7113 (define_insn "*<u>mulvqi4"
7114   [(set (reg:CCO FLAGS_REG)
7115         (eq:CCO (mult:HI
7116                    (any_extend:HI
7117                       (match_operand:QI 1 "nonimmediate_operand" "%0"))
7118                    (any_extend:HI
7119                       (match_operand:QI 2 "nonimmediate_operand" "qm")))
7120                 (any_extend:HI
7121                    (mult:QI (match_dup 1) (match_dup 2)))))
7122    (set (match_operand:QI 0 "register_operand" "=a")
7123         (mult:QI (match_dup 1) (match_dup 2)))]
7124   "TARGET_QIMODE_MATH
7125    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7126   "<sgnprefix>mul{b}\t%2"
7127   [(set_attr "type" "imul")
7128    (set_attr "length_immediate" "0")
7129    (set (attr "athlon_decode")
7130      (if_then_else (eq_attr "cpu" "athlon")
7131         (const_string "vector")
7132         (const_string "direct")))
7133    (set_attr "amdfam10_decode" "direct")
7134    (set_attr "bdver1_decode" "direct")
7135    (set_attr "mode" "QI")])
7137 (define_expand "<u>mul<mode><dwi>3"
7138   [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7139                    (mult:<DWI>
7140                      (any_extend:<DWI>
7141                        (match_operand:DWIH 1 "nonimmediate_operand"))
7142                      (any_extend:<DWI>
7143                        (match_operand:DWIH 2 "register_operand"))))
7144               (clobber (reg:CC FLAGS_REG))])])
7146 (define_expand "<u>mulqihi3"
7147   [(parallel [(set (match_operand:HI 0 "register_operand")
7148                    (mult:HI
7149                      (any_extend:HI
7150                        (match_operand:QI 1 "nonimmediate_operand"))
7151                      (any_extend:HI
7152                        (match_operand:QI 2 "register_operand"))))
7153               (clobber (reg:CC FLAGS_REG))])]
7154   "TARGET_QIMODE_MATH")
7156 (define_insn "*bmi2_umul<mode><dwi>3_1"
7157   [(set (match_operand:DWIH 0 "register_operand" "=r")
7158         (mult:DWIH
7159           (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7160           (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7161    (set (match_operand:DWIH 1 "register_operand" "=r")
7162         (truncate:DWIH
7163           (lshiftrt:<DWI>
7164             (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7165                         (zero_extend:<DWI> (match_dup 3)))
7166             (match_operand:QI 4 "const_int_operand" "n"))))]
7167   "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7168    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7169   "mulx\t{%3, %0, %1|%1, %0, %3}"
7170   [(set_attr "type" "imulx")
7171    (set_attr "prefix" "vex")
7172    (set_attr "mode" "<MODE>")])
7174 (define_insn "*umul<mode><dwi>3_1"
7175   [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7176         (mult:<DWI>
7177           (zero_extend:<DWI>
7178             (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7179           (zero_extend:<DWI>
7180             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7181    (clobber (reg:CC FLAGS_REG))]
7182   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7183   "@
7184    #
7185    mul{<imodesuffix>}\t%2"
7186   [(set_attr "isa" "bmi2,*")
7187    (set_attr "type" "imulx,imul")
7188    (set_attr "length_immediate" "*,0")
7189    (set (attr "athlon_decode")
7190         (cond [(eq_attr "alternative" "1")
7191                  (if_then_else (eq_attr "cpu" "athlon")
7192                    (const_string "vector")
7193                    (const_string "double"))]
7194               (const_string "*")))
7195    (set_attr "amdfam10_decode" "*,double")
7196    (set_attr "bdver1_decode" "*,direct")
7197    (set_attr "prefix" "vex,orig")
7198    (set_attr "mode" "<MODE>")])
7200 ;; Convert mul to the mulx pattern to avoid flags dependency.
7201 (define_split
7202  [(set (match_operand:<DWI> 0 "register_operand")
7203        (mult:<DWI>
7204          (zero_extend:<DWI>
7205            (match_operand:DWIH 1 "register_operand"))
7206          (zero_extend:<DWI>
7207            (match_operand:DWIH 2 "nonimmediate_operand"))))
7208   (clobber (reg:CC FLAGS_REG))]
7209  "TARGET_BMI2 && reload_completed
7210   && true_regnum (operands[1]) == DX_REG"
7211   [(parallel [(set (match_dup 3)
7212                    (mult:DWIH (match_dup 1) (match_dup 2)))
7213               (set (match_dup 4)
7214                    (truncate:DWIH
7215                      (lshiftrt:<DWI>
7216                        (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7217                                    (zero_extend:<DWI> (match_dup 2)))
7218                        (match_dup 5))))])]
7220   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7222   operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7225 (define_insn "*mul<mode><dwi>3_1"
7226   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7227         (mult:<DWI>
7228           (sign_extend:<DWI>
7229             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7230           (sign_extend:<DWI>
7231             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7232    (clobber (reg:CC FLAGS_REG))]
7233   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7234   "imul{<imodesuffix>}\t%2"
7235   [(set_attr "type" "imul")
7236    (set_attr "length_immediate" "0")
7237    (set (attr "athlon_decode")
7238      (if_then_else (eq_attr "cpu" "athlon")
7239         (const_string "vector")
7240         (const_string "double")))
7241    (set_attr "amdfam10_decode" "double")
7242    (set_attr "bdver1_decode" "direct")
7243    (set_attr "mode" "<MODE>")])
7245 (define_insn "*<u>mulqihi3_1"
7246   [(set (match_operand:HI 0 "register_operand" "=a")
7247         (mult:HI
7248           (any_extend:HI
7249             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7250           (any_extend:HI
7251             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7252    (clobber (reg:CC FLAGS_REG))]
7253   "TARGET_QIMODE_MATH
7254    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7255   "<sgnprefix>mul{b}\t%2"
7256   [(set_attr "type" "imul")
7257    (set_attr "length_immediate" "0")
7258    (set (attr "athlon_decode")
7259      (if_then_else (eq_attr "cpu" "athlon")
7260         (const_string "vector")
7261         (const_string "direct")))
7262    (set_attr "amdfam10_decode" "direct")
7263    (set_attr "bdver1_decode" "direct")
7264    (set_attr "mode" "QI")])
7266 (define_expand "<s>mul<mode>3_highpart"
7267   [(parallel [(set (match_operand:SWI48 0 "register_operand")
7268                    (truncate:SWI48
7269                      (lshiftrt:<DWI>
7270                        (mult:<DWI>
7271                          (any_extend:<DWI>
7272                            (match_operand:SWI48 1 "nonimmediate_operand"))
7273                          (any_extend:<DWI>
7274                            (match_operand:SWI48 2 "register_operand")))
7275                        (match_dup 4))))
7276               (clobber (match_scratch:SWI48 3))
7277               (clobber (reg:CC FLAGS_REG))])]
7278   ""
7279   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7281 (define_insn "*<s>muldi3_highpart_1"
7282   [(set (match_operand:DI 0 "register_operand" "=d")
7283         (truncate:DI
7284           (lshiftrt:TI
7285             (mult:TI
7286               (any_extend:TI
7287                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7288               (any_extend:TI
7289                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7290             (const_int 64))))
7291    (clobber (match_scratch:DI 3 "=1"))
7292    (clobber (reg:CC FLAGS_REG))]
7293   "TARGET_64BIT
7294    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7295   "<sgnprefix>mul{q}\t%2"
7296   [(set_attr "type" "imul")
7297    (set_attr "length_immediate" "0")
7298    (set (attr "athlon_decode")
7299      (if_then_else (eq_attr "cpu" "athlon")
7300         (const_string "vector")
7301         (const_string "double")))
7302    (set_attr "amdfam10_decode" "double")
7303    (set_attr "bdver1_decode" "direct")
7304    (set_attr "mode" "DI")])
7306 (define_insn "*<s>mulsi3_highpart_1"
7307   [(set (match_operand:SI 0 "register_operand" "=d")
7308         (truncate:SI
7309           (lshiftrt:DI
7310             (mult:DI
7311               (any_extend:DI
7312                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7313               (any_extend:DI
7314                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7315             (const_int 32))))
7316    (clobber (match_scratch:SI 3 "=1"))
7317    (clobber (reg:CC FLAGS_REG))]
7318   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7319   "<sgnprefix>mul{l}\t%2"
7320   [(set_attr "type" "imul")
7321    (set_attr "length_immediate" "0")
7322    (set (attr "athlon_decode")
7323      (if_then_else (eq_attr "cpu" "athlon")
7324         (const_string "vector")
7325         (const_string "double")))
7326    (set_attr "amdfam10_decode" "double")
7327    (set_attr "bdver1_decode" "direct")
7328    (set_attr "mode" "SI")])
7330 (define_insn "*<s>mulsi3_highpart_zext"
7331   [(set (match_operand:DI 0 "register_operand" "=d")
7332         (zero_extend:DI (truncate:SI
7333           (lshiftrt:DI
7334             (mult:DI (any_extend:DI
7335                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7336                      (any_extend:DI
7337                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7338             (const_int 32)))))
7339    (clobber (match_scratch:SI 3 "=1"))
7340    (clobber (reg:CC FLAGS_REG))]
7341   "TARGET_64BIT
7342    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7343   "<sgnprefix>mul{l}\t%2"
7344   [(set_attr "type" "imul")
7345    (set_attr "length_immediate" "0")
7346    (set (attr "athlon_decode")
7347      (if_then_else (eq_attr "cpu" "athlon")
7348         (const_string "vector")
7349         (const_string "double")))
7350    (set_attr "amdfam10_decode" "double")
7351    (set_attr "bdver1_decode" "direct")
7352    (set_attr "mode" "SI")])
7354 ;; The patterns that match these are at the end of this file.
7356 (define_expand "mulxf3"
7357   [(set (match_operand:XF 0 "register_operand")
7358         (mult:XF (match_operand:XF 1 "register_operand")
7359                  (match_operand:XF 2 "register_operand")))]
7360   "TARGET_80387")
7362 (define_expand "mul<mode>3"
7363   [(set (match_operand:MODEF 0 "register_operand")
7364         (mult:MODEF (match_operand:MODEF 1 "register_operand")
7365                     (match_operand:MODEF 2 "nonimmediate_operand")))]
7366   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7367     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7369 ;; Divide instructions
7371 ;; The patterns that match these are at the end of this file.
7373 (define_expand "divxf3"
7374   [(set (match_operand:XF 0 "register_operand")
7375         (div:XF (match_operand:XF 1 "register_operand")
7376                 (match_operand:XF 2 "register_operand")))]
7377   "TARGET_80387")
7379 (define_expand "divdf3"
7380   [(set (match_operand:DF 0 "register_operand")
7381         (div:DF (match_operand:DF 1 "register_operand")
7382                 (match_operand:DF 2 "nonimmediate_operand")))]
7383    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7384     || (TARGET_SSE2 && TARGET_SSE_MATH)")
7386 (define_expand "divsf3"
7387   [(set (match_operand:SF 0 "register_operand")
7388         (div:SF (match_operand:SF 1 "register_operand")
7389                 (match_operand:SF 2 "nonimmediate_operand")))]
7390   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7391     || TARGET_SSE_MATH"
7393   if (TARGET_SSE_MATH
7394       && TARGET_RECIP_DIV
7395       && optimize_insn_for_speed_p ()
7396       && flag_finite_math_only && !flag_trapping_math
7397       && flag_unsafe_math_optimizations)
7398     {
7399       ix86_emit_swdivsf (operands[0], operands[1],
7400                          operands[2], SFmode);
7401       DONE;
7402     }
7405 ;; Divmod instructions.
7407 (define_expand "divmod<mode>4"
7408   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7409                    (div:SWIM248
7410                      (match_operand:SWIM248 1 "register_operand")
7411                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7412               (set (match_operand:SWIM248 3 "register_operand")
7413                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7414               (clobber (reg:CC FLAGS_REG))])])
7416 ;; Split with 8bit unsigned divide:
7417 ;;      if (dividend an divisor are in [0-255])
7418 ;;         use 8bit unsigned integer divide
7419 ;;       else
7420 ;;         use original integer divide
7421 (define_split
7422   [(set (match_operand:SWI48 0 "register_operand")
7423         (div:SWI48 (match_operand:SWI48 2 "register_operand")
7424                     (match_operand:SWI48 3 "nonimmediate_operand")))
7425    (set (match_operand:SWI48 1 "register_operand")
7426         (mod:SWI48 (match_dup 2) (match_dup 3)))
7427    (clobber (reg:CC FLAGS_REG))]
7428   "TARGET_USE_8BIT_IDIV
7429    && TARGET_QIMODE_MATH
7430    && can_create_pseudo_p ()
7431    && !optimize_insn_for_size_p ()"
7432   [(const_int 0)]
7433   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7435 (define_insn_and_split "divmod<mode>4_1"
7436   [(set (match_operand:SWI48 0 "register_operand" "=a")
7437         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7438                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7439    (set (match_operand:SWI48 1 "register_operand" "=&d")
7440         (mod:SWI48 (match_dup 2) (match_dup 3)))
7441    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7442    (clobber (reg:CC FLAGS_REG))]
7443   ""
7444   "#"
7445   "reload_completed"
7446   [(parallel [(set (match_dup 1)
7447                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7448               (clobber (reg:CC FLAGS_REG))])
7449    (parallel [(set (match_dup 0)
7450                    (div:SWI48 (match_dup 2) (match_dup 3)))
7451               (set (match_dup 1)
7452                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7453               (use (match_dup 1))
7454               (clobber (reg:CC FLAGS_REG))])]
7456   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7458   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7459     operands[4] = operands[2];
7460   else
7461     {
7462       /* Avoid use of cltd in favor of a mov+shift.  */
7463       emit_move_insn (operands[1], operands[2]);
7464       operands[4] = operands[1];
7465     }
7467   [(set_attr "type" "multi")
7468    (set_attr "mode" "<MODE>")])
7470 (define_insn_and_split "*divmod<mode>4"
7471   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7472         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7473                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7474    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7475         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7476    (clobber (reg:CC FLAGS_REG))]
7477   ""
7478   "#"
7479   "reload_completed"
7480   [(parallel [(set (match_dup 1)
7481                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7482               (clobber (reg:CC FLAGS_REG))])
7483    (parallel [(set (match_dup 0)
7484                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7485               (set (match_dup 1)
7486                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7487               (use (match_dup 1))
7488               (clobber (reg:CC FLAGS_REG))])]
7490   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7492   if (<MODE>mode != HImode
7493       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7494     operands[4] = operands[2];
7495   else
7496     {
7497       /* Avoid use of cltd in favor of a mov+shift.  */
7498       emit_move_insn (operands[1], operands[2]);
7499       operands[4] = operands[1];
7500     }
7502   [(set_attr "type" "multi")
7503    (set_attr "mode" "<MODE>")])
7505 (define_insn "*divmod<mode>4_noext"
7506   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7507         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7508                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7509    (set (match_operand:SWIM248 1 "register_operand" "=d")
7510         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7511    (use (match_operand:SWIM248 4 "register_operand" "1"))
7512    (clobber (reg:CC FLAGS_REG))]
7513   ""
7514   "idiv{<imodesuffix>}\t%3"
7515   [(set_attr "type" "idiv")
7516    (set_attr "mode" "<MODE>")])
7518 (define_expand "divmodqi4"
7519   [(parallel [(set (match_operand:QI 0 "register_operand")
7520                    (div:QI
7521                      (match_operand:QI 1 "register_operand")
7522                      (match_operand:QI 2 "nonimmediate_operand")))
7523               (set (match_operand:QI 3 "register_operand")
7524                    (mod:QI (match_dup 1) (match_dup 2)))
7525               (clobber (reg:CC FLAGS_REG))])]
7526   "TARGET_QIMODE_MATH"
7528   rtx div, mod;
7529   rtx tmp0, tmp1;
7530   
7531   tmp0 = gen_reg_rtx (HImode);
7532   tmp1 = gen_reg_rtx (HImode);
7534   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7535      in AX.  */
7536   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7537   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7539   /* Extract remainder from AH.  */
7540   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7541   rtx_insn *insn = emit_move_insn (operands[3], tmp1);
7543   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7544   set_unique_reg_note (insn, REG_EQUAL, mod);
7546   /* Extract quotient from AL.  */
7547   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7549   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7550   set_unique_reg_note (insn, REG_EQUAL, div);
7552   DONE;
7555 ;; Divide AX by r/m8, with result stored in
7556 ;; AL <- Quotient
7557 ;; AH <- Remainder
7558 ;; Change div/mod to HImode and extend the second argument to HImode
7559 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7560 ;; combine may fail.
7561 (define_insn "divmodhiqi3"
7562   [(set (match_operand:HI 0 "register_operand" "=a")
7563         (ior:HI
7564           (ashift:HI
7565             (zero_extend:HI
7566               (truncate:QI
7567                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7568                         (sign_extend:HI
7569                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7570             (const_int 8))
7571           (zero_extend:HI
7572             (truncate:QI
7573               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7574    (clobber (reg:CC FLAGS_REG))]
7575   "TARGET_QIMODE_MATH"
7576   "idiv{b}\t%2"
7577   [(set_attr "type" "idiv")
7578    (set_attr "mode" "QI")])
7580 (define_expand "udivmod<mode>4"
7581   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7582                    (udiv:SWIM248
7583                      (match_operand:SWIM248 1 "register_operand")
7584                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7585               (set (match_operand:SWIM248 3 "register_operand")
7586                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7587               (clobber (reg:CC FLAGS_REG))])])
7589 ;; Split with 8bit unsigned divide:
7590 ;;      if (dividend an divisor are in [0-255])
7591 ;;         use 8bit unsigned integer divide
7592 ;;       else
7593 ;;         use original integer divide
7594 (define_split
7595   [(set (match_operand:SWI48 0 "register_operand")
7596         (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7597                     (match_operand:SWI48 3 "nonimmediate_operand")))
7598    (set (match_operand:SWI48 1 "register_operand")
7599         (umod:SWI48 (match_dup 2) (match_dup 3)))
7600    (clobber (reg:CC FLAGS_REG))]
7601   "TARGET_USE_8BIT_IDIV
7602    && TARGET_QIMODE_MATH
7603    && can_create_pseudo_p ()
7604    && !optimize_insn_for_size_p ()"
7605   [(const_int 0)]
7606   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7608 (define_insn_and_split "udivmod<mode>4_1"
7609   [(set (match_operand:SWI48 0 "register_operand" "=a")
7610         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7611                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7612    (set (match_operand:SWI48 1 "register_operand" "=&d")
7613         (umod:SWI48 (match_dup 2) (match_dup 3)))
7614    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7615    (clobber (reg:CC FLAGS_REG))]
7616   ""
7617   "#"
7618   "reload_completed"
7619   [(set (match_dup 1) (const_int 0))
7620    (parallel [(set (match_dup 0)
7621                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7622               (set (match_dup 1)
7623                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7624               (use (match_dup 1))
7625               (clobber (reg:CC FLAGS_REG))])]
7626   ""
7627   [(set_attr "type" "multi")
7628    (set_attr "mode" "<MODE>")])
7630 (define_insn_and_split "*udivmod<mode>4"
7631   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7632         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7633                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7634    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7635         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7636    (clobber (reg:CC FLAGS_REG))]
7637   ""
7638   "#"
7639   "reload_completed"
7640   [(set (match_dup 1) (const_int 0))
7641    (parallel [(set (match_dup 0)
7642                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7643               (set (match_dup 1)
7644                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7645               (use (match_dup 1))
7646               (clobber (reg:CC FLAGS_REG))])]
7647   ""
7648   [(set_attr "type" "multi")
7649    (set_attr "mode" "<MODE>")])
7651 ;; Optimize division or modulo by constant power of 2, if the constant
7652 ;; materializes only after expansion.
7653 (define_insn_and_split "*udivmod<mode>4_pow2"
7654   [(set (match_operand:SWI48 0 "register_operand" "=r")
7655         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7656                     (match_operand:SWI48 3 "const_int_operand" "n")))
7657    (set (match_operand:SWI48 1 "register_operand" "=r")
7658         (umod:SWI48 (match_dup 2) (match_dup 3)))
7659    (clobber (reg:CC FLAGS_REG))]
7660   "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
7661    && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
7662   "#"
7663   "&& 1"
7664   [(set (match_dup 1) (match_dup 2))
7665    (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
7666               (clobber (reg:CC FLAGS_REG))])
7667    (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
7668               (clobber (reg:CC FLAGS_REG))])]
7670   int v = exact_log2 (UINTVAL (operands[3]));
7671   operands[4] = GEN_INT (v);
7672   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7674   [(set_attr "type" "multi")
7675    (set_attr "mode" "<MODE>")])
7677 (define_insn "*udivmod<mode>4_noext"
7678   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7679         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7680                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7681    (set (match_operand:SWIM248 1 "register_operand" "=d")
7682         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7683    (use (match_operand:SWIM248 4 "register_operand" "1"))
7684    (clobber (reg:CC FLAGS_REG))]
7685   ""
7686   "div{<imodesuffix>}\t%3"
7687   [(set_attr "type" "idiv")
7688    (set_attr "mode" "<MODE>")])
7690 (define_expand "udivmodqi4"
7691   [(parallel [(set (match_operand:QI 0 "register_operand")
7692                    (udiv:QI
7693                      (match_operand:QI 1 "register_operand")
7694                      (match_operand:QI 2 "nonimmediate_operand")))
7695               (set (match_operand:QI 3 "register_operand")
7696                    (umod:QI (match_dup 1) (match_dup 2)))
7697               (clobber (reg:CC FLAGS_REG))])]
7698   "TARGET_QIMODE_MATH"
7700   rtx div, mod;
7701   rtx tmp0, tmp1;
7702   
7703   tmp0 = gen_reg_rtx (HImode);
7704   tmp1 = gen_reg_rtx (HImode);
7706   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7707      in AX.  */
7708   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7709   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7711   /* Extract remainder from AH.  */
7712   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7713   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7714   rtx_insn *insn = emit_move_insn (operands[3], tmp1);
7716   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7717   set_unique_reg_note (insn, REG_EQUAL, mod);
7719   /* Extract quotient from AL.  */
7720   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7722   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7723   set_unique_reg_note (insn, REG_EQUAL, div);
7725   DONE;
7728 (define_insn "udivmodhiqi3"
7729   [(set (match_operand:HI 0 "register_operand" "=a")
7730         (ior:HI
7731           (ashift:HI
7732             (zero_extend:HI
7733               (truncate:QI
7734                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7735                         (zero_extend:HI
7736                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7737             (const_int 8))
7738           (zero_extend:HI
7739             (truncate:QI
7740               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7741    (clobber (reg:CC FLAGS_REG))]
7742   "TARGET_QIMODE_MATH"
7743   "div{b}\t%2"
7744   [(set_attr "type" "idiv")
7745    (set_attr "mode" "QI")])
7747 ;; We cannot use div/idiv for double division, because it causes
7748 ;; "division by zero" on the overflow and that's not what we expect
7749 ;; from truncate.  Because true (non truncating) double division is
7750 ;; never generated, we can't create this insn anyway.
7752 ;(define_insn ""
7753 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7754 ;       (truncate:SI
7755 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7756 ;                  (zero_extend:DI
7757 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7758 ;   (set (match_operand:SI 3 "register_operand" "=d")
7759 ;       (truncate:SI
7760 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7761 ;   (clobber (reg:CC FLAGS_REG))]
7762 ;  ""
7763 ;  "div{l}\t{%2, %0|%0, %2}"
7764 ;  [(set_attr "type" "idiv")])
7766 ;;- Logical AND instructions
7768 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7769 ;; Note that this excludes ah.
7771 (define_expand "testsi_ccno_1"
7772   [(set (reg:CCNO FLAGS_REG)
7773         (compare:CCNO
7774           (and:SI (match_operand:SI 0 "nonimmediate_operand")
7775                   (match_operand:SI 1 "x86_64_nonmemory_operand"))
7776           (const_int 0)))])
7778 (define_expand "testqi_ccz_1"
7779   [(set (reg:CCZ FLAGS_REG)
7780         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7781                              (match_operand:QI 1 "nonmemory_operand"))
7782                  (const_int 0)))])
7784 (define_expand "testdi_ccno_1"
7785   [(set (reg:CCNO FLAGS_REG)
7786         (compare:CCNO
7787           (and:DI (match_operand:DI 0 "nonimmediate_operand")
7788                   (match_operand:DI 1 "x86_64_szext_general_operand"))
7789           (const_int 0)))]
7790   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7792 (define_insn "*testdi_1"
7793   [(set (reg FLAGS_REG)
7794         (compare
7795          (and:DI
7796           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7797           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7798          (const_int 0)))]
7799   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7800    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7801   "@
7802    test{l}\t{%k1, %k0|%k0, %k1}
7803    test{l}\t{%k1, %k0|%k0, %k1}
7804    test{q}\t{%1, %0|%0, %1}
7805    test{q}\t{%1, %0|%0, %1}
7806    test{q}\t{%1, %0|%0, %1}"
7807   [(set_attr "type" "test")
7808    (set_attr "modrm" "0,1,0,1,1")
7809    (set_attr "mode" "SI,SI,DI,DI,DI")])
7811 (define_insn "*testqi_1_maybe_si"
7812   [(set (reg FLAGS_REG)
7813         (compare
7814           (and:QI
7815             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7816             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7817           (const_int 0)))]
7818    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7819     && ix86_match_ccmode (insn,
7820                          CONST_INT_P (operands[1])
7821                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7823   if (which_alternative == 3)
7824     {
7825       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7826         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7827       return "test{l}\t{%1, %k0|%k0, %1}";
7828     }
7829   return "test{b}\t{%1, %0|%0, %1}";
7831   [(set_attr "type" "test")
7832    (set_attr "modrm" "0,1,1,1")
7833    (set_attr "mode" "QI,QI,QI,SI")
7834    (set_attr "pent_pair" "uv,np,uv,np")])
7836 (define_insn "*test<mode>_1"
7837   [(set (reg FLAGS_REG)
7838         (compare
7839          (and:SWI124
7840           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7841           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7842          (const_int 0)))]
7843   "ix86_match_ccmode (insn, CCNOmode)
7844    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7845   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7846   [(set_attr "type" "test")
7847    (set_attr "modrm" "0,1,1")
7848    (set_attr "mode" "<MODE>")
7849    (set_attr "pent_pair" "uv,np,uv")])
7851 (define_expand "testqi_ext_ccno_0"
7852   [(set (reg:CCNO FLAGS_REG)
7853         (compare:CCNO
7854           (and:SI
7855             (zero_extract:SI
7856               (match_operand 0 "ext_register_operand")
7857               (const_int 8)
7858               (const_int 8))
7859             (match_operand 1 "const_int_operand"))
7860           (const_int 0)))])
7862 (define_insn "*testqi_ext_0"
7863   [(set (reg FLAGS_REG)
7864         (compare
7865           (and:SI
7866             (zero_extract:SI
7867               (match_operand 0 "ext_register_operand" "Q")
7868               (const_int 8)
7869               (const_int 8))
7870             (match_operand 1 "const_int_operand" "n"))
7871           (const_int 0)))]
7872   "ix86_match_ccmode (insn, CCNOmode)"
7873   "test{b}\t{%1, %h0|%h0, %1}"
7874   [(set_attr "type" "test")
7875    (set_attr "mode" "QI")
7876    (set_attr "length_immediate" "1")
7877    (set_attr "modrm" "1")
7878    (set_attr "pent_pair" "np")])
7880 (define_insn "*testqi_ext_1"
7881   [(set (reg FLAGS_REG)
7882         (compare
7883           (and:SI
7884             (zero_extract:SI
7885               (match_operand 0 "ext_register_operand" "Q,Q")
7886               (const_int 8)
7887               (const_int 8))
7888             (zero_extend:SI
7889               (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7890           (const_int 0)))]
7891   "ix86_match_ccmode (insn, CCNOmode)"
7892   "test{b}\t{%1, %h0|%h0, %1}"
7893   [(set_attr "isa" "*,nox64")
7894    (set_attr "type" "test")
7895    (set_attr "mode" "QI")])
7897 (define_insn "*testqi_ext_2"
7898   [(set (reg FLAGS_REG)
7899         (compare
7900           (and:SI
7901             (zero_extract:SI
7902               (match_operand 0 "ext_register_operand" "Q")
7903               (const_int 8)
7904               (const_int 8))
7905             (zero_extract:SI
7906               (match_operand 1 "ext_register_operand" "Q")
7907               (const_int 8)
7908               (const_int 8)))
7909           (const_int 0)))]
7910   "ix86_match_ccmode (insn, CCNOmode)"
7911   "test{b}\t{%h1, %h0|%h0, %h1}"
7912   [(set_attr "type" "test")
7913    (set_attr "mode" "QI")])
7915 ;; Combine likes to form bit extractions for some tests.  Humor it.
7916 (define_insn "*testqi_ext_3"
7917   [(set (reg FLAGS_REG)
7918         (compare (zero_extract:SWI248
7919                    (match_operand 0 "nonimmediate_operand" "rm")
7920                    (match_operand 1 "const_int_operand" "n")
7921                    (match_operand 2 "const_int_operand" "n"))
7922                  (const_int 0)))]
7923   "ix86_match_ccmode (insn, CCNOmode)
7924    && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7925        || GET_MODE (operands[0]) == SImode
7926        || GET_MODE (operands[0]) == HImode
7927        || GET_MODE (operands[0]) == QImode)
7928    /* Ensure that resulting mask is zero or sign extended operand.  */
7929    && INTVAL (operands[2]) >= 0
7930    && ((INTVAL (operands[1]) > 0
7931         && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7932        || (<MODE>mode == DImode
7933            && INTVAL (operands[1]) > 32
7934            && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7935   "#")
7937 (define_split
7938   [(set (match_operand 0 "flags_reg_operand")
7939         (match_operator 1 "compare_operator"
7940           [(zero_extract
7941              (match_operand 2 "nonimmediate_operand")
7942              (match_operand 3 "const_int_operand")
7943              (match_operand 4 "const_int_operand"))
7944            (const_int 0)]))]
7945   "ix86_match_ccmode (insn, CCNOmode)"
7946   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7948   rtx val = operands[2];
7949   HOST_WIDE_INT len = INTVAL (operands[3]);
7950   HOST_WIDE_INT pos = INTVAL (operands[4]);
7951   HOST_WIDE_INT mask;
7952   machine_mode mode, submode;
7954   mode = GET_MODE (val);
7955   if (MEM_P (val))
7956     {
7957       /* ??? Combine likes to put non-volatile mem extractions in QImode
7958          no matter the size of the test.  So find a mode that works.  */
7959       if (! MEM_VOLATILE_P (val))
7960         {
7961           mode = smallest_mode_for_size (pos + len, MODE_INT);
7962           val = adjust_address (val, mode, 0);
7963         }
7964     }
7965   else if (SUBREG_P (val)
7966            && (submode = GET_MODE (SUBREG_REG (val)),
7967                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7968            && pos + len <= GET_MODE_BITSIZE (submode)
7969            && GET_MODE_CLASS (submode) == MODE_INT)
7970     {
7971       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7972       mode = submode;
7973       val = SUBREG_REG (val);
7974     }
7975   else if (mode == HImode && pos + len <= 8)
7976     {
7977       /* Small HImode tests can be converted to QImode.  */
7978       mode = QImode;
7979       val = gen_lowpart (QImode, val);
7980     }
7982   if (len == HOST_BITS_PER_WIDE_INT)
7983     mask = -1;
7984   else
7985     mask = ((HOST_WIDE_INT)1 << len) - 1;
7986   mask <<= pos;
7988   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7991 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7992 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7993 ;; this is relatively important trick.
7994 ;; Do the conversion only post-reload to avoid limiting of the register class
7995 ;; to QI regs.
7996 (define_split
7997   [(set (match_operand 0 "flags_reg_operand")
7998         (match_operator 1 "compare_operator"
7999           [(and (match_operand 2 "QIreg_operand")
8000                 (match_operand 3 "const_int_operand"))
8001            (const_int 0)]))]
8002    "reload_completed
8003     && GET_MODE (operands[2]) != QImode
8004     && ((ix86_match_ccmode (insn, CCZmode)
8005          && !(INTVAL (operands[3]) & ~(255 << 8)))
8006         || (ix86_match_ccmode (insn, CCNOmode)
8007             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8008   [(set (match_dup 0)
8009         (match_op_dup 1
8010           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8011                    (match_dup 3))
8012            (const_int 0)]))]
8014   operands[2] = gen_lowpart (SImode, operands[2]);
8015   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
8018 (define_split
8019   [(set (match_operand 0 "flags_reg_operand")
8020         (match_operator 1 "compare_operator"
8021           [(and (match_operand 2 "nonimmediate_operand")
8022                 (match_operand 3 "const_int_operand"))
8023            (const_int 0)]))]
8024    "reload_completed
8025     && GET_MODE (operands[2]) != QImode
8026     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8027     && ((ix86_match_ccmode (insn, CCZmode)
8028          && !(INTVAL (operands[3]) & ~255))
8029         || (ix86_match_ccmode (insn, CCNOmode)
8030             && !(INTVAL (operands[3]) & ~127)))"
8031   [(set (match_dup 0)
8032         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8033                          (const_int 0)]))]
8035   operands[2] = gen_lowpart (QImode, operands[2]);
8036   operands[3] = gen_lowpart (QImode, operands[3]);
8039 (define_split
8040   [(set (match_operand:SWI1248x 0 "mask_reg_operand")
8041         (any_logic:SWI1248x (match_operand:SWI1248x 1 "mask_reg_operand")
8042                             (match_operand:SWI1248x 2 "mask_reg_operand")))
8043    (clobber (reg:CC FLAGS_REG))]
8044   "TARGET_AVX512F && reload_completed"
8045   [(set (match_dup 0)
8046         (any_logic:SWI1248x (match_dup 1)
8047                             (match_dup 2)))])
8049 (define_mode_iterator SWI1248_AVX512BW
8050   [QI HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
8052 (define_insn "*k<logic><mode>"
8053   [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand" "=k")
8054         (any_logic:SWI1248_AVX512BW (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand" "k")
8055                                     (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand" "k")))]
8056   "TARGET_AVX512F"
8057   {
8058     if (!TARGET_AVX512DQ && <MODE>mode == QImode)
8059       return "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
8060     else
8061       return "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
8062   }
8063   [(set_attr "mode" "<MODE>")
8064    (set_attr "type" "msklog")
8065    (set_attr "prefix" "vex")])
8067 ;; %%% This used to optimize known byte-wide and operations to memory,
8068 ;; and sometimes to QImode registers.  If this is considered useful,
8069 ;; it should be done with splitters.
8071 (define_expand "and<mode>3"
8072   [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8073         (and:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8074                       (match_operand:SWIM1248x 2 "<general_szext_operand>")))]
8075   ""
8077   machine_mode mode = <MODE>mode;
8078   rtx (*insn) (rtx, rtx);
8080   if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
8081     {
8082       HOST_WIDE_INT ival = INTVAL (operands[2]);
8084       if (ival == (HOST_WIDE_INT) 0xffffffff)
8085         mode = SImode;
8086       else if (ival == 0xffff)
8087         mode = HImode;
8088       else if (ival == 0xff)
8089         mode = QImode;
8090       }
8092   if (mode == <MODE>mode)
8093     {
8094       ix86_expand_binary_operator (AND, <MODE>mode, operands);
8095       DONE;
8096     }
8098   if (<MODE>mode == DImode)
8099     insn = (mode == SImode)
8100            ? gen_zero_extendsidi2
8101            : (mode == HImode)
8102            ? gen_zero_extendhidi2
8103            : gen_zero_extendqidi2;
8104   else if (<MODE>mode == SImode)
8105     insn = (mode == HImode)
8106            ? gen_zero_extendhisi2
8107            : gen_zero_extendqisi2;
8108   else if (<MODE>mode == HImode)
8109     insn = gen_zero_extendqihi2;
8110   else
8111     gcc_unreachable ();
8113   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8114   DONE;
8117 (define_insn "*anddi_1"
8118   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,!k")
8119         (and:DI
8120          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
8121          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L,k")))
8122    (clobber (reg:CC FLAGS_REG))]
8123   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8125   switch (get_attr_type (insn))
8126     {
8127     case TYPE_IMOVX:
8128       return "#";
8130     case TYPE_MSKLOG:
8131       return "kandq\t{%2, %1, %0|%0, %1, %2}";
8133     default:
8134       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8135       if (get_attr_mode (insn) == MODE_SI)
8136         return "and{l}\t{%k2, %k0|%k0, %k2}";
8137       else
8138         return "and{q}\t{%2, %0|%0, %2}";
8139     }
8141   [(set_attr "type" "alu,alu,alu,imovx,msklog")
8142    (set_attr "length_immediate" "*,*,*,0,0")
8143    (set (attr "prefix_rex")
8144      (if_then_else
8145        (and (eq_attr "type" "imovx")
8146             (and (match_test "INTVAL (operands[2]) == 0xff")
8147                  (match_operand 1 "ext_QIreg_operand")))
8148        (const_string "1")
8149        (const_string "*")))
8150    (set_attr "mode" "SI,DI,DI,SI,DI")])
8152 (define_insn_and_split "*anddi3_doubleword"
8153   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8154         (and:DI
8155          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8156          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8157    (clobber (reg:CC FLAGS_REG))]
8158   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8159    && ix86_binary_operator_ok (AND, DImode, operands)"
8160   "#"
8161   "&& reload_completed"
8162   [(const_int 0)]
8164   split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8165   if (operands[2] == const0_rtx)
8166     {
8167       operands[1] = const0_rtx;
8168       ix86_expand_move (SImode, &operands[0]);
8169     }
8170   else if (operands[2] != constm1_rtx)
8171     ix86_expand_binary_operator (AND, SImode, &operands[0]);
8172   else if (operands[5] == constm1_rtx)
8173     emit_note (NOTE_INSN_DELETED);
8174   if (operands[5] == const0_rtx)
8175     {
8176       operands[4] = const0_rtx;
8177       ix86_expand_move (SImode, &operands[3]);
8178     }
8179   else if (operands[5] != constm1_rtx)
8180     ix86_expand_binary_operator (AND, SImode, &operands[3]);
8181   DONE;
8184 (define_insn "*andsi_1"
8185   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
8186         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm,k")
8187                 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L,k")))
8188    (clobber (reg:CC FLAGS_REG))]
8189   "ix86_binary_operator_ok (AND, SImode, operands)"
8191   switch (get_attr_type (insn))
8192     {
8193     case TYPE_IMOVX:
8194       return "#";
8196     case TYPE_MSKLOG:
8197       return "kandd\t{%2, %1, %0|%0, %1, %2}";
8199     default:
8200       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8201       return "and{l}\t{%2, %0|%0, %2}";
8202     }
8204   [(set_attr "type" "alu,alu,imovx,msklog")
8205    (set (attr "prefix_rex")
8206      (if_then_else
8207        (and (eq_attr "type" "imovx")
8208             (and (match_test "INTVAL (operands[2]) == 0xff")
8209                  (match_operand 1 "ext_QIreg_operand")))
8210        (const_string "1")
8211        (const_string "*")))
8212    (set_attr "length_immediate" "*,*,0,0")
8213    (set_attr "mode" "SI")])
8215 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8216 (define_insn "*andsi_1_zext"
8217   [(set (match_operand:DI 0 "register_operand" "=r")
8218         (zero_extend:DI
8219           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8220                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8221    (clobber (reg:CC FLAGS_REG))]
8222   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8223   "and{l}\t{%2, %k0|%k0, %2}"
8224   [(set_attr "type" "alu")
8225    (set_attr "mode" "SI")])
8227 (define_insn "*andhi_1"
8228   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
8229         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k")
8230                 (match_operand:HI 2 "general_operand" "rn,rm,L,k")))
8231    (clobber (reg:CC FLAGS_REG))]
8232   "ix86_binary_operator_ok (AND, HImode, operands)"
8234   switch (get_attr_type (insn))
8235     {
8236     case TYPE_IMOVX:
8237       return "#";
8239     case TYPE_MSKLOG:
8240       return "kandw\t{%2, %1, %0|%0, %1, %2}";
8242     default:
8243       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8244       return "and{w}\t{%2, %0|%0, %2}";
8245     }
8247   [(set_attr "type" "alu,alu,imovx,msklog")
8248    (set_attr "length_immediate" "*,*,0,*")
8249    (set (attr "prefix_rex")
8250      (if_then_else
8251        (and (eq_attr "type" "imovx")
8252             (match_operand 1 "ext_QIreg_operand"))
8253        (const_string "1")
8254        (const_string "*")))
8255    (set_attr "mode" "HI,HI,SI,HI")])
8257 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8258 (define_insn "*andqi_1"
8259   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
8260         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8261                 (match_operand:QI 2 "general_operand" "qn,qmn,rn,k")))
8262    (clobber (reg:CC FLAGS_REG))]
8263   "ix86_binary_operator_ok (AND, QImode, operands)"
8265   switch (which_alternative)
8266     {
8267     case 0:
8268     case 1:
8269       return "and{b}\t{%2, %0|%0, %2}";
8270     case 2:
8271       return "and{l}\t{%k2, %k0|%k0, %k2}";
8272     case 3:
8273       return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}"
8274                              : "kandw\t{%2, %1, %0|%0, %1, %2}";
8275     default:
8276       gcc_unreachable ();
8277     }
8279   [(set_attr "type" "alu,alu,alu,msklog")
8280    (set_attr "mode" "QI,QI,SI,HI")])
8282 (define_insn "*andqi_1_slp"
8283   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8284         (and:QI (match_dup 0)
8285                 (match_operand:QI 1 "general_operand" "qn,qmn")))
8286    (clobber (reg:CC FLAGS_REG))]
8287   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8288    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8289   "and{b}\t{%1, %0|%0, %1}"
8290   [(set_attr "type" "alu1")
8291    (set_attr "mode" "QI")])
8293 (define_insn "kandn<mode>"
8294   [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k")
8295         (and:SWI12
8296           (not:SWI12
8297             (match_operand:SWI12 1 "register_operand" "r,0,k"))
8298           (match_operand:SWI12 2 "register_operand" "r,r,k")))
8299    (clobber (reg:CC FLAGS_REG))]
8300   "TARGET_AVX512F"
8302   switch (which_alternative)
8303     {
8304     case 0:
8305       return "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}";
8306     case 1:
8307       return "#";
8308     case 2:
8309       if (TARGET_AVX512DQ && <MODE>mode == QImode)
8310         return "kandnb\t{%2, %1, %0|%0, %1, %2}";
8311       else
8312         return "kandnw\t{%2, %1, %0|%0, %1, %2}";
8313     default:
8314       gcc_unreachable ();
8315     }
8317   [(set_attr "isa" "bmi,*,avx512f")
8318    (set_attr "type" "bitmanip,*,msklog")
8319    (set_attr "prefix" "*,*,vex")
8320    (set_attr "btver2_decode" "direct,*,*")
8321    (set_attr "mode" "<MODE>")])
8323 (define_split
8324   [(set (match_operand:SWI12 0 "general_reg_operand")
8325         (and:SWI12
8326           (not:SWI12
8327             (match_dup 0))
8328           (match_operand:SWI12 1 "general_reg_operand")))
8329    (clobber (reg:CC FLAGS_REG))]
8330   "TARGET_AVX512F && !TARGET_BMI && reload_completed"
8331   [(set (match_dup 0)
8332         (not:SWI12 (match_dup 0)))
8333    (parallel [(set (match_dup 0)
8334                    (and:SWI12 (match_dup 0)
8335                               (match_dup 1)))
8336               (clobber (reg:CC FLAGS_REG))])])
8338 ;; Turn *anddi_1 into *andsi_1_zext if possible.
8339 (define_split
8340   [(set (match_operand:DI 0 "register_operand")
8341         (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8342                 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8343    (clobber (reg:CC FLAGS_REG))]
8344   "TARGET_64BIT"
8345   [(parallel [(set (match_dup 0)
8346                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8347               (clobber (reg:CC FLAGS_REG))])]
8348   "operands[2] = gen_lowpart (SImode, operands[2]);")
8350 (define_split
8351   [(set (match_operand:SWI248 0 "register_operand")
8352         (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8353                     (match_operand:SWI248 2 "const_int_operand")))
8354    (clobber (reg:CC FLAGS_REG))]
8355   "reload_completed
8356    && true_regnum (operands[0]) != true_regnum (operands[1])"
8357   [(const_int 0)]
8359   HOST_WIDE_INT ival = INTVAL (operands[2]);
8360   machine_mode mode;
8361   rtx (*insn) (rtx, rtx);
8363   if (ival == (HOST_WIDE_INT) 0xffffffff)
8364     mode = SImode;
8365   else if (ival == 0xffff)
8366     mode = HImode;
8367   else
8368     {
8369       gcc_assert (ival == 0xff);
8370       mode = QImode;
8371     }
8373   if (<MODE>mode == DImode)
8374     insn = (mode == SImode)
8375            ? gen_zero_extendsidi2
8376            : (mode == HImode)
8377            ? gen_zero_extendhidi2
8378            : gen_zero_extendqidi2;
8379   else
8380     {
8381       if (<MODE>mode != SImode)
8382         /* Zero extend to SImode to avoid partial register stalls.  */
8383         operands[0] = gen_lowpart (SImode, operands[0]);
8385       insn = (mode == HImode)
8386              ? gen_zero_extendhisi2
8387              : gen_zero_extendqisi2;
8388     }
8389   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8390   DONE;
8393 (define_split
8394   [(set (match_operand:SWI48 0 "register_operand")
8395         (and:SWI48 (match_dup 0)
8396                    (const_int -65536)))
8397    (clobber (reg:CC FLAGS_REG))]
8398   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8399     || optimize_function_for_size_p (cfun)"
8400   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8401   "operands[1] = gen_lowpart (HImode, operands[0]);")
8403 (define_split
8404   [(set (match_operand:SWI248 0 "any_QIreg_operand")
8405         (and:SWI248 (match_dup 0)
8406                     (const_int -256)))
8407    (clobber (reg:CC FLAGS_REG))]
8408   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8409    && reload_completed"
8410   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8411   "operands[1] = gen_lowpart (QImode, operands[0]);")
8413 (define_split
8414   [(set (match_operand:SWI248 0 "QIreg_operand")
8415         (and:SWI248 (match_dup 0)
8416                     (const_int -65281)))
8417    (clobber (reg:CC FLAGS_REG))]
8418   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8419    && reload_completed"
8420   [(parallel [(set (zero_extract:SI (match_dup 0)
8421                                     (const_int 8)
8422                                     (const_int 8))
8423                    (xor:SI
8424                      (zero_extract:SI (match_dup 0)
8425                                       (const_int 8)
8426                                       (const_int 8))
8427                      (zero_extract:SI (match_dup 0)
8428                                       (const_int 8)
8429                                       (const_int 8))))
8430               (clobber (reg:CC FLAGS_REG))])]
8431   "operands[0] = gen_lowpart (SImode, operands[0]);")
8433 (define_insn "*anddi_2"
8434   [(set (reg FLAGS_REG)
8435         (compare
8436          (and:DI
8437           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8438           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8439          (const_int 0)))
8440    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8441         (and:DI (match_dup 1) (match_dup 2)))]
8442   "TARGET_64BIT
8443    && ix86_match_ccmode
8444         (insn,
8445          /* If we are going to emit andl instead of andq, and the operands[2]
8446             constant might have the SImode sign bit set, make sure the sign
8447             flag isn't tested, because the instruction will set the sign flag
8448             based on bit 31 rather than bit 63.  If it isn't CONST_INT,
8449             conservatively assume it might have bit 31 set.  */
8450          (satisfies_constraint_Z (operands[2])
8451           && (!CONST_INT_P (operands[2])
8452               || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8453          ? CCZmode : CCNOmode)
8454    && ix86_binary_operator_ok (AND, DImode, operands)"
8455   "@
8456    and{l}\t{%k2, %k0|%k0, %k2}
8457    and{q}\t{%2, %0|%0, %2}
8458    and{q}\t{%2, %0|%0, %2}"
8459   [(set_attr "type" "alu")
8460    (set_attr "mode" "SI,DI,DI")])
8462 (define_insn "*andqi_2_maybe_si"
8463   [(set (reg FLAGS_REG)
8464         (compare (and:QI
8465                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8466                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8467                  (const_int 0)))
8468    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8469         (and:QI (match_dup 1) (match_dup 2)))]
8470   "ix86_binary_operator_ok (AND, QImode, operands)
8471    && ix86_match_ccmode (insn,
8472                          CONST_INT_P (operands[2])
8473                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8475   if (which_alternative == 2)
8476     {
8477       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8478         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8479       return "and{l}\t{%2, %k0|%k0, %2}";
8480     }
8481   return "and{b}\t{%2, %0|%0, %2}";
8483   [(set_attr "type" "alu")
8484    (set_attr "mode" "QI,QI,SI")])
8486 (define_insn "*and<mode>_2"
8487   [(set (reg FLAGS_REG)
8488         (compare (and:SWI124
8489                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8490                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8491                  (const_int 0)))
8492    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8493         (and:SWI124 (match_dup 1) (match_dup 2)))]
8494   "ix86_match_ccmode (insn, CCNOmode)
8495    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8496   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8497   [(set_attr "type" "alu")
8498    (set_attr "mode" "<MODE>")])
8500 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8501 (define_insn "*andsi_2_zext"
8502   [(set (reg FLAGS_REG)
8503         (compare (and:SI
8504                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8505                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
8506                  (const_int 0)))
8507    (set (match_operand:DI 0 "register_operand" "=r")
8508         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8509   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8510    && ix86_binary_operator_ok (AND, SImode, operands)"
8511   "and{l}\t{%2, %k0|%k0, %2}"
8512   [(set_attr "type" "alu")
8513    (set_attr "mode" "SI")])
8515 (define_insn "*andqi_2_slp"
8516   [(set (reg FLAGS_REG)
8517         (compare (and:QI
8518                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8519                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8520                  (const_int 0)))
8521    (set (strict_low_part (match_dup 0))
8522         (and:QI (match_dup 0) (match_dup 1)))]
8523   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8524    && ix86_match_ccmode (insn, CCNOmode)
8525    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8526   "and{b}\t{%1, %0|%0, %1}"
8527   [(set_attr "type" "alu1")
8528    (set_attr "mode" "QI")])
8530 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8531 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8532 ;; for a QImode operand, which of course failed.
8533 (define_insn "andqi_ext_0"
8534   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8535                          (const_int 8)
8536                          (const_int 8))
8537         (and:SI
8538           (zero_extract:SI
8539             (match_operand 1 "ext_register_operand" "0")
8540             (const_int 8)
8541             (const_int 8))
8542           (match_operand 2 "const_int_operand" "n")))
8543    (clobber (reg:CC FLAGS_REG))]
8544   ""
8545   "and{b}\t{%2, %h0|%h0, %2}"
8546   [(set_attr "type" "alu")
8547    (set_attr "length_immediate" "1")
8548    (set_attr "modrm" "1")
8549    (set_attr "mode" "QI")])
8551 ;; Generated by peephole translating test to and.  This shows up
8552 ;; often in fp comparisons.
8553 (define_insn "*andqi_ext_0_cc"
8554   [(set (reg FLAGS_REG)
8555         (compare
8556           (and:SI
8557             (zero_extract:SI
8558               (match_operand 1 "ext_register_operand" "0")
8559               (const_int 8)
8560               (const_int 8))
8561             (match_operand 2 "const_int_operand" "n"))
8562           (const_int 0)))
8563    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8564                          (const_int 8)
8565                          (const_int 8))
8566         (and:SI
8567           (zero_extract:SI
8568             (match_dup 1)
8569             (const_int 8)
8570             (const_int 8))
8571           (match_dup 2)))]
8572   "ix86_match_ccmode (insn, CCNOmode)"
8573   "and{b}\t{%2, %h0|%h0, %2}"
8574   [(set_attr "type" "alu")
8575    (set_attr "length_immediate" "1")
8576    (set_attr "modrm" "1")
8577    (set_attr "mode" "QI")])
8579 (define_insn "*andqi_ext_1"
8580   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8581                          (const_int 8)
8582                          (const_int 8))
8583         (and:SI
8584           (zero_extract:SI
8585             (match_operand 1 "ext_register_operand" "0,0")
8586             (const_int 8)
8587             (const_int 8))
8588           (zero_extend:SI
8589             (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8590    (clobber (reg:CC FLAGS_REG))]
8591   ""
8592   "and{b}\t{%2, %h0|%h0, %2}"
8593   [(set_attr "isa" "*,nox64")
8594    (set_attr "type" "alu")
8595    (set_attr "length_immediate" "0")
8596    (set_attr "mode" "QI")])
8598 (define_insn "*andqi_ext_2"
8599   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8600                          (const_int 8)
8601                          (const_int 8))
8602         (and:SI
8603           (zero_extract:SI
8604             (match_operand 1 "ext_register_operand" "%0")
8605             (const_int 8)
8606             (const_int 8))
8607           (zero_extract:SI
8608             (match_operand 2 "ext_register_operand" "Q")
8609             (const_int 8)
8610             (const_int 8))))
8611    (clobber (reg:CC FLAGS_REG))]
8612   ""
8613   "and{b}\t{%h2, %h0|%h0, %h2}"
8614   [(set_attr "type" "alu")
8615    (set_attr "length_immediate" "0")
8616    (set_attr "mode" "QI")])
8618 ;; Convert wide AND instructions with immediate operand to shorter QImode
8619 ;; equivalents when possible.
8620 ;; Don't do the splitting with memory operands, since it introduces risk
8621 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8622 ;; for size, but that can (should?) be handled by generic code instead.
8623 (define_split
8624   [(set (match_operand 0 "QIreg_operand")
8625         (and (match_operand 1 "register_operand")
8626              (match_operand 2 "const_int_operand")))
8627    (clobber (reg:CC FLAGS_REG))]
8628    "reload_completed
8629     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8630     && !(~INTVAL (operands[2]) & ~(255 << 8))
8631     && GET_MODE (operands[0]) != QImode"
8632   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8633                    (and:SI (zero_extract:SI (match_dup 1)
8634                                             (const_int 8) (const_int 8))
8635                            (match_dup 2)))
8636               (clobber (reg:CC FLAGS_REG))])]
8638   operands[0] = gen_lowpart (SImode, operands[0]);
8639   operands[1] = gen_lowpart (SImode, operands[1]);
8640   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8643 ;; Since AND can be encoded with sign extended immediate, this is only
8644 ;; profitable when 7th bit is not set.
8645 (define_split
8646   [(set (match_operand 0 "any_QIreg_operand")
8647         (and (match_operand 1 "general_operand")
8648              (match_operand 2 "const_int_operand")))
8649    (clobber (reg:CC FLAGS_REG))]
8650    "reload_completed
8651     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8652     && !(~INTVAL (operands[2]) & ~255)
8653     && !(INTVAL (operands[2]) & 128)
8654     && GET_MODE (operands[0]) != QImode"
8655   [(parallel [(set (strict_low_part (match_dup 0))
8656                    (and:QI (match_dup 1)
8657                            (match_dup 2)))
8658               (clobber (reg:CC FLAGS_REG))])]
8660   operands[0] = gen_lowpart (QImode, operands[0]);
8661   operands[1] = gen_lowpart (QImode, operands[1]);
8662   operands[2] = gen_lowpart (QImode, operands[2]);
8665 ;; Logical inclusive and exclusive OR instructions
8667 ;; %%% This used to optimize known byte-wide and operations to memory.
8668 ;; If this is considered useful, it should be done with splitters.
8670 (define_expand "<code><mode>3"
8671   [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8672         (any_or:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8673                              (match_operand:SWIM1248x 2 "<general_operand>")))]
8674   ""
8675   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8677 (define_insn "*<code><mode>_1"
8678   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,k")
8679         (any_or:SWI48
8680          (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,k")
8681          (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,k")))
8682    (clobber (reg:CC FLAGS_REG))]
8683   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8684   "@
8685    <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8686    <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8687    k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8688   [(set_attr "type" "alu,alu,msklog")
8689    (set_attr "mode" "<MODE>")])
8691 (define_insn_and_split "*<code>di3_doubleword"
8692   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8693         (any_or:DI
8694          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8695          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8696    (clobber (reg:CC FLAGS_REG))]
8697   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8698    && ix86_binary_operator_ok (<CODE>, DImode, operands)"
8699   "#"
8700   "&& reload_completed"
8701   [(const_int 0)]
8703   split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8704   if (operands[2] == constm1_rtx)
8705     {
8706       if (<CODE> == IOR)
8707         {
8708           operands[1] = constm1_rtx;
8709           ix86_expand_move (SImode, &operands[0]);
8710         }
8711       else
8712         ix86_expand_unary_operator (NOT, SImode, &operands[0]);
8713     }
8714   else if (operands[2] != const0_rtx)
8715     ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
8716   else if (operands[5] == const0_rtx)
8717     emit_note (NOTE_INSN_DELETED);
8718   if (operands[5] == constm1_rtx)
8719     {
8720       if (<CODE> == IOR)
8721         {
8722           operands[4] = constm1_rtx;
8723           ix86_expand_move (SImode, &operands[3]);
8724         }
8725       else
8726         ix86_expand_unary_operator (NOT, SImode, &operands[3]);
8727     }
8728   else if (operands[5] != const0_rtx)
8729     ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
8730   DONE;
8733 (define_insn_and_split "*andndi3_doubleword"
8734   [(set (match_operand:DI 0 "register_operand" "=r,r")
8735         (and:DI
8736           (not:DI (match_operand:DI 1 "register_operand" "r,r"))
8737           (match_operand:DI 2 "nonimmediate_operand" "r,m")))
8738    (clobber (reg:CC FLAGS_REG))]
8739   "TARGET_BMI && !TARGET_64BIT && TARGET_STV && TARGET_SSE"
8740   "#"
8741   "&& reload_completed"
8742   [(parallel [(set (match_dup 0)
8743                    (and:SI (not:SI (match_dup 1)) (match_dup 2)))
8744               (clobber (reg:CC FLAGS_REG))])
8745    (parallel [(set (match_dup 3)
8746                    (and:SI (not:SI (match_dup 4)) (match_dup 5)))
8747               (clobber (reg:CC FLAGS_REG))])]
8748   "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
8750 (define_insn "*<code>hi_1"
8751   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
8752         (any_or:HI
8753          (match_operand:HI 1 "nonimmediate_operand" "%0,0,k")
8754          (match_operand:HI 2 "general_operand" "<g>,r<i>,k")))
8755    (clobber (reg:CC FLAGS_REG))]
8756   "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8757   "@
8758   <logic>{w}\t{%2, %0|%0, %2}
8759   <logic>{w}\t{%2, %0|%0, %2}
8760   k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8761   [(set_attr "type" "alu,alu,msklog")
8762    (set_attr "mode" "HI")])
8764 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8765 (define_insn "*<code>qi_1"
8766   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
8767         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8768                    (match_operand:QI 2 "general_operand" "qmn,qn,rn,k")))
8769    (clobber (reg:CC FLAGS_REG))]
8770   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8771   "@
8772    <logic>{b}\t{%2, %0|%0, %2}
8773    <logic>{b}\t{%2, %0|%0, %2}
8774    <logic>{l}\t{%k2, %k0|%k0, %k2}
8775    k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8776   [(set_attr "type" "alu,alu,alu,msklog")
8777    (set_attr "mode" "QI,QI,SI,HI")])
8779 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8780 (define_insn "*<code>si_1_zext"
8781   [(set (match_operand:DI 0 "register_operand" "=r")
8782         (zero_extend:DI
8783          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8784                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8785    (clobber (reg:CC FLAGS_REG))]
8786   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8787   "<logic>{l}\t{%2, %k0|%k0, %2}"
8788   [(set_attr "type" "alu")
8789    (set_attr "mode" "SI")])
8791 (define_insn "*<code>si_1_zext_imm"
8792   [(set (match_operand:DI 0 "register_operand" "=r")
8793         (any_or:DI
8794          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8795          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8796    (clobber (reg:CC FLAGS_REG))]
8797   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8798   "<logic>{l}\t{%2, %k0|%k0, %2}"
8799   [(set_attr "type" "alu")
8800    (set_attr "mode" "SI")])
8802 (define_insn "*<code>qi_1_slp"
8803   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8804         (any_or:QI (match_dup 0)
8805                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8806    (clobber (reg:CC FLAGS_REG))]
8807   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8808    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8809   "<logic>{b}\t{%1, %0|%0, %1}"
8810   [(set_attr "type" "alu1")
8811    (set_attr "mode" "QI")])
8813 (define_insn "*<code><mode>_2"
8814   [(set (reg FLAGS_REG)
8815         (compare (any_or:SWI
8816                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8817                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8818                  (const_int 0)))
8819    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8820         (any_or:SWI (match_dup 1) (match_dup 2)))]
8821   "ix86_match_ccmode (insn, CCNOmode)
8822    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8823   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8824   [(set_attr "type" "alu")
8825    (set_attr "mode" "<MODE>")])
8827 (define_insn "kxnor<mode>"
8828   [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
8829         (not:SWI12
8830           (xor:SWI12
8831             (match_operand:SWI12 1 "register_operand" "0,k")
8832             (match_operand:SWI12 2 "register_operand" "r,k"))))
8833    (clobber (reg:CC FLAGS_REG))]
8834   "TARGET_AVX512F"
8836   if (which_alternative == 1 && <MODE>mode == QImode && TARGET_AVX512DQ)
8837     return "kxnorb\t{%2, %1, %0|%0, %1, %2}";
8838   return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
8840   [(set_attr "type" "*,msklog")
8841    (set_attr "prefix" "*,vex")
8842    (set_attr "mode" "<MODE>")])
8844 (define_insn "kxnor<mode>"
8845   [(set (match_operand:SWI48x 0 "register_operand" "=r,!k")
8846         (not:SWI48x
8847           (xor:SWI48x
8848             (match_operand:SWI48x 1 "register_operand" "0,k")
8849             (match_operand:SWI48x 2 "register_operand" "r,k"))))
8850    (clobber (reg:CC FLAGS_REG))]
8851   "TARGET_AVX512BW"
8852   "@
8853    #
8854    kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8855   [(set_attr "type" "*,msklog")
8856    (set_attr "prefix" "*,vex")
8857    (set_attr "mode" "<MODE>")])
8859 (define_split
8860   [(set (match_operand:SWI1248x 0 "general_reg_operand")
8861         (not:SWI1248x
8862           (xor:SWI1248x
8863             (match_dup 0)
8864             (match_operand:SWI1248x 1 "general_reg_operand"))))
8865    (clobber (reg:CC FLAGS_REG))]
8866   "TARGET_AVX512F && reload_completed"
8867    [(parallel [(set (match_dup 0)
8868                     (xor:SWI1248x (match_dup 0)
8869                                   (match_dup 1)))
8870                (clobber (reg:CC FLAGS_REG))])
8871     (set (match_dup 0)
8872          (not:SWI1248x (match_dup 0)))])
8874 ;;There are kortrest[bdq] but no intrinsics for them.
8875 ;;We probably don't need to implement them.
8876 (define_insn "kortestzhi"
8877   [(set (reg:CCZ FLAGS_REG)
8878         (compare:CCZ
8879           (ior:HI
8880             (match_operand:HI 0 "register_operand" "k")
8881             (match_operand:HI 1 "register_operand" "k"))
8882           (const_int 0)))]
8883   "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8884   "kortestw\t{%1, %0|%0, %1}"
8885   [(set_attr "mode" "HI")
8886    (set_attr "type" "msklog")
8887    (set_attr "prefix" "vex")])
8889 (define_insn "kortestchi"
8890   [(set (reg:CCC FLAGS_REG)
8891         (compare:CCC
8892           (ior:HI
8893             (match_operand:HI 0 "register_operand" "k")
8894             (match_operand:HI 1 "register_operand" "k"))
8895           (const_int -1)))]
8896   "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8897   "kortestw\t{%1, %0|%0, %1}"
8898   [(set_attr "mode" "HI")
8899    (set_attr "type" "msklog")
8900    (set_attr "prefix" "vex")])
8902 (define_insn "kunpckhi"
8903   [(set (match_operand:HI 0 "register_operand" "=k")
8904         (ior:HI
8905           (ashift:HI
8906             (zero_extend:HI (match_operand:QI 1 "register_operand" "k"))
8907             (const_int 8))
8908           (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
8909   "TARGET_AVX512F"
8910   "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8911   [(set_attr "mode" "HI")
8912    (set_attr "type" "msklog")
8913    (set_attr "prefix" "vex")])
8915 (define_insn "kunpcksi"
8916   [(set (match_operand:SI 0 "register_operand" "=k")
8917         (ior:SI
8918           (ashift:SI
8919             (zero_extend:SI (match_operand:HI 1 "register_operand" "k"))
8920             (const_int 16))
8921           (zero_extend:SI (match_operand:HI 2 "register_operand" "k"))))]
8922   "TARGET_AVX512BW"
8923   "kunpckwd\t{%2, %1, %0|%0, %1, %2}"
8924   [(set_attr "mode" "SI")])
8926 (define_insn "kunpckdi"
8927   [(set (match_operand:DI 0 "register_operand" "=k")
8928         (ior:DI
8929           (ashift:DI
8930             (zero_extend:DI (match_operand:SI 1 "register_operand" "k"))
8931             (const_int 32))
8932           (zero_extend:DI (match_operand:SI 2 "register_operand" "k"))))]
8933   "TARGET_AVX512BW"
8934   "kunpckdq\t{%2, %1, %0|%0, %1, %2}"
8935   [(set_attr "mode" "DI")])
8937 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8938 ;; ??? Special case for immediate operand is missing - it is tricky.
8939 (define_insn "*<code>si_2_zext"
8940   [(set (reg FLAGS_REG)
8941         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8942                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
8943                  (const_int 0)))
8944    (set (match_operand:DI 0 "register_operand" "=r")
8945         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8946   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8947    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8948   "<logic>{l}\t{%2, %k0|%k0, %2}"
8949   [(set_attr "type" "alu")
8950    (set_attr "mode" "SI")])
8952 (define_insn "*<code>si_2_zext_imm"
8953   [(set (reg FLAGS_REG)
8954         (compare (any_or:SI
8955                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8956                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8957                  (const_int 0)))
8958    (set (match_operand:DI 0 "register_operand" "=r")
8959         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8960   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8961    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8962   "<logic>{l}\t{%2, %k0|%k0, %2}"
8963   [(set_attr "type" "alu")
8964    (set_attr "mode" "SI")])
8966 (define_insn "*<code>qi_2_slp"
8967   [(set (reg FLAGS_REG)
8968         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8969                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8970                  (const_int 0)))
8971    (set (strict_low_part (match_dup 0))
8972         (any_or:QI (match_dup 0) (match_dup 1)))]
8973   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8974    && ix86_match_ccmode (insn, CCNOmode)
8975    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8976   "<logic>{b}\t{%1, %0|%0, %1}"
8977   [(set_attr "type" "alu1")
8978    (set_attr "mode" "QI")])
8980 (define_insn "*<code><mode>_3"
8981   [(set (reg FLAGS_REG)
8982         (compare (any_or:SWI
8983                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8984                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8985                  (const_int 0)))
8986    (clobber (match_scratch:SWI 0 "=<r>"))]
8987   "ix86_match_ccmode (insn, CCNOmode)
8988    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8989   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8990   [(set_attr "type" "alu")
8991    (set_attr "mode" "<MODE>")])
8993 (define_insn "*<code>qi_ext_0"
8994   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8995                          (const_int 8)
8996                          (const_int 8))
8997         (any_or:SI
8998           (zero_extract:SI
8999             (match_operand 1 "ext_register_operand" "0")
9000             (const_int 8)
9001             (const_int 8))
9002           (match_operand 2 "const_int_operand" "n")))
9003    (clobber (reg:CC FLAGS_REG))]
9004   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9005   "<logic>{b}\t{%2, %h0|%h0, %2}"
9006   [(set_attr "type" "alu")
9007    (set_attr "length_immediate" "1")
9008    (set_attr "modrm" "1")
9009    (set_attr "mode" "QI")])
9011 (define_insn "*<code>qi_ext_1"
9012   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
9013                          (const_int 8)
9014                          (const_int 8))
9015         (any_or:SI
9016           (zero_extract:SI
9017             (match_operand 1 "ext_register_operand" "0,0")
9018             (const_int 8)
9019             (const_int 8))
9020           (zero_extend:SI
9021             (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
9022    (clobber (reg:CC FLAGS_REG))]
9023   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9024   "<logic>{b}\t{%2, %h0|%h0, %2}"
9025   [(set_attr "isa" "*,nox64")
9026    (set_attr "type" "alu")
9027    (set_attr "length_immediate" "0")
9028    (set_attr "mode" "QI")])
9030 (define_insn "*<code>qi_ext_2"
9031   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9032                          (const_int 8)
9033                          (const_int 8))
9034         (any_or:SI
9035           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9036                            (const_int 8)
9037                            (const_int 8))
9038           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9039                            (const_int 8)
9040                            (const_int 8))))
9041    (clobber (reg:CC FLAGS_REG))]
9042   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9043   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
9044   [(set_attr "type" "alu")
9045    (set_attr "length_immediate" "0")
9046    (set_attr "mode" "QI")])
9048 (define_split
9049   [(set (match_operand 0 "QIreg_operand")
9050         (any_or (match_operand 1 "register_operand")
9051                 (match_operand 2 "const_int_operand")))
9052    (clobber (reg:CC FLAGS_REG))]
9053    "reload_completed
9054     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9055     && !(INTVAL (operands[2]) & ~(255 << 8))
9056     && GET_MODE (operands[0]) != QImode"
9057   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9058                    (any_or:SI (zero_extract:SI (match_dup 1)
9059                                                (const_int 8) (const_int 8))
9060                               (match_dup 2)))
9061               (clobber (reg:CC FLAGS_REG))])]
9063   operands[0] = gen_lowpart (SImode, operands[0]);
9064   operands[1] = gen_lowpart (SImode, operands[1]);
9065   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
9068 ;; Since OR can be encoded with sign extended immediate, this is only
9069 ;; profitable when 7th bit is set.
9070 (define_split
9071   [(set (match_operand 0 "any_QIreg_operand")
9072         (any_or (match_operand 1 "general_operand")
9073                 (match_operand 2 "const_int_operand")))
9074    (clobber (reg:CC FLAGS_REG))]
9075    "reload_completed
9076     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9077     && !(INTVAL (operands[2]) & ~255)
9078     && (INTVAL (operands[2]) & 128)
9079     && GET_MODE (operands[0]) != QImode"
9080   [(parallel [(set (strict_low_part (match_dup 0))
9081                    (any_or:QI (match_dup 1)
9082                               (match_dup 2)))
9083               (clobber (reg:CC FLAGS_REG))])]
9085   operands[0] = gen_lowpart (QImode, operands[0]);
9086   operands[1] = gen_lowpart (QImode, operands[1]);
9087   operands[2] = gen_lowpart (QImode, operands[2]);
9090 (define_expand "xorqi_cc_ext_1"
9091   [(parallel [
9092      (set (reg:CCNO FLAGS_REG)
9093           (compare:CCNO
9094             (xor:SI
9095               (zero_extract:SI
9096                 (match_operand 1 "ext_register_operand")
9097                 (const_int 8)
9098                 (const_int 8))
9099               (match_operand:QI 2 "const_int_operand"))
9100             (const_int 0)))
9101      (set (zero_extract:SI (match_operand 0 "ext_register_operand")
9102                            (const_int 8)
9103                            (const_int 8))
9104           (xor:SI
9105             (zero_extract:SI
9106              (match_dup 1)
9107              (const_int 8)
9108              (const_int 8))
9109             (match_dup 2)))])])
9111 (define_insn "*xorqi_cc_ext_1"
9112   [(set (reg FLAGS_REG)
9113         (compare
9114           (xor:SI
9115             (zero_extract:SI
9116               (match_operand 1 "ext_register_operand" "0,0")
9117               (const_int 8)
9118               (const_int 8))
9119             (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
9120           (const_int 0)))
9121    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
9122                          (const_int 8)
9123                          (const_int 8))
9124         (xor:SI
9125           (zero_extract:SI
9126            (match_dup 1)
9127            (const_int 8)
9128            (const_int 8))
9129           (match_dup 2)))]
9130   "ix86_match_ccmode (insn, CCNOmode)"
9131   "xor{b}\t{%2, %h0|%h0, %2}"
9132   [(set_attr "isa" "*,nox64")
9133    (set_attr "type" "alu")
9134    (set_attr "modrm" "1")
9135    (set_attr "mode" "QI")])
9137 ;; Negation instructions
9139 (define_expand "neg<mode>2"
9140   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
9141         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
9142   ""
9143   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9145 (define_insn_and_split "*neg<dwi>2_doubleword"
9146   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9147         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9148    (clobber (reg:CC FLAGS_REG))]
9149   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9150   "#"
9151   "reload_completed"
9152   [(parallel
9153     [(set (reg:CCZ FLAGS_REG)
9154           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9155      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9156    (parallel
9157     [(set (match_dup 2)
9158           (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9159                                 (match_dup 3))
9160                      (const_int 0)))
9161      (clobber (reg:CC FLAGS_REG))])
9162    (parallel
9163     [(set (match_dup 2)
9164           (neg:DWIH (match_dup 2)))
9165      (clobber (reg:CC FLAGS_REG))])]
9166   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
9168 (define_insn "*neg<mode>2_1"
9169   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9170         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9171    (clobber (reg:CC FLAGS_REG))]
9172   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9173   "neg{<imodesuffix>}\t%0"
9174   [(set_attr "type" "negnot")
9175    (set_attr "mode" "<MODE>")])
9177 ;; Combine is quite creative about this pattern.
9178 (define_insn "*negsi2_1_zext"
9179   [(set (match_operand:DI 0 "register_operand" "=r")
9180         (lshiftrt:DI
9181           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9182                              (const_int 32)))
9183         (const_int 32)))
9184    (clobber (reg:CC FLAGS_REG))]
9185   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9186   "neg{l}\t%k0"
9187   [(set_attr "type" "negnot")
9188    (set_attr "mode" "SI")])
9190 ;; The problem with neg is that it does not perform (compare x 0),
9191 ;; it really performs (compare 0 x), which leaves us with the zero
9192 ;; flag being the only useful item.
9194 (define_insn "*neg<mode>2_cmpz"
9195   [(set (reg:CCZ FLAGS_REG)
9196         (compare:CCZ
9197           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9198                    (const_int 0)))
9199    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9200         (neg:SWI (match_dup 1)))]
9201   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9202   "neg{<imodesuffix>}\t%0"
9203   [(set_attr "type" "negnot")
9204    (set_attr "mode" "<MODE>")])
9206 (define_insn "*negsi2_cmpz_zext"
9207   [(set (reg:CCZ FLAGS_REG)
9208         (compare:CCZ
9209           (lshiftrt:DI
9210             (neg:DI (ashift:DI
9211                       (match_operand:DI 1 "register_operand" "0")
9212                       (const_int 32)))
9213             (const_int 32))
9214           (const_int 0)))
9215    (set (match_operand:DI 0 "register_operand" "=r")
9216         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9217                                         (const_int 32)))
9218                      (const_int 32)))]
9219   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9220   "neg{l}\t%k0"
9221   [(set_attr "type" "negnot")
9222    (set_attr "mode" "SI")])
9224 ;; Negate with jump on overflow.
9225 (define_expand "negv<mode>3"
9226   [(parallel [(set (reg:CCO FLAGS_REG)
9227                    (ne:CCO (match_operand:SWI 1 "register_operand")
9228                            (match_dup 3)))
9229               (set (match_operand:SWI 0 "register_operand")
9230                    (neg:SWI (match_dup 1)))])
9231    (set (pc) (if_then_else
9232                (eq (reg:CCO FLAGS_REG) (const_int 0))
9233                (label_ref (match_operand 2))
9234                (pc)))]
9235   ""
9237   operands[3]
9238     = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
9239                     <MODE>mode);
9242 (define_insn "*negv<mode>3"
9243   [(set (reg:CCO FLAGS_REG)
9244         (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
9245                 (match_operand:SWI 2 "const_int_operand")))
9246    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9247         (neg:SWI (match_dup 1)))]
9248   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
9249    && mode_signbit_p (<MODE>mode, operands[2])"
9250   "neg{<imodesuffix>}\t%0"
9251   [(set_attr "type" "negnot")
9252    (set_attr "mode" "<MODE>")])
9254 ;; Changing of sign for FP values is doable using integer unit too.
9256 (define_expand "<code><mode>2"
9257   [(set (match_operand:X87MODEF 0 "register_operand")
9258         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
9259   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9260   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9262 (define_insn "*absneg<mode>2_mixed"
9263   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
9264         (match_operator:MODEF 3 "absneg_operator"
9265           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
9266    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
9267    (clobber (reg:CC FLAGS_REG))]
9268   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9269   "#"
9270   [(set (attr "enabled")
9271      (cond [(eq_attr "alternative" "2")
9272               (symbol_ref "TARGET_MIX_SSE_I387")
9273            ]
9274            (symbol_ref "true")))])
9276 (define_insn "*absneg<mode>2_i387"
9277   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9278         (match_operator:X87MODEF 3 "absneg_operator"
9279           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
9280    (use (match_operand 2))
9281    (clobber (reg:CC FLAGS_REG))]
9282   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9283   "#")
9285 (define_expand "<code>tf2"
9286   [(set (match_operand:TF 0 "register_operand")
9287         (absneg:TF (match_operand:TF 1 "register_operand")))]
9288   "TARGET_SSE"
9289   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9291 (define_insn "*absnegtf2_sse"
9292   [(set (match_operand:TF 0 "register_operand" "=x,x")
9293         (match_operator:TF 3 "absneg_operator"
9294           [(match_operand:TF 1 "register_operand" "0,x")]))
9295    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
9296    (clobber (reg:CC FLAGS_REG))]
9297   "TARGET_SSE"
9298   "#")
9300 ;; Splitters for fp abs and neg.
9302 (define_split
9303   [(set (match_operand 0 "fp_register_operand")
9304         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9305    (use (match_operand 2))
9306    (clobber (reg:CC FLAGS_REG))]
9307   "reload_completed"
9308   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9310 (define_split
9311   [(set (match_operand 0 "register_operand")
9312         (match_operator 3 "absneg_operator"
9313           [(match_operand 1 "register_operand")]))
9314    (use (match_operand 2 "nonimmediate_operand"))
9315    (clobber (reg:CC FLAGS_REG))]
9316   "reload_completed && SSE_REG_P (operands[0])"
9317   [(set (match_dup 0) (match_dup 3))]
9319   machine_mode mode = GET_MODE (operands[0]);
9320   machine_mode vmode = GET_MODE (operands[2]);
9321   rtx tmp;
9323   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9324   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9325   if (operands_match_p (operands[0], operands[2]))
9326     std::swap (operands[1], operands[2]);
9327   if (GET_CODE (operands[3]) == ABS)
9328     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9329   else
9330     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9331   operands[3] = tmp;
9334 (define_split
9335   [(set (match_operand:SF 0 "general_reg_operand")
9336         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9337    (use (match_operand:V4SF 2))
9338    (clobber (reg:CC FLAGS_REG))]
9339   "reload_completed"
9340   [(parallel [(set (match_dup 0) (match_dup 1))
9341               (clobber (reg:CC FLAGS_REG))])]
9343   rtx tmp;
9344   operands[0] = gen_lowpart (SImode, operands[0]);
9345   if (GET_CODE (operands[1]) == ABS)
9346     {
9347       tmp = gen_int_mode (0x7fffffff, SImode);
9348       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9349     }
9350   else
9351     {
9352       tmp = gen_int_mode (0x80000000, SImode);
9353       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9354     }
9355   operands[1] = tmp;
9358 (define_split
9359   [(set (match_operand:DF 0 "general_reg_operand")
9360         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9361    (use (match_operand 2))
9362    (clobber (reg:CC FLAGS_REG))]
9363   "reload_completed"
9364   [(parallel [(set (match_dup 0) (match_dup 1))
9365               (clobber (reg:CC FLAGS_REG))])]
9367   rtx tmp;
9368   if (TARGET_64BIT)
9369     {
9370       tmp = gen_lowpart (DImode, operands[0]);
9371       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9372       operands[0] = tmp;
9374       if (GET_CODE (operands[1]) == ABS)
9375         tmp = const0_rtx;
9376       else
9377         tmp = gen_rtx_NOT (DImode, tmp);
9378     }
9379   else
9380     {
9381       operands[0] = gen_highpart (SImode, operands[0]);
9382       if (GET_CODE (operands[1]) == ABS)
9383         {
9384           tmp = gen_int_mode (0x7fffffff, SImode);
9385           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9386         }
9387       else
9388         {
9389           tmp = gen_int_mode (0x80000000, SImode);
9390           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9391         }
9392     }
9393   operands[1] = tmp;
9396 (define_split
9397   [(set (match_operand:XF 0 "general_reg_operand")
9398         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9399    (use (match_operand 2))
9400    (clobber (reg:CC FLAGS_REG))]
9401   "reload_completed"
9402   [(parallel [(set (match_dup 0) (match_dup 1))
9403               (clobber (reg:CC FLAGS_REG))])]
9405   rtx tmp;
9406   operands[0] = gen_rtx_REG (SImode,
9407                              true_regnum (operands[0])
9408                              + (TARGET_64BIT ? 1 : 2));
9409   if (GET_CODE (operands[1]) == ABS)
9410     {
9411       tmp = GEN_INT (0x7fff);
9412       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9413     }
9414   else
9415     {
9416       tmp = GEN_INT (0x8000);
9417       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9418     }
9419   operands[1] = tmp;
9422 ;; Conditionalize these after reload. If they match before reload, we
9423 ;; lose the clobber and ability to use integer instructions.
9425 (define_insn "*<code><mode>2_1"
9426   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9427         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9428   "TARGET_80387
9429    && (reload_completed
9430        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9431   "f<absneg_mnemonic>"
9432   [(set_attr "type" "fsgn")
9433    (set_attr "mode" "<MODE>")])
9435 (define_insn "*<code>extendsfdf2"
9436   [(set (match_operand:DF 0 "register_operand" "=f")
9437         (absneg:DF (float_extend:DF
9438                      (match_operand:SF 1 "register_operand" "0"))))]
9439   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9440   "f<absneg_mnemonic>"
9441   [(set_attr "type" "fsgn")
9442    (set_attr "mode" "DF")])
9444 (define_insn "*<code>extendsfxf2"
9445   [(set (match_operand:XF 0 "register_operand" "=f")
9446         (absneg:XF (float_extend:XF
9447                      (match_operand:SF 1 "register_operand" "0"))))]
9448   "TARGET_80387"
9449   "f<absneg_mnemonic>"
9450   [(set_attr "type" "fsgn")
9451    (set_attr "mode" "XF")])
9453 (define_insn "*<code>extenddfxf2"
9454   [(set (match_operand:XF 0 "register_operand" "=f")
9455         (absneg:XF (float_extend:XF
9456                      (match_operand:DF 1 "register_operand" "0"))))]
9457   "TARGET_80387"
9458   "f<absneg_mnemonic>"
9459   [(set_attr "type" "fsgn")
9460    (set_attr "mode" "XF")])
9462 ;; Copysign instructions
9464 (define_mode_iterator CSGNMODE [SF DF TF])
9465 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9467 (define_expand "copysign<mode>3"
9468   [(match_operand:CSGNMODE 0 "register_operand")
9469    (match_operand:CSGNMODE 1 "nonmemory_operand")
9470    (match_operand:CSGNMODE 2 "register_operand")]
9471   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9472    || (TARGET_SSE && (<MODE>mode == TFmode))"
9473   "ix86_expand_copysign (operands); DONE;")
9475 (define_insn_and_split "copysign<mode>3_const"
9476   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9477         (unspec:CSGNMODE
9478           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9479            (match_operand:CSGNMODE 2 "register_operand" "0")
9480            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9481           UNSPEC_COPYSIGN))]
9482   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9483    || (TARGET_SSE && (<MODE>mode == TFmode))"
9484   "#"
9485   "&& reload_completed"
9486   [(const_int 0)]
9487   "ix86_split_copysign_const (operands); DONE;")
9489 (define_insn "copysign<mode>3_var"
9490   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9491         (unspec:CSGNMODE
9492           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9493            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9494            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9495            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9496           UNSPEC_COPYSIGN))
9497    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9498   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9499    || (TARGET_SSE && (<MODE>mode == TFmode))"
9500   "#")
9502 (define_split
9503   [(set (match_operand:CSGNMODE 0 "register_operand")
9504         (unspec:CSGNMODE
9505           [(match_operand:CSGNMODE 2 "register_operand")
9506            (match_operand:CSGNMODE 3 "register_operand")
9507            (match_operand:<CSGNVMODE> 4)
9508            (match_operand:<CSGNVMODE> 5)]
9509           UNSPEC_COPYSIGN))
9510    (clobber (match_scratch:<CSGNVMODE> 1))]
9511   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9512     || (TARGET_SSE && (<MODE>mode == TFmode)))
9513    && reload_completed"
9514   [(const_int 0)]
9515   "ix86_split_copysign_var (operands); DONE;")
9517 ;; One complement instructions
9519 (define_expand "one_cmpl<mode>2"
9520   [(set (match_operand:SWIM 0 "nonimmediate_operand")
9521         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
9522   ""
9523   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9525 (define_insn "*one_cmpl<mode>2_1"
9526   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,k")
9527         (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,k")))]
9528   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9529   "@
9530    not{<imodesuffix>}\t%0
9531    knot<mskmodesuffix>\t{%1, %0|%0, %1}"
9532   [(set_attr "isa" "*,avx512bw")
9533    (set_attr "type" "negnot,msklog")
9534    (set_attr "prefix" "*,vex")
9535    (set_attr "mode" "<MODE>")])
9537 (define_insn "*one_cmplhi2_1"
9538   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k")
9539         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))]
9540   "ix86_unary_operator_ok (NOT, HImode, operands)"
9541   "@
9542    not{w}\t%0
9543    knotw\t{%1, %0|%0, %1}"
9544   [(set_attr "isa" "*,avx512f")
9545    (set_attr "type" "negnot,msklog")
9546    (set_attr "prefix" "*,vex")
9547    (set_attr "mode" "HI")])
9549 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9550 (define_insn "*one_cmplqi2_1"
9551   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
9552         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
9553   "ix86_unary_operator_ok (NOT, QImode, operands)"
9555   switch (which_alternative)
9556     {
9557     case 0:
9558       return "not{b}\t%0";
9559     case 1:
9560       return "not{l}\t%k0";
9561     case 2:
9562       if (TARGET_AVX512DQ)
9563         return "knotb\t{%1, %0|%0, %1}";
9564       return "knotw\t{%1, %0|%0, %1}";
9565     default:
9566       gcc_unreachable ();
9567     }
9569   [(set_attr "isa" "*,*,avx512f")
9570    (set_attr "type" "negnot,negnot,msklog")
9571    (set_attr "prefix" "*,*,vex")
9572    (set_attr "mode" "QI,SI,QI")])
9574 ;; ??? Currently never generated - xor is used instead.
9575 (define_insn "*one_cmplsi2_1_zext"
9576   [(set (match_operand:DI 0 "register_operand" "=r")
9577         (zero_extend:DI
9578           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9579   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9580   "not{l}\t%k0"
9581   [(set_attr "type" "negnot")
9582    (set_attr "mode" "SI")])
9584 (define_insn "*one_cmpl<mode>2_2"
9585   [(set (reg FLAGS_REG)
9586         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9587                  (const_int 0)))
9588    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9589         (not:SWI (match_dup 1)))]
9590   "ix86_match_ccmode (insn, CCNOmode)
9591    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9592   "#"
9593   [(set_attr "type" "alu1")
9594    (set_attr "mode" "<MODE>")])
9596 (define_split
9597   [(set (match_operand 0 "flags_reg_operand")
9598         (match_operator 2 "compare_operator"
9599           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9600            (const_int 0)]))
9601    (set (match_operand:SWI 1 "nonimmediate_operand")
9602         (not:SWI (match_dup 3)))]
9603   "ix86_match_ccmode (insn, CCNOmode)"
9604   [(parallel [(set (match_dup 0)
9605                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9606                                     (const_int 0)]))
9607               (set (match_dup 1)
9608                    (xor:SWI (match_dup 3) (const_int -1)))])])
9610 ;; ??? Currently never generated - xor is used instead.
9611 (define_insn "*one_cmplsi2_2_zext"
9612   [(set (reg FLAGS_REG)
9613         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9614                  (const_int 0)))
9615    (set (match_operand:DI 0 "register_operand" "=r")
9616         (zero_extend:DI (not:SI (match_dup 1))))]
9617   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9618    && ix86_unary_operator_ok (NOT, SImode, operands)"
9619   "#"
9620   [(set_attr "type" "alu1")
9621    (set_attr "mode" "SI")])
9623 (define_split
9624   [(set (match_operand 0 "flags_reg_operand")
9625         (match_operator 2 "compare_operator"
9626           [(not:SI (match_operand:SI 3 "register_operand"))
9627            (const_int 0)]))
9628    (set (match_operand:DI 1 "register_operand")
9629         (zero_extend:DI (not:SI (match_dup 3))))]
9630   "ix86_match_ccmode (insn, CCNOmode)"
9631   [(parallel [(set (match_dup 0)
9632                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9633                                     (const_int 0)]))
9634               (set (match_dup 1)
9635                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9637 ;; Shift instructions
9639 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9640 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9641 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9642 ;; from the assembler input.
9644 ;; This instruction shifts the target reg/mem as usual, but instead of
9645 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9646 ;; is a left shift double, bits are taken from the high order bits of
9647 ;; reg, else if the insn is a shift right double, bits are taken from the
9648 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9649 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9651 ;; Since sh[lr]d does not change the `reg' operand, that is done
9652 ;; separately, making all shifts emit pairs of shift double and normal
9653 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9654 ;; support a 63 bit shift, each shift where the count is in a reg expands
9655 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9657 ;; If the shift count is a constant, we need never emit more than one
9658 ;; shift pair, instead using moves and sign extension for counts greater
9659 ;; than 31.
9661 (define_insn "*<mshift><mode>3"
9662   [(set (match_operand:SWI1248_AVX512BWDQ 0 "register_operand" "=k")
9663         (any_lshift:SWI1248_AVX512BWDQ (match_operand:SWI1248_AVX512BWDQ 1 "register_operand" "k")
9664                                        (match_operand:QI 2 "immediate_operand" "i")))]
9665   "TARGET_AVX512F"
9666   "k<mshift><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
9667   [(set_attr "type" "msklog")
9668    (set_attr "prefix" "vex")])
9670 (define_expand "ashl<mode>3"
9671   [(set (match_operand:SDWIM 0 "<shift_operand>")
9672         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9673                       (match_operand:QI 2 "nonmemory_operand")))]
9674   ""
9675   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9677 (define_insn "*ashl<mode>3_doubleword"
9678   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9679         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9680                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9681    (clobber (reg:CC FLAGS_REG))]
9682   ""
9683   "#"
9684   [(set_attr "type" "multi")])
9686 (define_split
9687   [(set (match_operand:DWI 0 "register_operand")
9688         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9689                     (match_operand:QI 2 "nonmemory_operand")))
9690    (clobber (reg:CC FLAGS_REG))]
9691   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9692   [(const_int 0)]
9693   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9695 ;; By default we don't ask for a scratch register, because when DWImode
9696 ;; values are manipulated, registers are already at a premium.  But if
9697 ;; we have one handy, we won't turn it away.
9699 (define_peephole2
9700   [(match_scratch:DWIH 3 "r")
9701    (parallel [(set (match_operand:<DWI> 0 "register_operand")
9702                    (ashift:<DWI>
9703                      (match_operand:<DWI> 1 "nonmemory_operand")
9704                      (match_operand:QI 2 "nonmemory_operand")))
9705               (clobber (reg:CC FLAGS_REG))])
9706    (match_dup 3)]
9707   "TARGET_CMOVE"
9708   [(const_int 0)]
9709   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9711 (define_insn "x86_64_shld"
9712   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9713         (ior:DI (ashift:DI (match_dup 0)
9714                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9715                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9716                   (minus:QI (const_int 64) (match_dup 2)))))
9717    (clobber (reg:CC FLAGS_REG))]
9718   "TARGET_64BIT"
9719   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9720   [(set_attr "type" "ishift")
9721    (set_attr "prefix_0f" "1")
9722    (set_attr "mode" "DI")
9723    (set_attr "athlon_decode" "vector")
9724    (set_attr "amdfam10_decode" "vector")
9725    (set_attr "bdver1_decode" "vector")])
9727 (define_insn "x86_shld"
9728   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9729         (ior:SI (ashift:SI (match_dup 0)
9730                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9731                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9732                   (minus:QI (const_int 32) (match_dup 2)))))
9733    (clobber (reg:CC FLAGS_REG))]
9734   ""
9735   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9736   [(set_attr "type" "ishift")
9737    (set_attr "prefix_0f" "1")
9738    (set_attr "mode" "SI")
9739    (set_attr "pent_pair" "np")
9740    (set_attr "athlon_decode" "vector")
9741    (set_attr "amdfam10_decode" "vector")
9742    (set_attr "bdver1_decode" "vector")])
9744 (define_expand "x86_shift<mode>_adj_1"
9745   [(set (reg:CCZ FLAGS_REG)
9746         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9747                              (match_dup 4))
9748                      (const_int 0)))
9749    (set (match_operand:SWI48 0 "register_operand")
9750         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9751                             (match_operand:SWI48 1 "register_operand")
9752                             (match_dup 0)))
9753    (set (match_dup 1)
9754         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9755                             (match_operand:SWI48 3 "register_operand")
9756                             (match_dup 1)))]
9757   "TARGET_CMOVE"
9758   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9760 (define_expand "x86_shift<mode>_adj_2"
9761   [(use (match_operand:SWI48 0 "register_operand"))
9762    (use (match_operand:SWI48 1 "register_operand"))
9763    (use (match_operand:QI 2 "register_operand"))]
9764   ""
9766   rtx_code_label *label = gen_label_rtx ();
9767   rtx tmp;
9769   emit_insn (gen_testqi_ccz_1 (operands[2],
9770                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9772   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9773   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9774   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9775                               gen_rtx_LABEL_REF (VOIDmode, label),
9776                               pc_rtx);
9777   tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
9778   JUMP_LABEL (tmp) = label;
9780   emit_move_insn (operands[0], operands[1]);
9781   ix86_expand_clear (operands[1]);
9783   emit_label (label);
9784   LABEL_NUSES (label) = 1;
9786   DONE;
9789 ;; Avoid useless masking of count operand.
9790 (define_insn "*ashl<mode>3_mask"
9791   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9792         (ashift:SWI48
9793           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9794           (subreg:QI
9795             (and:SI
9796               (match_operand:SI 2 "register_operand" "c")
9797               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9798    (clobber (reg:CC FLAGS_REG))]
9799   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9800    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9801       == GET_MODE_BITSIZE (<MODE>mode)-1"
9803   return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9805   [(set_attr "type" "ishift")
9806    (set_attr "mode" "<MODE>")])
9808 (define_insn "*bmi2_ashl<mode>3_1"
9809   [(set (match_operand:SWI48 0 "register_operand" "=r")
9810         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9811                       (match_operand:SWI48 2 "register_operand" "r")))]
9812   "TARGET_BMI2"
9813   "shlx\t{%2, %1, %0|%0, %1, %2}"
9814   [(set_attr "type" "ishiftx")
9815    (set_attr "mode" "<MODE>")])
9817 (define_insn "*ashl<mode>3_1"
9818   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9819         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9820                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9821    (clobber (reg:CC FLAGS_REG))]
9822   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9824   switch (get_attr_type (insn))
9825     {
9826     case TYPE_LEA:
9827     case TYPE_ISHIFTX:
9828       return "#";
9830     case TYPE_ALU:
9831       gcc_assert (operands[2] == const1_rtx);
9832       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9833       return "add{<imodesuffix>}\t%0, %0";
9835     default:
9836       if (operands[2] == const1_rtx
9837           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9838         return "sal{<imodesuffix>}\t%0";
9839       else
9840         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9841     }
9843   [(set_attr "isa" "*,*,bmi2")
9844    (set (attr "type")
9845      (cond [(eq_attr "alternative" "1")
9846               (const_string "lea")
9847             (eq_attr "alternative" "2")
9848               (const_string "ishiftx")
9849             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9850                       (match_operand 0 "register_operand"))
9851                  (match_operand 2 "const1_operand"))
9852               (const_string "alu")
9853            ]
9854            (const_string "ishift")))
9855    (set (attr "length_immediate")
9856      (if_then_else
9857        (ior (eq_attr "type" "alu")
9858             (and (eq_attr "type" "ishift")
9859                  (and (match_operand 2 "const1_operand")
9860                       (ior (match_test "TARGET_SHIFT1")
9861                            (match_test "optimize_function_for_size_p (cfun)")))))
9862        (const_string "0")
9863        (const_string "*")))
9864    (set_attr "mode" "<MODE>")])
9866 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9867 (define_split
9868   [(set (match_operand:SWI48 0 "register_operand")
9869         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9870                       (match_operand:QI 2 "register_operand")))
9871    (clobber (reg:CC FLAGS_REG))]
9872   "TARGET_BMI2 && reload_completed"
9873   [(set (match_dup 0)
9874         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9875   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9877 (define_insn "*bmi2_ashlsi3_1_zext"
9878   [(set (match_operand:DI 0 "register_operand" "=r")
9879         (zero_extend:DI
9880           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9881                      (match_operand:SI 2 "register_operand" "r"))))]
9882   "TARGET_64BIT && TARGET_BMI2"
9883   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9884   [(set_attr "type" "ishiftx")
9885    (set_attr "mode" "SI")])
9887 (define_insn "*ashlsi3_1_zext"
9888   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9889         (zero_extend:DI
9890           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9891                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9892    (clobber (reg:CC FLAGS_REG))]
9893   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9895   switch (get_attr_type (insn))
9896     {
9897     case TYPE_LEA:
9898     case TYPE_ISHIFTX:
9899       return "#";
9901     case TYPE_ALU:
9902       gcc_assert (operands[2] == const1_rtx);
9903       return "add{l}\t%k0, %k0";
9905     default:
9906       if (operands[2] == const1_rtx
9907           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9908         return "sal{l}\t%k0";
9909       else
9910         return "sal{l}\t{%2, %k0|%k0, %2}";
9911     }
9913   [(set_attr "isa" "*,*,bmi2")
9914    (set (attr "type")
9915      (cond [(eq_attr "alternative" "1")
9916               (const_string "lea")
9917             (eq_attr "alternative" "2")
9918               (const_string "ishiftx")
9919             (and (match_test "TARGET_DOUBLE_WITH_ADD")
9920                  (match_operand 2 "const1_operand"))
9921               (const_string "alu")
9922            ]
9923            (const_string "ishift")))
9924    (set (attr "length_immediate")
9925      (if_then_else
9926        (ior (eq_attr "type" "alu")
9927             (and (eq_attr "type" "ishift")
9928                  (and (match_operand 2 "const1_operand")
9929                       (ior (match_test "TARGET_SHIFT1")
9930                            (match_test "optimize_function_for_size_p (cfun)")))))
9931        (const_string "0")
9932        (const_string "*")))
9933    (set_attr "mode" "SI")])
9935 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9936 (define_split
9937   [(set (match_operand:DI 0 "register_operand")
9938         (zero_extend:DI
9939           (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9940                      (match_operand:QI 2 "register_operand"))))
9941    (clobber (reg:CC FLAGS_REG))]
9942   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9943   [(set (match_dup 0)
9944         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9945   "operands[2] = gen_lowpart (SImode, operands[2]);")
9947 (define_insn "*ashlhi3_1"
9948   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9949         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9950                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9951    (clobber (reg:CC FLAGS_REG))]
9952   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9954   switch (get_attr_type (insn))
9955     {
9956     case TYPE_LEA:
9957       return "#";
9959     case TYPE_ALU:
9960       gcc_assert (operands[2] == const1_rtx);
9961       return "add{w}\t%0, %0";
9963     default:
9964       if (operands[2] == const1_rtx
9965           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9966         return "sal{w}\t%0";
9967       else
9968         return "sal{w}\t{%2, %0|%0, %2}";
9969     }
9971   [(set (attr "type")
9972      (cond [(eq_attr "alternative" "1")
9973               (const_string "lea")
9974             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9975                       (match_operand 0 "register_operand"))
9976                  (match_operand 2 "const1_operand"))
9977               (const_string "alu")
9978            ]
9979            (const_string "ishift")))
9980    (set (attr "length_immediate")
9981      (if_then_else
9982        (ior (eq_attr "type" "alu")
9983             (and (eq_attr "type" "ishift")
9984                  (and (match_operand 2 "const1_operand")
9985                       (ior (match_test "TARGET_SHIFT1")
9986                            (match_test "optimize_function_for_size_p (cfun)")))))
9987        (const_string "0")
9988        (const_string "*")))
9989    (set_attr "mode" "HI,SI")])
9991 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9992 (define_insn "*ashlqi3_1"
9993   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9994         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9995                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9996    (clobber (reg:CC FLAGS_REG))]
9997   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9999   switch (get_attr_type (insn))
10000     {
10001     case TYPE_LEA:
10002       return "#";
10004     case TYPE_ALU:
10005       gcc_assert (operands[2] == const1_rtx);
10006       if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
10007         return "add{l}\t%k0, %k0";
10008       else
10009         return "add{b}\t%0, %0";
10011     default:
10012       if (operands[2] == const1_rtx
10013           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10014         {
10015           if (get_attr_mode (insn) == MODE_SI)
10016             return "sal{l}\t%k0";
10017           else
10018             return "sal{b}\t%0";
10019         }
10020       else
10021         {
10022           if (get_attr_mode (insn) == MODE_SI)
10023             return "sal{l}\t{%2, %k0|%k0, %2}";
10024           else
10025             return "sal{b}\t{%2, %0|%0, %2}";
10026         }
10027     }
10029   [(set (attr "type")
10030      (cond [(eq_attr "alternative" "2")
10031               (const_string "lea")
10032             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10033                       (match_operand 0 "register_operand"))
10034                  (match_operand 2 "const1_operand"))
10035               (const_string "alu")
10036            ]
10037            (const_string "ishift")))
10038    (set (attr "length_immediate")
10039      (if_then_else
10040        (ior (eq_attr "type" "alu")
10041             (and (eq_attr "type" "ishift")
10042                  (and (match_operand 2 "const1_operand")
10043                       (ior (match_test "TARGET_SHIFT1")
10044                            (match_test "optimize_function_for_size_p (cfun)")))))
10045        (const_string "0")
10046        (const_string "*")))
10047    (set_attr "mode" "QI,SI,SI")])
10049 (define_insn "*ashlqi3_1_slp"
10050   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10051         (ashift:QI (match_dup 0)
10052                    (match_operand:QI 1 "nonmemory_operand" "cI")))
10053    (clobber (reg:CC FLAGS_REG))]
10054   "(optimize_function_for_size_p (cfun)
10055     || !TARGET_PARTIAL_FLAG_REG_STALL
10056     || (operands[1] == const1_rtx
10057         && (TARGET_SHIFT1
10058             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10060   switch (get_attr_type (insn))
10061     {
10062     case TYPE_ALU:
10063       gcc_assert (operands[1] == const1_rtx);
10064       return "add{b}\t%0, %0";
10066     default:
10067       if (operands[1] == const1_rtx
10068           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10069         return "sal{b}\t%0";
10070       else
10071         return "sal{b}\t{%1, %0|%0, %1}";
10072     }
10074   [(set (attr "type")
10075      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10076                       (match_operand 0 "register_operand"))
10077                  (match_operand 1 "const1_operand"))
10078               (const_string "alu")
10079            ]
10080            (const_string "ishift1")))
10081    (set (attr "length_immediate")
10082      (if_then_else
10083        (ior (eq_attr "type" "alu")
10084             (and (eq_attr "type" "ishift1")
10085                  (and (match_operand 1 "const1_operand")
10086                       (ior (match_test "TARGET_SHIFT1")
10087                            (match_test "optimize_function_for_size_p (cfun)")))))
10088        (const_string "0")
10089        (const_string "*")))
10090    (set_attr "mode" "QI")])
10092 ;; Convert ashift to the lea pattern to avoid flags dependency.
10093 (define_split
10094   [(set (match_operand 0 "register_operand")
10095         (ashift (match_operand 1 "index_register_operand")
10096                 (match_operand:QI 2 "const_int_operand")))
10097    (clobber (reg:CC FLAGS_REG))]
10098   "GET_MODE (operands[0]) == GET_MODE (operands[1])
10099    && reload_completed
10100    && true_regnum (operands[0]) != true_regnum (operands[1])"
10101   [(const_int 0)]
10103   machine_mode mode = GET_MODE (operands[0]);
10104   rtx pat;
10106   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
10107     { 
10108       mode = SImode; 
10109       operands[0] = gen_lowpart (mode, operands[0]);
10110       operands[1] = gen_lowpart (mode, operands[1]);
10111     }
10113   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
10115   pat = gen_rtx_MULT (mode, operands[1], operands[2]);
10117   emit_insn (gen_rtx_SET (operands[0], pat));
10118   DONE;
10121 ;; Convert ashift to the lea pattern to avoid flags dependency.
10122 (define_split
10123   [(set (match_operand:DI 0 "register_operand")
10124         (zero_extend:DI
10125           (ashift:SI (match_operand:SI 1 "index_register_operand")
10126                      (match_operand:QI 2 "const_int_operand"))))
10127    (clobber (reg:CC FLAGS_REG))]
10128   "TARGET_64BIT && reload_completed
10129    && true_regnum (operands[0]) != true_regnum (operands[1])"
10130   [(set (match_dup 0)
10131         (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
10133   operands[1] = gen_lowpart (SImode, operands[1]);
10134   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
10137 ;; This pattern can't accept a variable shift count, since shifts by
10138 ;; zero don't affect the flags.  We assume that shifts by constant
10139 ;; zero are optimized away.
10140 (define_insn "*ashl<mode>3_cmp"
10141   [(set (reg FLAGS_REG)
10142         (compare
10143           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10144                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10145           (const_int 0)))
10146    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10147         (ashift:SWI (match_dup 1) (match_dup 2)))]
10148   "(optimize_function_for_size_p (cfun)
10149     || !TARGET_PARTIAL_FLAG_REG_STALL
10150     || (operands[2] == const1_rtx
10151         && (TARGET_SHIFT1
10152             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10153    && ix86_match_ccmode (insn, CCGOCmode)
10154    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10156   switch (get_attr_type (insn))
10157     {
10158     case TYPE_ALU:
10159       gcc_assert (operands[2] == const1_rtx);
10160       return "add{<imodesuffix>}\t%0, %0";
10162     default:
10163       if (operands[2] == const1_rtx
10164           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10165         return "sal{<imodesuffix>}\t%0";
10166       else
10167         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10168     }
10170   [(set (attr "type")
10171      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10172                       (match_operand 0 "register_operand"))
10173                  (match_operand 2 "const1_operand"))
10174               (const_string "alu")
10175            ]
10176            (const_string "ishift")))
10177    (set (attr "length_immediate")
10178      (if_then_else
10179        (ior (eq_attr "type" "alu")
10180             (and (eq_attr "type" "ishift")
10181                  (and (match_operand 2 "const1_operand")
10182                       (ior (match_test "TARGET_SHIFT1")
10183                            (match_test "optimize_function_for_size_p (cfun)")))))
10184        (const_string "0")
10185        (const_string "*")))
10186    (set_attr "mode" "<MODE>")])
10188 (define_insn "*ashlsi3_cmp_zext"
10189   [(set (reg FLAGS_REG)
10190         (compare
10191           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10192                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10193           (const_int 0)))
10194    (set (match_operand:DI 0 "register_operand" "=r")
10195         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10196   "TARGET_64BIT
10197    && (optimize_function_for_size_p (cfun)
10198        || !TARGET_PARTIAL_FLAG_REG_STALL
10199        || (operands[2] == const1_rtx
10200            && (TARGET_SHIFT1
10201                || TARGET_DOUBLE_WITH_ADD)))
10202    && ix86_match_ccmode (insn, CCGOCmode)
10203    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10205   switch (get_attr_type (insn))
10206     {
10207     case TYPE_ALU:
10208       gcc_assert (operands[2] == const1_rtx);
10209       return "add{l}\t%k0, %k0";
10211     default:
10212       if (operands[2] == const1_rtx
10213           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10214         return "sal{l}\t%k0";
10215       else
10216         return "sal{l}\t{%2, %k0|%k0, %2}";
10217     }
10219   [(set (attr "type")
10220      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
10221                  (match_operand 2 "const1_operand"))
10222               (const_string "alu")
10223            ]
10224            (const_string "ishift")))
10225    (set (attr "length_immediate")
10226      (if_then_else
10227        (ior (eq_attr "type" "alu")
10228             (and (eq_attr "type" "ishift")
10229                  (and (match_operand 2 "const1_operand")
10230                       (ior (match_test "TARGET_SHIFT1")
10231                            (match_test "optimize_function_for_size_p (cfun)")))))
10232        (const_string "0")
10233        (const_string "*")))
10234    (set_attr "mode" "SI")])
10236 (define_insn "*ashl<mode>3_cconly"
10237   [(set (reg FLAGS_REG)
10238         (compare
10239           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
10240                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10241           (const_int 0)))
10242    (clobber (match_scratch:SWI 0 "=<r>"))]
10243   "(optimize_function_for_size_p (cfun)
10244     || !TARGET_PARTIAL_FLAG_REG_STALL
10245     || (operands[2] == const1_rtx
10246         && (TARGET_SHIFT1
10247             || TARGET_DOUBLE_WITH_ADD)))
10248    && ix86_match_ccmode (insn, CCGOCmode)"
10250   switch (get_attr_type (insn))
10251     {
10252     case TYPE_ALU:
10253       gcc_assert (operands[2] == const1_rtx);
10254       return "add{<imodesuffix>}\t%0, %0";
10256     default:
10257       if (operands[2] == const1_rtx
10258           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10259         return "sal{<imodesuffix>}\t%0";
10260       else
10261         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10262     }
10264   [(set (attr "type")
10265      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10266                       (match_operand 0 "register_operand"))
10267                  (match_operand 2 "const1_operand"))
10268               (const_string "alu")
10269            ]
10270            (const_string "ishift")))
10271    (set (attr "length_immediate")
10272      (if_then_else
10273        (ior (eq_attr "type" "alu")
10274             (and (eq_attr "type" "ishift")
10275                  (and (match_operand 2 "const1_operand")
10276                       (ior (match_test "TARGET_SHIFT1")
10277                            (match_test "optimize_function_for_size_p (cfun)")))))
10278        (const_string "0")
10279        (const_string "*")))
10280    (set_attr "mode" "<MODE>")])
10282 ;; See comment above `ashl<mode>3' about how this works.
10284 (define_expand "<shift_insn><mode>3"
10285   [(set (match_operand:SDWIM 0 "<shift_operand>")
10286         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
10287                            (match_operand:QI 2 "nonmemory_operand")))]
10288   ""
10289   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10291 ;; Avoid useless masking of count operand.
10292 (define_insn "*<shift_insn><mode>3_mask"
10293   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10294         (any_shiftrt:SWI48
10295           (match_operand:SWI48 1 "nonimmediate_operand" "0")
10296           (subreg:QI
10297             (and:SI
10298               (match_operand:SI 2 "register_operand" "c")
10299               (match_operand:SI 3 "const_int_operand" "n")) 0)))
10300    (clobber (reg:CC FLAGS_REG))]
10301   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10302    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10303       == GET_MODE_BITSIZE (<MODE>mode)-1"
10305   return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10307   [(set_attr "type" "ishift")
10308    (set_attr "mode" "<MODE>")])
10310 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
10311   [(set (match_operand:DWI 0 "register_operand" "=r")
10312         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10313                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10314    (clobber (reg:CC FLAGS_REG))]
10315   ""
10316   "#"
10317   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10318   [(const_int 0)]
10319   "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10320   [(set_attr "type" "multi")])
10322 ;; By default we don't ask for a scratch register, because when DWImode
10323 ;; values are manipulated, registers are already at a premium.  But if
10324 ;; we have one handy, we won't turn it away.
10326 (define_peephole2
10327   [(match_scratch:DWIH 3 "r")
10328    (parallel [(set (match_operand:<DWI> 0 "register_operand")
10329                    (any_shiftrt:<DWI>
10330                      (match_operand:<DWI> 1 "register_operand")
10331                      (match_operand:QI 2 "nonmemory_operand")))
10332               (clobber (reg:CC FLAGS_REG))])
10333    (match_dup 3)]
10334   "TARGET_CMOVE"
10335   [(const_int 0)]
10336   "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
10338 (define_insn "x86_64_shrd"
10339   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10340         (ior:DI (lshiftrt:DI (match_dup 0)
10341                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
10342                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10343                   (minus:QI (const_int 64) (match_dup 2)))))
10344    (clobber (reg:CC FLAGS_REG))]
10345   "TARGET_64BIT"
10346   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10347   [(set_attr "type" "ishift")
10348    (set_attr "prefix_0f" "1")
10349    (set_attr "mode" "DI")
10350    (set_attr "athlon_decode" "vector")
10351    (set_attr "amdfam10_decode" "vector")
10352    (set_attr "bdver1_decode" "vector")])
10354 (define_insn "x86_shrd"
10355   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10356         (ior:SI (lshiftrt:SI (match_dup 0)
10357                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
10358                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10359                   (minus:QI (const_int 32) (match_dup 2)))))
10360    (clobber (reg:CC FLAGS_REG))]
10361   ""
10362   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10363   [(set_attr "type" "ishift")
10364    (set_attr "prefix_0f" "1")
10365    (set_attr "mode" "SI")
10366    (set_attr "pent_pair" "np")
10367    (set_attr "athlon_decode" "vector")
10368    (set_attr "amdfam10_decode" "vector")
10369    (set_attr "bdver1_decode" "vector")])
10371 (define_insn "ashrdi3_cvt"
10372   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10373         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10374                      (match_operand:QI 2 "const_int_operand")))
10375    (clobber (reg:CC FLAGS_REG))]
10376   "TARGET_64BIT && INTVAL (operands[2]) == 63
10377    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10378    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10379   "@
10380    {cqto|cqo}
10381    sar{q}\t{%2, %0|%0, %2}"
10382   [(set_attr "type" "imovx,ishift")
10383    (set_attr "prefix_0f" "0,*")
10384    (set_attr "length_immediate" "0,*")
10385    (set_attr "modrm" "0,1")
10386    (set_attr "mode" "DI")])
10388 (define_insn "ashrsi3_cvt"
10389   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10390         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10391                      (match_operand:QI 2 "const_int_operand")))
10392    (clobber (reg:CC FLAGS_REG))]
10393   "INTVAL (operands[2]) == 31
10394    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10395    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10396   "@
10397    {cltd|cdq}
10398    sar{l}\t{%2, %0|%0, %2}"
10399   [(set_attr "type" "imovx,ishift")
10400    (set_attr "prefix_0f" "0,*")
10401    (set_attr "length_immediate" "0,*")
10402    (set_attr "modrm" "0,1")
10403    (set_attr "mode" "SI")])
10405 (define_insn "*ashrsi3_cvt_zext"
10406   [(set (match_operand:DI 0 "register_operand" "=*d,r")
10407         (zero_extend:DI
10408           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10409                        (match_operand:QI 2 "const_int_operand"))))
10410    (clobber (reg:CC FLAGS_REG))]
10411   "TARGET_64BIT && INTVAL (operands[2]) == 31
10412    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10413    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10414   "@
10415    {cltd|cdq}
10416    sar{l}\t{%2, %k0|%k0, %2}"
10417   [(set_attr "type" "imovx,ishift")
10418    (set_attr "prefix_0f" "0,*")
10419    (set_attr "length_immediate" "0,*")
10420    (set_attr "modrm" "0,1")
10421    (set_attr "mode" "SI")])
10423 (define_expand "x86_shift<mode>_adj_3"
10424   [(use (match_operand:SWI48 0 "register_operand"))
10425    (use (match_operand:SWI48 1 "register_operand"))
10426    (use (match_operand:QI 2 "register_operand"))]
10427   ""
10429   rtx_code_label *label = gen_label_rtx ();
10430   rtx tmp;
10432   emit_insn (gen_testqi_ccz_1 (operands[2],
10433                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10435   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10436   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10437   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10438                               gen_rtx_LABEL_REF (VOIDmode, label),
10439                               pc_rtx);
10440   tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10441   JUMP_LABEL (tmp) = label;
10443   emit_move_insn (operands[0], operands[1]);
10444   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10445                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10446   emit_label (label);
10447   LABEL_NUSES (label) = 1;
10449   DONE;
10452 (define_insn "*bmi2_<shift_insn><mode>3_1"
10453   [(set (match_operand:SWI48 0 "register_operand" "=r")
10454         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10455                            (match_operand:SWI48 2 "register_operand" "r")))]
10456   "TARGET_BMI2"
10457   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
10458   [(set_attr "type" "ishiftx")
10459    (set_attr "mode" "<MODE>")])
10461 (define_insn "*<shift_insn><mode>3_1"
10462   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10463         (any_shiftrt:SWI48
10464           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10465           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
10466    (clobber (reg:CC FLAGS_REG))]
10467   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10469   switch (get_attr_type (insn))
10470     {
10471     case TYPE_ISHIFTX:
10472       return "#";
10474     default:
10475       if (operands[2] == const1_rtx
10476           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10477         return "<shift>{<imodesuffix>}\t%0";
10478       else
10479         return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10480     }
10482   [(set_attr "isa" "*,bmi2")
10483    (set_attr "type" "ishift,ishiftx")
10484    (set (attr "length_immediate")
10485      (if_then_else
10486        (and (match_operand 2 "const1_operand")
10487             (ior (match_test "TARGET_SHIFT1")
10488                  (match_test "optimize_function_for_size_p (cfun)")))
10489        (const_string "0")
10490        (const_string "*")))
10491    (set_attr "mode" "<MODE>")])
10493 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10494 (define_split
10495   [(set (match_operand:SWI48 0 "register_operand")
10496         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10497                            (match_operand:QI 2 "register_operand")))
10498    (clobber (reg:CC FLAGS_REG))]
10499   "TARGET_BMI2 && reload_completed"
10500   [(set (match_dup 0)
10501         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10502   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10504 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10505   [(set (match_operand:DI 0 "register_operand" "=r")
10506         (zero_extend:DI
10507           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10508                           (match_operand:SI 2 "register_operand" "r"))))]
10509   "TARGET_64BIT && TARGET_BMI2"
10510   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10511   [(set_attr "type" "ishiftx")
10512    (set_attr "mode" "SI")])
10514 (define_insn "*<shift_insn>si3_1_zext"
10515   [(set (match_operand:DI 0 "register_operand" "=r,r")
10516         (zero_extend:DI
10517           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10518                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10519    (clobber (reg:CC FLAGS_REG))]
10520   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10522   switch (get_attr_type (insn))
10523     {
10524     case TYPE_ISHIFTX:
10525       return "#";
10527     default:
10528       if (operands[2] == const1_rtx
10529           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10530         return "<shift>{l}\t%k0";
10531       else
10532         return "<shift>{l}\t{%2, %k0|%k0, %2}";
10533     }
10535   [(set_attr "isa" "*,bmi2")
10536    (set_attr "type" "ishift,ishiftx")
10537    (set (attr "length_immediate")
10538      (if_then_else
10539        (and (match_operand 2 "const1_operand")
10540             (ior (match_test "TARGET_SHIFT1")
10541                  (match_test "optimize_function_for_size_p (cfun)")))
10542        (const_string "0")
10543        (const_string "*")))
10544    (set_attr "mode" "SI")])
10546 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10547 (define_split
10548   [(set (match_operand:DI 0 "register_operand")
10549         (zero_extend:DI
10550           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10551                           (match_operand:QI 2 "register_operand"))))
10552    (clobber (reg:CC FLAGS_REG))]
10553   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10554   [(set (match_dup 0)
10555         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10556   "operands[2] = gen_lowpart (SImode, operands[2]);")
10558 (define_insn "*<shift_insn><mode>3_1"
10559   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10560         (any_shiftrt:SWI12
10561           (match_operand:SWI12 1 "nonimmediate_operand" "0")
10562           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10563    (clobber (reg:CC FLAGS_REG))]
10564   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10566   if (operands[2] == const1_rtx
10567       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10568     return "<shift>{<imodesuffix>}\t%0";
10569   else
10570     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10572   [(set_attr "type" "ishift")
10573    (set (attr "length_immediate")
10574      (if_then_else
10575        (and (match_operand 2 "const1_operand")
10576             (ior (match_test "TARGET_SHIFT1")
10577                  (match_test "optimize_function_for_size_p (cfun)")))
10578        (const_string "0")
10579        (const_string "*")))
10580    (set_attr "mode" "<MODE>")])
10582 (define_insn "*<shift_insn>qi3_1_slp"
10583   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10584         (any_shiftrt:QI (match_dup 0)
10585                         (match_operand:QI 1 "nonmemory_operand" "cI")))
10586    (clobber (reg:CC FLAGS_REG))]
10587   "(optimize_function_for_size_p (cfun)
10588     || !TARGET_PARTIAL_REG_STALL
10589     || (operands[1] == const1_rtx
10590         && TARGET_SHIFT1))"
10592   if (operands[1] == const1_rtx
10593       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10594     return "<shift>{b}\t%0";
10595   else
10596     return "<shift>{b}\t{%1, %0|%0, %1}";
10598   [(set_attr "type" "ishift1")
10599    (set (attr "length_immediate")
10600      (if_then_else
10601        (and (match_operand 1 "const1_operand")
10602             (ior (match_test "TARGET_SHIFT1")
10603                  (match_test "optimize_function_for_size_p (cfun)")))
10604        (const_string "0")
10605        (const_string "*")))
10606    (set_attr "mode" "QI")])
10608 ;; This pattern can't accept a variable shift count, since shifts by
10609 ;; zero don't affect the flags.  We assume that shifts by constant
10610 ;; zero are optimized away.
10611 (define_insn "*<shift_insn><mode>3_cmp"
10612   [(set (reg FLAGS_REG)
10613         (compare
10614           (any_shiftrt:SWI
10615             (match_operand:SWI 1 "nonimmediate_operand" "0")
10616             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10617           (const_int 0)))
10618    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10619         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10620   "(optimize_function_for_size_p (cfun)
10621     || !TARGET_PARTIAL_FLAG_REG_STALL
10622     || (operands[2] == const1_rtx
10623         && TARGET_SHIFT1))
10624    && ix86_match_ccmode (insn, CCGOCmode)
10625    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10627   if (operands[2] == const1_rtx
10628       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10629     return "<shift>{<imodesuffix>}\t%0";
10630   else
10631     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10633   [(set_attr "type" "ishift")
10634    (set (attr "length_immediate")
10635      (if_then_else
10636        (and (match_operand 2 "const1_operand")
10637             (ior (match_test "TARGET_SHIFT1")
10638                  (match_test "optimize_function_for_size_p (cfun)")))
10639        (const_string "0")
10640        (const_string "*")))
10641    (set_attr "mode" "<MODE>")])
10643 (define_insn "*<shift_insn>si3_cmp_zext"
10644   [(set (reg FLAGS_REG)
10645         (compare
10646           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10647                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
10648           (const_int 0)))
10649    (set (match_operand:DI 0 "register_operand" "=r")
10650         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10651   "TARGET_64BIT
10652    && (optimize_function_for_size_p (cfun)
10653        || !TARGET_PARTIAL_FLAG_REG_STALL
10654        || (operands[2] == const1_rtx
10655            && TARGET_SHIFT1))
10656    && ix86_match_ccmode (insn, CCGOCmode)
10657    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10659   if (operands[2] == const1_rtx
10660       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10661     return "<shift>{l}\t%k0";
10662   else
10663     return "<shift>{l}\t{%2, %k0|%k0, %2}";
10665   [(set_attr "type" "ishift")
10666    (set (attr "length_immediate")
10667      (if_then_else
10668        (and (match_operand 2 "const1_operand")
10669             (ior (match_test "TARGET_SHIFT1")
10670                  (match_test "optimize_function_for_size_p (cfun)")))
10671        (const_string "0")
10672        (const_string "*")))
10673    (set_attr "mode" "SI")])
10675 (define_insn "*<shift_insn><mode>3_cconly"
10676   [(set (reg FLAGS_REG)
10677         (compare
10678           (any_shiftrt:SWI
10679             (match_operand:SWI 1 "register_operand" "0")
10680             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10681           (const_int 0)))
10682    (clobber (match_scratch:SWI 0 "=<r>"))]
10683   "(optimize_function_for_size_p (cfun)
10684     || !TARGET_PARTIAL_FLAG_REG_STALL
10685     || (operands[2] == const1_rtx
10686         && TARGET_SHIFT1))
10687    && ix86_match_ccmode (insn, CCGOCmode)"
10689   if (operands[2] == const1_rtx
10690       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10691     return "<shift>{<imodesuffix>}\t%0";
10692   else
10693     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10695   [(set_attr "type" "ishift")
10696    (set (attr "length_immediate")
10697      (if_then_else
10698        (and (match_operand 2 "const1_operand")
10699             (ior (match_test "TARGET_SHIFT1")
10700                  (match_test "optimize_function_for_size_p (cfun)")))
10701        (const_string "0")
10702        (const_string "*")))
10703    (set_attr "mode" "<MODE>")])
10705 ;; Rotate instructions
10707 (define_expand "<rotate_insn>ti3"
10708   [(set (match_operand:TI 0 "register_operand")
10709         (any_rotate:TI (match_operand:TI 1 "register_operand")
10710                        (match_operand:QI 2 "nonmemory_operand")))]
10711   "TARGET_64BIT"
10713   if (const_1_to_63_operand (operands[2], VOIDmode))
10714     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10715                 (operands[0], operands[1], operands[2]));
10716   else
10717     FAIL;
10719   DONE;
10722 (define_expand "<rotate_insn>di3"
10723   [(set (match_operand:DI 0 "shiftdi_operand")
10724         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10725                        (match_operand:QI 2 "nonmemory_operand")))]
10726  ""
10728   if (TARGET_64BIT)
10729     ix86_expand_binary_operator (<CODE>, DImode, operands);
10730   else if (const_1_to_31_operand (operands[2], VOIDmode))
10731     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10732                 (operands[0], operands[1], operands[2]));
10733   else
10734     FAIL;
10736   DONE;
10739 (define_expand "<rotate_insn><mode>3"
10740   [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10741         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10742                             (match_operand:QI 2 "nonmemory_operand")))]
10743   ""
10744   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10746 ;; Avoid useless masking of count operand.
10747 (define_insn "*<rotate_insn><mode>3_mask"
10748   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10749         (any_rotate:SWI48
10750           (match_operand:SWI48 1 "nonimmediate_operand" "0")
10751           (subreg:QI
10752             (and:SI
10753               (match_operand:SI 2 "register_operand" "c")
10754               (match_operand:SI 3 "const_int_operand" "n")) 0)))
10755    (clobber (reg:CC FLAGS_REG))]
10756   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10757    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10758       == GET_MODE_BITSIZE (<MODE>mode)-1"
10760   return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10762   [(set_attr "type" "rotate")
10763    (set_attr "mode" "<MODE>")])
10765 ;; Implement rotation using two double-precision
10766 ;; shift instructions and a scratch register.
10768 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10769  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10770        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10771                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10772   (clobber (reg:CC FLAGS_REG))
10773   (clobber (match_scratch:DWIH 3 "=&r"))]
10774  ""
10775  "#"
10776  "reload_completed"
10777  [(set (match_dup 3) (match_dup 4))
10778   (parallel
10779    [(set (match_dup 4)
10780          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10781                    (lshiftrt:DWIH (match_dup 5)
10782                                   (minus:QI (match_dup 6) (match_dup 2)))))
10783     (clobber (reg:CC FLAGS_REG))])
10784   (parallel
10785    [(set (match_dup 5)
10786          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10787                    (lshiftrt:DWIH (match_dup 3)
10788                                   (minus:QI (match_dup 6) (match_dup 2)))))
10789     (clobber (reg:CC FLAGS_REG))])]
10791   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10793   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10796 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10797  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10798        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10799                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10800   (clobber (reg:CC FLAGS_REG))
10801   (clobber (match_scratch:DWIH 3 "=&r"))]
10802  ""
10803  "#"
10804  "reload_completed"
10805  [(set (match_dup 3) (match_dup 4))
10806   (parallel
10807    [(set (match_dup 4)
10808          (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10809                    (ashift:DWIH (match_dup 5)
10810                                 (minus:QI (match_dup 6) (match_dup 2)))))
10811     (clobber (reg:CC FLAGS_REG))])
10812   (parallel
10813    [(set (match_dup 5)
10814          (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10815                    (ashift:DWIH (match_dup 3)
10816                                 (minus:QI (match_dup 6) (match_dup 2)))))
10817     (clobber (reg:CC FLAGS_REG))])]
10819   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10821   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10824 (define_insn "*bmi2_rorx<mode>3_1"
10825   [(set (match_operand:SWI48 0 "register_operand" "=r")
10826         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10827                         (match_operand:QI 2 "immediate_operand" "<S>")))]
10828   "TARGET_BMI2"
10829   "rorx\t{%2, %1, %0|%0, %1, %2}"
10830   [(set_attr "type" "rotatex")
10831    (set_attr "mode" "<MODE>")])
10833 (define_insn "*<rotate_insn><mode>3_1"
10834   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10835         (any_rotate:SWI48
10836           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10837           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10838    (clobber (reg:CC FLAGS_REG))]
10839   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10841   switch (get_attr_type (insn))
10842     {
10843     case TYPE_ROTATEX:
10844       return "#";
10846     default:
10847       if (operands[2] == const1_rtx
10848           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10849         return "<rotate>{<imodesuffix>}\t%0";
10850       else
10851         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10852     }
10854   [(set_attr "isa" "*,bmi2")
10855    (set_attr "type" "rotate,rotatex")
10856    (set (attr "length_immediate")
10857      (if_then_else
10858        (and (eq_attr "type" "rotate")
10859             (and (match_operand 2 "const1_operand")
10860                  (ior (match_test "TARGET_SHIFT1")
10861                       (match_test "optimize_function_for_size_p (cfun)"))))
10862        (const_string "0")
10863        (const_string "*")))
10864    (set_attr "mode" "<MODE>")])
10866 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10867 (define_split
10868   [(set (match_operand:SWI48 0 "register_operand")
10869         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10870                       (match_operand:QI 2 "immediate_operand")))
10871    (clobber (reg:CC FLAGS_REG))]
10872   "TARGET_BMI2 && reload_completed"
10873   [(set (match_dup 0)
10874         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10876   operands[2]
10877     = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10880 (define_split
10881   [(set (match_operand:SWI48 0 "register_operand")
10882         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10883                         (match_operand:QI 2 "immediate_operand")))
10884    (clobber (reg:CC FLAGS_REG))]
10885   "TARGET_BMI2 && reload_completed"
10886   [(set (match_dup 0)
10887         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10889 (define_insn "*bmi2_rorxsi3_1_zext"
10890   [(set (match_operand:DI 0 "register_operand" "=r")
10891         (zero_extend:DI
10892           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10893                        (match_operand:QI 2 "immediate_operand" "I"))))]
10894   "TARGET_64BIT && TARGET_BMI2"
10895   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10896   [(set_attr "type" "rotatex")
10897    (set_attr "mode" "SI")])
10899 (define_insn "*<rotate_insn>si3_1_zext"
10900   [(set (match_operand:DI 0 "register_operand" "=r,r")
10901         (zero_extend:DI
10902           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10903                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10904    (clobber (reg:CC FLAGS_REG))]
10905   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10907   switch (get_attr_type (insn))
10908     {
10909     case TYPE_ROTATEX:
10910       return "#";
10912     default:
10913       if (operands[2] == const1_rtx
10914           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10915         return "<rotate>{l}\t%k0";
10916       else
10917         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10918     }
10920   [(set_attr "isa" "*,bmi2")
10921    (set_attr "type" "rotate,rotatex")
10922    (set (attr "length_immediate")
10923      (if_then_else
10924        (and (eq_attr "type" "rotate")
10925             (and (match_operand 2 "const1_operand")
10926                  (ior (match_test "TARGET_SHIFT1")
10927                       (match_test "optimize_function_for_size_p (cfun)"))))
10928        (const_string "0")
10929        (const_string "*")))
10930    (set_attr "mode" "SI")])
10932 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10933 (define_split
10934   [(set (match_operand:DI 0 "register_operand")
10935         (zero_extend:DI
10936           (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10937                      (match_operand:QI 2 "immediate_operand"))))
10938    (clobber (reg:CC FLAGS_REG))]
10939   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10940   [(set (match_dup 0)
10941         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10943   operands[2]
10944     = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10947 (define_split
10948   [(set (match_operand:DI 0 "register_operand")
10949         (zero_extend:DI
10950           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10951                        (match_operand:QI 2 "immediate_operand"))))
10952    (clobber (reg:CC FLAGS_REG))]
10953   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10954   [(set (match_dup 0)
10955         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10957 (define_insn "*<rotate_insn><mode>3_1"
10958   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10959         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10960                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10961    (clobber (reg:CC FLAGS_REG))]
10962   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10964   if (operands[2] == const1_rtx
10965       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10966     return "<rotate>{<imodesuffix>}\t%0";
10967   else
10968     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10970   [(set_attr "type" "rotate")
10971    (set (attr "length_immediate")
10972      (if_then_else
10973        (and (match_operand 2 "const1_operand")
10974             (ior (match_test "TARGET_SHIFT1")
10975                  (match_test "optimize_function_for_size_p (cfun)")))
10976        (const_string "0")
10977        (const_string "*")))
10978    (set_attr "mode" "<MODE>")])
10980 (define_insn "*<rotate_insn>qi3_1_slp"
10981   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10982         (any_rotate:QI (match_dup 0)
10983                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10984    (clobber (reg:CC FLAGS_REG))]
10985   "(optimize_function_for_size_p (cfun)
10986     || !TARGET_PARTIAL_REG_STALL
10987     || (operands[1] == const1_rtx
10988         && TARGET_SHIFT1))"
10990   if (operands[1] == const1_rtx
10991       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10992     return "<rotate>{b}\t%0";
10993   else
10994     return "<rotate>{b}\t{%1, %0|%0, %1}";
10996   [(set_attr "type" "rotate1")
10997    (set (attr "length_immediate")
10998      (if_then_else
10999        (and (match_operand 1 "const1_operand")
11000             (ior (match_test "TARGET_SHIFT1")
11001                  (match_test "optimize_function_for_size_p (cfun)")))
11002        (const_string "0")
11003        (const_string "*")))
11004    (set_attr "mode" "QI")])
11006 (define_split
11007  [(set (match_operand:HI 0 "register_operand")
11008        (any_rotate:HI (match_dup 0) (const_int 8)))
11009   (clobber (reg:CC FLAGS_REG))]
11010  "reload_completed
11011   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
11012  [(parallel [(set (strict_low_part (match_dup 0))
11013                   (bswap:HI (match_dup 0)))
11014              (clobber (reg:CC FLAGS_REG))])])
11016 ;; Bit set / bit test instructions
11018 ;; %%% bts, btr, btc, bt.
11019 ;; In general these instructions are *slow* when applied to memory,
11020 ;; since they enforce atomic operation.  When applied to registers,
11021 ;; it depends on the cpu implementation.  They're never faster than
11022 ;; the corresponding and/ior/xor operations, so with 32-bit there's
11023 ;; no point.  But in 64-bit, we can't hold the relevant immediates
11024 ;; within the instruction itself, so operating on bits in the high
11025 ;; 32-bits of a register becomes easier.
11027 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
11028 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
11029 ;; negdf respectively, so they can never be disabled entirely.
11031 (define_insn "*btsq"
11032   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
11033                          (const_int 1)
11034                          (match_operand 1 "const_0_to_63_operand" "J"))
11035         (const_int 1))
11036    (clobber (reg:CC FLAGS_REG))]
11037   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11038   "bts{q}\t{%1, %0|%0, %1}"
11039   [(set_attr "type" "alu1")
11040    (set_attr "prefix_0f" "1")
11041    (set_attr "znver1_decode" "double")
11042    (set_attr "mode" "DI")])
11044 (define_insn "*btrq"
11045   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
11046                          (const_int 1)
11047                          (match_operand 1 "const_0_to_63_operand" "J"))
11048         (const_int 0))
11049    (clobber (reg:CC FLAGS_REG))]
11050   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11051   "btr{q}\t{%1, %0|%0, %1}"
11052   [(set_attr "type" "alu1")
11053    (set_attr "prefix_0f" "1")
11054    (set_attr "znver1_decode" "double")
11055    (set_attr "mode" "DI")])
11057 (define_insn "*btcq"
11058   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
11059                          (const_int 1)
11060                          (match_operand 1 "const_0_to_63_operand" "J"))
11061         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
11062    (clobber (reg:CC FLAGS_REG))]
11063   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11064   "btc{q}\t{%1, %0|%0, %1}"
11065   [(set_attr "type" "alu1")
11066    (set_attr "prefix_0f" "1")
11067    (set_attr "znver1_decode" "double")
11068    (set_attr "mode" "DI")])
11070 ;; Allow Nocona to avoid these instructions if a register is available.
11072 (define_peephole2
11073   [(match_scratch:DI 2 "r")
11074    (parallel [(set (zero_extract:DI
11075                      (match_operand:DI 0 "register_operand")
11076                      (const_int 1)
11077                      (match_operand 1 "const_0_to_63_operand"))
11078                    (const_int 1))
11079               (clobber (reg:CC FLAGS_REG))])]
11080   "TARGET_64BIT && !TARGET_USE_BT"
11081   [(parallel [(set (match_dup 0)
11082                    (ior:DI (match_dup 0) (match_dup 3)))
11083               (clobber (reg:CC FLAGS_REG))])]
11085   int i = INTVAL (operands[1]);
11087   operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11089   if (!x86_64_immediate_operand (operands[3], DImode))
11090     {
11091       emit_move_insn (operands[2], operands[3]);
11092       operands[3] = operands[2];
11093     }
11096 (define_peephole2
11097   [(match_scratch:DI 2 "r")
11098    (parallel [(set (zero_extract:DI
11099                      (match_operand:DI 0 "register_operand")
11100                      (const_int 1)
11101                      (match_operand 1 "const_0_to_63_operand"))
11102                    (const_int 0))
11103               (clobber (reg:CC FLAGS_REG))])]
11104   "TARGET_64BIT && !TARGET_USE_BT"
11105   [(parallel [(set (match_dup 0)
11106                    (and:DI (match_dup 0) (match_dup 3)))
11107               (clobber (reg:CC FLAGS_REG))])]
11109   int i = INTVAL (operands[1]);
11111   operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
11113   if (!x86_64_immediate_operand (operands[3], DImode))
11114     {
11115       emit_move_insn (operands[2], operands[3]);
11116       operands[3] = operands[2];
11117     }
11120 (define_peephole2
11121   [(match_scratch:DI 2 "r")
11122    (parallel [(set (zero_extract:DI
11123                      (match_operand:DI 0 "register_operand")
11124                      (const_int 1)
11125                      (match_operand 1 "const_0_to_63_operand"))
11126               (not:DI (zero_extract:DI
11127                         (match_dup 0) (const_int 1) (match_dup 1))))
11128               (clobber (reg:CC FLAGS_REG))])]
11129   "TARGET_64BIT && !TARGET_USE_BT"
11130   [(parallel [(set (match_dup 0)
11131                    (xor:DI (match_dup 0) (match_dup 3)))
11132               (clobber (reg:CC FLAGS_REG))])]
11134   int i = INTVAL (operands[1]);
11136   operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11138   if (!x86_64_immediate_operand (operands[3], DImode))
11139     {
11140       emit_move_insn (operands[2], operands[3]);
11141       operands[3] = operands[2];
11142     }
11145 (define_insn "*bt<mode>"
11146   [(set (reg:CCC FLAGS_REG)
11147         (compare:CCC
11148           (zero_extract:SWI48
11149             (match_operand:SWI48 0 "register_operand" "r")
11150             (const_int 1)
11151             (match_operand:SI 1 "nonmemory_operand" "rN"))
11152           (const_int 0)))]
11153   ""
11155   switch (get_attr_mode (insn))
11156     {
11157     case MODE_SI:
11158       return "bt{l}\t{%1, %k0|%k0, %1}";
11160     case MODE_DI:
11161       return "bt{q}\t{%q1, %0|%0, %q1}";
11163     default:
11164       gcc_unreachable ();
11165     }
11167   [(set_attr "type" "alu1")
11168    (set_attr "prefix_0f" "1")
11169    (set (attr "mode")
11170         (if_then_else
11171           (and (match_test "CONST_INT_P (operands[1])")
11172                (match_test "INTVAL (operands[1]) < 32"))
11173           (const_string "SI")
11174           (const_string "<MODE>")))])
11176 (define_insn_and_split "*jcc_bt<mode>"
11177   [(set (pc)
11178         (if_then_else (match_operator 0 "bt_comparison_operator"
11179                         [(zero_extract:SWI48
11180                            (match_operand:SWI48 1 "register_operand")
11181                            (const_int 1)
11182                            (match_operand:SI 2 "nonmemory_operand"))
11183                          (const_int 0)])
11184                       (label_ref (match_operand 3))
11185                       (pc)))
11186    (clobber (reg:CC FLAGS_REG))]
11187   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11188    && (CONST_INT_P (operands[2])
11189        ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
11190           && INTVAL (operands[2])
11191                >= (optimize_function_for_size_p (cfun) ? 8 : 32))
11192        : register_operand (operands[2], SImode))
11193    && can_create_pseudo_p ()"
11194   "#"
11195   "&& 1"
11196   [(set (reg:CCC FLAGS_REG)
11197         (compare:CCC
11198           (zero_extract:SWI48
11199             (match_dup 1)
11200             (const_int 1)
11201             (match_dup 2))
11202           (const_int 0)))
11203    (set (pc)
11204         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11205                       (label_ref (match_dup 3))
11206                       (pc)))]
11208   operands[0] = shallow_copy_rtx (operands[0]);
11209   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11212 (define_insn_and_split "*jcc_bt<mode>_1"
11213   [(set (pc)
11214         (if_then_else (match_operator 0 "bt_comparison_operator"
11215                         [(zero_extract:SWI48
11216                            (match_operand:SWI48 1 "register_operand")
11217                            (const_int 1)
11218                            (zero_extend:SI
11219                              (match_operand:QI 2 "register_operand")))
11220                          (const_int 0)])
11221                       (label_ref (match_operand 3))
11222                       (pc)))
11223    (clobber (reg:CC FLAGS_REG))]
11224   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11225    && can_create_pseudo_p ()"
11226   "#"
11227   "&& 1"
11228   [(set (reg:CCC FLAGS_REG)
11229         (compare:CCC
11230           (zero_extract:SWI48
11231             (match_dup 1)
11232             (const_int 1)
11233             (match_dup 2))
11234           (const_int 0)))
11235    (set (pc)
11236         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11237                       (label_ref (match_dup 3))
11238                       (pc)))]
11240   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11241   operands[0] = shallow_copy_rtx (operands[0]);
11242   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11245 ;; Avoid useless masking of bit offset operand.
11246 (define_insn_and_split "*jcc_bt<mode>_mask"
11247   [(set (pc)
11248         (if_then_else (match_operator 0 "bt_comparison_operator"
11249                         [(zero_extract:SWI48
11250                            (match_operand:SWI48 1 "register_operand")
11251                            (const_int 1)
11252                            (and:SI
11253                              (match_operand:SI 2 "register_operand")
11254                              (match_operand 3 "const_int_operand")))])
11255                       (label_ref (match_operand 4))
11256                       (pc)))
11257    (clobber (reg:CC FLAGS_REG))]
11258   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11259    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11260       == GET_MODE_BITSIZE (<MODE>mode)-1
11261    && can_create_pseudo_p ()"
11262   "#"
11263   "&& 1"
11264   [(set (reg:CCC FLAGS_REG)
11265         (compare:CCC
11266           (zero_extract:SWI48
11267             (match_dup 1)
11268             (const_int 1)
11269             (match_dup 2))
11270           (const_int 0)))
11271    (set (pc)
11272         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11273                       (label_ref (match_dup 4))
11274                       (pc)))]
11276   operands[0] = shallow_copy_rtx (operands[0]);
11277   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11280 ;; Store-flag instructions.
11282 ;; For all sCOND expanders, also expand the compare or test insn that
11283 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
11285 (define_insn_and_split "*setcc_di_1"
11286   [(set (match_operand:DI 0 "register_operand" "=q")
11287         (match_operator:DI 1 "ix86_comparison_operator"
11288           [(reg FLAGS_REG) (const_int 0)]))]
11289   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
11290   "#"
11291   "&& reload_completed"
11292   [(set (match_dup 2) (match_dup 1))
11293    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
11295   operands[1] = shallow_copy_rtx (operands[1]);
11296   PUT_MODE (operands[1], QImode);
11297   operands[2] = gen_lowpart (QImode, operands[0]);
11300 (define_insn_and_split "*setcc_si_1_and"
11301   [(set (match_operand:SI 0 "register_operand" "=q")
11302         (match_operator:SI 1 "ix86_comparison_operator"
11303           [(reg FLAGS_REG) (const_int 0)]))
11304    (clobber (reg:CC FLAGS_REG))]
11305   "!TARGET_PARTIAL_REG_STALL
11306    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
11307   "#"
11308   "&& reload_completed"
11309   [(set (match_dup 2) (match_dup 1))
11310    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
11311               (clobber (reg:CC FLAGS_REG))])]
11313   operands[1] = shallow_copy_rtx (operands[1]);
11314   PUT_MODE (operands[1], QImode);
11315   operands[2] = gen_lowpart (QImode, operands[0]);
11318 (define_insn_and_split "*setcc_si_1_movzbl"
11319   [(set (match_operand:SI 0 "register_operand" "=q")
11320         (match_operator:SI 1 "ix86_comparison_operator"
11321           [(reg FLAGS_REG) (const_int 0)]))]
11322   "!TARGET_PARTIAL_REG_STALL
11323    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
11324   "#"
11325   "&& reload_completed"
11326   [(set (match_dup 2) (match_dup 1))
11327    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
11329   operands[1] = shallow_copy_rtx (operands[1]);
11330   PUT_MODE (operands[1], QImode);
11331   operands[2] = gen_lowpart (QImode, operands[0]);
11334 (define_insn "*setcc_qi"
11335   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11336         (match_operator:QI 1 "ix86_comparison_operator"
11337           [(reg FLAGS_REG) (const_int 0)]))]
11338   ""
11339   "set%C1\t%0"
11340   [(set_attr "type" "setcc")
11341    (set_attr "mode" "QI")])
11343 (define_insn "*setcc_qi_slp"
11344   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11345         (match_operator:QI 1 "ix86_comparison_operator"
11346           [(reg FLAGS_REG) (const_int 0)]))]
11347   ""
11348   "set%C1\t%0"
11349   [(set_attr "type" "setcc")
11350    (set_attr "mode" "QI")])
11352 ;; In general it is not safe to assume too much about CCmode registers,
11353 ;; so simplify-rtx stops when it sees a second one.  Under certain
11354 ;; conditions this is safe on x86, so help combine not create
11356 ;;      seta    %al
11357 ;;      testb   %al, %al
11358 ;;      sete    %al
11360 (define_split
11361   [(set (match_operand:QI 0 "nonimmediate_operand")
11362         (ne:QI (match_operator 1 "ix86_comparison_operator"
11363                  [(reg FLAGS_REG) (const_int 0)])
11364             (const_int 0)))]
11365   ""
11366   [(set (match_dup 0) (match_dup 1))]
11368   operands[1] = shallow_copy_rtx (operands[1]);
11369   PUT_MODE (operands[1], QImode);
11372 (define_split
11373   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11374         (ne:QI (match_operator 1 "ix86_comparison_operator"
11375                  [(reg FLAGS_REG) (const_int 0)])
11376             (const_int 0)))]
11377   ""
11378   [(set (match_dup 0) (match_dup 1))]
11380   operands[1] = shallow_copy_rtx (operands[1]);
11381   PUT_MODE (operands[1], QImode);
11384 (define_split
11385   [(set (match_operand:QI 0 "nonimmediate_operand")
11386         (eq:QI (match_operator 1 "ix86_comparison_operator"
11387                  [(reg FLAGS_REG) (const_int 0)])
11388             (const_int 0)))]
11389   ""
11390   [(set (match_dup 0) (match_dup 1))]
11392   operands[1] = shallow_copy_rtx (operands[1]);
11393   PUT_MODE (operands[1], QImode);
11394   PUT_CODE (operands[1],
11395             ix86_reverse_condition (GET_CODE (operands[1]),
11396                                     GET_MODE (XEXP (operands[1], 0))));
11398   /* Make sure that (a) the CCmode we have for the flags is strong
11399      enough for the reversed compare or (b) we have a valid FP compare.  */
11400   if (! ix86_comparison_operator (operands[1], VOIDmode))
11401     FAIL;
11404 (define_split
11405   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11406         (eq:QI (match_operator 1 "ix86_comparison_operator"
11407                  [(reg FLAGS_REG) (const_int 0)])
11408             (const_int 0)))]
11409   ""
11410   [(set (match_dup 0) (match_dup 1))]
11412   operands[1] = shallow_copy_rtx (operands[1]);
11413   PUT_MODE (operands[1], QImode);
11414   PUT_CODE (operands[1],
11415             ix86_reverse_condition (GET_CODE (operands[1]),
11416                                     GET_MODE (XEXP (operands[1], 0))));
11418   /* Make sure that (a) the CCmode we have for the flags is strong
11419      enough for the reversed compare or (b) we have a valid FP compare.  */
11420   if (! ix86_comparison_operator (operands[1], VOIDmode))
11421     FAIL;
11424 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
11425 ;; subsequent logical operations are used to imitate conditional moves.
11426 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
11427 ;; it directly.
11429 (define_insn "setcc_<mode>_sse"
11430   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
11431         (match_operator:MODEF 3 "sse_comparison_operator"
11432           [(match_operand:MODEF 1 "register_operand" "0,x")
11433            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
11434   "SSE_FLOAT_MODE_P (<MODE>mode)"
11435   "@
11436    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
11437    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
11438   [(set_attr "isa" "noavx,avx")
11439    (set_attr "type" "ssecmp")
11440    (set_attr "length_immediate" "1")
11441    (set_attr "prefix" "orig,vex")
11442    (set_attr "mode" "<MODE>")])
11444 ;; Basic conditional jump instructions.
11445 ;; We ignore the overflow flag for signed branch instructions.
11447 (define_insn "*jcc_1"
11448   [(set (pc)
11449         (if_then_else (match_operator 1 "ix86_comparison_operator"
11450                                       [(reg FLAGS_REG) (const_int 0)])
11451                       (label_ref (match_operand 0))
11452                       (pc)))]
11453   ""
11454   "%!%+j%C1\t%l0"
11455   [(set_attr "type" "ibr")
11456    (set_attr "modrm" "0")
11457    (set (attr "length")
11458         (if_then_else
11459           (and (ge (minus (match_dup 0) (pc))
11460                    (const_int -126))
11461                (lt (minus (match_dup 0) (pc))
11462                    (const_int 128)))
11463           (const_int 2)
11464           (const_int 6)))
11465    (set_attr "maybe_prefix_bnd" "1")])
11467 (define_insn "*jcc_2"
11468   [(set (pc)
11469         (if_then_else (match_operator 1 "ix86_comparison_operator"
11470                                       [(reg FLAGS_REG) (const_int 0)])
11471                       (pc)
11472                       (label_ref (match_operand 0))))]
11473   ""
11474   "%!%+j%c1\t%l0"
11475   [(set_attr "type" "ibr")
11476    (set_attr "modrm" "0")
11477    (set (attr "length")
11478         (if_then_else
11479           (and (ge (minus (match_dup 0) (pc))
11480                    (const_int -126))
11481                (lt (minus (match_dup 0) (pc))
11482                    (const_int 128)))
11483           (const_int 2)
11484           (const_int 6)))
11485    (set_attr "maybe_prefix_bnd" "1")])
11487 ;; In general it is not safe to assume too much about CCmode registers,
11488 ;; so simplify-rtx stops when it sees a second one.  Under certain
11489 ;; conditions this is safe on x86, so help combine not create
11491 ;;      seta    %al
11492 ;;      testb   %al, %al
11493 ;;      je      Lfoo
11495 (define_split
11496   [(set (pc)
11497         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11498                                       [(reg FLAGS_REG) (const_int 0)])
11499                           (const_int 0))
11500                       (label_ref (match_operand 1))
11501                       (pc)))]
11502   ""
11503   [(set (pc)
11504         (if_then_else (match_dup 0)
11505                       (label_ref (match_dup 1))
11506                       (pc)))]
11508   operands[0] = shallow_copy_rtx (operands[0]);
11509   PUT_MODE (operands[0], VOIDmode);
11512 (define_split
11513   [(set (pc)
11514         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11515                                       [(reg FLAGS_REG) (const_int 0)])
11516                           (const_int 0))
11517                       (label_ref (match_operand 1))
11518                       (pc)))]
11519   ""
11520   [(set (pc)
11521         (if_then_else (match_dup 0)
11522                       (label_ref (match_dup 1))
11523                       (pc)))]
11525   operands[0] = shallow_copy_rtx (operands[0]);
11526   PUT_MODE (operands[0], VOIDmode);
11527   PUT_CODE (operands[0],
11528             ix86_reverse_condition (GET_CODE (operands[0]),
11529                                     GET_MODE (XEXP (operands[0], 0))));
11531   /* Make sure that (a) the CCmode we have for the flags is strong
11532      enough for the reversed compare or (b) we have a valid FP compare.  */
11533   if (! ix86_comparison_operator (operands[0], VOIDmode))
11534     FAIL;
11537 ;; Define combination compare-and-branch fp compare instructions to help
11538 ;; combine.
11540 (define_insn "*jcc<mode>_0_i387"
11541   [(set (pc)
11542         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11543                         [(match_operand:X87MODEF 1 "register_operand" "f")
11544                          (match_operand:X87MODEF 2 "const0_operand")])
11545           (label_ref (match_operand 3))
11546           (pc)))
11547    (clobber (reg:CCFP FPSR_REG))
11548    (clobber (reg:CCFP FLAGS_REG))
11549    (clobber (match_scratch:HI 4 "=a"))]
11550   "TARGET_80387 && !TARGET_CMOVE"
11551   "#")
11553 (define_insn "*jcc<mode>_0_r_i387"
11554   [(set (pc)
11555         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11556                         [(match_operand:X87MODEF 1 "register_operand" "f")
11557                          (match_operand:X87MODEF 2 "const0_operand")])
11558           (pc)
11559           (label_ref (match_operand 3))))
11560    (clobber (reg:CCFP FPSR_REG))
11561    (clobber (reg:CCFP FLAGS_REG))
11562    (clobber (match_scratch:HI 4 "=a"))]
11563   "TARGET_80387 && !TARGET_CMOVE"
11564   "#")
11566 (define_insn "*jccxf_i387"
11567   [(set (pc)
11568         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11569                         [(match_operand:XF 1 "register_operand" "f")
11570                          (match_operand:XF 2 "register_operand" "f")])
11571           (label_ref (match_operand 3))
11572           (pc)))
11573    (clobber (reg:CCFP FPSR_REG))
11574    (clobber (reg:CCFP FLAGS_REG))
11575    (clobber (match_scratch:HI 4 "=a"))]
11576   "TARGET_80387 && !TARGET_CMOVE"
11577   "#")
11579 (define_insn "*jccxf_r_i387"
11580   [(set (pc)
11581         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11582                         [(match_operand:XF 1 "register_operand" "f")
11583                          (match_operand:XF 2 "register_operand" "f")])
11584           (pc)
11585           (label_ref (match_operand 3))))
11586    (clobber (reg:CCFP FPSR_REG))
11587    (clobber (reg:CCFP FLAGS_REG))
11588    (clobber (match_scratch:HI 4 "=a"))]
11589   "TARGET_80387 && !TARGET_CMOVE"
11590   "#")
11592 (define_insn "*jcc<mode>_i387"
11593   [(set (pc)
11594         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11595                         [(match_operand:MODEF 1 "register_operand" "f")
11596                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11597           (label_ref (match_operand 3))
11598           (pc)))
11599    (clobber (reg:CCFP FPSR_REG))
11600    (clobber (reg:CCFP FLAGS_REG))
11601    (clobber (match_scratch:HI 4 "=a"))]
11602   "TARGET_80387 && !TARGET_CMOVE"
11603   "#")
11605 (define_insn "*jcc<mode>_r_i387"
11606   [(set (pc)
11607         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11608                         [(match_operand:MODEF 1 "register_operand" "f")
11609                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11610           (pc)
11611           (label_ref (match_operand 3))))
11612    (clobber (reg:CCFP FPSR_REG))
11613    (clobber (reg:CCFP FLAGS_REG))
11614    (clobber (match_scratch:HI 4 "=a"))]
11615   "TARGET_80387 && !TARGET_CMOVE"
11616   "#")
11618 (define_insn "*jccu<mode>_i387"
11619   [(set (pc)
11620         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11621                         [(match_operand:X87MODEF 1 "register_operand" "f")
11622                          (match_operand:X87MODEF 2 "register_operand" "f")])
11623           (label_ref (match_operand 3))
11624           (pc)))
11625    (clobber (reg:CCFP FPSR_REG))
11626    (clobber (reg:CCFP FLAGS_REG))
11627    (clobber (match_scratch:HI 4 "=a"))]
11628   "TARGET_80387 && !TARGET_CMOVE"
11629   "#")
11631 (define_insn "*jccu<mode>_r_i387"
11632   [(set (pc)
11633         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11634                         [(match_operand:X87MODEF 1 "register_operand" "f")
11635                          (match_operand:X87MODEF 2 "register_operand" "f")])
11636           (pc)
11637           (label_ref (match_operand 3))))
11638    (clobber (reg:CCFP FPSR_REG))
11639    (clobber (reg:CCFP FLAGS_REG))
11640    (clobber (match_scratch:HI 4 "=a"))]
11641   "TARGET_80387 && !TARGET_CMOVE"
11642   "#")
11644 (define_split
11645   [(set (pc)
11646         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11647                         [(match_operand:X87MODEF 1 "register_operand")
11648                          (match_operand:X87MODEF 2 "nonimmediate_operand")])
11649           (match_operand 3)
11650           (match_operand 4)))
11651    (clobber (reg:CCFP FPSR_REG))
11652    (clobber (reg:CCFP FLAGS_REG))]
11653   "TARGET_80387 && !TARGET_CMOVE
11654    && reload_completed"
11655   [(const_int 0)]
11657   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11658                         operands[3], operands[4], NULL_RTX);
11659   DONE;
11662 (define_split
11663   [(set (pc)
11664         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11665                         [(match_operand:X87MODEF 1 "register_operand")
11666                          (match_operand:X87MODEF 2 "general_operand")])
11667           (match_operand 3)
11668           (match_operand 4)))
11669    (clobber (reg:CCFP FPSR_REG))
11670    (clobber (reg:CCFP FLAGS_REG))
11671    (clobber (match_scratch:HI 5))]
11672   "TARGET_80387 && !TARGET_CMOVE
11673    && reload_completed"
11674   [(const_int 0)]
11676   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11677                         operands[3], operands[4], operands[5]);
11678   DONE;
11681 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11682 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11683 ;; with a precedence over other operators and is always put in the first
11684 ;; place. Swap condition and operands to match ficom instruction.
11686 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11687   [(set (pc)
11688         (if_then_else
11689           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11690             [(match_operator:X87MODEF 1 "float_operator"
11691               [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11692              (match_operand:X87MODEF 3 "register_operand" "f")])
11693           (label_ref (match_operand 4))
11694           (pc)))
11695    (clobber (reg:CCFP FPSR_REG))
11696    (clobber (reg:CCFP FLAGS_REG))
11697    (clobber (match_scratch:HI 5 "=a"))]
11698   "TARGET_80387 && !TARGET_CMOVE
11699    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11700        || optimize_function_for_size_p (cfun))"
11701   "#")
11703 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11704   [(set (pc)
11705         (if_then_else
11706           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11707             [(match_operator:X87MODEF 1 "float_operator"
11708               [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11709              (match_operand:X87MODEF 3 "register_operand" "f")])
11710           (pc)
11711           (label_ref (match_operand 4))))
11712    (clobber (reg:CCFP FPSR_REG))
11713    (clobber (reg:CCFP FLAGS_REG))
11714    (clobber (match_scratch:HI 5 "=a"))]
11715   "TARGET_80387 && !TARGET_CMOVE
11716    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11717        || optimize_function_for_size_p (cfun))"
11718   "#")
11720 (define_split
11721   [(set (pc)
11722         (if_then_else
11723           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11724             [(match_operator:X87MODEF 1 "float_operator"
11725               [(match_operand:SWI24 2 "memory_operand")])
11726              (match_operand:X87MODEF 3 "register_operand")])
11727           (match_operand 4)
11728           (match_operand 5)))
11729    (clobber (reg:CCFP FPSR_REG))
11730    (clobber (reg:CCFP FLAGS_REG))
11731    (clobber (match_scratch:HI 6))]
11732   "TARGET_80387 && !TARGET_CMOVE
11733    && reload_completed"
11734   [(const_int 0)]
11736   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11737                         gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11738                         operands[4], operands[5], operands[6]);
11739   DONE;
11742 ;; Unconditional and other jump instructions
11744 (define_insn "jump"
11745   [(set (pc)
11746         (label_ref (match_operand 0)))]
11747   ""
11748   "%!jmp\t%l0"
11749   [(set_attr "type" "ibr")
11750    (set_attr "modrm" "0")
11751    (set (attr "length")
11752         (if_then_else
11753           (and (ge (minus (match_dup 0) (pc))
11754                    (const_int -126))
11755                (lt (minus (match_dup 0) (pc))
11756                    (const_int 128)))
11757           (const_int 2)
11758           (const_int 5)))
11759    (set_attr "maybe_prefix_bnd" "1")])
11761 (define_expand "indirect_jump"
11762   [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11763   ""
11765   if (TARGET_X32)
11766     operands[0] = convert_memory_address (word_mode, operands[0]);
11769 (define_insn "*indirect_jump"
11770   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11771   ""
11772   "%!jmp\t%A0"
11773   [(set_attr "type" "ibr")
11774    (set_attr "length_immediate" "0")
11775    (set_attr "maybe_prefix_bnd" "1")])
11777 (define_expand "tablejump"
11778   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11779               (use (label_ref (match_operand 1)))])]
11780   ""
11782   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11783      relative.  Convert the relative address to an absolute address.  */
11784   if (flag_pic)
11785     {
11786       rtx op0, op1;
11787       enum rtx_code code;
11789       /* We can't use @GOTOFF for text labels on VxWorks;
11790          see gotoff_operand.  */
11791       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11792         {
11793           code = PLUS;
11794           op0 = operands[0];
11795           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11796         }
11797       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11798         {
11799           code = PLUS;
11800           op0 = operands[0];
11801           op1 = pic_offset_table_rtx;
11802         }
11803       else
11804         {
11805           code = MINUS;
11806           op0 = pic_offset_table_rtx;
11807           op1 = operands[0];
11808         }
11810       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11811                                          OPTAB_DIRECT);
11812     }
11814   if (TARGET_X32)
11815     operands[0] = convert_memory_address (word_mode, operands[0]);
11818 (define_insn "*tablejump_1"
11819   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11820    (use (label_ref (match_operand 1)))]
11821   ""
11822   "%!jmp\t%A0"
11823   [(set_attr "type" "ibr")
11824    (set_attr "length_immediate" "0")
11825    (set_attr "maybe_prefix_bnd" "1")])
11827 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11829 (define_peephole2
11830   [(set (reg FLAGS_REG) (match_operand 0))
11831    (set (match_operand:QI 1 "register_operand")
11832         (match_operator:QI 2 "ix86_comparison_operator"
11833           [(reg FLAGS_REG) (const_int 0)]))
11834    (set (match_operand 3 "any_QIreg_operand")
11835         (zero_extend (match_dup 1)))]
11836   "(peep2_reg_dead_p (3, operands[1])
11837     || operands_match_p (operands[1], operands[3]))
11838    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11839   [(set (match_dup 4) (match_dup 0))
11840    (set (strict_low_part (match_dup 5))
11841         (match_dup 2))]
11843   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11844   operands[5] = gen_lowpart (QImode, operands[3]);
11845   ix86_expand_clear (operands[3]);
11848 (define_peephole2
11849   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11850               (match_operand 4)])
11851    (set (match_operand:QI 1 "register_operand")
11852         (match_operator:QI 2 "ix86_comparison_operator"
11853           [(reg FLAGS_REG) (const_int 0)]))
11854    (set (match_operand 3 "any_QIreg_operand")
11855         (zero_extend (match_dup 1)))]
11856   "(peep2_reg_dead_p (3, operands[1])
11857     || operands_match_p (operands[1], operands[3]))
11858    && ! reg_overlap_mentioned_p (operands[3], operands[0])
11859    && ! reg_set_p (operands[3], operands[4])"
11860   [(parallel [(set (match_dup 5) (match_dup 0))
11861               (match_dup 4)])
11862    (set (strict_low_part (match_dup 6))
11863         (match_dup 2))]
11865   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11866   operands[6] = gen_lowpart (QImode, operands[3]);
11867   ix86_expand_clear (operands[3]);
11870 ;; Similar, but match zero extend with andsi3.
11872 (define_peephole2
11873   [(set (reg FLAGS_REG) (match_operand 0))
11874    (set (match_operand:QI 1 "register_operand")
11875         (match_operator:QI 2 "ix86_comparison_operator"
11876           [(reg FLAGS_REG) (const_int 0)]))
11877    (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
11878                    (and:SI (match_dup 3) (const_int 255)))
11879               (clobber (reg:CC FLAGS_REG))])]
11880   "REGNO (operands[1]) == REGNO (operands[3])
11881    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11882   [(set (match_dup 4) (match_dup 0))
11883    (set (strict_low_part (match_dup 5))
11884         (match_dup 2))]
11886   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11887   operands[5] = gen_lowpart (QImode, operands[3]);
11888   ix86_expand_clear (operands[3]);
11891 (define_peephole2
11892   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11893               (match_operand 4)])
11894    (set (match_operand:QI 1 "register_operand")
11895         (match_operator:QI 2 "ix86_comparison_operator"
11896           [(reg FLAGS_REG) (const_int 0)]))
11897    (parallel [(set (match_operand 3 "any_QIreg_operand")
11898                    (zero_extend (match_dup 1)))
11899               (clobber (reg:CC FLAGS_REG))])]
11900   "(peep2_reg_dead_p (3, operands[1])
11901     || operands_match_p (operands[1], operands[3]))
11902    && ! reg_overlap_mentioned_p (operands[3], operands[0])
11903    && ! reg_set_p (operands[3], operands[4])"
11904   [(parallel [(set (match_dup 5) (match_dup 0))
11905               (match_dup 4)])
11906    (set (strict_low_part (match_dup 6))
11907         (match_dup 2))]
11909   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11910   operands[6] = gen_lowpart (QImode, operands[3]);
11911   ix86_expand_clear (operands[3]);
11914 ;; Call instructions.
11916 ;; The predicates normally associated with named expanders are not properly
11917 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11918 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11920 ;; P6 processors will jump to the address after the decrement when %esp
11921 ;; is used as a call operand, so they will execute return address as a code.
11922 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11924 ;; Register constraint for call instruction.
11925 (define_mode_attr c [(SI "l") (DI "r")])
11927 ;; Call subroutine returning no value.
11929 (define_expand "call"
11930   [(call (match_operand:QI 0)
11931          (match_operand 1))
11932    (use (match_operand 2))]
11933   ""
11935   ix86_expand_call (NULL, operands[0], operands[1],
11936                     operands[2], NULL, false);
11937   DONE;
11940 (define_expand "sibcall"
11941   [(call (match_operand:QI 0)
11942          (match_operand 1))
11943    (use (match_operand 2))]
11944   ""
11946   ix86_expand_call (NULL, operands[0], operands[1],
11947                     operands[2], NULL, true);
11948   DONE;
11951 (define_insn "*call"
11952   [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
11953          (match_operand 1))]
11954   "!SIBLING_CALL_P (insn)"
11955   "* return ix86_output_call_insn (insn, operands[0]);"
11956   [(set_attr "type" "call")])
11958 ;; This covers both call and sibcall since only GOT slot is allowed.
11959 (define_insn "*call_got_x32"
11960   [(call (mem:QI (zero_extend:DI
11961                    (match_operand:SI 0 "GOT_memory_operand" "Bg")))
11962          (match_operand 1))]
11963   "TARGET_X32"
11964   "* return ix86_output_call_insn (insn, operands[0]);"
11965   [(set_attr "type" "call")])
11967 ;; Since sibcall never returns, we can only use call-clobbered register
11968 ;; as GOT base.
11969 (define_insn "*sibcall_GOT_32"
11970   [(call (mem:QI
11971            (mem:SI (plus:SI
11972                      (match_operand:SI 0 "register_no_elim_operand" "U")
11973                      (match_operand:SI 1 "GOT32_symbol_operand"))))
11974          (match_operand 2))]
11975   "!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11977   rtx fnaddr = gen_rtx_PLUS (Pmode, operands[0], operands[1]);
11978   fnaddr = gen_const_mem (Pmode, fnaddr);
11979   return ix86_output_call_insn (insn, fnaddr);
11981   [(set_attr "type" "call")])
11983 (define_insn "*sibcall"
11984   [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
11985          (match_operand 1))]
11986   "SIBLING_CALL_P (insn)"
11987   "* return ix86_output_call_insn (insn, operands[0]);"
11988   [(set_attr "type" "call")])
11990 (define_insn "*sibcall_memory"
11991   [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
11992          (match_operand 1))
11993    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11994   "!TARGET_X32"
11995   "* return ix86_output_call_insn (insn, operands[0]);"
11996   [(set_attr "type" "call")])
11998 (define_peephole2
11999   [(set (match_operand:W 0 "register_operand")
12000         (match_operand:W 1 "memory_operand"))
12001    (call (mem:QI (match_dup 0))
12002          (match_operand 3))]
12003   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
12004    && !reg_mentioned_p (operands[0],
12005                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12006   [(parallel [(call (mem:QI (match_dup 1))
12007                     (match_dup 3))
12008               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12010 (define_peephole2
12011   [(set (match_operand:W 0 "register_operand")
12012         (match_operand:W 1 "memory_operand"))
12013    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12014    (call (mem:QI (match_dup 0))
12015          (match_operand 3))]
12016   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
12017    && !reg_mentioned_p (operands[0],
12018                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12019   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12020    (parallel [(call (mem:QI (match_dup 1))
12021                     (match_dup 3))
12022               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12024 (define_expand "call_pop"
12025   [(parallel [(call (match_operand:QI 0)
12026                     (match_operand:SI 1))
12027               (set (reg:SI SP_REG)
12028                    (plus:SI (reg:SI SP_REG)
12029                             (match_operand:SI 3)))])]
12030   "!TARGET_64BIT"
12032   ix86_expand_call (NULL, operands[0], operands[1],
12033                     operands[2], operands[3], false);
12034   DONE;
12037 (define_insn "*call_pop"
12038   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
12039          (match_operand 1))
12040    (set (reg:SI SP_REG)
12041         (plus:SI (reg:SI SP_REG)
12042                  (match_operand:SI 2 "immediate_operand" "i")))]
12043   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12044   "* return ix86_output_call_insn (insn, operands[0]);"
12045   [(set_attr "type" "call")])
12047 (define_insn "*sibcall_pop"
12048   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
12049          (match_operand 1))
12050    (set (reg:SI SP_REG)
12051         (plus:SI (reg:SI SP_REG)
12052                  (match_operand:SI 2 "immediate_operand" "i")))]
12053   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12054   "* return ix86_output_call_insn (insn, operands[0]);"
12055   [(set_attr "type" "call")])
12057 (define_insn "*sibcall_pop_memory"
12058   [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
12059          (match_operand 1))
12060    (set (reg:SI SP_REG)
12061         (plus:SI (reg:SI SP_REG)
12062                  (match_operand:SI 2 "immediate_operand" "i")))
12063    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12064   "!TARGET_64BIT"
12065   "* return ix86_output_call_insn (insn, operands[0]);"
12066   [(set_attr "type" "call")])
12068 (define_peephole2
12069   [(set (match_operand:SI 0 "register_operand")
12070         (match_operand:SI 1 "memory_operand"))
12071    (parallel [(call (mem:QI (match_dup 0))
12072                     (match_operand 3))
12073               (set (reg:SI SP_REG)
12074                    (plus:SI (reg:SI SP_REG)
12075                             (match_operand:SI 4 "immediate_operand")))])]
12076   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12077    && !reg_mentioned_p (operands[0],
12078                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12079   [(parallel [(call (mem:QI (match_dup 1))
12080                     (match_dup 3))
12081               (set (reg:SI SP_REG)
12082                    (plus:SI (reg:SI SP_REG)
12083                             (match_dup 4)))
12084               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12086 (define_peephole2
12087   [(set (match_operand:SI 0 "register_operand")
12088         (match_operand:SI 1 "memory_operand"))
12089    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12090    (parallel [(call (mem:QI (match_dup 0))
12091                     (match_operand 3))
12092               (set (reg:SI SP_REG)
12093                    (plus:SI (reg:SI SP_REG)
12094                             (match_operand:SI 4 "immediate_operand")))])]
12095   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12096    && !reg_mentioned_p (operands[0],
12097                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12098   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12099    (parallel [(call (mem:QI (match_dup 1))
12100                     (match_dup 3))
12101               (set (reg:SI SP_REG)
12102                    (plus:SI (reg:SI SP_REG)
12103                             (match_dup 4)))
12104               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12106 ;; Combining simple memory jump instruction
12108 (define_peephole2
12109   [(set (match_operand:W 0 "register_operand")
12110         (match_operand:W 1 "memory_operand"))
12111    (set (pc) (match_dup 0))]
12112   "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
12113   [(set (pc) (match_dup 1))])
12115 ;; Call subroutine, returning value in operand 0
12117 (define_expand "call_value"
12118   [(set (match_operand 0)
12119         (call (match_operand:QI 1)
12120               (match_operand 2)))
12121    (use (match_operand 3))]
12122   ""
12124   ix86_expand_call (operands[0], operands[1], operands[2],
12125                     operands[3], NULL, false);
12126   DONE;
12129 (define_expand "sibcall_value"
12130   [(set (match_operand 0)
12131         (call (match_operand:QI 1)
12132               (match_operand 2)))
12133    (use (match_operand 3))]
12134   ""
12136   ix86_expand_call (operands[0], operands[1], operands[2],
12137                     operands[3], NULL, true);
12138   DONE;
12141 (define_insn "*call_value"
12142   [(set (match_operand 0)
12143         (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
12144               (match_operand 2)))]
12145   "!SIBLING_CALL_P (insn)"
12146   "* return ix86_output_call_insn (insn, operands[1]);"
12147   [(set_attr "type" "callv")])
12149 ;; This covers both call and sibcall since only GOT slot is allowed.
12150 (define_insn "*call_value_got_x32"
12151   [(set (match_operand 0)
12152         (call (mem:QI
12153                 (zero_extend:DI
12154                   (match_operand:SI 1 "GOT_memory_operand" "Bg")))
12155               (match_operand 2)))]
12156   "TARGET_X32"
12157   "* return ix86_output_call_insn (insn, operands[1]);"
12158   [(set_attr "type" "callv")])
12160 ;; Since sibcall never returns, we can only use call-clobbered register
12161 ;; as GOT base.
12162 (define_insn "*sibcall_value_GOT_32"
12163   [(set (match_operand 0)
12164         (call (mem:QI
12165                 (mem:SI (plus:SI
12166                           (match_operand:SI 1 "register_no_elim_operand" "U")
12167                           (match_operand:SI 2 "GOT32_symbol_operand"))))
12168          (match_operand 3)))]
12169   "!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)"
12171   rtx fnaddr = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
12172   fnaddr = gen_const_mem (Pmode, fnaddr);
12173   return ix86_output_call_insn (insn, fnaddr);
12175   [(set_attr "type" "callv")])
12177 (define_insn "*sibcall_value"
12178   [(set (match_operand 0)
12179         (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
12180               (match_operand 2)))]
12181   "SIBLING_CALL_P (insn)"
12182   "* return ix86_output_call_insn (insn, operands[1]);"
12183   [(set_attr "type" "callv")])
12185 (define_insn "*sibcall_value_memory"
12186   [(set (match_operand 0)
12187         (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
12188               (match_operand 2)))
12189    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12190   "!TARGET_X32"
12191   "* return ix86_output_call_insn (insn, operands[1]);"
12192   [(set_attr "type" "callv")])
12194 (define_peephole2
12195   [(set (match_operand:W 0 "register_operand")
12196         (match_operand:W 1 "memory_operand"))
12197    (set (match_operand 2)
12198    (call (mem:QI (match_dup 0))
12199                  (match_operand 3)))]
12200   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
12201    && !reg_mentioned_p (operands[0],
12202                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12203   [(parallel [(set (match_dup 2)
12204                    (call (mem:QI (match_dup 1))
12205                          (match_dup 3)))
12206               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12208 (define_peephole2
12209   [(set (match_operand:W 0 "register_operand")
12210         (match_operand:W 1 "memory_operand"))
12211    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12212    (set (match_operand 2)
12213         (call (mem:QI (match_dup 0))
12214               (match_operand 3)))]
12215   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
12216    && !reg_mentioned_p (operands[0],
12217                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12218   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12219    (parallel [(set (match_dup 2)
12220                    (call (mem:QI (match_dup 1))
12221                          (match_dup 3)))
12222               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12224 (define_expand "call_value_pop"
12225   [(parallel [(set (match_operand 0)
12226                    (call (match_operand:QI 1)
12227                          (match_operand:SI 2)))
12228               (set (reg:SI SP_REG)
12229                    (plus:SI (reg:SI SP_REG)
12230                             (match_operand:SI 4)))])]
12231   "!TARGET_64BIT"
12233   ix86_expand_call (operands[0], operands[1], operands[2],
12234                     operands[3], operands[4], false);
12235   DONE;
12238 (define_insn "*call_value_pop"
12239   [(set (match_operand 0)
12240         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
12241               (match_operand 2)))
12242    (set (reg:SI SP_REG)
12243         (plus:SI (reg:SI SP_REG)
12244                  (match_operand:SI 3 "immediate_operand" "i")))]
12245   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12246   "* return ix86_output_call_insn (insn, operands[1]);"
12247   [(set_attr "type" "callv")])
12249 (define_insn "*sibcall_value_pop"
12250   [(set (match_operand 0)
12251         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
12252               (match_operand 2)))
12253    (set (reg:SI SP_REG)
12254         (plus:SI (reg:SI SP_REG)
12255                  (match_operand:SI 3 "immediate_operand" "i")))]
12256   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12257   "* return ix86_output_call_insn (insn, operands[1]);"
12258   [(set_attr "type" "callv")])
12260 (define_insn "*sibcall_value_pop_memory"
12261   [(set (match_operand 0)
12262         (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
12263               (match_operand 2)))
12264    (set (reg:SI SP_REG)
12265         (plus:SI (reg:SI SP_REG)
12266                  (match_operand:SI 3 "immediate_operand" "i")))
12267    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12268   "!TARGET_64BIT"
12269   "* return ix86_output_call_insn (insn, operands[1]);"
12270   [(set_attr "type" "callv")])
12272 (define_peephole2
12273   [(set (match_operand:SI 0 "register_operand")
12274         (match_operand:SI 1 "memory_operand"))
12275    (parallel [(set (match_operand 2)
12276                    (call (mem:QI (match_dup 0))
12277                          (match_operand 3)))
12278               (set (reg:SI SP_REG)
12279                    (plus:SI (reg:SI SP_REG)
12280                             (match_operand:SI 4 "immediate_operand")))])]
12281   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12282    && !reg_mentioned_p (operands[0],
12283                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12284   [(parallel [(set (match_dup 2)
12285                    (call (mem:QI (match_dup 1))
12286                          (match_dup 3)))
12287               (set (reg:SI SP_REG)
12288                    (plus:SI (reg:SI SP_REG)
12289                             (match_dup 4)))
12290               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12292 (define_peephole2
12293   [(set (match_operand:SI 0 "register_operand")
12294         (match_operand:SI 1 "memory_operand"))
12295    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12296    (parallel [(set (match_operand 2)
12297                    (call (mem:QI (match_dup 0))
12298                          (match_operand 3)))
12299               (set (reg:SI SP_REG)
12300                    (plus:SI (reg:SI SP_REG)
12301                             (match_operand:SI 4 "immediate_operand")))])]
12302   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12303    && !reg_mentioned_p (operands[0],
12304                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12305   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12306    (parallel [(set (match_dup 2)
12307                    (call (mem:QI (match_dup 1))
12308                          (match_dup 3)))
12309               (set (reg:SI SP_REG)
12310                    (plus:SI (reg:SI SP_REG)
12311                             (match_dup 4)))
12312               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12314 ;; Call subroutine returning any type.
12316 (define_expand "untyped_call"
12317   [(parallel [(call (match_operand 0)
12318                     (const_int 0))
12319               (match_operand 1)
12320               (match_operand 2)])]
12321   ""
12323   int i;
12325   /* In order to give reg-stack an easier job in validating two
12326      coprocessor registers as containing a possible return value,
12327      simply pretend the untyped call returns a complex long double
12328      value. 
12330      We can't use SSE_REGPARM_MAX here since callee is unprototyped
12331      and should have the default ABI.  */
12333   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
12334                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
12335                     operands[0], const0_rtx,
12336                     GEN_INT ((TARGET_64BIT
12337                               ? (ix86_abi == SYSV_ABI
12338                                  ? X86_64_SSE_REGPARM_MAX
12339                                  : X86_64_MS_SSE_REGPARM_MAX)
12340                               : X86_32_SSE_REGPARM_MAX)
12341                              - 1),
12342                     NULL, false);
12344   for (i = 0; i < XVECLEN (operands[2], 0); i++)
12345     {
12346       rtx set = XVECEXP (operands[2], 0, i);
12347       emit_move_insn (SET_DEST (set), SET_SRC (set));
12348     }
12350   /* The optimizer does not know that the call sets the function value
12351      registers we stored in the result block.  We avoid problems by
12352      claiming that all hard registers are used and clobbered at this
12353      point.  */
12354   emit_insn (gen_blockage ());
12356   DONE;
12359 ;; Prologue and epilogue instructions
12361 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
12362 ;; all of memory.  This blocks insns from being moved across this point.
12364 (define_insn "blockage"
12365   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
12366   ""
12367   ""
12368   [(set_attr "length" "0")])
12370 ;; Do not schedule instructions accessing memory across this point.
12372 (define_expand "memory_blockage"
12373   [(set (match_dup 0)
12374         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12375   ""
12377   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12378   MEM_VOLATILE_P (operands[0]) = 1;
12381 (define_insn "*memory_blockage"
12382   [(set (match_operand:BLK 0)
12383         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12384   ""
12385   ""
12386   [(set_attr "length" "0")])
12388 ;; As USE insns aren't meaningful after reload, this is used instead
12389 ;; to prevent deleting instructions setting registers for PIC code
12390 (define_insn "prologue_use"
12391   [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
12392   ""
12393   ""
12394   [(set_attr "length" "0")])
12396 ;; Insn emitted into the body of a function to return from a function.
12397 ;; This is only done if the function's epilogue is known to be simple.
12398 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12400 (define_expand "return"
12401   [(simple_return)]
12402   "ix86_can_use_return_insn_p ()"
12404   if (crtl->args.pops_args)
12405     {
12406       rtx popc = GEN_INT (crtl->args.pops_args);
12407       emit_jump_insn (gen_simple_return_pop_internal (popc));
12408       DONE;
12409     }
12412 ;; We need to disable this for TARGET_SEH, as otherwise
12413 ;; shrink-wrapped prologue gets enabled too.  This might exceed
12414 ;; the maximum size of prologue in unwind information.
12415 ;; Also disallow shrink-wrapping if using stack slot to pass the
12416 ;; static chain pointer - the first instruction has to be pushl %esi
12417 ;; and it can't be moved around, as we use alternate entry points
12418 ;; in that case.
12420 (define_expand "simple_return"
12421   [(simple_return)]
12422   "!TARGET_SEH && !ix86_static_chain_on_stack"
12424   if (crtl->args.pops_args)
12425     {
12426       rtx popc = GEN_INT (crtl->args.pops_args);
12427       emit_jump_insn (gen_simple_return_pop_internal (popc));
12428       DONE;
12429     }
12432 (define_insn "simple_return_internal"
12433   [(simple_return)]
12434   "reload_completed"
12435   "%!ret"
12436   [(set_attr "length" "1")
12437    (set_attr "atom_unit" "jeu")
12438    (set_attr "length_immediate" "0")
12439    (set_attr "modrm" "0")
12440    (set_attr "maybe_prefix_bnd" "1")])
12442 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12443 ;; instruction Athlon and K8 have.
12445 (define_insn "simple_return_internal_long"
12446   [(simple_return)
12447    (unspec [(const_int 0)] UNSPEC_REP)]
12448   "reload_completed"
12450   if (ix86_bnd_prefixed_insn_p (insn))
12451     return "%!ret";
12453   return "rep%; ret";
12455   [(set_attr "length" "2")
12456    (set_attr "atom_unit" "jeu")
12457    (set_attr "length_immediate" "0")
12458    (set_attr "prefix_rep" "1")
12459    (set_attr "modrm" "0")])
12461 (define_insn "simple_return_pop_internal"
12462   [(simple_return)
12463    (use (match_operand:SI 0 "const_int_operand"))]
12464   "reload_completed"
12465   "%!ret\t%0"
12466   [(set_attr "length" "3")
12467    (set_attr "atom_unit" "jeu")
12468    (set_attr "length_immediate" "2")
12469    (set_attr "modrm" "0")
12470    (set_attr "maybe_prefix_bnd" "1")])
12472 (define_insn "simple_return_indirect_internal"
12473   [(simple_return)
12474    (use (match_operand:SI 0 "register_operand" "r"))]
12475   "reload_completed"
12476   "%!jmp\t%A0"
12477   [(set_attr "type" "ibr")
12478    (set_attr "length_immediate" "0")
12479    (set_attr "maybe_prefix_bnd" "1")])
12481 (define_insn "nop"
12482   [(const_int 0)]
12483   ""
12484   "nop"
12485   [(set_attr "length" "1")
12486    (set_attr "length_immediate" "0")
12487    (set_attr "modrm" "0")])
12489 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
12490 (define_insn "nops"
12491   [(unspec_volatile [(match_operand 0 "const_int_operand")]
12492                     UNSPECV_NOPS)]
12493   "reload_completed"
12495   int num = INTVAL (operands[0]);
12497   gcc_assert (IN_RANGE (num, 1, 8));
12499   while (num--)
12500     fputs ("\tnop\n", asm_out_file);
12502   return "";
12504   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12505    (set_attr "length_immediate" "0")
12506    (set_attr "modrm" "0")])
12508 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
12509 ;; branch prediction penalty for the third jump in a 16-byte
12510 ;; block on K8.
12512 (define_insn "pad"
12513   [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12514   ""
12516 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12517   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12518 #else
12519   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12520      The align insn is used to avoid 3 jump instructions in the row to improve
12521      branch prediction and the benefits hardly outweigh the cost of extra 8
12522      nops on the average inserted by full alignment pseudo operation.  */
12523 #endif
12524   return "";
12526   [(set_attr "length" "16")])
12528 (define_expand "prologue"
12529   [(const_int 0)]
12530   ""
12531   "ix86_expand_prologue (); DONE;")
12533 (define_expand "set_got"
12534   [(parallel
12535      [(set (match_operand:SI 0 "register_operand" "=r")
12536            (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12537       (clobber (reg:CC FLAGS_REG))])]
12538   "!TARGET_64BIT"
12540   if (flag_pic && !TARGET_VXWORKS_RTP)
12541     ix86_pc_thunk_call_expanded = true;
12544 (define_insn "*set_got"
12545   [(set (match_operand:SI 0 "register_operand" "=r")
12546         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12547    (clobber (reg:CC FLAGS_REG))]
12548   "!TARGET_64BIT"
12549   "* return output_set_got (operands[0], NULL_RTX);"
12550   [(set_attr "type" "multi")
12551    (set_attr "length" "12")])
12553 (define_expand "set_got_labelled"
12554   [(parallel
12555      [(set (match_operand:SI 0 "register_operand" "=r")
12556            (unspec:SI [(label_ref (match_operand 1))]
12557                       UNSPEC_SET_GOT))
12558       (clobber (reg:CC FLAGS_REG))])]
12559   "!TARGET_64BIT"
12561   if (flag_pic && !TARGET_VXWORKS_RTP)
12562     ix86_pc_thunk_call_expanded = true;
12565 (define_insn "*set_got_labelled"
12566   [(set (match_operand:SI 0 "register_operand" "=r")
12567         (unspec:SI [(label_ref (match_operand 1))]
12568          UNSPEC_SET_GOT))
12569    (clobber (reg:CC FLAGS_REG))]
12570   "!TARGET_64BIT"
12571   "* return output_set_got (operands[0], operands[1]);"
12572   [(set_attr "type" "multi")
12573    (set_attr "length" "12")])
12575 (define_insn "set_got_rex64"
12576   [(set (match_operand:DI 0 "register_operand" "=r")
12577         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12578   "TARGET_64BIT"
12579   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12580   [(set_attr "type" "lea")
12581    (set_attr "length_address" "4")
12582    (set_attr "modrm_class" "unknown")
12583    (set_attr "mode" "DI")])
12585 (define_insn "set_rip_rex64"
12586   [(set (match_operand:DI 0 "register_operand" "=r")
12587         (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12588   "TARGET_64BIT"
12589   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12590   [(set_attr "type" "lea")
12591    (set_attr "length_address" "4")
12592    (set_attr "mode" "DI")])
12594 (define_insn "set_got_offset_rex64"
12595   [(set (match_operand:DI 0 "register_operand" "=r")
12596         (unspec:DI
12597           [(label_ref (match_operand 1))]
12598           UNSPEC_SET_GOT_OFFSET))]
12599   "TARGET_LP64"
12600   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12601   [(set_attr "type" "imov")
12602    (set_attr "length_immediate" "0")
12603    (set_attr "length_address" "8")
12604    (set_attr "mode" "DI")])
12606 (define_expand "epilogue"
12607   [(const_int 0)]
12608   ""
12609   "ix86_expand_epilogue (1); DONE;")
12611 (define_expand "sibcall_epilogue"
12612   [(const_int 0)]
12613   ""
12614   "ix86_expand_epilogue (0); DONE;")
12616 (define_expand "eh_return"
12617   [(use (match_operand 0 "register_operand"))]
12618   ""
12620   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12622   /* Tricky bit: we write the address of the handler to which we will
12623      be returning into someone else's stack frame, one word below the
12624      stack address we wish to restore.  */
12625   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12626   tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12627   tmp = gen_rtx_MEM (Pmode, tmp);
12628   emit_move_insn (tmp, ra);
12630   emit_jump_insn (gen_eh_return_internal ());
12631   emit_barrier ();
12632   DONE;
12635 (define_insn_and_split "eh_return_internal"
12636   [(eh_return)]
12637   ""
12638   "#"
12639   "epilogue_completed"
12640   [(const_int 0)]
12641   "ix86_expand_epilogue (2); DONE;")
12643 (define_insn "leave"
12644   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12645    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12646    (clobber (mem:BLK (scratch)))]
12647   "!TARGET_64BIT"
12648   "leave"
12649   [(set_attr "type" "leave")])
12651 (define_insn "leave_rex64"
12652   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12653    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12654    (clobber (mem:BLK (scratch)))]
12655   "TARGET_64BIT"
12656   "leave"
12657   [(set_attr "type" "leave")])
12659 ;; Handle -fsplit-stack.
12661 (define_expand "split_stack_prologue"
12662   [(const_int 0)]
12663   ""
12665   ix86_expand_split_stack_prologue ();
12666   DONE;
12669 ;; In order to support the call/return predictor, we use a return
12670 ;; instruction which the middle-end doesn't see.
12671 (define_insn "split_stack_return"
12672   [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12673                      UNSPECV_SPLIT_STACK_RETURN)]
12674   ""
12676   if (operands[0] == const0_rtx)
12677     return "ret";
12678   else
12679     return "ret\t%0";
12681   [(set_attr "atom_unit" "jeu")
12682    (set_attr "modrm" "0")
12683    (set (attr "length")
12684         (if_then_else (match_operand:SI 0 "const0_operand")
12685                       (const_int 1)
12686                       (const_int 3)))
12687    (set (attr "length_immediate")
12688         (if_then_else (match_operand:SI 0 "const0_operand")
12689                       (const_int 0)
12690                       (const_int 2)))])
12692 ;; If there are operand 0 bytes available on the stack, jump to
12693 ;; operand 1.
12695 (define_expand "split_stack_space_check"
12696   [(set (pc) (if_then_else
12697               (ltu (minus (reg SP_REG)
12698                           (match_operand 0 "register_operand"))
12699                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12700               (label_ref (match_operand 1))
12701               (pc)))]
12702   ""
12704   rtx reg, size, limit;
12706   reg = gen_reg_rtx (Pmode);
12707   size = force_reg (Pmode, operands[0]);
12708   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12709   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12710                           UNSPEC_STACK_CHECK);
12711   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12712   ix86_expand_branch (GEU, reg, limit, operands[1]);
12714   DONE;
12717 ;; Bit manipulation instructions.
12719 (define_expand "ffs<mode>2"
12720   [(set (match_dup 2) (const_int -1))
12721    (parallel [(set (match_dup 3) (match_dup 4))
12722               (set (match_operand:SWI48 0 "register_operand")
12723                    (ctz:SWI48
12724                      (match_operand:SWI48 1 "nonimmediate_operand")))])
12725    (set (match_dup 0) (if_then_else:SWI48
12726                         (eq (match_dup 3) (const_int 0))
12727                         (match_dup 2)
12728                         (match_dup 0)))
12729    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12730               (clobber (reg:CC FLAGS_REG))])]
12731   ""
12733   machine_mode flags_mode;
12735   if (<MODE>mode == SImode && !TARGET_CMOVE)
12736     {
12737       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12738       DONE;
12739     }
12741   flags_mode
12742     = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12744   operands[2] = gen_reg_rtx (<MODE>mode);
12745   operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12746   operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12749 (define_insn_and_split "ffssi2_no_cmove"
12750   [(set (match_operand:SI 0 "register_operand" "=r")
12751         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12752    (clobber (match_scratch:SI 2 "=&q"))
12753    (clobber (reg:CC FLAGS_REG))]
12754   "!TARGET_CMOVE"
12755   "#"
12756   "&& reload_completed"
12757   [(parallel [(set (match_dup 4) (match_dup 5))
12758               (set (match_dup 0) (ctz:SI (match_dup 1)))])
12759    (set (strict_low_part (match_dup 3))
12760         (eq:QI (match_dup 4) (const_int 0)))
12761    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12762               (clobber (reg:CC FLAGS_REG))])
12763    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12764               (clobber (reg:CC FLAGS_REG))])
12765    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12766               (clobber (reg:CC FLAGS_REG))])]
12768   machine_mode flags_mode
12769     = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12771   operands[3] = gen_lowpart (QImode, operands[2]);
12772   operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12773   operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12775   ix86_expand_clear (operands[2]);
12778 (define_insn "*tzcnt<mode>_1"
12779   [(set (reg:CCC FLAGS_REG)
12780         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12781                      (const_int 0)))
12782    (set (match_operand:SWI48 0 "register_operand" "=r")
12783         (ctz:SWI48 (match_dup 1)))]
12784   "TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI"
12785   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12786   [(set_attr "type" "alu1")
12787    (set_attr "prefix_0f" "1")
12788    (set_attr "prefix_rep" "1")
12789    (set_attr "btver2_decode" "double")
12790    (set_attr "mode" "<MODE>")])
12792 (define_insn "*bsf<mode>_1"
12793   [(set (reg:CCZ FLAGS_REG)
12794         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12795                      (const_int 0)))
12796    (set (match_operand:SWI48 0 "register_operand" "=r")
12797         (ctz:SWI48 (match_dup 1)))]
12798   ""
12799   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12800   [(set_attr "type" "alu1")
12801    (set_attr "prefix_0f" "1")
12802    (set_attr "btver2_decode" "double")
12803    (set_attr "znver1_decode" "vector")
12804    (set_attr "mode" "<MODE>")])
12806 (define_expand "ctz<mode>2"
12807   [(parallel
12808     [(set (match_operand:SWI248 0 "register_operand")
12809           (ctz:SWI248
12810             (match_operand:SWI248 1 "nonimmediate_operand")))
12811      (clobber (reg:CC FLAGS_REG))])])
12813 ; False dependency happens when destination is only updated by tzcnt,
12814 ; lzcnt or popcnt.  There is no false dependency when destination is
12815 ; also used in source.
12816 (define_insn_and_split "*ctz<mode>2_falsedep_1"
12817   [(set (match_operand:SWI48 0 "register_operand" "=r")
12818         (ctz:SWI48
12819           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12820    (clobber (reg:CC FLAGS_REG))]
12821   "(TARGET_BMI || TARGET_GENERIC)
12822    && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12823   "#"
12824   "&& reload_completed"
12825   [(parallel
12826     [(set (match_dup 0)
12827           (ctz:SWI48 (match_dup 1)))
12828      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12829      (clobber (reg:CC FLAGS_REG))])]
12831   if (!reg_mentioned_p (operands[0], operands[1]))
12832     ix86_expand_clear (operands[0]);
12835 (define_insn "*ctz<mode>2_falsedep"
12836   [(set (match_operand:SWI48 0 "register_operand" "=r")
12837         (ctz:SWI48
12838           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12839    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12840            UNSPEC_INSN_FALSE_DEP)
12841    (clobber (reg:CC FLAGS_REG))]
12842   ""
12844   if (TARGET_BMI)
12845     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12846   else if (TARGET_GENERIC)
12847     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
12848     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12849   else
12850     gcc_unreachable ();
12852   [(set_attr "type" "alu1")
12853    (set_attr "prefix_0f" "1")
12854    (set_attr "prefix_rep" "1")
12855    (set_attr "mode" "<MODE>")])
12857 (define_insn "*ctz<mode>2"
12858   [(set (match_operand:SWI248 0 "register_operand" "=r")
12859         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12860    (clobber (reg:CC FLAGS_REG))]
12861   ""
12863   if (TARGET_BMI)
12864     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12865   else if (optimize_function_for_size_p (cfun))
12866     ;
12867   else if (TARGET_GENERIC)
12868     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
12869     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12871   return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12873   [(set_attr "type" "alu1")
12874    (set_attr "prefix_0f" "1")
12875    (set (attr "prefix_rep")
12876      (if_then_else
12877        (ior (match_test "TARGET_BMI")
12878             (and (not (match_test "optimize_function_for_size_p (cfun)"))
12879                  (match_test "TARGET_GENERIC")))
12880        (const_string "1")
12881        (const_string "0")))
12882    (set_attr "mode" "<MODE>")])
12884 (define_expand "clz<mode>2"
12885   [(parallel
12886      [(set (match_operand:SWI248 0 "register_operand")
12887            (minus:SWI248
12888              (match_dup 2)
12889              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12890       (clobber (reg:CC FLAGS_REG))])
12891    (parallel
12892      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12893       (clobber (reg:CC FLAGS_REG))])]
12894   ""
12896   if (TARGET_LZCNT)
12897     {
12898       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12899       DONE;
12900     }
12901   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12904 (define_expand "clz<mode>2_lzcnt"
12905   [(parallel
12906     [(set (match_operand:SWI248 0 "register_operand")
12907           (clz:SWI248
12908             (match_operand:SWI248 1 "nonimmediate_operand")))
12909      (clobber (reg:CC FLAGS_REG))])]
12910   "TARGET_LZCNT")
12912 (define_insn_and_split "*clz<mode>2_lzcnt_falsedep_1"
12913   [(set (match_operand:SWI48 0 "register_operand" "=r")
12914         (clz:SWI48
12915           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12916    (clobber (reg:CC FLAGS_REG))]
12917   "TARGET_LZCNT
12918    && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12919   "#"
12920   "&& reload_completed"
12921   [(parallel
12922     [(set (match_dup 0)
12923           (clz:SWI48 (match_dup 1)))
12924      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12925      (clobber (reg:CC FLAGS_REG))])]
12927   if (!reg_mentioned_p (operands[0], operands[1]))
12928     ix86_expand_clear (operands[0]);
12931 (define_insn "*clz<mode>2_lzcnt_falsedep"
12932   [(set (match_operand:SWI48 0 "register_operand" "=r")
12933         (clz:SWI48
12934           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12935    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12936            UNSPEC_INSN_FALSE_DEP)
12937    (clobber (reg:CC FLAGS_REG))]
12938   "TARGET_LZCNT"
12939   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12940   [(set_attr "prefix_rep" "1")
12941    (set_attr "type" "bitmanip")
12942    (set_attr "mode" "<MODE>")])
12944 (define_insn "*clz<mode>2_lzcnt"
12945   [(set (match_operand:SWI248 0 "register_operand" "=r")
12946         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12947    (clobber (reg:CC FLAGS_REG))]
12948   "TARGET_LZCNT"
12949   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12950   [(set_attr "prefix_rep" "1")
12951    (set_attr "type" "bitmanip")
12952    (set_attr "mode" "<MODE>")])
12954 ;; BMI instructions.
12955 (define_insn "*bmi_andn_<mode>"
12956   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12957         (and:SWI48
12958           (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
12959           (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12960    (clobber (reg:CC FLAGS_REG))]
12961   "TARGET_BMI"
12962   "andn\t{%2, %1, %0|%0, %1, %2}"
12963   [(set_attr "type" "bitmanip")
12964    (set_attr "btver2_decode" "direct, double")
12965    (set_attr "mode" "<MODE>")])
12967 (define_insn "*bmi_andn_<mode>_ccno"
12968   [(set (reg FLAGS_REG)
12969         (compare
12970           (and:SWI48
12971             (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
12972             (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
12973           (const_int 0)))
12974    (clobber (match_scratch:SWI48 0 "=r,r"))]
12975   "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
12976   "andn\t{%2, %1, %0|%0, %1, %2}"
12977   [(set_attr "type" "bitmanip")
12978    (set_attr "btver2_decode" "direct, double")
12979    (set_attr "mode" "<MODE>")])
12981 (define_insn "bmi_bextr_<mode>"
12982   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12983         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12984                        (match_operand:SWI48 2 "register_operand" "r,r")]
12985                       UNSPEC_BEXTR))
12986    (clobber (reg:CC FLAGS_REG))]
12987   "TARGET_BMI"
12988   "bextr\t{%2, %1, %0|%0, %1, %2}"
12989   [(set_attr "type" "bitmanip")
12990    (set_attr "btver2_decode" "direct, double")
12991    (set_attr "mode" "<MODE>")])
12993 (define_insn "*bmi_bextr_<mode>_ccz"
12994   [(set (reg:CCZ FLAGS_REG)
12995         (compare:CCZ
12996           (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12997                          (match_operand:SWI48 2 "register_operand" "r,r")]
12998                         UNSPEC_BEXTR)
12999           (const_int 0)))
13000    (clobber (match_scratch:SWI48 0 "=r,r"))]
13001   "TARGET_BMI"
13002   "bextr\t{%2, %1, %0|%0, %1, %2}"
13003   [(set_attr "type" "bitmanip")
13004    (set_attr "btver2_decode" "direct, double")
13005    (set_attr "mode" "<MODE>")])
13007 (define_insn "*bmi_blsi_<mode>"
13008   [(set (match_operand:SWI48 0 "register_operand" "=r")
13009         (and:SWI48
13010           (neg:SWI48
13011             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
13012           (match_dup 1)))
13013    (clobber (reg:CC FLAGS_REG))]
13014   "TARGET_BMI"
13015   "blsi\t{%1, %0|%0, %1}"
13016   [(set_attr "type" "bitmanip")
13017    (set_attr "btver2_decode" "double")
13018    (set_attr "mode" "<MODE>")])
13020 (define_insn "*bmi_blsmsk_<mode>"
13021   [(set (match_operand:SWI48 0 "register_operand" "=r")
13022         (xor:SWI48
13023           (plus:SWI48
13024             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13025             (const_int -1))
13026           (match_dup 1)))
13027    (clobber (reg:CC FLAGS_REG))]
13028   "TARGET_BMI"
13029   "blsmsk\t{%1, %0|%0, %1}"
13030   [(set_attr "type" "bitmanip")
13031    (set_attr "btver2_decode" "double")
13032    (set_attr "mode" "<MODE>")])
13034 (define_insn "*bmi_blsr_<mode>"
13035   [(set (match_operand:SWI48 0 "register_operand" "=r")
13036         (and:SWI48
13037           (plus:SWI48
13038             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13039             (const_int -1))
13040           (match_dup 1)))
13041    (clobber (reg:CC FLAGS_REG))]
13042    "TARGET_BMI"
13043    "blsr\t{%1, %0|%0, %1}"
13044   [(set_attr "type" "bitmanip")
13045    (set_attr "btver2_decode" "double")
13046    (set_attr "mode" "<MODE>")])
13048 ;; BMI2 instructions.
13049 (define_expand "bmi2_bzhi_<mode>3"
13050   [(parallel
13051     [(set (match_operand:SWI48 0 "register_operand")
13052           (zero_extract:SWI48
13053             (match_operand:SWI48 1 "nonimmediate_operand")
13054             (umin:SWI48
13055               (and:SWI48 (match_operand:SWI48 2 "register_operand")
13056                          (const_int 255))
13057               (match_dup 3))
13058             (const_int 0)))
13059      (clobber (reg:CC FLAGS_REG))])]
13060   "TARGET_BMI2"
13061   "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
13063 (define_insn "*bmi2_bzhi_<mode>3"
13064   [(set (match_operand:SWI48 0 "register_operand" "=r")
13065         (zero_extract:SWI48
13066           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13067           (umin:SWI48
13068             (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
13069                        (const_int 255))
13070             (match_operand:SWI48 3 "const_int_operand" "n"))
13071           (const_int 0)))
13072    (clobber (reg:CC FLAGS_REG))]
13073   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13074   "bzhi\t{%2, %1, %0|%0, %1, %2}"
13075   [(set_attr "type" "bitmanip")
13076    (set_attr "prefix" "vex")
13077    (set_attr "mode" "<MODE>")])
13079 (define_mode_attr k [(SI "k") (DI "q")])
13081 (define_insn "*bmi2_bzhi_<mode>3_1"
13082   [(set (match_operand:SWI48 0 "register_operand" "=r")
13083         (zero_extract:SWI48
13084           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13085           (umin:SWI48
13086             (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13087             (match_operand:SWI48 3 "const_int_operand" "n"))
13088           (const_int 0)))
13089    (clobber (reg:CC FLAGS_REG))]
13090   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13091   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13092   [(set_attr "type" "bitmanip")
13093    (set_attr "prefix" "vex")
13094    (set_attr "mode" "<MODE>")])
13096 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
13097   [(set (reg:CCZ FLAGS_REG)
13098         (compare:CCZ
13099           (zero_extract:SWI48
13100             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13101             (umin:SWI48
13102               (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13103               (match_operand:SWI48 3 "const_int_operand" "n"))
13104             (const_int 0))
13105         (const_int 0)))
13106    (clobber (match_scratch:SWI48 0 "=r"))]
13107   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13108   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13109   [(set_attr "type" "bitmanip")
13110    (set_attr "prefix" "vex")
13111    (set_attr "mode" "<MODE>")])
13113 (define_insn "bmi2_pdep_<mode>3"
13114   [(set (match_operand:SWI48 0 "register_operand" "=r")
13115         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13116                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13117                        UNSPEC_PDEP))]
13118   "TARGET_BMI2"
13119   "pdep\t{%2, %1, %0|%0, %1, %2}"
13120   [(set_attr "type" "bitmanip")
13121    (set_attr "prefix" "vex")
13122    (set_attr "mode" "<MODE>")])
13124 (define_insn "bmi2_pext_<mode>3"
13125   [(set (match_operand:SWI48 0 "register_operand" "=r")
13126         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13127                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13128                        UNSPEC_PEXT))]
13129   "TARGET_BMI2"
13130   "pext\t{%2, %1, %0|%0, %1, %2}"
13131   [(set_attr "type" "bitmanip")
13132    (set_attr "prefix" "vex")
13133    (set_attr "mode" "<MODE>")])
13135 ;; TBM instructions.
13136 (define_insn "tbm_bextri_<mode>"
13137   [(set (match_operand:SWI48 0 "register_operand" "=r")
13138         (zero_extract:SWI48
13139           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13140           (match_operand 2 "const_0_to_255_operand" "N")
13141           (match_operand 3 "const_0_to_255_operand" "N")))
13142    (clobber (reg:CC FLAGS_REG))]
13143    "TARGET_TBM"
13145   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
13146   return "bextr\t{%2, %1, %0|%0, %1, %2}";
13148   [(set_attr "type" "bitmanip")
13149    (set_attr "mode" "<MODE>")])
13151 (define_insn "*tbm_blcfill_<mode>"
13152   [(set (match_operand:SWI48 0 "register_operand" "=r")
13153         (and:SWI48
13154           (plus:SWI48
13155             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13156             (const_int 1))
13157           (match_dup 1)))
13158    (clobber (reg:CC FLAGS_REG))]
13159    "TARGET_TBM"
13160    "blcfill\t{%1, %0|%0, %1}"
13161   [(set_attr "type" "bitmanip")
13162    (set_attr "mode" "<MODE>")])
13164 (define_insn "*tbm_blci_<mode>"
13165   [(set (match_operand:SWI48 0 "register_operand" "=r")
13166         (ior:SWI48
13167           (not:SWI48
13168             (plus:SWI48
13169               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13170               (const_int 1)))
13171           (match_dup 1)))
13172    (clobber (reg:CC FLAGS_REG))]
13173    "TARGET_TBM"
13174    "blci\t{%1, %0|%0, %1}"
13175   [(set_attr "type" "bitmanip")
13176    (set_attr "mode" "<MODE>")])
13178 (define_insn "*tbm_blcic_<mode>"
13179   [(set (match_operand:SWI48 0 "register_operand" "=r")
13180         (and:SWI48
13181           (plus:SWI48
13182             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13183             (const_int 1))
13184           (not:SWI48
13185             (match_dup 1))))
13186    (clobber (reg:CC FLAGS_REG))]
13187    "TARGET_TBM"
13188    "blcic\t{%1, %0|%0, %1}"
13189   [(set_attr "type" "bitmanip")
13190    (set_attr "mode" "<MODE>")])
13192 (define_insn "*tbm_blcmsk_<mode>"
13193   [(set (match_operand:SWI48 0 "register_operand" "=r")
13194         (xor:SWI48
13195           (plus:SWI48
13196             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13197             (const_int 1))
13198           (match_dup 1)))
13199    (clobber (reg:CC FLAGS_REG))]
13200    "TARGET_TBM"
13201    "blcmsk\t{%1, %0|%0, %1}"
13202   [(set_attr "type" "bitmanip")
13203    (set_attr "mode" "<MODE>")])
13205 (define_insn "*tbm_blcs_<mode>"
13206   [(set (match_operand:SWI48 0 "register_operand" "=r")
13207         (ior:SWI48
13208           (plus:SWI48
13209             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13210             (const_int 1))
13211           (match_dup 1)))
13212    (clobber (reg:CC FLAGS_REG))]
13213    "TARGET_TBM"
13214    "blcs\t{%1, %0|%0, %1}"
13215   [(set_attr "type" "bitmanip")
13216    (set_attr "mode" "<MODE>")])
13218 (define_insn "*tbm_blsfill_<mode>"
13219   [(set (match_operand:SWI48 0 "register_operand" "=r")
13220         (ior:SWI48
13221           (plus:SWI48
13222             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13223             (const_int -1))
13224           (match_dup 1)))
13225    (clobber (reg:CC FLAGS_REG))]
13226    "TARGET_TBM"
13227    "blsfill\t{%1, %0|%0, %1}"
13228   [(set_attr "type" "bitmanip")
13229    (set_attr "mode" "<MODE>")])
13231 (define_insn "*tbm_blsic_<mode>"
13232   [(set (match_operand:SWI48 0 "register_operand" "=r")
13233         (ior:SWI48
13234           (plus:SWI48
13235             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13236             (const_int -1))
13237           (not:SWI48
13238             (match_dup 1))))
13239    (clobber (reg:CC FLAGS_REG))]
13240    "TARGET_TBM"
13241    "blsic\t{%1, %0|%0, %1}"
13242   [(set_attr "type" "bitmanip")
13243    (set_attr "mode" "<MODE>")])
13245 (define_insn "*tbm_t1mskc_<mode>"
13246   [(set (match_operand:SWI48 0 "register_operand" "=r")
13247         (ior:SWI48
13248           (plus:SWI48
13249             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13250             (const_int 1))
13251           (not:SWI48
13252             (match_dup 1))))
13253    (clobber (reg:CC FLAGS_REG))]
13254    "TARGET_TBM"
13255    "t1mskc\t{%1, %0|%0, %1}"
13256   [(set_attr "type" "bitmanip")
13257    (set_attr "mode" "<MODE>")])
13259 (define_insn "*tbm_tzmsk_<mode>"
13260   [(set (match_operand:SWI48 0 "register_operand" "=r")
13261         (and:SWI48
13262           (plus:SWI48
13263             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13264             (const_int -1))
13265           (not:SWI48
13266             (match_dup 1))))
13267    (clobber (reg:CC FLAGS_REG))]
13268    "TARGET_TBM"
13269    "tzmsk\t{%1, %0|%0, %1}"
13270   [(set_attr "type" "bitmanip")
13271    (set_attr "mode" "<MODE>")])
13273 (define_insn "bsr_rex64"
13274   [(set (match_operand:DI 0 "register_operand" "=r")
13275         (minus:DI (const_int 63)
13276                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13277    (clobber (reg:CC FLAGS_REG))]
13278   "TARGET_64BIT"
13279   "bsr{q}\t{%1, %0|%0, %1}"
13280   [(set_attr "type" "alu1")
13281    (set_attr "prefix_0f" "1")
13282    (set_attr "znver1_decode" "vector")
13283    (set_attr "mode" "DI")])
13285 (define_insn "bsr"
13286   [(set (match_operand:SI 0 "register_operand" "=r")
13287         (minus:SI (const_int 31)
13288                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13289    (clobber (reg:CC FLAGS_REG))]
13290   ""
13291   "bsr{l}\t{%1, %0|%0, %1}"
13292   [(set_attr "type" "alu1")
13293    (set_attr "prefix_0f" "1")
13294    (set_attr "znver1_decode" "vector")
13295    (set_attr "mode" "SI")])
13297 (define_insn "*bsrhi"
13298   [(set (match_operand:HI 0 "register_operand" "=r")
13299         (minus:HI (const_int 15)
13300                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
13301    (clobber (reg:CC FLAGS_REG))]
13302   ""
13303   "bsr{w}\t{%1, %0|%0, %1}"
13304   [(set_attr "type" "alu1")
13305    (set_attr "prefix_0f" "1")
13306    (set_attr "znver1_decode" "vector")
13307    (set_attr "mode" "HI")])
13309 (define_expand "popcount<mode>2"
13310   [(parallel
13311     [(set (match_operand:SWI248 0 "register_operand")
13312           (popcount:SWI248
13313             (match_operand:SWI248 1 "nonimmediate_operand")))
13314      (clobber (reg:CC FLAGS_REG))])]
13315   "TARGET_POPCNT")
13317 (define_insn_and_split "*popcount<mode>2_falsedep_1"
13318   [(set (match_operand:SWI48 0 "register_operand" "=r")
13319         (popcount:SWI48
13320           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13321    (clobber (reg:CC FLAGS_REG))]
13322   "TARGET_POPCNT
13323    && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
13324   "#"
13325   "&& reload_completed"
13326   [(parallel
13327     [(set (match_dup 0)
13328           (popcount:SWI48 (match_dup 1)))
13329      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13330      (clobber (reg:CC FLAGS_REG))])]
13332   if (!reg_mentioned_p (operands[0], operands[1]))
13333     ix86_expand_clear (operands[0]);
13336 (define_insn "*popcount<mode>2_falsedep"
13337   [(set (match_operand:SWI48 0 "register_operand" "=r")
13338         (popcount:SWI48
13339           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13340    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13341            UNSPEC_INSN_FALSE_DEP)
13342    (clobber (reg:CC FLAGS_REG))]
13343   "TARGET_POPCNT"
13345 #if TARGET_MACHO
13346   return "popcnt\t{%1, %0|%0, %1}";
13347 #else
13348   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13349 #endif
13351   [(set_attr "prefix_rep" "1")
13352    (set_attr "type" "bitmanip")
13353    (set_attr "mode" "<MODE>")])
13355 (define_insn "*popcount<mode>2"
13356   [(set (match_operand:SWI248 0 "register_operand" "=r")
13357         (popcount:SWI248
13358           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
13359    (clobber (reg:CC FLAGS_REG))]
13360   "TARGET_POPCNT"
13362 #if TARGET_MACHO
13363   return "popcnt\t{%1, %0|%0, %1}";
13364 #else
13365   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13366 #endif
13368   [(set_attr "prefix_rep" "1")
13369    (set_attr "type" "bitmanip")
13370    (set_attr "mode" "<MODE>")])
13372 (define_expand "bswapdi2"
13373   [(set (match_operand:DI 0 "register_operand")
13374         (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
13375   "TARGET_64BIT"
13377   if (!TARGET_MOVBE)
13378     operands[1] = force_reg (DImode, operands[1]);
13381 (define_expand "bswapsi2"
13382   [(set (match_operand:SI 0 "register_operand")
13383         (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
13384   ""
13386   if (TARGET_MOVBE)
13387     ;
13388   else if (TARGET_BSWAP)
13389     operands[1] = force_reg (SImode, operands[1]);
13390   else
13391     {
13392       rtx x = operands[0];
13394       emit_move_insn (x, operands[1]);
13395       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13396       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
13397       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13398       DONE;
13399     }
13402 (define_insn "*bswap<mode>2_movbe"
13403   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
13404         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
13405   "TARGET_MOVBE
13406    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13407   "@
13408     bswap\t%0
13409     movbe\t{%1, %0|%0, %1}
13410     movbe\t{%1, %0|%0, %1}"
13411   [(set_attr "type" "bitmanip,imov,imov")
13412    (set_attr "modrm" "0,1,1")
13413    (set_attr "prefix_0f" "*,1,1")
13414    (set_attr "prefix_extra" "*,1,1")
13415    (set_attr "mode" "<MODE>")])
13417 (define_insn "*bswap<mode>2"
13418   [(set (match_operand:SWI48 0 "register_operand" "=r")
13419         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
13420   "TARGET_BSWAP"
13421   "bswap\t%0"
13422   [(set_attr "type" "bitmanip")
13423    (set_attr "modrm" "0")
13424    (set_attr "mode" "<MODE>")])
13426 (define_insn "*bswaphi_lowpart_1"
13427   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
13428         (bswap:HI (match_dup 0)))
13429    (clobber (reg:CC FLAGS_REG))]
13430   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
13431   "@
13432     xchg{b}\t{%h0, %b0|%b0, %h0}
13433     rol{w}\t{$8, %0|%0, 8}"
13434   [(set_attr "length" "2,4")
13435    (set_attr "mode" "QI,HI")])
13437 (define_insn "bswaphi_lowpart"
13438   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
13439         (bswap:HI (match_dup 0)))
13440    (clobber (reg:CC FLAGS_REG))]
13441   ""
13442   "rol{w}\t{$8, %0|%0, 8}"
13443   [(set_attr "length" "4")
13444    (set_attr "mode" "HI")])
13446 (define_expand "paritydi2"
13447   [(set (match_operand:DI 0 "register_operand")
13448         (parity:DI (match_operand:DI 1 "register_operand")))]
13449   "! TARGET_POPCNT"
13451   rtx scratch = gen_reg_rtx (QImode);
13452   rtx cond;
13454   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
13455                                 NULL_RTX, operands[1]));
13457   cond = gen_rtx_fmt_ee (ORDERED, QImode,
13458                          gen_rtx_REG (CCmode, FLAGS_REG),
13459                          const0_rtx);
13460   emit_insn (gen_rtx_SET (scratch, cond));
13462   if (TARGET_64BIT)
13463     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
13464   else
13465     {
13466       rtx tmp = gen_reg_rtx (SImode);
13468       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
13469       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
13470     }
13471   DONE;
13474 (define_expand "paritysi2"
13475   [(set (match_operand:SI 0 "register_operand")
13476         (parity:SI (match_operand:SI 1 "register_operand")))]
13477   "! TARGET_POPCNT"
13479   rtx scratch = gen_reg_rtx (QImode);
13480   rtx cond;
13482   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
13484   cond = gen_rtx_fmt_ee (ORDERED, QImode,
13485                          gen_rtx_REG (CCmode, FLAGS_REG),
13486                          const0_rtx);
13487   emit_insn (gen_rtx_SET (scratch, cond));
13489   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
13490   DONE;
13493 (define_insn_and_split "paritydi2_cmp"
13494   [(set (reg:CC FLAGS_REG)
13495         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
13496                    UNSPEC_PARITY))
13497    (clobber (match_scratch:DI 0 "=r"))
13498    (clobber (match_scratch:SI 1 "=&r"))
13499    (clobber (match_scratch:HI 2 "=Q"))]
13500   "! TARGET_POPCNT"
13501   "#"
13502   "&& reload_completed"
13503   [(parallel
13504      [(set (match_dup 1)
13505            (xor:SI (match_dup 1) (match_dup 4)))
13506       (clobber (reg:CC FLAGS_REG))])
13507    (parallel
13508      [(set (reg:CC FLAGS_REG)
13509            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13510       (clobber (match_dup 1))
13511       (clobber (match_dup 2))])]
13513   operands[4] = gen_lowpart (SImode, operands[3]);
13515   if (TARGET_64BIT)
13516     {
13517       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
13518       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
13519     }
13520   else
13521     operands[1] = gen_highpart (SImode, operands[3]);
13524 (define_insn_and_split "paritysi2_cmp"
13525   [(set (reg:CC FLAGS_REG)
13526         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
13527                    UNSPEC_PARITY))
13528    (clobber (match_scratch:SI 0 "=r"))
13529    (clobber (match_scratch:HI 1 "=&Q"))]
13530   "! TARGET_POPCNT"
13531   "#"
13532   "&& reload_completed"
13533   [(parallel
13534      [(set (match_dup 1)
13535            (xor:HI (match_dup 1) (match_dup 3)))
13536       (clobber (reg:CC FLAGS_REG))])
13537    (parallel
13538      [(set (reg:CC FLAGS_REG)
13539            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13540       (clobber (match_dup 1))])]
13542   operands[3] = gen_lowpart (HImode, operands[2]);
13544   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
13545   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
13548 (define_insn "*parityhi2_cmp"
13549   [(set (reg:CC FLAGS_REG)
13550         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
13551                    UNSPEC_PARITY))
13552    (clobber (match_scratch:HI 0 "=Q"))]
13553   "! TARGET_POPCNT"
13554   "xor{b}\t{%h0, %b0|%b0, %h0}"
13555   [(set_attr "length" "2")
13556    (set_attr "mode" "HI")])
13559 ;; Thread-local storage patterns for ELF.
13561 ;; Note that these code sequences must appear exactly as shown
13562 ;; in order to allow linker relaxation.
13564 (define_insn "*tls_global_dynamic_32_gnu"
13565   [(set (match_operand:SI 0 "register_operand" "=a")
13566         (unspec:SI
13567          [(match_operand:SI 1 "register_operand" "b")
13568           (match_operand 2 "tls_symbolic_operand")
13569           (match_operand 3 "constant_call_address_operand" "Bz")
13570           (reg:SI SP_REG)]
13571          UNSPEC_TLS_GD))
13572    (clobber (match_scratch:SI 4 "=d"))
13573    (clobber (match_scratch:SI 5 "=c"))
13574    (clobber (reg:CC FLAGS_REG))]
13575   "!TARGET_64BIT && TARGET_GNU_TLS"
13577   output_asm_insn
13578     ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
13579   if (TARGET_SUN_TLS)
13580 #ifdef HAVE_AS_IX86_TLSGDPLT
13581     return "call\t%a2@tlsgdplt";
13582 #else
13583     return "call\t%p3@plt";
13584 #endif
13585   return "call\t%P3";
13587   [(set_attr "type" "multi")
13588    (set_attr "length" "12")])
13590 (define_expand "tls_global_dynamic_32"
13591   [(parallel
13592     [(set (match_operand:SI 0 "register_operand")
13593           (unspec:SI [(match_operand:SI 2 "register_operand")
13594                       (match_operand 1 "tls_symbolic_operand")
13595                       (match_operand 3 "constant_call_address_operand")
13596                       (reg:SI SP_REG)]
13597                      UNSPEC_TLS_GD))
13598      (clobber (match_scratch:SI 4))
13599      (clobber (match_scratch:SI 5))
13600      (clobber (reg:CC FLAGS_REG))])]
13601   ""
13602   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13604 (define_insn "*tls_global_dynamic_64_<mode>"
13605   [(set (match_operand:P 0 "register_operand" "=a")
13606         (call:P
13607          (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
13608          (match_operand 3)))
13609    (unspec:P [(match_operand 1 "tls_symbolic_operand")
13610               (reg:P SP_REG)]
13611              UNSPEC_TLS_GD)]
13612   "TARGET_64BIT"
13614   if (!TARGET_X32)
13615     fputs (ASM_BYTE "0x66\n", asm_out_file);
13616   output_asm_insn
13617     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13618   fputs (ASM_SHORT "0x6666\n", asm_out_file);
13619   fputs ("\trex64\n", asm_out_file);
13620   if (TARGET_SUN_TLS)
13621     return "call\t%p2@plt";
13622   return "call\t%P2";
13624   [(set_attr "type" "multi")
13625    (set (attr "length")
13626         (symbol_ref "TARGET_X32 ? 15 : 16"))])
13628 (define_insn "*tls_global_dynamic_64_largepic"
13629   [(set (match_operand:DI 0 "register_operand" "=a")
13630         (call:DI
13631          (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
13632                           (match_operand:DI 3 "immediate_operand" "i")))
13633          (match_operand 4)))
13634    (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13635                (reg:DI SP_REG)]
13636               UNSPEC_TLS_GD)]
13637   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13638    && GET_CODE (operands[3]) == CONST
13639    && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
13640    && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
13642   output_asm_insn
13643     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13644   output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
13645   output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
13646   return "call\t{*%%rax|rax}";
13648   [(set_attr "type" "multi")
13649    (set_attr "length" "22")])
13651 (define_expand "tls_global_dynamic_64_<mode>"
13652   [(parallel
13653     [(set (match_operand:P 0 "register_operand")
13654           (call:P
13655            (mem:QI (match_operand 2))
13656            (const_int 0)))
13657      (unspec:P [(match_operand 1 "tls_symbolic_operand")
13658                 (reg:P SP_REG)]
13659                UNSPEC_TLS_GD)])]
13660   "TARGET_64BIT"
13661   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13663 (define_insn "*tls_local_dynamic_base_32_gnu"
13664   [(set (match_operand:SI 0 "register_operand" "=a")
13665         (unspec:SI
13666          [(match_operand:SI 1 "register_operand" "b")
13667           (match_operand 2 "constant_call_address_operand" "Bz")
13668           (reg:SI SP_REG)]
13669          UNSPEC_TLS_LD_BASE))
13670    (clobber (match_scratch:SI 3 "=d"))
13671    (clobber (match_scratch:SI 4 "=c"))
13672    (clobber (reg:CC FLAGS_REG))]
13673   "!TARGET_64BIT && TARGET_GNU_TLS"
13675   output_asm_insn
13676     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
13677   if (TARGET_SUN_TLS)
13678     {
13679       if (HAVE_AS_IX86_TLSLDMPLT)
13680         return "call\t%&@tlsldmplt";
13681       else
13682         return "call\t%p2@plt";
13683     }
13684   return "call\t%P2";
13686   [(set_attr "type" "multi")
13687    (set_attr "length" "11")])
13689 (define_expand "tls_local_dynamic_base_32"
13690   [(parallel
13691      [(set (match_operand:SI 0 "register_operand")
13692            (unspec:SI
13693             [(match_operand:SI 1 "register_operand")
13694              (match_operand 2 "constant_call_address_operand")
13695              (reg:SI SP_REG)]
13696             UNSPEC_TLS_LD_BASE))
13697       (clobber (match_scratch:SI 3))
13698       (clobber (match_scratch:SI 4))
13699       (clobber (reg:CC FLAGS_REG))])]
13700   ""
13701   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13703 (define_insn "*tls_local_dynamic_base_64_<mode>"
13704   [(set (match_operand:P 0 "register_operand" "=a")
13705         (call:P
13706          (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
13707          (match_operand 2)))
13708    (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
13709   "TARGET_64BIT"
13711   output_asm_insn
13712     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13713   if (TARGET_SUN_TLS)
13714     return "call\t%p1@plt";
13715   return "call\t%P1";
13717   [(set_attr "type" "multi")
13718    (set_attr "length" "12")])
13720 (define_insn "*tls_local_dynamic_base_64_largepic"
13721   [(set (match_operand:DI 0 "register_operand" "=a")
13722         (call:DI
13723          (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13724                           (match_operand:DI 2 "immediate_operand" "i")))
13725          (match_operand 3)))
13726    (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
13727   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13728    && GET_CODE (operands[2]) == CONST
13729    && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13730    && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13732   output_asm_insn
13733     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13734   output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13735   output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13736   return "call\t{*%%rax|rax}";
13738   [(set_attr "type" "multi")
13739    (set_attr "length" "22")])
13741 (define_expand "tls_local_dynamic_base_64_<mode>"
13742   [(parallel
13743      [(set (match_operand:P 0 "register_operand")
13744            (call:P
13745             (mem:QI (match_operand 1))
13746             (const_int 0)))
13747       (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
13748   "TARGET_64BIT"
13749   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13751 ;; Local dynamic of a single variable is a lose.  Show combine how
13752 ;; to convert that back to global dynamic.
13754 (define_insn_and_split "*tls_local_dynamic_32_once"
13755   [(set (match_operand:SI 0 "register_operand" "=a")
13756         (plus:SI
13757          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13758                      (match_operand 2 "constant_call_address_operand" "Bz")
13759                      (reg:SI SP_REG)]
13760                     UNSPEC_TLS_LD_BASE)
13761          (const:SI (unspec:SI
13762                     [(match_operand 3 "tls_symbolic_operand")]
13763                     UNSPEC_DTPOFF))))
13764    (clobber (match_scratch:SI 4 "=d"))
13765    (clobber (match_scratch:SI 5 "=c"))
13766    (clobber (reg:CC FLAGS_REG))]
13767   ""
13768   "#"
13769   ""
13770   [(parallel
13771      [(set (match_dup 0)
13772            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13773                        (reg:SI SP_REG)]
13774                       UNSPEC_TLS_GD))
13775       (clobber (match_dup 4))
13776       (clobber (match_dup 5))
13777       (clobber (reg:CC FLAGS_REG))])])
13779 ;; Segment register for the thread base ptr load
13780 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13782 ;; Load and add the thread base pointer from %<tp_seg>:0.
13783 (define_insn "*load_tp_x32"
13784   [(set (match_operand:SI 0 "register_operand" "=r")
13785         (unspec:SI [(const_int 0)] UNSPEC_TP))]
13786   "TARGET_X32"
13787   "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13788   [(set_attr "type" "imov")
13789    (set_attr "modrm" "0")
13790    (set_attr "length" "7")
13791    (set_attr "memory" "load")
13792    (set_attr "imm_disp" "false")])
13794 (define_insn "*load_tp_x32_zext"
13795   [(set (match_operand:DI 0 "register_operand" "=r")
13796         (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13797   "TARGET_X32"
13798   "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13799   [(set_attr "type" "imov")
13800    (set_attr "modrm" "0")
13801    (set_attr "length" "7")
13802    (set_attr "memory" "load")
13803    (set_attr "imm_disp" "false")])
13805 (define_insn "*load_tp_<mode>"
13806   [(set (match_operand:P 0 "register_operand" "=r")
13807         (unspec:P [(const_int 0)] UNSPEC_TP))]
13808   "!TARGET_X32"
13809   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13810   [(set_attr "type" "imov")
13811    (set_attr "modrm" "0")
13812    (set_attr "length" "7")
13813    (set_attr "memory" "load")
13814    (set_attr "imm_disp" "false")])
13816 (define_insn "*add_tp_x32"
13817   [(set (match_operand:SI 0 "register_operand" "=r")
13818         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13819                  (match_operand:SI 1 "register_operand" "0")))
13820    (clobber (reg:CC FLAGS_REG))]
13821   "TARGET_X32"
13822   "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13823   [(set_attr "type" "alu")
13824    (set_attr "modrm" "0")
13825    (set_attr "length" "7")
13826    (set_attr "memory" "load")
13827    (set_attr "imm_disp" "false")])
13829 (define_insn "*add_tp_x32_zext"
13830   [(set (match_operand:DI 0 "register_operand" "=r")
13831         (zero_extend:DI
13832           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13833                    (match_operand:SI 1 "register_operand" "0"))))
13834    (clobber (reg:CC FLAGS_REG))]
13835   "TARGET_X32"
13836   "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13837   [(set_attr "type" "alu")
13838    (set_attr "modrm" "0")
13839    (set_attr "length" "7")
13840    (set_attr "memory" "load")
13841    (set_attr "imm_disp" "false")])
13843 (define_insn "*add_tp_<mode>"
13844   [(set (match_operand:P 0 "register_operand" "=r")
13845         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13846                 (match_operand:P 1 "register_operand" "0")))
13847    (clobber (reg:CC FLAGS_REG))]
13848   "!TARGET_X32"
13849   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13850   [(set_attr "type" "alu")
13851    (set_attr "modrm" "0")
13852    (set_attr "length" "7")
13853    (set_attr "memory" "load")
13854    (set_attr "imm_disp" "false")])
13856 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13857 ;; %rax as destination of the initial executable code sequence.
13858 (define_insn "tls_initial_exec_64_sun"
13859   [(set (match_operand:DI 0 "register_operand" "=a")
13860         (unspec:DI
13861          [(match_operand 1 "tls_symbolic_operand")]
13862          UNSPEC_TLS_IE_SUN))
13863    (clobber (reg:CC FLAGS_REG))]
13864   "TARGET_64BIT && TARGET_SUN_TLS"
13866   output_asm_insn
13867     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13868   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13870   [(set_attr "type" "multi")])
13872 ;; GNU2 TLS patterns can be split.
13874 (define_expand "tls_dynamic_gnu2_32"
13875   [(set (match_dup 3)
13876         (plus:SI (match_operand:SI 2 "register_operand")
13877                  (const:SI
13878                   (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13879                              UNSPEC_TLSDESC))))
13880    (parallel
13881     [(set (match_operand:SI 0 "register_operand")
13882           (unspec:SI [(match_dup 1) (match_dup 3)
13883                       (match_dup 2) (reg:SI SP_REG)]
13884                       UNSPEC_TLSDESC))
13885      (clobber (reg:CC FLAGS_REG))])]
13886   "!TARGET_64BIT && TARGET_GNU2_TLS"
13888   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13889   ix86_tls_descriptor_calls_expanded_in_cfun = true;
13892 (define_insn "*tls_dynamic_gnu2_lea_32"
13893   [(set (match_operand:SI 0 "register_operand" "=r")
13894         (plus:SI (match_operand:SI 1 "register_operand" "b")
13895                  (const:SI
13896                   (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13897                               UNSPEC_TLSDESC))))]
13898   "!TARGET_64BIT && TARGET_GNU2_TLS"
13899   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13900   [(set_attr "type" "lea")
13901    (set_attr "mode" "SI")
13902    (set_attr "length" "6")
13903    (set_attr "length_address" "4")])
13905 (define_insn "*tls_dynamic_gnu2_call_32"
13906   [(set (match_operand:SI 0 "register_operand" "=a")
13907         (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13908                     (match_operand:SI 2 "register_operand" "0")
13909                     ;; we have to make sure %ebx still points to the GOT
13910                     (match_operand:SI 3 "register_operand" "b")
13911                     (reg:SI SP_REG)]
13912                    UNSPEC_TLSDESC))
13913    (clobber (reg:CC FLAGS_REG))]
13914   "!TARGET_64BIT && TARGET_GNU2_TLS"
13915   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13916   [(set_attr "type" "call")
13917    (set_attr "length" "2")
13918    (set_attr "length_address" "0")])
13920 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13921   [(set (match_operand:SI 0 "register_operand" "=&a")
13922         (plus:SI
13923          (unspec:SI [(match_operand 3 "tls_modbase_operand")
13924                      (match_operand:SI 4)
13925                      (match_operand:SI 2 "register_operand" "b")
13926                      (reg:SI SP_REG)]
13927                     UNSPEC_TLSDESC)
13928          (const:SI (unspec:SI
13929                     [(match_operand 1 "tls_symbolic_operand")]
13930                     UNSPEC_DTPOFF))))
13931    (clobber (reg:CC FLAGS_REG))]
13932   "!TARGET_64BIT && TARGET_GNU2_TLS"
13933   "#"
13934   ""
13935   [(set (match_dup 0) (match_dup 5))]
13937   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13938   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13941 (define_expand "tls_dynamic_gnu2_64"
13942   [(set (match_dup 2)
13943         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13944                    UNSPEC_TLSDESC))
13945    (parallel
13946     [(set (match_operand:DI 0 "register_operand")
13947           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13948                      UNSPEC_TLSDESC))
13949      (clobber (reg:CC FLAGS_REG))])]
13950   "TARGET_64BIT && TARGET_GNU2_TLS"
13952   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13953   ix86_tls_descriptor_calls_expanded_in_cfun = true;
13956 (define_insn "*tls_dynamic_gnu2_lea_64"
13957   [(set (match_operand:DI 0 "register_operand" "=r")
13958         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13959                    UNSPEC_TLSDESC))]
13960   "TARGET_64BIT && TARGET_GNU2_TLS"
13961   "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13962   [(set_attr "type" "lea")
13963    (set_attr "mode" "DI")
13964    (set_attr "length" "7")
13965    (set_attr "length_address" "4")])
13967 (define_insn "*tls_dynamic_gnu2_call_64"
13968   [(set (match_operand:DI 0 "register_operand" "=a")
13969         (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13970                     (match_operand:DI 2 "register_operand" "0")
13971                     (reg:DI SP_REG)]
13972                    UNSPEC_TLSDESC))
13973    (clobber (reg:CC FLAGS_REG))]
13974   "TARGET_64BIT && TARGET_GNU2_TLS"
13975   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13976   [(set_attr "type" "call")
13977    (set_attr "length" "2")
13978    (set_attr "length_address" "0")])
13980 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13981   [(set (match_operand:DI 0 "register_operand" "=&a")
13982         (plus:DI
13983          (unspec:DI [(match_operand 2 "tls_modbase_operand")
13984                      (match_operand:DI 3)
13985                      (reg:DI SP_REG)]
13986                     UNSPEC_TLSDESC)
13987          (const:DI (unspec:DI
13988                     [(match_operand 1 "tls_symbolic_operand")]
13989                     UNSPEC_DTPOFF))))
13990    (clobber (reg:CC FLAGS_REG))]
13991   "TARGET_64BIT && TARGET_GNU2_TLS"
13992   "#"
13993   ""
13994   [(set (match_dup 0) (match_dup 4))]
13996   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13997   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14000 ;; These patterns match the binary 387 instructions for addM3, subM3,
14001 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14002 ;; SFmode.  The first is the normal insn, the second the same insn but
14003 ;; with one operand a conversion, and the third the same insn but with
14004 ;; the other operand a conversion.  The conversion may be SFmode or
14005 ;; SImode if the target mode DFmode, but only SImode if the target mode
14006 ;; is SFmode.
14008 ;; Gcc is slightly more smart about handling normal two address instructions
14009 ;; so use special patterns for add and mull.
14011 (define_insn "*fop_<mode>_comm_mixed"
14012   [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
14013         (match_operator:MODEF 3 "binary_fp_operator"
14014           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
14015            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
14016   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14017    && COMMUTATIVE_ARITH_P (operands[3])
14018    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14019   "* return output_387_binary_op (insn, operands);"
14020   [(set (attr "type")
14021         (if_then_else (eq_attr "alternative" "1,2")
14022            (if_then_else (match_operand:MODEF 3 "mult_operator")
14023               (const_string "ssemul")
14024               (const_string "sseadd"))
14025            (if_then_else (match_operand:MODEF 3 "mult_operator")
14026               (const_string "fmul")
14027               (const_string "fop"))))
14028    (set_attr "isa" "*,noavx,avx")
14029    (set_attr "prefix" "orig,orig,vex")
14030    (set_attr "mode" "<MODE>")
14031    (set (attr "enabled")
14032      (cond [(eq_attr "alternative" "0")
14033               (symbol_ref "TARGET_MIX_SSE_I387")
14034            ]
14035            (const_string "*")))])
14037 (define_insn "*fop_<mode>_comm_i387"
14038   [(set (match_operand:MODEF 0 "register_operand" "=f")
14039         (match_operator:MODEF 3 "binary_fp_operator"
14040           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
14041            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
14042   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
14043    && COMMUTATIVE_ARITH_P (operands[3])
14044    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14045   "* return output_387_binary_op (insn, operands);"
14046   [(set (attr "type")
14047         (if_then_else (match_operand:MODEF 3 "mult_operator")
14048            (const_string "fmul")
14049            (const_string "fop")))
14050    (set_attr "mode" "<MODE>")])
14052 (define_insn "*rcpsf2_sse"
14053   [(set (match_operand:SF 0 "register_operand" "=x")
14054         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14055                    UNSPEC_RCP))]
14056   "TARGET_SSE_MATH"
14057   "%vrcpss\t{%1, %d0|%d0, %1}"
14058   [(set_attr "type" "sse")
14059    (set_attr "atom_sse_attr" "rcp")
14060    (set_attr "btver2_sse_attr" "rcp")
14061    (set_attr "prefix" "maybe_vex")
14062    (set_attr "mode" "SF")])
14064 (define_insn "*fop_<mode>_1_mixed"
14065   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
14066         (match_operator:MODEF 3 "binary_fp_operator"
14067           [(match_operand:MODEF 1
14068              "register_mixssei387nonimm_operand" "0,fm,0,v")
14069            (match_operand:MODEF 2
14070              "nonimmediate_operand"              "fm,0,xm,vm")]))]
14071   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14072    && !COMMUTATIVE_ARITH_P (operands[3])
14073    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14074   "* return output_387_binary_op (insn, operands);"
14075   [(set (attr "type")
14076         (cond [(and (eq_attr "alternative" "2,3")
14077                     (match_operand:MODEF 3 "mult_operator"))
14078                  (const_string "ssemul")
14079                (and (eq_attr "alternative" "2,3")
14080                     (match_operand:MODEF 3 "div_operator"))
14081                  (const_string "ssediv")
14082                (eq_attr "alternative" "2,3")
14083                  (const_string "sseadd")
14084                (match_operand:MODEF 3 "mult_operator")
14085                  (const_string "fmul")
14086                (match_operand:MODEF 3 "div_operator")
14087                  (const_string "fdiv")
14088               ]
14089               (const_string "fop")))
14090    (set_attr "isa" "*,*,noavx,avx")
14091    (set_attr "prefix" "orig,orig,orig,vex")
14092    (set_attr "mode" "<MODE>")
14093    (set (attr "enabled")
14094      (cond [(eq_attr "alternative" "0,1")
14095               (symbol_ref "TARGET_MIX_SSE_I387")
14096            ]
14097            (const_string "*")))])
14099 ;; This pattern is not fully shadowed by the pattern above.
14100 (define_insn "*fop_<mode>_1_i387"
14101   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
14102         (match_operator:MODEF 3 "binary_fp_operator"
14103           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
14104            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
14105   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
14106    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14107    && !COMMUTATIVE_ARITH_P (operands[3])
14108    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14109   "* return output_387_binary_op (insn, operands);"
14110   [(set (attr "type")
14111         (cond [(match_operand:MODEF 3 "mult_operator")
14112                  (const_string "fmul")
14113                (match_operand:MODEF 3 "div_operator")
14114                  (const_string "fdiv")
14115               ]
14116               (const_string "fop")))
14117    (set_attr "mode" "<MODE>")])
14119 ;; ??? Add SSE splitters for these!
14120 (define_insn "*fop_<MODEF:mode>_2_i387"
14121   [(set (match_operand:MODEF 0 "register_operand" "=f")
14122         (match_operator:MODEF 3 "binary_fp_operator"
14123           [(float:MODEF
14124              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14125            (match_operand:MODEF 2 "register_operand" "0")]))]
14126   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14127    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14128    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14129        || optimize_function_for_size_p (cfun))"
14130   { return output_387_binary_op (insn, operands); }
14131   [(set (attr "type")
14132         (cond [(match_operand:MODEF 3 "mult_operator")
14133                  (const_string "fmul")
14134                (match_operand:MODEF 3 "div_operator")
14135                  (const_string "fdiv")
14136               ]
14137               (const_string "fop")))
14138    (set_attr "fp_int_src" "true")
14139    (set_attr "mode" "<SWI24:MODE>")])
14141 (define_insn "*fop_<MODEF:mode>_3_i387"
14142   [(set (match_operand:MODEF 0 "register_operand" "=f")
14143         (match_operator:MODEF 3 "binary_fp_operator"
14144           [(match_operand:MODEF 1 "register_operand" "0")
14145            (float:MODEF
14146              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14147   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14148    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14149    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14150        || optimize_function_for_size_p (cfun))"
14151   { return output_387_binary_op (insn, operands); }
14152   [(set (attr "type")
14153         (cond [(match_operand:MODEF 3 "mult_operator")
14154                  (const_string "fmul")
14155                (match_operand:MODEF 3 "div_operator")
14156                  (const_string "fdiv")
14157               ]
14158               (const_string "fop")))
14159    (set_attr "fp_int_src" "true")
14160    (set_attr "mode" "<MODE>")])
14162 (define_insn "*fop_df_4_i387"
14163   [(set (match_operand:DF 0 "register_operand" "=f,f")
14164         (match_operator:DF 3 "binary_fp_operator"
14165            [(float_extend:DF
14166              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14167             (match_operand:DF 2 "register_operand" "0,f")]))]
14168   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14169    && !(TARGET_SSE2 && TARGET_SSE_MATH)
14170    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14171   "* return output_387_binary_op (insn, operands);"
14172   [(set (attr "type")
14173         (cond [(match_operand:DF 3 "mult_operator")
14174                  (const_string "fmul")
14175                (match_operand:DF 3 "div_operator")
14176                  (const_string "fdiv")
14177               ]
14178               (const_string "fop")))
14179    (set_attr "mode" "SF")])
14181 (define_insn "*fop_df_5_i387"
14182   [(set (match_operand:DF 0 "register_operand" "=f,f")
14183         (match_operator:DF 3 "binary_fp_operator"
14184           [(match_operand:DF 1 "register_operand" "0,f")
14185            (float_extend:DF
14186             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14187   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14188    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14189   "* return output_387_binary_op (insn, operands);"
14190   [(set (attr "type")
14191         (cond [(match_operand:DF 3 "mult_operator")
14192                  (const_string "fmul")
14193                (match_operand:DF 3 "div_operator")
14194                  (const_string "fdiv")
14195               ]
14196               (const_string "fop")))
14197    (set_attr "mode" "SF")])
14199 (define_insn "*fop_df_6_i387"
14200   [(set (match_operand:DF 0 "register_operand" "=f,f")
14201         (match_operator:DF 3 "binary_fp_operator"
14202           [(float_extend:DF
14203             (match_operand:SF 1 "register_operand" "0,f"))
14204            (float_extend:DF
14205             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14206   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14207    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14208   "* return output_387_binary_op (insn, operands);"
14209   [(set (attr "type")
14210         (cond [(match_operand:DF 3 "mult_operator")
14211                  (const_string "fmul")
14212                (match_operand:DF 3 "div_operator")
14213                  (const_string "fdiv")
14214               ]
14215               (const_string "fop")))
14216    (set_attr "mode" "SF")])
14218 (define_insn "*fop_xf_comm_i387"
14219   [(set (match_operand:XF 0 "register_operand" "=f")
14220         (match_operator:XF 3 "binary_fp_operator"
14221                         [(match_operand:XF 1 "register_operand" "%0")
14222                          (match_operand:XF 2 "register_operand" "f")]))]
14223   "TARGET_80387
14224    && COMMUTATIVE_ARITH_P (operands[3])"
14225   "* return output_387_binary_op (insn, operands);"
14226   [(set (attr "type")
14227         (if_then_else (match_operand:XF 3 "mult_operator")
14228            (const_string "fmul")
14229            (const_string "fop")))
14230    (set_attr "mode" "XF")])
14232 (define_insn "*fop_xf_1_i387"
14233   [(set (match_operand:XF 0 "register_operand" "=f,f")
14234         (match_operator:XF 3 "binary_fp_operator"
14235                         [(match_operand:XF 1 "register_operand" "0,f")
14236                          (match_operand:XF 2 "register_operand" "f,0")]))]
14237   "TARGET_80387
14238    && !COMMUTATIVE_ARITH_P (operands[3])"
14239   "* return output_387_binary_op (insn, operands);"
14240   [(set (attr "type")
14241         (cond [(match_operand:XF 3 "mult_operator")
14242                  (const_string "fmul")
14243                (match_operand:XF 3 "div_operator")
14244                  (const_string "fdiv")
14245               ]
14246               (const_string "fop")))
14247    (set_attr "mode" "XF")])
14249 (define_insn "*fop_xf_2_i387"
14250   [(set (match_operand:XF 0 "register_operand" "=f")
14251         (match_operator:XF 3 "binary_fp_operator"
14252           [(float:XF
14253              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14254            (match_operand:XF 2 "register_operand" "0")]))]
14255   "TARGET_80387
14256    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14257   { return output_387_binary_op (insn, operands); }
14258   [(set (attr "type")
14259         (cond [(match_operand:XF 3 "mult_operator")
14260                  (const_string "fmul")
14261                (match_operand:XF 3 "div_operator")
14262                  (const_string "fdiv")
14263               ]
14264               (const_string "fop")))
14265    (set_attr "fp_int_src" "true")
14266    (set_attr "mode" "<MODE>")])
14268 (define_insn "*fop_xf_3_i387"
14269   [(set (match_operand:XF 0 "register_operand" "=f")
14270         (match_operator:XF 3 "binary_fp_operator"
14271           [(match_operand:XF 1 "register_operand" "0")
14272            (float:XF
14273              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14274   "TARGET_80387
14275    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14276   { return output_387_binary_op (insn, operands); }
14277   [(set (attr "type")
14278         (cond [(match_operand:XF 3 "mult_operator")
14279                  (const_string "fmul")
14280                (match_operand:XF 3 "div_operator")
14281                  (const_string "fdiv")
14282               ]
14283               (const_string "fop")))
14284    (set_attr "fp_int_src" "true")
14285    (set_attr "mode" "<MODE>")])
14287 (define_insn "*fop_xf_4_i387"
14288   [(set (match_operand:XF 0 "register_operand" "=f,f")
14289         (match_operator:XF 3 "binary_fp_operator"
14290            [(float_extend:XF
14291               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
14292             (match_operand:XF 2 "register_operand" "0,f")]))]
14293   "TARGET_80387"
14294   "* return output_387_binary_op (insn, operands);"
14295   [(set (attr "type")
14296         (cond [(match_operand:XF 3 "mult_operator")
14297                  (const_string "fmul")
14298                (match_operand:XF 3 "div_operator")
14299                  (const_string "fdiv")
14300               ]
14301               (const_string "fop")))
14302    (set_attr "mode" "<MODE>")])
14304 (define_insn "*fop_xf_5_i387"
14305   [(set (match_operand:XF 0 "register_operand" "=f,f")
14306         (match_operator:XF 3 "binary_fp_operator"
14307           [(match_operand:XF 1 "register_operand" "0,f")
14308            (float_extend:XF
14309              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14310   "TARGET_80387"
14311   "* return output_387_binary_op (insn, operands);"
14312   [(set (attr "type")
14313         (cond [(match_operand:XF 3 "mult_operator")
14314                  (const_string "fmul")
14315                (match_operand:XF 3 "div_operator")
14316                  (const_string "fdiv")
14317               ]
14318               (const_string "fop")))
14319    (set_attr "mode" "<MODE>")])
14321 (define_insn "*fop_xf_6_i387"
14322   [(set (match_operand:XF 0 "register_operand" "=f,f")
14323         (match_operator:XF 3 "binary_fp_operator"
14324           [(float_extend:XF
14325              (match_operand:MODEF 1 "register_operand" "0,f"))
14326            (float_extend:XF
14327              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14328   "TARGET_80387"
14329   "* return output_387_binary_op (insn, operands);"
14330   [(set (attr "type")
14331         (cond [(match_operand:XF 3 "mult_operator")
14332                  (const_string "fmul")
14333                (match_operand:XF 3 "div_operator")
14334                  (const_string "fdiv")
14335               ]
14336               (const_string "fop")))
14337    (set_attr "mode" "<MODE>")])
14339 ;; FPU special functions.
14341 ;; This pattern implements a no-op XFmode truncation for
14342 ;; all fancy i386 XFmode math functions.
14344 (define_insn "truncxf<mode>2_i387_noop_unspec"
14345   [(set (match_operand:MODEF 0 "register_operand" "=f")
14346         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
14347         UNSPEC_TRUNC_NOOP))]
14348   "TARGET_USE_FANCY_MATH_387"
14349   "* return output_387_reg_move (insn, operands);"
14350   [(set_attr "type" "fmov")
14351    (set_attr "mode" "<MODE>")])
14353 (define_insn "sqrtxf2"
14354   [(set (match_operand:XF 0 "register_operand" "=f")
14355         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14356   "TARGET_USE_FANCY_MATH_387"
14357   "fsqrt"
14358   [(set_attr "type" "fpspc")
14359    (set_attr "mode" "XF")
14360    (set_attr "athlon_decode" "direct")
14361    (set_attr "amdfam10_decode" "direct")
14362    (set_attr "bdver1_decode" "direct")])
14364 (define_insn "sqrt_extend<mode>xf2_i387"
14365   [(set (match_operand:XF 0 "register_operand" "=f")
14366         (sqrt:XF
14367           (float_extend:XF
14368             (match_operand:MODEF 1 "register_operand" "0"))))]
14369   "TARGET_USE_FANCY_MATH_387"
14370   "fsqrt"
14371   [(set_attr "type" "fpspc")
14372    (set_attr "mode" "XF")
14373    (set_attr "athlon_decode" "direct")
14374    (set_attr "amdfam10_decode" "direct")
14375    (set_attr "bdver1_decode" "direct")])
14377 (define_insn "*rsqrtsf2_sse"
14378   [(set (match_operand:SF 0 "register_operand" "=x")
14379         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14380                    UNSPEC_RSQRT))]
14381   "TARGET_SSE_MATH"
14382   "%vrsqrtss\t{%1, %d0|%d0, %1}"
14383   [(set_attr "type" "sse")
14384    (set_attr "atom_sse_attr" "rcp")
14385    (set_attr "btver2_sse_attr" "rcp")
14386    (set_attr "prefix" "maybe_vex")
14387    (set_attr "mode" "SF")])
14389 (define_expand "rsqrtsf2"
14390   [(set (match_operand:SF 0 "register_operand")
14391         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
14392                    UNSPEC_RSQRT))]
14393   "TARGET_SSE_MATH"
14395   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
14396   DONE;
14399 (define_insn "*sqrt<mode>2_sse"
14400   [(set (match_operand:MODEF 0 "register_operand" "=v")
14401         (sqrt:MODEF
14402           (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
14403   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
14404   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
14405   [(set_attr "type" "sse")
14406    (set_attr "atom_sse_attr" "sqrt")
14407    (set_attr "btver2_sse_attr" "sqrt")
14408    (set_attr "prefix" "maybe_vex")
14409    (set_attr "mode" "<MODE>")
14410    (set_attr "athlon_decode" "*")
14411    (set_attr "amdfam10_decode" "*")
14412    (set_attr "bdver1_decode" "*")])
14414 (define_expand "sqrt<mode>2"
14415   [(set (match_operand:MODEF 0 "register_operand")
14416         (sqrt:MODEF
14417           (match_operand:MODEF 1 "nonimmediate_operand")))]
14418   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
14419    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14421   if (<MODE>mode == SFmode
14422       && TARGET_SSE_MATH
14423       && TARGET_RECIP_SQRT
14424       && !optimize_function_for_size_p (cfun)
14425       && flag_finite_math_only && !flag_trapping_math
14426       && flag_unsafe_math_optimizations)
14427     {
14428       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
14429       DONE;
14430     }
14432   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
14433     {
14434       rtx op0 = gen_reg_rtx (XFmode);
14435       rtx op1 = force_reg (<MODE>mode, operands[1]);
14437       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
14438       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
14439       DONE;
14440    }
14443 (define_insn "fpremxf4_i387"
14444   [(set (match_operand:XF 0 "register_operand" "=f")
14445         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14446                     (match_operand:XF 3 "register_operand" "1")]
14447                    UNSPEC_FPREM_F))
14448    (set (match_operand:XF 1 "register_operand" "=u")
14449         (unspec:XF [(match_dup 2) (match_dup 3)]
14450                    UNSPEC_FPREM_U))
14451    (set (reg:CCFP FPSR_REG)
14452         (unspec:CCFP [(match_dup 2) (match_dup 3)]
14453                      UNSPEC_C2_FLAG))]
14454   "TARGET_USE_FANCY_MATH_387
14455    && flag_finite_math_only"
14456   "fprem"
14457   [(set_attr "type" "fpspc")
14458    (set_attr "znver1_decode" "vector")
14459    (set_attr "mode" "XF")])
14461 (define_expand "fmodxf3"
14462   [(use (match_operand:XF 0 "register_operand"))
14463    (use (match_operand:XF 1 "general_operand"))
14464    (use (match_operand:XF 2 "general_operand"))]
14465   "TARGET_USE_FANCY_MATH_387
14466    && flag_finite_math_only"
14468   rtx_code_label *label = gen_label_rtx ();
14470   rtx op1 = gen_reg_rtx (XFmode);
14471   rtx op2 = gen_reg_rtx (XFmode);
14473   emit_move_insn (op2, operands[2]);
14474   emit_move_insn (op1, operands[1]);
14476   emit_label (label);
14477   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14478   ix86_emit_fp_unordered_jump (label);
14479   LABEL_NUSES (label) = 1;
14481   emit_move_insn (operands[0], op1);
14482   DONE;
14485 (define_expand "fmod<mode>3"
14486   [(use (match_operand:MODEF 0 "register_operand"))
14487    (use (match_operand:MODEF 1 "general_operand"))
14488    (use (match_operand:MODEF 2 "general_operand"))]
14489   "TARGET_USE_FANCY_MATH_387
14490    && flag_finite_math_only"
14492   rtx (*gen_truncxf) (rtx, rtx);
14494   rtx_code_label *label = gen_label_rtx ();
14496   rtx op1 = gen_reg_rtx (XFmode);
14497   rtx op2 = gen_reg_rtx (XFmode);
14499   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14500   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14502   emit_label (label);
14503   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14504   ix86_emit_fp_unordered_jump (label);
14505   LABEL_NUSES (label) = 1;
14507   /* Truncate the result properly for strict SSE math.  */
14508   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14509       && !TARGET_MIX_SSE_I387)
14510     gen_truncxf = gen_truncxf<mode>2;
14511   else
14512     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14514   emit_insn (gen_truncxf (operands[0], op1));
14515   DONE;
14518 (define_insn "fprem1xf4_i387"
14519   [(set (match_operand:XF 0 "register_operand" "=f")
14520         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14521                     (match_operand:XF 3 "register_operand" "1")]
14522                    UNSPEC_FPREM1_F))
14523    (set (match_operand:XF 1 "register_operand" "=u")
14524         (unspec:XF [(match_dup 2) (match_dup 3)]
14525                    UNSPEC_FPREM1_U))
14526    (set (reg:CCFP FPSR_REG)
14527         (unspec:CCFP [(match_dup 2) (match_dup 3)]
14528                      UNSPEC_C2_FLAG))]
14529   "TARGET_USE_FANCY_MATH_387
14530    && flag_finite_math_only"
14531   "fprem1"
14532   [(set_attr "type" "fpspc")
14533    (set_attr "znver1_decode" "vector")
14534    (set_attr "mode" "XF")])
14536 (define_expand "remainderxf3"
14537   [(use (match_operand:XF 0 "register_operand"))
14538    (use (match_operand:XF 1 "general_operand"))
14539    (use (match_operand:XF 2 "general_operand"))]
14540   "TARGET_USE_FANCY_MATH_387
14541    && flag_finite_math_only"
14543   rtx_code_label *label = gen_label_rtx ();
14545   rtx op1 = gen_reg_rtx (XFmode);
14546   rtx op2 = gen_reg_rtx (XFmode);
14548   emit_move_insn (op2, operands[2]);
14549   emit_move_insn (op1, operands[1]);
14551   emit_label (label);
14552   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14553   ix86_emit_fp_unordered_jump (label);
14554   LABEL_NUSES (label) = 1;
14556   emit_move_insn (operands[0], op1);
14557   DONE;
14560 (define_expand "remainder<mode>3"
14561   [(use (match_operand:MODEF 0 "register_operand"))
14562    (use (match_operand:MODEF 1 "general_operand"))
14563    (use (match_operand:MODEF 2 "general_operand"))]
14564   "TARGET_USE_FANCY_MATH_387
14565    && flag_finite_math_only"
14567   rtx (*gen_truncxf) (rtx, rtx);
14569   rtx_code_label *label = gen_label_rtx ();
14571   rtx op1 = gen_reg_rtx (XFmode);
14572   rtx op2 = gen_reg_rtx (XFmode);
14574   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14575   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14577   emit_label (label);
14579   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14580   ix86_emit_fp_unordered_jump (label);
14581   LABEL_NUSES (label) = 1;
14583   /* Truncate the result properly for strict SSE math.  */
14584   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14585       && !TARGET_MIX_SSE_I387)
14586     gen_truncxf = gen_truncxf<mode>2;
14587   else
14588     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14590   emit_insn (gen_truncxf (operands[0], op1));
14591   DONE;
14594 (define_int_iterator SINCOS
14595         [UNSPEC_SIN
14596          UNSPEC_COS])
14598 (define_int_attr sincos
14599         [(UNSPEC_SIN "sin")
14600          (UNSPEC_COS "cos")])
14602 (define_insn "*<sincos>xf2_i387"
14603   [(set (match_operand:XF 0 "register_operand" "=f")
14604         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14605                    SINCOS))]
14606   "TARGET_USE_FANCY_MATH_387
14607    && flag_unsafe_math_optimizations"
14608   "f<sincos>"
14609   [(set_attr "type" "fpspc")
14610    (set_attr "znver1_decode" "vector")
14611    (set_attr "mode" "XF")])
14613 (define_insn "*<sincos>_extend<mode>xf2_i387"
14614   [(set (match_operand:XF 0 "register_operand" "=f")
14615         (unspec:XF [(float_extend:XF
14616                       (match_operand:MODEF 1 "register_operand" "0"))]
14617                    SINCOS))]
14618   "TARGET_USE_FANCY_MATH_387
14619    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14620        || TARGET_MIX_SSE_I387)
14621    && flag_unsafe_math_optimizations"
14622   "f<sincos>"
14623   [(set_attr "type" "fpspc")
14624    (set_attr "znver1_decode" "vector")
14625    (set_attr "mode" "XF")])
14627 ;; When sincos pattern is defined, sin and cos builtin functions will be
14628 ;; expanded to sincos pattern with one of its outputs left unused.
14629 ;; CSE pass will figure out if two sincos patterns can be combined,
14630 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14631 ;; depending on the unused output.
14633 (define_insn "sincosxf3"
14634   [(set (match_operand:XF 0 "register_operand" "=f")
14635         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14636                    UNSPEC_SINCOS_COS))
14637    (set (match_operand:XF 1 "register_operand" "=u")
14638         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14639   "TARGET_USE_FANCY_MATH_387
14640    && flag_unsafe_math_optimizations"
14641   "fsincos"
14642   [(set_attr "type" "fpspc")
14643    (set_attr "znver1_decode" "vector")
14644    (set_attr "mode" "XF")])
14646 (define_split
14647   [(set (match_operand:XF 0 "register_operand")
14648         (unspec:XF [(match_operand:XF 2 "register_operand")]
14649                    UNSPEC_SINCOS_COS))
14650    (set (match_operand:XF 1 "register_operand")
14651         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14652   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14653    && can_create_pseudo_p ()"
14654   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
14656 (define_split
14657   [(set (match_operand:XF 0 "register_operand")
14658         (unspec:XF [(match_operand:XF 2 "register_operand")]
14659                    UNSPEC_SINCOS_COS))
14660    (set (match_operand:XF 1 "register_operand")
14661         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14662   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14663    && can_create_pseudo_p ()"
14664   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
14666 (define_insn "sincos_extend<mode>xf3_i387"
14667   [(set (match_operand:XF 0 "register_operand" "=f")
14668         (unspec:XF [(float_extend:XF
14669                       (match_operand:MODEF 2 "register_operand" "0"))]
14670                    UNSPEC_SINCOS_COS))
14671    (set (match_operand:XF 1 "register_operand" "=u")
14672         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14673   "TARGET_USE_FANCY_MATH_387
14674    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14675        || TARGET_MIX_SSE_I387)
14676    && flag_unsafe_math_optimizations"
14677   "fsincos"
14678   [(set_attr "type" "fpspc")
14679    (set_attr "znver1_decode" "vector")
14680    (set_attr "mode" "XF")])
14682 (define_split
14683   [(set (match_operand:XF 0 "register_operand")
14684         (unspec:XF [(float_extend:XF
14685                       (match_operand:MODEF 2 "register_operand"))]
14686                    UNSPEC_SINCOS_COS))
14687    (set (match_operand:XF 1 "register_operand")
14688         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14689   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14690    && can_create_pseudo_p ()"
14691   [(set (match_dup 1)
14692         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14694 (define_split
14695   [(set (match_operand:XF 0 "register_operand")
14696         (unspec:XF [(float_extend:XF
14697                       (match_operand:MODEF 2 "register_operand"))]
14698                    UNSPEC_SINCOS_COS))
14699    (set (match_operand:XF 1 "register_operand")
14700         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14701   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14702    && can_create_pseudo_p ()"
14703   [(set (match_dup 0)
14704         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14706 (define_expand "sincos<mode>3"
14707   [(use (match_operand:MODEF 0 "register_operand"))
14708    (use (match_operand:MODEF 1 "register_operand"))
14709    (use (match_operand:MODEF 2 "register_operand"))]
14710   "TARGET_USE_FANCY_MATH_387
14711    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14712        || TARGET_MIX_SSE_I387)
14713    && flag_unsafe_math_optimizations"
14715   rtx op0 = gen_reg_rtx (XFmode);
14716   rtx op1 = gen_reg_rtx (XFmode);
14718   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14719   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14720   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14721   DONE;
14724 (define_insn "fptanxf4_i387"
14725   [(set (match_operand:XF 0 "register_operand" "=f")
14726         (match_operand:XF 3 "const_double_operand" "F"))
14727    (set (match_operand:XF 1 "register_operand" "=u")
14728         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14729                    UNSPEC_TAN))]
14730   "TARGET_USE_FANCY_MATH_387
14731    && flag_unsafe_math_optimizations
14732    && standard_80387_constant_p (operands[3]) == 2"
14733   "fptan"
14734   [(set_attr "type" "fpspc")
14735    (set_attr "znver1_decode" "vector")
14736    (set_attr "mode" "XF")])
14738 (define_insn "fptan_extend<mode>xf4_i387"
14739   [(set (match_operand:MODEF 0 "register_operand" "=f")
14740         (match_operand:MODEF 3 "const_double_operand" "F"))
14741    (set (match_operand:XF 1 "register_operand" "=u")
14742         (unspec:XF [(float_extend:XF
14743                       (match_operand:MODEF 2 "register_operand" "0"))]
14744                    UNSPEC_TAN))]
14745   "TARGET_USE_FANCY_MATH_387
14746    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14747        || TARGET_MIX_SSE_I387)
14748    && flag_unsafe_math_optimizations
14749    && standard_80387_constant_p (operands[3]) == 2"
14750   "fptan"
14751   [(set_attr "type" "fpspc")
14752    (set_attr "znver1_decode" "vector")
14753    (set_attr "mode" "XF")])
14755 (define_expand "tanxf2"
14756   [(use (match_operand:XF 0 "register_operand"))
14757    (use (match_operand:XF 1 "register_operand"))]
14758   "TARGET_USE_FANCY_MATH_387
14759    && flag_unsafe_math_optimizations"
14761   rtx one = gen_reg_rtx (XFmode);
14762   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14764   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14765   DONE;
14768 (define_expand "tan<mode>2"
14769   [(use (match_operand:MODEF 0 "register_operand"))
14770    (use (match_operand:MODEF 1 "register_operand"))]
14771   "TARGET_USE_FANCY_MATH_387
14772    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14773        || TARGET_MIX_SSE_I387)
14774    && flag_unsafe_math_optimizations"
14776   rtx op0 = gen_reg_rtx (XFmode);
14778   rtx one = gen_reg_rtx (<MODE>mode);
14779   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14781   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14782                                              operands[1], op2));
14783   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14784   DONE;
14787 (define_insn "*fpatanxf3_i387"
14788   [(set (match_operand:XF 0 "register_operand" "=f")
14789         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14790                     (match_operand:XF 2 "register_operand" "u")]
14791                    UNSPEC_FPATAN))
14792    (clobber (match_scratch:XF 3 "=2"))]
14793   "TARGET_USE_FANCY_MATH_387
14794    && flag_unsafe_math_optimizations"
14795   "fpatan"
14796   [(set_attr "type" "fpspc")
14797    (set_attr "znver1_decode" "vector")
14798    (set_attr "mode" "XF")])
14800 (define_insn "fpatan_extend<mode>xf3_i387"
14801   [(set (match_operand:XF 0 "register_operand" "=f")
14802         (unspec:XF [(float_extend:XF
14803                       (match_operand:MODEF 1 "register_operand" "0"))
14804                     (float_extend:XF
14805                       (match_operand:MODEF 2 "register_operand" "u"))]
14806                    UNSPEC_FPATAN))
14807    (clobber (match_scratch:XF 3 "=2"))]
14808   "TARGET_USE_FANCY_MATH_387
14809    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14810        || TARGET_MIX_SSE_I387)
14811    && flag_unsafe_math_optimizations"
14812   "fpatan"
14813   [(set_attr "type" "fpspc")
14814    (set_attr "znver1_decode" "vector")
14815    (set_attr "mode" "XF")])
14817 (define_expand "atan2xf3"
14818   [(parallel [(set (match_operand:XF 0 "register_operand")
14819                    (unspec:XF [(match_operand:XF 2 "register_operand")
14820                                (match_operand:XF 1 "register_operand")]
14821                               UNSPEC_FPATAN))
14822               (clobber (match_scratch:XF 3))])]
14823   "TARGET_USE_FANCY_MATH_387
14824    && flag_unsafe_math_optimizations")
14826 (define_expand "atan2<mode>3"
14827   [(use (match_operand:MODEF 0 "register_operand"))
14828    (use (match_operand:MODEF 1 "register_operand"))
14829    (use (match_operand:MODEF 2 "register_operand"))]
14830   "TARGET_USE_FANCY_MATH_387
14831    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14832        || TARGET_MIX_SSE_I387)
14833    && flag_unsafe_math_optimizations"
14835   rtx op0 = gen_reg_rtx (XFmode);
14837   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14838   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14839   DONE;
14842 (define_expand "atanxf2"
14843   [(parallel [(set (match_operand:XF 0 "register_operand")
14844                    (unspec:XF [(match_dup 2)
14845                                (match_operand:XF 1 "register_operand")]
14846                               UNSPEC_FPATAN))
14847               (clobber (match_scratch:XF 3))])]
14848   "TARGET_USE_FANCY_MATH_387
14849    && flag_unsafe_math_optimizations"
14851   operands[2] = gen_reg_rtx (XFmode);
14852   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
14855 (define_expand "atan<mode>2"
14856   [(use (match_operand:MODEF 0 "register_operand"))
14857    (use (match_operand:MODEF 1 "register_operand"))]
14858   "TARGET_USE_FANCY_MATH_387
14859    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14860        || TARGET_MIX_SSE_I387)
14861    && flag_unsafe_math_optimizations"
14863   rtx op0 = gen_reg_rtx (XFmode);
14865   rtx op2 = gen_reg_rtx (<MODE>mode);
14866   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
14868   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14869   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14870   DONE;
14873 (define_expand "asinxf2"
14874   [(set (match_dup 2)
14875         (mult:XF (match_operand:XF 1 "register_operand")
14876                  (match_dup 1)))
14877    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14878    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14879    (parallel [(set (match_operand:XF 0 "register_operand")
14880                    (unspec:XF [(match_dup 5) (match_dup 1)]
14881                               UNSPEC_FPATAN))
14882               (clobber (match_scratch:XF 6))])]
14883   "TARGET_USE_FANCY_MATH_387
14884    && flag_unsafe_math_optimizations"
14886   int i;
14888   for (i = 2; i < 6; i++)
14889     operands[i] = gen_reg_rtx (XFmode);
14891   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14894 (define_expand "asin<mode>2"
14895   [(use (match_operand:MODEF 0 "register_operand"))
14896    (use (match_operand:MODEF 1 "general_operand"))]
14897  "TARGET_USE_FANCY_MATH_387
14898    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14899        || TARGET_MIX_SSE_I387)
14900    && flag_unsafe_math_optimizations"
14902   rtx op0 = gen_reg_rtx (XFmode);
14903   rtx op1 = gen_reg_rtx (XFmode);
14905   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14906   emit_insn (gen_asinxf2 (op0, op1));
14907   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14908   DONE;
14911 (define_expand "acosxf2"
14912   [(set (match_dup 2)
14913         (mult:XF (match_operand:XF 1 "register_operand")
14914                  (match_dup 1)))
14915    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14916    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14917    (parallel [(set (match_operand:XF 0 "register_operand")
14918                    (unspec:XF [(match_dup 1) (match_dup 5)]
14919                               UNSPEC_FPATAN))
14920               (clobber (match_scratch:XF 6))])]
14921   "TARGET_USE_FANCY_MATH_387
14922    && flag_unsafe_math_optimizations"
14924   int i;
14926   for (i = 2; i < 6; i++)
14927     operands[i] = gen_reg_rtx (XFmode);
14929   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14932 (define_expand "acos<mode>2"
14933   [(use (match_operand:MODEF 0 "register_operand"))
14934    (use (match_operand:MODEF 1 "general_operand"))]
14935  "TARGET_USE_FANCY_MATH_387
14936    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14937        || TARGET_MIX_SSE_I387)
14938    && flag_unsafe_math_optimizations"
14940   rtx op0 = gen_reg_rtx (XFmode);
14941   rtx op1 = gen_reg_rtx (XFmode);
14943   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14944   emit_insn (gen_acosxf2 (op0, op1));
14945   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14946   DONE;
14949 (define_insn "fyl2xxf3_i387"
14950   [(set (match_operand:XF 0 "register_operand" "=f")
14951         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14952                     (match_operand:XF 2 "register_operand" "u")]
14953                    UNSPEC_FYL2X))
14954    (clobber (match_scratch:XF 3 "=2"))]
14955   "TARGET_USE_FANCY_MATH_387
14956    && flag_unsafe_math_optimizations"
14957   "fyl2x"
14958   [(set_attr "type" "fpspc")
14959    (set_attr "znver1_decode" "vector")
14960    (set_attr "mode" "XF")])
14962 (define_insn "fyl2x_extend<mode>xf3_i387"
14963   [(set (match_operand:XF 0 "register_operand" "=f")
14964         (unspec:XF [(float_extend:XF
14965                       (match_operand:MODEF 1 "register_operand" "0"))
14966                     (match_operand:XF 2 "register_operand" "u")]
14967                    UNSPEC_FYL2X))
14968    (clobber (match_scratch:XF 3 "=2"))]
14969   "TARGET_USE_FANCY_MATH_387
14970    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14971        || TARGET_MIX_SSE_I387)
14972    && flag_unsafe_math_optimizations"
14973   "fyl2x"
14974   [(set_attr "type" "fpspc")
14975    (set_attr "znver1_decode" "vector")
14976    (set_attr "mode" "XF")])
14978 (define_expand "logxf2"
14979   [(parallel [(set (match_operand:XF 0 "register_operand")
14980                    (unspec:XF [(match_operand:XF 1 "register_operand")
14981                                (match_dup 2)] UNSPEC_FYL2X))
14982               (clobber (match_scratch:XF 3))])]
14983   "TARGET_USE_FANCY_MATH_387
14984    && flag_unsafe_math_optimizations"
14986   operands[2] = gen_reg_rtx (XFmode);
14987   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14990 (define_expand "log<mode>2"
14991   [(use (match_operand:MODEF 0 "register_operand"))
14992    (use (match_operand:MODEF 1 "register_operand"))]
14993   "TARGET_USE_FANCY_MATH_387
14994    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14995        || TARGET_MIX_SSE_I387)
14996    && flag_unsafe_math_optimizations"
14998   rtx op0 = gen_reg_rtx (XFmode);
15000   rtx op2 = gen_reg_rtx (XFmode);
15001   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
15003   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15004   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15005   DONE;
15008 (define_expand "log10xf2"
15009   [(parallel [(set (match_operand:XF 0 "register_operand")
15010                    (unspec:XF [(match_operand:XF 1 "register_operand")
15011                                (match_dup 2)] UNSPEC_FYL2X))
15012               (clobber (match_scratch:XF 3))])]
15013   "TARGET_USE_FANCY_MATH_387
15014    && flag_unsafe_math_optimizations"
15016   operands[2] = gen_reg_rtx (XFmode);
15017   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
15020 (define_expand "log10<mode>2"
15021   [(use (match_operand:MODEF 0 "register_operand"))
15022    (use (match_operand:MODEF 1 "register_operand"))]
15023   "TARGET_USE_FANCY_MATH_387
15024    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15025        || TARGET_MIX_SSE_I387)
15026    && flag_unsafe_math_optimizations"
15028   rtx op0 = gen_reg_rtx (XFmode);
15030   rtx op2 = gen_reg_rtx (XFmode);
15031   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
15033   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15034   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15035   DONE;
15038 (define_expand "log2xf2"
15039   [(parallel [(set (match_operand:XF 0 "register_operand")
15040                    (unspec:XF [(match_operand:XF 1 "register_operand")
15041                                (match_dup 2)] UNSPEC_FYL2X))
15042               (clobber (match_scratch:XF 3))])]
15043   "TARGET_USE_FANCY_MATH_387
15044    && flag_unsafe_math_optimizations"
15046   operands[2] = gen_reg_rtx (XFmode);
15047   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15050 (define_expand "log2<mode>2"
15051   [(use (match_operand:MODEF 0 "register_operand"))
15052    (use (match_operand:MODEF 1 "register_operand"))]
15053   "TARGET_USE_FANCY_MATH_387
15054    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15055        || TARGET_MIX_SSE_I387)
15056    && flag_unsafe_math_optimizations"
15058   rtx op0 = gen_reg_rtx (XFmode);
15060   rtx op2 = gen_reg_rtx (XFmode);
15061   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
15063   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15064   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15065   DONE;
15068 (define_insn "fyl2xp1xf3_i387"
15069   [(set (match_operand:XF 0 "register_operand" "=f")
15070         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15071                     (match_operand:XF 2 "register_operand" "u")]
15072                    UNSPEC_FYL2XP1))
15073    (clobber (match_scratch:XF 3 "=2"))]
15074   "TARGET_USE_FANCY_MATH_387
15075    && flag_unsafe_math_optimizations"
15076   "fyl2xp1"
15077   [(set_attr "type" "fpspc")
15078    (set_attr "znver1_decode" "vector")
15079    (set_attr "mode" "XF")])
15081 (define_insn "fyl2xp1_extend<mode>xf3_i387"
15082   [(set (match_operand:XF 0 "register_operand" "=f")
15083         (unspec:XF [(float_extend:XF
15084                       (match_operand:MODEF 1 "register_operand" "0"))
15085                     (match_operand:XF 2 "register_operand" "u")]
15086                    UNSPEC_FYL2XP1))
15087    (clobber (match_scratch:XF 3 "=2"))]
15088   "TARGET_USE_FANCY_MATH_387
15089    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15090        || TARGET_MIX_SSE_I387)
15091    && flag_unsafe_math_optimizations"
15092   "fyl2xp1"
15093   [(set_attr "type" "fpspc")
15094    (set_attr "znver1_decode" "vector")
15095    (set_attr "mode" "XF")])
15097 (define_expand "log1pxf2"
15098   [(use (match_operand:XF 0 "register_operand"))
15099    (use (match_operand:XF 1 "register_operand"))]
15100   "TARGET_USE_FANCY_MATH_387
15101    && flag_unsafe_math_optimizations"
15103   ix86_emit_i387_log1p (operands[0], operands[1]);
15104   DONE;
15107 (define_expand "log1p<mode>2"
15108   [(use (match_operand:MODEF 0 "register_operand"))
15109    (use (match_operand:MODEF 1 "register_operand"))]
15110   "TARGET_USE_FANCY_MATH_387
15111    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15112        || TARGET_MIX_SSE_I387)
15113    && flag_unsafe_math_optimizations"
15115   rtx op0;
15117   op0 = gen_reg_rtx (XFmode);
15119   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
15121   ix86_emit_i387_log1p (op0, operands[1]);
15122   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15123   DONE;
15126 (define_insn "fxtractxf3_i387"
15127   [(set (match_operand:XF 0 "register_operand" "=f")
15128         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15129                    UNSPEC_XTRACT_FRACT))
15130    (set (match_operand:XF 1 "register_operand" "=u")
15131         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15132   "TARGET_USE_FANCY_MATH_387
15133    && flag_unsafe_math_optimizations"
15134   "fxtract"
15135   [(set_attr "type" "fpspc")
15136    (set_attr "znver1_decode" "vector")
15137    (set_attr "mode" "XF")])
15139 (define_insn "fxtract_extend<mode>xf3_i387"
15140   [(set (match_operand:XF 0 "register_operand" "=f")
15141         (unspec:XF [(float_extend:XF
15142                       (match_operand:MODEF 2 "register_operand" "0"))]
15143                    UNSPEC_XTRACT_FRACT))
15144    (set (match_operand:XF 1 "register_operand" "=u")
15145         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
15146   "TARGET_USE_FANCY_MATH_387
15147    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15148        || TARGET_MIX_SSE_I387)
15149    && flag_unsafe_math_optimizations"
15150   "fxtract"
15151   [(set_attr "type" "fpspc")
15152    (set_attr "znver1_decode" "vector")
15153    (set_attr "mode" "XF")])
15155 (define_expand "logbxf2"
15156   [(parallel [(set (match_dup 2)
15157                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15158                               UNSPEC_XTRACT_FRACT))
15159               (set (match_operand:XF 0 "register_operand")
15160                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15161   "TARGET_USE_FANCY_MATH_387
15162    && flag_unsafe_math_optimizations"
15163   "operands[2] = gen_reg_rtx (XFmode);")
15165 (define_expand "logb<mode>2"
15166   [(use (match_operand:MODEF 0 "register_operand"))
15167    (use (match_operand:MODEF 1 "register_operand"))]
15168   "TARGET_USE_FANCY_MATH_387
15169    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15170        || TARGET_MIX_SSE_I387)
15171    && flag_unsafe_math_optimizations"
15173   rtx op0 = gen_reg_rtx (XFmode);
15174   rtx op1 = gen_reg_rtx (XFmode);
15176   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15177   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
15178   DONE;
15181 (define_expand "ilogbxf2"
15182   [(use (match_operand:SI 0 "register_operand"))
15183    (use (match_operand:XF 1 "register_operand"))]
15184   "TARGET_USE_FANCY_MATH_387
15185    && flag_unsafe_math_optimizations"
15187   rtx op0, op1;
15189   if (optimize_insn_for_size_p ())
15190     FAIL;
15192   op0 = gen_reg_rtx (XFmode);
15193   op1 = gen_reg_rtx (XFmode);
15195   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
15196   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15197   DONE;
15200 (define_expand "ilogb<mode>2"
15201   [(use (match_operand:SI 0 "register_operand"))
15202    (use (match_operand:MODEF 1 "register_operand"))]
15203   "TARGET_USE_FANCY_MATH_387
15204    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15205        || TARGET_MIX_SSE_I387)
15206    && flag_unsafe_math_optimizations"
15208   rtx op0, op1;
15210   if (optimize_insn_for_size_p ())
15211     FAIL;
15213   op0 = gen_reg_rtx (XFmode);
15214   op1 = gen_reg_rtx (XFmode);
15216   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15217   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15218   DONE;
15221 (define_insn "*f2xm1xf2_i387"
15222   [(set (match_operand:XF 0 "register_operand" "=f")
15223         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15224                    UNSPEC_F2XM1))]
15225   "TARGET_USE_FANCY_MATH_387
15226    && flag_unsafe_math_optimizations"
15227   "f2xm1"
15228   [(set_attr "type" "fpspc")
15229    (set_attr "znver1_decode" "vector")
15230    (set_attr "mode" "XF")])
15232 (define_insn "fscalexf4_i387"
15233   [(set (match_operand:XF 0 "register_operand" "=f")
15234         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15235                     (match_operand:XF 3 "register_operand" "1")]
15236                    UNSPEC_FSCALE_FRACT))
15237    (set (match_operand:XF 1 "register_operand" "=u")
15238         (unspec:XF [(match_dup 2) (match_dup 3)]
15239                    UNSPEC_FSCALE_EXP))]
15240   "TARGET_USE_FANCY_MATH_387
15241    && flag_unsafe_math_optimizations"
15242   "fscale"
15243   [(set_attr "type" "fpspc")
15244    (set_attr "znver1_decode" "vector")
15245    (set_attr "mode" "XF")])
15247 (define_expand "expNcorexf3"
15248   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15249                                (match_operand:XF 2 "register_operand")))
15250    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15251    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15252    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15253    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15254    (parallel [(set (match_operand:XF 0 "register_operand")
15255                    (unspec:XF [(match_dup 8) (match_dup 4)]
15256                               UNSPEC_FSCALE_FRACT))
15257               (set (match_dup 9)
15258                    (unspec:XF [(match_dup 8) (match_dup 4)]
15259                               UNSPEC_FSCALE_EXP))])]
15260   "TARGET_USE_FANCY_MATH_387
15261    && flag_unsafe_math_optimizations"
15263   int i;
15265   for (i = 3; i < 10; i++)
15266     operands[i] = gen_reg_rtx (XFmode);
15268   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15271 (define_expand "expxf2"
15272   [(use (match_operand:XF 0 "register_operand"))
15273    (use (match_operand:XF 1 "register_operand"))]
15274   "TARGET_USE_FANCY_MATH_387
15275    && flag_unsafe_math_optimizations"
15277   rtx op2;
15279   op2 = gen_reg_rtx (XFmode);
15280   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
15282   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15283   DONE;
15286 (define_expand "exp<mode>2"
15287   [(use (match_operand:MODEF 0 "register_operand"))
15288    (use (match_operand:MODEF 1 "general_operand"))]
15289  "TARGET_USE_FANCY_MATH_387
15290    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15291        || TARGET_MIX_SSE_I387)
15292    && flag_unsafe_math_optimizations"
15294   rtx op0, op1;
15296   op0 = gen_reg_rtx (XFmode);
15297   op1 = gen_reg_rtx (XFmode);
15299   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15300   emit_insn (gen_expxf2 (op0, op1));
15301   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15302   DONE;
15305 (define_expand "exp10xf2"
15306   [(use (match_operand:XF 0 "register_operand"))
15307    (use (match_operand:XF 1 "register_operand"))]
15308   "TARGET_USE_FANCY_MATH_387
15309    && flag_unsafe_math_optimizations"
15311   rtx op2;
15313   op2 = gen_reg_rtx (XFmode);
15314   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
15316   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15317   DONE;
15320 (define_expand "exp10<mode>2"
15321   [(use (match_operand:MODEF 0 "register_operand"))
15322    (use (match_operand:MODEF 1 "general_operand"))]
15323  "TARGET_USE_FANCY_MATH_387
15324    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15325        || TARGET_MIX_SSE_I387)
15326    && flag_unsafe_math_optimizations"
15328   rtx op0, op1;
15330   op0 = gen_reg_rtx (XFmode);
15331   op1 = gen_reg_rtx (XFmode);
15333   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15334   emit_insn (gen_exp10xf2 (op0, op1));
15335   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15336   DONE;
15339 (define_expand "exp2xf2"
15340   [(use (match_operand:XF 0 "register_operand"))
15341    (use (match_operand:XF 1 "register_operand"))]
15342   "TARGET_USE_FANCY_MATH_387
15343    && flag_unsafe_math_optimizations"
15345   rtx op2;
15347   op2 = gen_reg_rtx (XFmode);
15348   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
15350   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15351   DONE;
15354 (define_expand "exp2<mode>2"
15355   [(use (match_operand:MODEF 0 "register_operand"))
15356    (use (match_operand:MODEF 1 "general_operand"))]
15357  "TARGET_USE_FANCY_MATH_387
15358    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15359        || TARGET_MIX_SSE_I387)
15360    && flag_unsafe_math_optimizations"
15362   rtx op0, op1;
15364   op0 = gen_reg_rtx (XFmode);
15365   op1 = gen_reg_rtx (XFmode);
15367   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15368   emit_insn (gen_exp2xf2 (op0, op1));
15369   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15370   DONE;
15373 (define_expand "expm1xf2"
15374   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15375                                (match_dup 2)))
15376    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15377    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15378    (set (match_dup 9) (float_extend:XF (match_dup 13)))
15379    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15380    (parallel [(set (match_dup 7)
15381                    (unspec:XF [(match_dup 6) (match_dup 4)]
15382                               UNSPEC_FSCALE_FRACT))
15383               (set (match_dup 8)
15384                    (unspec:XF [(match_dup 6) (match_dup 4)]
15385                               UNSPEC_FSCALE_EXP))])
15386    (parallel [(set (match_dup 10)
15387                    (unspec:XF [(match_dup 9) (match_dup 8)]
15388                               UNSPEC_FSCALE_FRACT))
15389               (set (match_dup 11)
15390                    (unspec:XF [(match_dup 9) (match_dup 8)]
15391                               UNSPEC_FSCALE_EXP))])
15392    (set (match_dup 12) (minus:XF (match_dup 10)
15393                                  (float_extend:XF (match_dup 13))))
15394    (set (match_operand:XF 0 "register_operand")
15395         (plus:XF (match_dup 12) (match_dup 7)))]
15396   "TARGET_USE_FANCY_MATH_387
15397    && flag_unsafe_math_optimizations"
15399   int i;
15401   for (i = 2; i < 13; i++)
15402     operands[i] = gen_reg_rtx (XFmode);
15404   operands[13]
15405     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
15407   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
15410 (define_expand "expm1<mode>2"
15411   [(use (match_operand:MODEF 0 "register_operand"))
15412    (use (match_operand:MODEF 1 "general_operand"))]
15413  "TARGET_USE_FANCY_MATH_387
15414    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15415        || TARGET_MIX_SSE_I387)
15416    && flag_unsafe_math_optimizations"
15418   rtx op0, op1;
15420   op0 = gen_reg_rtx (XFmode);
15421   op1 = gen_reg_rtx (XFmode);
15423   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15424   emit_insn (gen_expm1xf2 (op0, op1));
15425   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15426   DONE;
15429 (define_expand "ldexpxf3"
15430   [(match_operand:XF 0 "register_operand")
15431    (match_operand:XF 1 "register_operand")
15432    (match_operand:SI 2 "register_operand")]
15433   "TARGET_USE_FANCY_MATH_387
15434    && flag_unsafe_math_optimizations"
15436   rtx tmp1, tmp2;
15438   tmp1 = gen_reg_rtx (XFmode);
15439   tmp2 = gen_reg_rtx (XFmode);
15441   emit_insn (gen_floatsixf2 (tmp1, operands[2]));
15442   emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
15443                                  operands[1], tmp1));
15444   DONE;
15447 (define_expand "ldexp<mode>3"
15448   [(use (match_operand:MODEF 0 "register_operand"))
15449    (use (match_operand:MODEF 1 "general_operand"))
15450    (use (match_operand:SI 2 "register_operand"))]
15451  "TARGET_USE_FANCY_MATH_387
15452    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15453        || TARGET_MIX_SSE_I387)
15454    && flag_unsafe_math_optimizations"
15456   rtx op0, op1;
15458   op0 = gen_reg_rtx (XFmode);
15459   op1 = gen_reg_rtx (XFmode);
15461   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15462   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
15463   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15464   DONE;
15467 (define_expand "scalbxf3"
15468   [(parallel [(set (match_operand:XF 0 " register_operand")
15469                    (unspec:XF [(match_operand:XF 1 "register_operand")
15470                                (match_operand:XF 2 "register_operand")]
15471                               UNSPEC_FSCALE_FRACT))
15472               (set (match_dup 3)
15473                    (unspec:XF [(match_dup 1) (match_dup 2)]
15474                               UNSPEC_FSCALE_EXP))])]
15475   "TARGET_USE_FANCY_MATH_387
15476    && flag_unsafe_math_optimizations"
15478   operands[3] = gen_reg_rtx (XFmode);
15481 (define_expand "scalb<mode>3"
15482   [(use (match_operand:MODEF 0 "register_operand"))
15483    (use (match_operand:MODEF 1 "general_operand"))
15484    (use (match_operand:MODEF 2 "general_operand"))]
15485  "TARGET_USE_FANCY_MATH_387
15486    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15487        || TARGET_MIX_SSE_I387)
15488    && flag_unsafe_math_optimizations"
15490   rtx op0, op1, op2;
15492   op0 = gen_reg_rtx (XFmode);
15493   op1 = gen_reg_rtx (XFmode);
15494   op2 = gen_reg_rtx (XFmode);
15496   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15497   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15498   emit_insn (gen_scalbxf3 (op0, op1, op2));
15499   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15500   DONE;
15503 (define_expand "significandxf2"
15504   [(parallel [(set (match_operand:XF 0 "register_operand")
15505                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15506                               UNSPEC_XTRACT_FRACT))
15507               (set (match_dup 2)
15508                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15509   "TARGET_USE_FANCY_MATH_387
15510    && flag_unsafe_math_optimizations"
15511   "operands[2] = gen_reg_rtx (XFmode);")
15513 (define_expand "significand<mode>2"
15514   [(use (match_operand:MODEF 0 "register_operand"))
15515    (use (match_operand:MODEF 1 "register_operand"))]
15516   "TARGET_USE_FANCY_MATH_387
15517    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15518        || TARGET_MIX_SSE_I387)
15519    && flag_unsafe_math_optimizations"
15521   rtx op0 = gen_reg_rtx (XFmode);
15522   rtx op1 = gen_reg_rtx (XFmode);
15524   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15525   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15526   DONE;
15530 (define_insn "sse4_1_round<mode>2"
15531   [(set (match_operand:MODEF 0 "register_operand" "=x")
15532         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
15533                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
15534                       UNSPEC_ROUND))]
15535   "TARGET_ROUND"
15536   "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
15537   [(set_attr "type" "ssecvt")
15538    (set_attr "prefix_extra" "1")
15539    (set_attr "prefix" "maybe_vex")
15540    (set_attr "mode" "<MODE>")])
15542 (define_insn "rintxf2"
15543   [(set (match_operand:XF 0 "register_operand" "=f")
15544         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15545                    UNSPEC_FRNDINT))]
15546   "TARGET_USE_FANCY_MATH_387
15547    && flag_unsafe_math_optimizations"
15548   "frndint"
15549   [(set_attr "type" "fpspc")
15550    (set_attr "znver1_decode" "vector")
15551    (set_attr "mode" "XF")])
15553 (define_expand "rint<mode>2"
15554   [(use (match_operand:MODEF 0 "register_operand"))
15555    (use (match_operand:MODEF 1 "register_operand"))]
15556   "(TARGET_USE_FANCY_MATH_387
15557     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15558         || TARGET_MIX_SSE_I387)
15559     && flag_unsafe_math_optimizations)
15560    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15561        && !flag_trapping_math)"
15563   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15564       && !flag_trapping_math)
15565     {
15566       if (TARGET_ROUND)
15567         emit_insn (gen_sse4_1_round<mode>2
15568                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
15569       else
15570         ix86_expand_rint (operands[0], operands[1]);
15571     }
15572   else
15573     {
15574       rtx op0 = gen_reg_rtx (XFmode);
15575       rtx op1 = gen_reg_rtx (XFmode);
15577       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15578       emit_insn (gen_rintxf2 (op0, op1));
15580       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15581     }
15582   DONE;
15585 (define_expand "round<mode>2"
15586   [(match_operand:X87MODEF 0 "register_operand")
15587    (match_operand:X87MODEF 1 "nonimmediate_operand")]
15588   "(TARGET_USE_FANCY_MATH_387
15589     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15590         || TARGET_MIX_SSE_I387)
15591     && flag_unsafe_math_optimizations)
15592    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15593        && !flag_trapping_math && !flag_rounding_math)"
15595   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15596       && !flag_trapping_math && !flag_rounding_math)
15597     {
15598       if (TARGET_ROUND)
15599         {
15600           operands[1] = force_reg (<MODE>mode, operands[1]);
15601           ix86_expand_round_sse4 (operands[0], operands[1]);
15602         }
15603       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15604         ix86_expand_round (operands[0], operands[1]);
15605       else
15606         ix86_expand_rounddf_32 (operands[0], operands[1]);
15607     }
15608   else
15609     {
15610       operands[1] = force_reg (<MODE>mode, operands[1]);
15611       ix86_emit_i387_round (operands[0], operands[1]);
15612     }
15613   DONE;
15616 (define_insn_and_split "*fistdi2_1"
15617   [(set (match_operand:DI 0 "nonimmediate_operand")
15618         (unspec:DI [(match_operand:XF 1 "register_operand")]
15619                    UNSPEC_FIST))]
15620   "TARGET_USE_FANCY_MATH_387
15621    && can_create_pseudo_p ()"
15622   "#"
15623   "&& 1"
15624   [(const_int 0)]
15626   if (memory_operand (operands[0], VOIDmode))
15627     emit_insn (gen_fistdi2 (operands[0], operands[1]));
15628   else
15629     {
15630       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15631       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15632                                          operands[2]));
15633     }
15634   DONE;
15636   [(set_attr "type" "fpspc")
15637    (set_attr "mode" "DI")])
15639 (define_insn "fistdi2"
15640   [(set (match_operand:DI 0 "memory_operand" "=m")
15641         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15642                    UNSPEC_FIST))
15643    (clobber (match_scratch:XF 2 "=&1f"))]
15644   "TARGET_USE_FANCY_MATH_387"
15645   "* return output_fix_trunc (insn, operands, false);"
15646   [(set_attr "type" "fpspc")
15647    (set_attr "mode" "DI")])
15649 (define_insn "fistdi2_with_temp"
15650   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15651         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15652                    UNSPEC_FIST))
15653    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15654    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15655   "TARGET_USE_FANCY_MATH_387"
15656   "#"
15657   [(set_attr "type" "fpspc")
15658    (set_attr "mode" "DI")])
15660 (define_split
15661   [(set (match_operand:DI 0 "register_operand")
15662         (unspec:DI [(match_operand:XF 1 "register_operand")]
15663                    UNSPEC_FIST))
15664    (clobber (match_operand:DI 2 "memory_operand"))
15665    (clobber (match_scratch 3))]
15666   "reload_completed"
15667   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15668               (clobber (match_dup 3))])
15669    (set (match_dup 0) (match_dup 2))])
15671 (define_split
15672   [(set (match_operand:DI 0 "memory_operand")
15673         (unspec:DI [(match_operand:XF 1 "register_operand")]
15674                    UNSPEC_FIST))
15675    (clobber (match_operand:DI 2 "memory_operand"))
15676    (clobber (match_scratch 3))]
15677   "reload_completed"
15678   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15679               (clobber (match_dup 3))])])
15681 (define_insn_and_split "*fist<mode>2_1"
15682   [(set (match_operand:SWI24 0 "register_operand")
15683         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15684                       UNSPEC_FIST))]
15685   "TARGET_USE_FANCY_MATH_387
15686    && can_create_pseudo_p ()"
15687   "#"
15688   "&& 1"
15689   [(const_int 0)]
15691   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15692   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15693                                         operands[2]));
15694   DONE;
15696   [(set_attr "type" "fpspc")
15697    (set_attr "mode" "<MODE>")])
15699 (define_insn "fist<mode>2"
15700   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15701         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15702                       UNSPEC_FIST))]
15703   "TARGET_USE_FANCY_MATH_387"
15704   "* return output_fix_trunc (insn, operands, false);"
15705   [(set_attr "type" "fpspc")
15706    (set_attr "mode" "<MODE>")])
15708 (define_insn "fist<mode>2_with_temp"
15709   [(set (match_operand:SWI24 0 "register_operand" "=r")
15710         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15711                       UNSPEC_FIST))
15712    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15713   "TARGET_USE_FANCY_MATH_387"
15714   "#"
15715   [(set_attr "type" "fpspc")
15716    (set_attr "mode" "<MODE>")])
15718 (define_split
15719   [(set (match_operand:SWI24 0 "register_operand")
15720         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15721                       UNSPEC_FIST))
15722    (clobber (match_operand:SWI24 2 "memory_operand"))]
15723   "reload_completed"
15724   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15725    (set (match_dup 0) (match_dup 2))])
15727 (define_split
15728   [(set (match_operand:SWI24 0 "memory_operand")
15729         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15730                       UNSPEC_FIST))
15731    (clobber (match_operand:SWI24 2 "memory_operand"))]
15732   "reload_completed"
15733   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15735 (define_expand "lrintxf<mode>2"
15736   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15737      (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15738                      UNSPEC_FIST))]
15739   "TARGET_USE_FANCY_MATH_387")
15741 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15742   [(set (match_operand:SWI48 0 "nonimmediate_operand")
15743      (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15744                    UNSPEC_FIX_NOTRUNC))]
15745   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15747 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15748   [(match_operand:SWI248x 0 "nonimmediate_operand")
15749    (match_operand:X87MODEF 1 "register_operand")]
15750   "(TARGET_USE_FANCY_MATH_387
15751     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15752         || TARGET_MIX_SSE_I387)
15753     && flag_unsafe_math_optimizations)
15754    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15755        && <SWI248x:MODE>mode != HImode 
15756        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15757        && !flag_trapping_math && !flag_rounding_math)"
15759   if (optimize_insn_for_size_p ())
15760     FAIL;
15762   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15763       && <SWI248x:MODE>mode != HImode
15764       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15765       && !flag_trapping_math && !flag_rounding_math)
15766     ix86_expand_lround (operands[0], operands[1]);
15767   else
15768     ix86_emit_i387_round (operands[0], operands[1]);
15769   DONE;
15772 (define_int_iterator FRNDINT_ROUNDING
15773         [UNSPEC_FRNDINT_FLOOR
15774          UNSPEC_FRNDINT_CEIL
15775          UNSPEC_FRNDINT_TRUNC])
15777 (define_int_iterator FIST_ROUNDING
15778         [UNSPEC_FIST_FLOOR
15779          UNSPEC_FIST_CEIL])
15781 ;; Base name for define_insn
15782 (define_int_attr rounding_insn
15783         [(UNSPEC_FRNDINT_FLOOR "floor")
15784          (UNSPEC_FRNDINT_CEIL "ceil")
15785          (UNSPEC_FRNDINT_TRUNC "btrunc")
15786          (UNSPEC_FIST_FLOOR "floor")
15787          (UNSPEC_FIST_CEIL "ceil")])
15789 (define_int_attr rounding
15790         [(UNSPEC_FRNDINT_FLOOR "floor")
15791          (UNSPEC_FRNDINT_CEIL "ceil")
15792          (UNSPEC_FRNDINT_TRUNC "trunc")
15793          (UNSPEC_FIST_FLOOR "floor")
15794          (UNSPEC_FIST_CEIL "ceil")])
15796 (define_int_attr ROUNDING
15797         [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15798          (UNSPEC_FRNDINT_CEIL "CEIL")
15799          (UNSPEC_FRNDINT_TRUNC "TRUNC")
15800          (UNSPEC_FIST_FLOOR "FLOOR")
15801          (UNSPEC_FIST_CEIL "CEIL")])
15803 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15804 (define_insn_and_split "frndintxf2_<rounding>"
15805   [(set (match_operand:XF 0 "register_operand")
15806         (unspec:XF [(match_operand:XF 1 "register_operand")]
15807                    FRNDINT_ROUNDING))
15808    (clobber (reg:CC FLAGS_REG))]
15809   "TARGET_USE_FANCY_MATH_387
15810    && flag_unsafe_math_optimizations
15811    && can_create_pseudo_p ()"
15812   "#"
15813   "&& 1"
15814   [(const_int 0)]
15816   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15818   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15819   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15821   emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15822                                              operands[2], operands[3]));
15823   DONE;
15825   [(set_attr "type" "frndint")
15826    (set_attr "i387_cw" "<rounding>")
15827    (set_attr "mode" "XF")])
15829 (define_insn "frndintxf2_<rounding>_i387"
15830   [(set (match_operand:XF 0 "register_operand" "=f")
15831         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15832                    FRNDINT_ROUNDING))
15833    (use (match_operand:HI 2 "memory_operand" "m"))
15834    (use (match_operand:HI 3 "memory_operand" "m"))]
15835   "TARGET_USE_FANCY_MATH_387
15836    && flag_unsafe_math_optimizations"
15837   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15838   [(set_attr "type" "frndint")
15839    (set_attr "i387_cw" "<rounding>")
15840    (set_attr "mode" "XF")])
15842 (define_expand "<rounding_insn>xf2"
15843   [(parallel [(set (match_operand:XF 0 "register_operand")
15844                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15845                               FRNDINT_ROUNDING))
15846               (clobber (reg:CC FLAGS_REG))])]
15847   "TARGET_USE_FANCY_MATH_387
15848    && flag_unsafe_math_optimizations")
15850 (define_expand "<rounding_insn><mode>2"
15851   [(parallel [(set (match_operand:MODEF 0 "register_operand")
15852                    (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15853                                  FRNDINT_ROUNDING))
15854               (clobber (reg:CC FLAGS_REG))])]
15855   "(TARGET_USE_FANCY_MATH_387
15856     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15857         || TARGET_MIX_SSE_I387)
15858     && flag_unsafe_math_optimizations)
15859    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15860        && !flag_trapping_math)"
15862   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15863       && !flag_trapping_math)
15864     {
15865       if (TARGET_ROUND)
15866         emit_insn (gen_sse4_1_round<mode>2
15867                    (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15868       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15869         {
15870           if (ROUND_<ROUNDING> == ROUND_FLOOR)
15871             ix86_expand_floorceil (operands[0], operands[1], true);
15872           else if (ROUND_<ROUNDING> == ROUND_CEIL)
15873             ix86_expand_floorceil (operands[0], operands[1], false);
15874           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15875             ix86_expand_trunc (operands[0], operands[1]);
15876           else
15877             gcc_unreachable ();
15878         }
15879       else
15880         {
15881           if (ROUND_<ROUNDING> == ROUND_FLOOR)
15882             ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15883           else if (ROUND_<ROUNDING> == ROUND_CEIL)
15884             ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15885           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15886             ix86_expand_truncdf_32 (operands[0], operands[1]);
15887           else
15888             gcc_unreachable ();
15889         }
15890     }
15891   else
15892     {
15893       rtx op0, op1;
15895       op0 = gen_reg_rtx (XFmode);
15896       op1 = gen_reg_rtx (XFmode);
15897       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15898       emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15900       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15901     }
15902   DONE;
15905 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15906 (define_insn_and_split "frndintxf2_mask_pm"
15907   [(set (match_operand:XF 0 "register_operand")
15908         (unspec:XF [(match_operand:XF 1 "register_operand")]
15909                    UNSPEC_FRNDINT_MASK_PM))
15910    (clobber (reg:CC FLAGS_REG))]
15911   "TARGET_USE_FANCY_MATH_387
15912    && flag_unsafe_math_optimizations
15913    && can_create_pseudo_p ()"
15914   "#"
15915   "&& 1"
15916   [(const_int 0)]
15918   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15920   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15921   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15923   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15924                                           operands[2], operands[3]));
15925   DONE;
15927   [(set_attr "type" "frndint")
15928    (set_attr "i387_cw" "mask_pm")
15929    (set_attr "mode" "XF")])
15931 (define_insn "frndintxf2_mask_pm_i387"
15932   [(set (match_operand:XF 0 "register_operand" "=f")
15933         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15934                    UNSPEC_FRNDINT_MASK_PM))
15935    (use (match_operand:HI 2 "memory_operand" "m"))
15936    (use (match_operand:HI 3 "memory_operand" "m"))]
15937   "TARGET_USE_FANCY_MATH_387
15938    && flag_unsafe_math_optimizations"
15939   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15940   [(set_attr "type" "frndint")
15941    (set_attr "i387_cw" "mask_pm")
15942    (set_attr "mode" "XF")])
15944 (define_expand "nearbyintxf2"
15945   [(parallel [(set (match_operand:XF 0 "register_operand")
15946                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15947                               UNSPEC_FRNDINT_MASK_PM))
15948               (clobber (reg:CC FLAGS_REG))])]
15949   "TARGET_USE_FANCY_MATH_387
15950    && flag_unsafe_math_optimizations")
15952 (define_expand "nearbyint<mode>2"
15953   [(use (match_operand:MODEF 0 "register_operand"))
15954    (use (match_operand:MODEF 1 "register_operand"))]
15955   "TARGET_USE_FANCY_MATH_387
15956    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15957        || TARGET_MIX_SSE_I387)
15958    && flag_unsafe_math_optimizations"
15960   rtx op0 = gen_reg_rtx (XFmode);
15961   rtx op1 = gen_reg_rtx (XFmode);
15963   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15964   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15966   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15967   DONE;
15970 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15971 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15972   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15973         (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15974                         FIST_ROUNDING))
15975    (clobber (reg:CC FLAGS_REG))]
15976   "TARGET_USE_FANCY_MATH_387
15977    && flag_unsafe_math_optimizations
15978    && can_create_pseudo_p ()"
15979   "#"
15980   "&& 1"
15981   [(const_int 0)]
15983   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15985   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15986   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15987   if (memory_operand (operands[0], VOIDmode))
15988     emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15989                                            operands[2], operands[3]));
15990   else
15991     {
15992       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15993       emit_insn (gen_fist<mode>2_<rounding>_with_temp
15994                   (operands[0], operands[1], operands[2],
15995                    operands[3], operands[4]));
15996     }
15997   DONE;
15999   [(set_attr "type" "fistp")
16000    (set_attr "i387_cw" "<rounding>")
16001    (set_attr "mode" "<MODE>")])
16003 (define_insn "fistdi2_<rounding>"
16004   [(set (match_operand:DI 0 "memory_operand" "=m")
16005         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16006                    FIST_ROUNDING))
16007    (use (match_operand:HI 2 "memory_operand" "m"))
16008    (use (match_operand:HI 3 "memory_operand" "m"))
16009    (clobber (match_scratch:XF 4 "=&1f"))]
16010   "TARGET_USE_FANCY_MATH_387
16011    && flag_unsafe_math_optimizations"
16012   "* return output_fix_trunc (insn, operands, false);"
16013   [(set_attr "type" "fistp")
16014    (set_attr "i387_cw" "<rounding>")
16015    (set_attr "mode" "DI")])
16017 (define_insn "fistdi2_<rounding>_with_temp"
16018   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16019         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16020                    FIST_ROUNDING))
16021    (use (match_operand:HI 2 "memory_operand" "m,m"))
16022    (use (match_operand:HI 3 "memory_operand" "m,m"))
16023    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
16024    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16025   "TARGET_USE_FANCY_MATH_387
16026    && flag_unsafe_math_optimizations"
16027   "#"
16028   [(set_attr "type" "fistp")
16029    (set_attr "i387_cw" "<rounding>")
16030    (set_attr "mode" "DI")])
16032 (define_split
16033   [(set (match_operand:DI 0 "register_operand")
16034         (unspec:DI [(match_operand:XF 1 "register_operand")]
16035                    FIST_ROUNDING))
16036    (use (match_operand:HI 2 "memory_operand"))
16037    (use (match_operand:HI 3 "memory_operand"))
16038    (clobber (match_operand:DI 4 "memory_operand"))
16039    (clobber (match_scratch 5))]
16040   "reload_completed"
16041   [(parallel [(set (match_dup 4)
16042                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
16043               (use (match_dup 2))
16044               (use (match_dup 3))
16045               (clobber (match_dup 5))])
16046    (set (match_dup 0) (match_dup 4))])
16048 (define_split
16049   [(set (match_operand:DI 0 "memory_operand")
16050         (unspec:DI [(match_operand:XF 1 "register_operand")]
16051                    FIST_ROUNDING))
16052    (use (match_operand:HI 2 "memory_operand"))
16053    (use (match_operand:HI 3 "memory_operand"))
16054    (clobber (match_operand:DI 4 "memory_operand"))
16055    (clobber (match_scratch 5))]
16056   "reload_completed"
16057   [(parallel [(set (match_dup 0)
16058                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
16059               (use (match_dup 2))
16060               (use (match_dup 3))
16061               (clobber (match_dup 5))])])
16063 (define_insn "fist<mode>2_<rounding>"
16064   [(set (match_operand:SWI24 0 "memory_operand" "=m")
16065         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16066                       FIST_ROUNDING))
16067    (use (match_operand:HI 2 "memory_operand" "m"))
16068    (use (match_operand:HI 3 "memory_operand" "m"))]
16069   "TARGET_USE_FANCY_MATH_387
16070    && flag_unsafe_math_optimizations"
16071   "* return output_fix_trunc (insn, operands, false);"
16072   [(set_attr "type" "fistp")
16073    (set_attr "i387_cw" "<rounding>")
16074    (set_attr "mode" "<MODE>")])
16076 (define_insn "fist<mode>2_<rounding>_with_temp"
16077   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
16078         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
16079                       FIST_ROUNDING))
16080    (use (match_operand:HI 2 "memory_operand" "m,m"))
16081    (use (match_operand:HI 3 "memory_operand" "m,m"))
16082    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
16083   "TARGET_USE_FANCY_MATH_387
16084    && flag_unsafe_math_optimizations"
16085   "#"
16086   [(set_attr "type" "fistp")
16087    (set_attr "i387_cw" "<rounding>")
16088    (set_attr "mode" "<MODE>")])
16090 (define_split
16091   [(set (match_operand:SWI24 0 "register_operand")
16092         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16093                       FIST_ROUNDING))
16094    (use (match_operand:HI 2 "memory_operand"))
16095    (use (match_operand:HI 3 "memory_operand"))
16096    (clobber (match_operand:SWI24 4 "memory_operand"))]
16097   "reload_completed"
16098   [(parallel [(set (match_dup 4)
16099                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16100               (use (match_dup 2))
16101               (use (match_dup 3))])
16102    (set (match_dup 0) (match_dup 4))])
16104 (define_split
16105   [(set (match_operand:SWI24 0 "memory_operand")
16106         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16107                       FIST_ROUNDING))
16108    (use (match_operand:HI 2 "memory_operand"))
16109    (use (match_operand:HI 3 "memory_operand"))
16110    (clobber (match_operand:SWI24 4 "memory_operand"))]
16111   "reload_completed"
16112   [(parallel [(set (match_dup 0)
16113                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16114               (use (match_dup 2))
16115               (use (match_dup 3))])])
16117 (define_expand "l<rounding_insn>xf<mode>2"
16118   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16119                    (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16120                                    FIST_ROUNDING))
16121               (clobber (reg:CC FLAGS_REG))])]
16122   "TARGET_USE_FANCY_MATH_387
16123    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16124    && flag_unsafe_math_optimizations")
16126 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
16127   [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
16128                    (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16129                                  FIST_ROUNDING))
16130               (clobber (reg:CC FLAGS_REG))])]
16131   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16132    && !flag_trapping_math"
16134   if (TARGET_64BIT && optimize_insn_for_size_p ())
16135     FAIL;
16137   if (ROUND_<ROUNDING> == ROUND_FLOOR)
16138     ix86_expand_lfloorceil (operands[0], operands[1], true);
16139   else if (ROUND_<ROUNDING> == ROUND_CEIL)
16140     ix86_expand_lfloorceil (operands[0], operands[1], false);
16141   else
16142     gcc_unreachable ();
16144   DONE;
16147 (define_insn "fxam<mode>2_i387"
16148   [(set (match_operand:HI 0 "register_operand" "=a")
16149         (unspec:HI
16150           [(match_operand:X87MODEF 1 "register_operand" "f")]
16151           UNSPEC_FXAM))]
16152   "TARGET_USE_FANCY_MATH_387"
16153   "fxam\n\tfnstsw\t%0"
16154   [(set_attr "type" "multi")
16155    (set_attr "length" "4")
16156    (set_attr "unit" "i387")
16157    (set_attr "mode" "<MODE>")])
16159 (define_insn_and_split "fxam<mode>2_i387_with_temp"
16160   [(set (match_operand:HI 0 "register_operand")
16161         (unspec:HI
16162           [(match_operand:MODEF 1 "memory_operand")]
16163           UNSPEC_FXAM_MEM))]
16164   "TARGET_USE_FANCY_MATH_387
16165    && can_create_pseudo_p ()"
16166   "#"
16167   "&& 1"
16168   [(set (match_dup 2)(match_dup 1))
16169    (set (match_dup 0)
16170         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
16172   operands[2] = gen_reg_rtx (<MODE>mode);
16174   MEM_VOLATILE_P (operands[1]) = 1;
16176   [(set_attr "type" "multi")
16177    (set_attr "unit" "i387")
16178    (set_attr "mode" "<MODE>")])
16180 (define_expand "isinfxf2"
16181   [(use (match_operand:SI 0 "register_operand"))
16182    (use (match_operand:XF 1 "register_operand"))]
16183   "TARGET_USE_FANCY_MATH_387
16184    && ix86_libc_has_function (function_c99_misc)"
16186   rtx mask = GEN_INT (0x45);
16187   rtx val = GEN_INT (0x05);
16189   rtx cond;
16191   rtx scratch = gen_reg_rtx (HImode);
16192   rtx res = gen_reg_rtx (QImode);
16194   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16196   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
16197   emit_insn (gen_cmpqi_ext_3 (scratch, val));
16198   cond = gen_rtx_fmt_ee (EQ, QImode,
16199                          gen_rtx_REG (CCmode, FLAGS_REG),
16200                          const0_rtx);
16201   emit_insn (gen_rtx_SET (res, cond));
16202   emit_insn (gen_zero_extendqisi2 (operands[0], res));
16203   DONE;
16206 (define_expand "isinf<mode>2"
16207   [(use (match_operand:SI 0 "register_operand"))
16208    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
16209   "TARGET_USE_FANCY_MATH_387
16210    && ix86_libc_has_function (function_c99_misc)
16211    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16213   rtx mask = GEN_INT (0x45);
16214   rtx val = GEN_INT (0x05);
16216   rtx cond;
16218   rtx scratch = gen_reg_rtx (HImode);
16219   rtx res = gen_reg_rtx (QImode);
16221   /* Remove excess precision by forcing value through memory. */
16222   if (memory_operand (operands[1], VOIDmode))
16223     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
16224   else
16225     {
16226       rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16228       emit_move_insn (temp, operands[1]);
16229       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
16230     }
16232   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
16233   emit_insn (gen_cmpqi_ext_3 (scratch, val));
16234   cond = gen_rtx_fmt_ee (EQ, QImode,
16235                          gen_rtx_REG (CCmode, FLAGS_REG),
16236                          const0_rtx);
16237   emit_insn (gen_rtx_SET (res, cond));
16238   emit_insn (gen_zero_extendqisi2 (operands[0], res));
16239   DONE;
16242 (define_expand "signbitxf2"
16243   [(use (match_operand:SI 0 "register_operand"))
16244    (use (match_operand:XF 1 "register_operand"))]
16245   "TARGET_USE_FANCY_MATH_387"
16247   rtx scratch = gen_reg_rtx (HImode);
16249   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16250   emit_insn (gen_andsi3 (operands[0],
16251              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16252   DONE;
16255 (define_insn "movmsk_df"
16256   [(set (match_operand:SI 0 "register_operand" "=r")
16257         (unspec:SI
16258           [(match_operand:DF 1 "register_operand" "x")]
16259           UNSPEC_MOVMSK))]
16260   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
16261   "%vmovmskpd\t{%1, %0|%0, %1}"
16262   [(set_attr "type" "ssemov")
16263    (set_attr "prefix" "maybe_vex")
16264    (set_attr "mode" "DF")])
16266 ;; Use movmskpd in SSE mode to avoid store forwarding stall
16267 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
16268 (define_expand "signbitdf2"
16269   [(use (match_operand:SI 0 "register_operand"))
16270    (use (match_operand:DF 1 "register_operand"))]
16271   "TARGET_USE_FANCY_MATH_387
16272    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
16274   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
16275     {
16276       emit_insn (gen_movmsk_df (operands[0], operands[1]));
16277       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
16278     }
16279   else
16280     {
16281       rtx scratch = gen_reg_rtx (HImode);
16283       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
16284       emit_insn (gen_andsi3 (operands[0],
16285                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16286     }
16287   DONE;
16290 (define_expand "signbitsf2"
16291   [(use (match_operand:SI 0 "register_operand"))
16292    (use (match_operand:SF 1 "register_operand"))]
16293   "TARGET_USE_FANCY_MATH_387
16294    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
16296   rtx scratch = gen_reg_rtx (HImode);
16298   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
16299   emit_insn (gen_andsi3 (operands[0],
16300              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16301   DONE;
16304 ;; Block operation instructions
16306 (define_insn "cld"
16307   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
16308   ""
16309   "cld"
16310   [(set_attr "length" "1")
16311    (set_attr "length_immediate" "0")
16312    (set_attr "modrm" "0")])
16314 (define_expand "movmem<mode>"
16315   [(use (match_operand:BLK 0 "memory_operand"))
16316    (use (match_operand:BLK 1 "memory_operand"))
16317    (use (match_operand:SWI48 2 "nonmemory_operand"))
16318    (use (match_operand:SWI48 3 "const_int_operand"))
16319    (use (match_operand:SI 4 "const_int_operand"))
16320    (use (match_operand:SI 5 "const_int_operand"))
16321    (use (match_operand:SI 6 ""))
16322    (use (match_operand:SI 7 ""))
16323    (use (match_operand:SI 8 ""))]
16324   ""
16326  if (ix86_expand_set_or_movmem (operands[0], operands[1],
16327                                 operands[2], NULL, operands[3],
16328                                 operands[4], operands[5],
16329                                 operands[6], operands[7],
16330                                 operands[8], false))
16331    DONE;
16332  else
16333    FAIL;
16336 ;; Most CPUs don't like single string operations
16337 ;; Handle this case here to simplify previous expander.
16339 (define_expand "strmov"
16340   [(set (match_dup 4) (match_operand 3 "memory_operand"))
16341    (set (match_operand 1 "memory_operand") (match_dup 4))
16342    (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
16343               (clobber (reg:CC FLAGS_REG))])
16344    (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
16345               (clobber (reg:CC FLAGS_REG))])]
16346   ""
16348   /* Can't use this for non-default address spaces.  */
16349   if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
16350     FAIL;
16352   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16354   /* If .md ever supports :P for Pmode, these can be directly
16355      in the pattern above.  */
16356   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16357   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16359   /* Can't use this if the user has appropriated esi or edi.  */
16360   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16361       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
16362     {
16363       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16364                                       operands[2], operands[3],
16365                                       operands[5], operands[6]));
16366       DONE;
16367     }
16369   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16372 (define_expand "strmov_singleop"
16373   [(parallel [(set (match_operand 1 "memory_operand")
16374                    (match_operand 3 "memory_operand"))
16375               (set (match_operand 0 "register_operand")
16376                    (match_operand 4))
16377               (set (match_operand 2 "register_operand")
16378                    (match_operand 5))])]
16379   ""
16380   "ix86_current_function_needs_cld = 1;")
16382 (define_insn "*strmovdi_rex_1"
16383   [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
16384         (mem:DI (match_operand:P 3 "register_operand" "1")))
16385    (set (match_operand:P 0 "register_operand" "=D")
16386         (plus:P (match_dup 2)
16387                 (const_int 8)))
16388    (set (match_operand:P 1 "register_operand" "=S")
16389         (plus:P (match_dup 3)
16390                 (const_int 8)))]
16391   "TARGET_64BIT
16392    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16393    && ix86_check_no_addr_space (insn)"
16394   "%^movsq"
16395   [(set_attr "type" "str")
16396    (set_attr "memory" "both")
16397    (set_attr "mode" "DI")])
16399 (define_insn "*strmovsi_1"
16400   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
16401         (mem:SI (match_operand:P 3 "register_operand" "1")))
16402    (set (match_operand:P 0 "register_operand" "=D")
16403         (plus:P (match_dup 2)
16404                 (const_int 4)))
16405    (set (match_operand:P 1 "register_operand" "=S")
16406         (plus:P (match_dup 3)
16407                 (const_int 4)))]
16408   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16409    && ix86_check_no_addr_space (insn)"
16410   "%^movs{l|d}"
16411   [(set_attr "type" "str")
16412    (set_attr "memory" "both")
16413    (set_attr "mode" "SI")])
16415 (define_insn "*strmovhi_1"
16416   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
16417         (mem:HI (match_operand:P 3 "register_operand" "1")))
16418    (set (match_operand:P 0 "register_operand" "=D")
16419         (plus:P (match_dup 2)
16420                 (const_int 2)))
16421    (set (match_operand:P 1 "register_operand" "=S")
16422         (plus:P (match_dup 3)
16423                 (const_int 2)))]
16424   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16425    && ix86_check_no_addr_space (insn)"
16426   "%^movsw"
16427   [(set_attr "type" "str")
16428    (set_attr "memory" "both")
16429    (set_attr "mode" "HI")])
16431 (define_insn "*strmovqi_1"
16432   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
16433         (mem:QI (match_operand:P 3 "register_operand" "1")))
16434    (set (match_operand:P 0 "register_operand" "=D")
16435         (plus:P (match_dup 2)
16436                 (const_int 1)))
16437    (set (match_operand:P 1 "register_operand" "=S")
16438         (plus:P (match_dup 3)
16439                 (const_int 1)))]
16440   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16441    && ix86_check_no_addr_space (insn)"
16442   "%^movsb"
16443   [(set_attr "type" "str")
16444    (set_attr "memory" "both")
16445    (set (attr "prefix_rex")
16446         (if_then_else
16447           (match_test "<P:MODE>mode == DImode")
16448           (const_string "0")
16449           (const_string "*")))
16450    (set_attr "mode" "QI")])
16452 (define_expand "rep_mov"
16453   [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
16454               (set (match_operand 0 "register_operand")
16455                    (match_operand 5))
16456               (set (match_operand 2 "register_operand")
16457                    (match_operand 6))
16458               (set (match_operand 1 "memory_operand")
16459                    (match_operand 3 "memory_operand"))
16460               (use (match_dup 4))])]
16461   ""
16462   "ix86_current_function_needs_cld = 1;")
16464 (define_insn "*rep_movdi_rex64"
16465   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16466    (set (match_operand:P 0 "register_operand" "=D")
16467         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16468                           (const_int 3))
16469                 (match_operand:P 3 "register_operand" "0")))
16470    (set (match_operand:P 1 "register_operand" "=S")
16471         (plus:P (ashift:P (match_dup 5) (const_int 3))
16472                 (match_operand:P 4 "register_operand" "1")))
16473    (set (mem:BLK (match_dup 3))
16474         (mem:BLK (match_dup 4)))
16475    (use (match_dup 5))]
16476   "TARGET_64BIT
16477    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16478    && ix86_check_no_addr_space (insn)"
16479   "%^rep{%;} movsq"
16480   [(set_attr "type" "str")
16481    (set_attr "prefix_rep" "1")
16482    (set_attr "memory" "both")
16483    (set_attr "mode" "DI")])
16485 (define_insn "*rep_movsi"
16486   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16487    (set (match_operand:P 0 "register_operand" "=D")
16488         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16489                           (const_int 2))
16490                  (match_operand:P 3 "register_operand" "0")))
16491    (set (match_operand:P 1 "register_operand" "=S")
16492         (plus:P (ashift:P (match_dup 5) (const_int 2))
16493                 (match_operand:P 4 "register_operand" "1")))
16494    (set (mem:BLK (match_dup 3))
16495         (mem:BLK (match_dup 4)))
16496    (use (match_dup 5))]
16497   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16498    && ix86_check_no_addr_space (insn)"
16499   "%^rep{%;} movs{l|d}"
16500   [(set_attr "type" "str")
16501    (set_attr "prefix_rep" "1")
16502    (set_attr "memory" "both")
16503    (set_attr "mode" "SI")])
16505 (define_insn "*rep_movqi"
16506   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16507    (set (match_operand:P 0 "register_operand" "=D")
16508         (plus:P (match_operand:P 3 "register_operand" "0")
16509                 (match_operand:P 5 "register_operand" "2")))
16510    (set (match_operand:P 1 "register_operand" "=S")
16511         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
16512    (set (mem:BLK (match_dup 3))
16513         (mem:BLK (match_dup 4)))
16514    (use (match_dup 5))]
16515   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16516    && ix86_check_no_addr_space (insn)"
16517   "%^rep{%;} movsb"
16518   [(set_attr "type" "str")
16519    (set_attr "prefix_rep" "1")
16520    (set_attr "memory" "both")
16521    (set_attr "mode" "QI")])
16523 (define_expand "setmem<mode>"
16524    [(use (match_operand:BLK 0 "memory_operand"))
16525     (use (match_operand:SWI48 1 "nonmemory_operand"))
16526     (use (match_operand:QI 2 "nonmemory_operand"))
16527     (use (match_operand 3 "const_int_operand"))
16528     (use (match_operand:SI 4 "const_int_operand"))
16529     (use (match_operand:SI 5 "const_int_operand"))
16530     (use (match_operand:SI 6 ""))
16531     (use (match_operand:SI 7 ""))
16532     (use (match_operand:SI 8 ""))]
16533   ""
16535  if (ix86_expand_set_or_movmem (operands[0], NULL,
16536                                 operands[1], operands[2],
16537                                 operands[3], operands[4],
16538                                 operands[5], operands[6],
16539                                 operands[7], operands[8], true))
16540    DONE;
16541  else
16542    FAIL;
16545 ;; Most CPUs don't like single string operations
16546 ;; Handle this case here to simplify previous expander.
16548 (define_expand "strset"
16549   [(set (match_operand 1 "memory_operand")
16550         (match_operand 2 "register_operand"))
16551    (parallel [(set (match_operand 0 "register_operand")
16552                    (match_dup 3))
16553               (clobber (reg:CC FLAGS_REG))])]
16554   ""
16556   /* Can't use this for non-default address spaces.  */
16557   if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
16558     FAIL;
16560   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16561     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16563   /* If .md ever supports :P for Pmode, this can be directly
16564      in the pattern above.  */
16565   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16566                               GEN_INT (GET_MODE_SIZE (GET_MODE
16567                                                       (operands[2]))));
16568   /* Can't use this if the user has appropriated eax or edi.  */
16569   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16570       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
16571     {
16572       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16573                                       operands[3]));
16574       DONE;
16575     }
16578 (define_expand "strset_singleop"
16579   [(parallel [(set (match_operand 1 "memory_operand")
16580                    (match_operand 2 "register_operand"))
16581               (set (match_operand 0 "register_operand")
16582                    (match_operand 3))
16583               (unspec [(const_int 0)] UNSPEC_STOS)])]
16584   ""
16585   "ix86_current_function_needs_cld = 1;")
16587 (define_insn "*strsetdi_rex_1"
16588   [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16589         (match_operand:DI 2 "register_operand" "a"))
16590    (set (match_operand:P 0 "register_operand" "=D")
16591         (plus:P (match_dup 1)
16592                 (const_int 8)))
16593    (unspec [(const_int 0)] UNSPEC_STOS)]
16594   "TARGET_64BIT
16595    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16596    && ix86_check_no_addr_space (insn)"
16597   "%^stosq"
16598   [(set_attr "type" "str")
16599    (set_attr "memory" "store")
16600    (set_attr "mode" "DI")])
16602 (define_insn "*strsetsi_1"
16603   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16604         (match_operand:SI 2 "register_operand" "a"))
16605    (set (match_operand:P 0 "register_operand" "=D")
16606         (plus:P (match_dup 1)
16607                 (const_int 4)))
16608    (unspec [(const_int 0)] UNSPEC_STOS)]
16609   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16610    && ix86_check_no_addr_space (insn)"
16611   "%^stos{l|d}"
16612   [(set_attr "type" "str")
16613    (set_attr "memory" "store")
16614    (set_attr "mode" "SI")])
16616 (define_insn "*strsethi_1"
16617   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16618         (match_operand:HI 2 "register_operand" "a"))
16619    (set (match_operand:P 0 "register_operand" "=D")
16620         (plus:P (match_dup 1)
16621                 (const_int 2)))
16622    (unspec [(const_int 0)] UNSPEC_STOS)]
16623   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16624    && ix86_check_no_addr_space (insn)"
16625   "%^stosw"
16626   [(set_attr "type" "str")
16627    (set_attr "memory" "store")
16628    (set_attr "mode" "HI")])
16630 (define_insn "*strsetqi_1"
16631   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16632         (match_operand:QI 2 "register_operand" "a"))
16633    (set (match_operand:P 0 "register_operand" "=D")
16634         (plus:P (match_dup 1)
16635                 (const_int 1)))
16636    (unspec [(const_int 0)] UNSPEC_STOS)]
16637   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16638    && ix86_check_no_addr_space (insn)"
16639   "%^stosb"
16640   [(set_attr "type" "str")
16641    (set_attr "memory" "store")
16642    (set (attr "prefix_rex")
16643         (if_then_else
16644           (match_test "<P:MODE>mode == DImode")
16645           (const_string "0")
16646           (const_string "*")))
16647    (set_attr "mode" "QI")])
16649 (define_expand "rep_stos"
16650   [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16651               (set (match_operand 0 "register_operand")
16652                    (match_operand 4))
16653               (set (match_operand 2 "memory_operand") (const_int 0))
16654               (use (match_operand 3 "register_operand"))
16655               (use (match_dup 1))])]
16656   ""
16657   "ix86_current_function_needs_cld = 1;")
16659 (define_insn "*rep_stosdi_rex64"
16660   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16661    (set (match_operand:P 0 "register_operand" "=D")
16662         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16663                           (const_int 3))
16664                  (match_operand:P 3 "register_operand" "0")))
16665    (set (mem:BLK (match_dup 3))
16666         (const_int 0))
16667    (use (match_operand:DI 2 "register_operand" "a"))
16668    (use (match_dup 4))]
16669   "TARGET_64BIT
16670    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16671    && ix86_check_no_addr_space (insn)"
16672   "%^rep{%;} stosq"
16673   [(set_attr "type" "str")
16674    (set_attr "prefix_rep" "1")
16675    (set_attr "memory" "store")
16676    (set_attr "mode" "DI")])
16678 (define_insn "*rep_stossi"
16679   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16680    (set (match_operand:P 0 "register_operand" "=D")
16681         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16682                           (const_int 2))
16683                  (match_operand:P 3 "register_operand" "0")))
16684    (set (mem:BLK (match_dup 3))
16685         (const_int 0))
16686    (use (match_operand:SI 2 "register_operand" "a"))
16687    (use (match_dup 4))]
16688   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16689    && ix86_check_no_addr_space (insn)"
16690   "%^rep{%;} stos{l|d}"
16691   [(set_attr "type" "str")
16692    (set_attr "prefix_rep" "1")
16693    (set_attr "memory" "store")
16694    (set_attr "mode" "SI")])
16696 (define_insn "*rep_stosqi"
16697   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16698    (set (match_operand:P 0 "register_operand" "=D")
16699         (plus:P (match_operand:P 3 "register_operand" "0")
16700                 (match_operand:P 4 "register_operand" "1")))
16701    (set (mem:BLK (match_dup 3))
16702         (const_int 0))
16703    (use (match_operand:QI 2 "register_operand" "a"))
16704    (use (match_dup 4))]
16705   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16706    && ix86_check_no_addr_space (insn)"
16707   "%^rep{%;} stosb"
16708   [(set_attr "type" "str")
16709    (set_attr "prefix_rep" "1")
16710    (set_attr "memory" "store")
16711    (set (attr "prefix_rex")
16712         (if_then_else
16713           (match_test "<P:MODE>mode == DImode")
16714           (const_string "0")
16715           (const_string "*")))
16716    (set_attr "mode" "QI")])
16718 (define_expand "cmpstrnsi"
16719   [(set (match_operand:SI 0 "register_operand")
16720         (compare:SI (match_operand:BLK 1 "general_operand")
16721                     (match_operand:BLK 2 "general_operand")))
16722    (use (match_operand 3 "general_operand"))
16723    (use (match_operand 4 "immediate_operand"))]
16724   ""
16726   rtx addr1, addr2, out, outlow, count, countreg, align;
16728   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16729     FAIL;
16731   /* Can't use this if the user has appropriated ecx, esi or edi.  */
16732   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16733     FAIL;
16735   out = operands[0];
16736   if (!REG_P (out))
16737     out = gen_reg_rtx (SImode);
16739   addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16740   addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16741   if (addr1 != XEXP (operands[1], 0))
16742     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16743   if (addr2 != XEXP (operands[2], 0))
16744     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16746   count = operands[3];
16747   countreg = ix86_zero_extend_to_Pmode (count);
16749   /* %%% Iff we are testing strict equality, we can use known alignment
16750      to good advantage.  This may be possible with combine, particularly
16751      once cc0 is dead.  */
16752   align = operands[4];
16754   if (CONST_INT_P (count))
16755     {
16756       if (INTVAL (count) == 0)
16757         {
16758           emit_move_insn (operands[0], const0_rtx);
16759           DONE;
16760         }
16761       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16762                                      operands[1], operands[2]));
16763     }
16764   else
16765     {
16766       rtx (*gen_cmp) (rtx, rtx);
16768       gen_cmp = (TARGET_64BIT
16769                  ? gen_cmpdi_1 : gen_cmpsi_1);
16771       emit_insn (gen_cmp (countreg, countreg));
16772       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16773                                   operands[1], operands[2]));
16774     }
16776   outlow = gen_lowpart (QImode, out);
16777   emit_insn (gen_cmpintqi (outlow));
16778   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16780   if (operands[0] != out)
16781     emit_move_insn (operands[0], out);
16783   DONE;
16786 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16788 (define_expand "cmpintqi"
16789   [(set (match_dup 1)
16790         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16791    (set (match_dup 2)
16792         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16793    (parallel [(set (match_operand:QI 0 "register_operand")
16794                    (minus:QI (match_dup 1)
16795                              (match_dup 2)))
16796               (clobber (reg:CC FLAGS_REG))])]
16797   ""
16799   operands[1] = gen_reg_rtx (QImode);
16800   operands[2] = gen_reg_rtx (QImode);
16803 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16804 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16806 (define_expand "cmpstrnqi_nz_1"
16807   [(parallel [(set (reg:CC FLAGS_REG)
16808                    (compare:CC (match_operand 4 "memory_operand")
16809                                (match_operand 5 "memory_operand")))
16810               (use (match_operand 2 "register_operand"))
16811               (use (match_operand:SI 3 "immediate_operand"))
16812               (clobber (match_operand 0 "register_operand"))
16813               (clobber (match_operand 1 "register_operand"))
16814               (clobber (match_dup 2))])]
16815   ""
16816   "ix86_current_function_needs_cld = 1;")
16818 (define_insn "*cmpstrnqi_nz_1"
16819   [(set (reg:CC FLAGS_REG)
16820         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16821                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16822    (use (match_operand:P 6 "register_operand" "2"))
16823    (use (match_operand:SI 3 "immediate_operand" "i"))
16824    (clobber (match_operand:P 0 "register_operand" "=S"))
16825    (clobber (match_operand:P 1 "register_operand" "=D"))
16826    (clobber (match_operand:P 2 "register_operand" "=c"))]
16827   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16828    && ix86_check_no_addr_space (insn)"
16829   "%^repz{%;} cmpsb"
16830   [(set_attr "type" "str")
16831    (set_attr "mode" "QI")
16832    (set (attr "prefix_rex")
16833         (if_then_else
16834           (match_test "<P:MODE>mode == DImode")
16835           (const_string "0")
16836           (const_string "*")))
16837    (set_attr "prefix_rep" "1")])
16839 ;; The same, but the count is not known to not be zero.
16841 (define_expand "cmpstrnqi_1"
16842   [(parallel [(set (reg:CC FLAGS_REG)
16843                 (if_then_else:CC (ne (match_operand 2 "register_operand")
16844                                      (const_int 0))
16845                   (compare:CC (match_operand 4 "memory_operand")
16846                               (match_operand 5 "memory_operand"))
16847                   (const_int 0)))
16848               (use (match_operand:SI 3 "immediate_operand"))
16849               (use (reg:CC FLAGS_REG))
16850               (clobber (match_operand 0 "register_operand"))
16851               (clobber (match_operand 1 "register_operand"))
16852               (clobber (match_dup 2))])]
16853   ""
16854   "ix86_current_function_needs_cld = 1;")
16856 (define_insn "*cmpstrnqi_1"
16857   [(set (reg:CC FLAGS_REG)
16858         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16859                              (const_int 0))
16860           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16861                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
16862           (const_int 0)))
16863    (use (match_operand:SI 3 "immediate_operand" "i"))
16864    (use (reg:CC FLAGS_REG))
16865    (clobber (match_operand:P 0 "register_operand" "=S"))
16866    (clobber (match_operand:P 1 "register_operand" "=D"))
16867    (clobber (match_operand:P 2 "register_operand" "=c"))]
16868   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16869    && ix86_check_no_addr_space (insn)"
16870   "%^repz{%;} cmpsb"
16871   [(set_attr "type" "str")
16872    (set_attr "mode" "QI")
16873    (set (attr "prefix_rex")
16874         (if_then_else
16875           (match_test "<P:MODE>mode == DImode")
16876           (const_string "0")
16877           (const_string "*")))
16878    (set_attr "prefix_rep" "1")])
16880 (define_expand "strlen<mode>"
16881   [(set (match_operand:P 0 "register_operand")
16882         (unspec:P [(match_operand:BLK 1 "general_operand")
16883                    (match_operand:QI 2 "immediate_operand")
16884                    (match_operand 3 "immediate_operand")]
16885                   UNSPEC_SCAS))]
16886   ""
16888  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16889    DONE;
16890  else
16891    FAIL;
16894 (define_expand "strlenqi_1"
16895   [(parallel [(set (match_operand 0 "register_operand")
16896                    (match_operand 2))
16897               (clobber (match_operand 1 "register_operand"))
16898               (clobber (reg:CC FLAGS_REG))])]
16899   ""
16900   "ix86_current_function_needs_cld = 1;")
16902 (define_insn "*strlenqi_1"
16903   [(set (match_operand:P 0 "register_operand" "=&c")
16904         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16905                    (match_operand:QI 2 "register_operand" "a")
16906                    (match_operand:P 3 "immediate_operand" "i")
16907                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16908    (clobber (match_operand:P 1 "register_operand" "=D"))
16909    (clobber (reg:CC FLAGS_REG))]
16910   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16911    && ix86_check_no_addr_space (insn)"
16912   "%^repnz{%;} scasb"
16913   [(set_attr "type" "str")
16914    (set_attr "mode" "QI")
16915    (set (attr "prefix_rex")
16916         (if_then_else
16917           (match_test "<P:MODE>mode == DImode")
16918           (const_string "0")
16919           (const_string "*")))
16920    (set_attr "prefix_rep" "1")])
16922 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
16923 ;; handled in combine, but it is not currently up to the task.
16924 ;; When used for their truth value, the cmpstrn* expanders generate
16925 ;; code like this:
16927 ;;   repz cmpsb
16928 ;;   seta       %al
16929 ;;   setb       %dl
16930 ;;   cmpb       %al, %dl
16931 ;;   jcc        label
16933 ;; The intermediate three instructions are unnecessary.
16935 ;; This one handles cmpstrn*_nz_1...
16936 (define_peephole2
16937   [(parallel[
16938      (set (reg:CC FLAGS_REG)
16939           (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16940                       (mem:BLK (match_operand 5 "register_operand"))))
16941      (use (match_operand 6 "register_operand"))
16942      (use (match_operand:SI 3 "immediate_operand"))
16943      (clobber (match_operand 0 "register_operand"))
16944      (clobber (match_operand 1 "register_operand"))
16945      (clobber (match_operand 2 "register_operand"))])
16946    (set (match_operand:QI 7 "register_operand")
16947         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16948    (set (match_operand:QI 8 "register_operand")
16949         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16950    (set (reg FLAGS_REG)
16951         (compare (match_dup 7) (match_dup 8)))
16952   ]
16953   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16954   [(parallel[
16955      (set (reg:CC FLAGS_REG)
16956           (compare:CC (mem:BLK (match_dup 4))
16957                       (mem:BLK (match_dup 5))))
16958      (use (match_dup 6))
16959      (use (match_dup 3))
16960      (clobber (match_dup 0))
16961      (clobber (match_dup 1))
16962      (clobber (match_dup 2))])])
16964 ;; ...and this one handles cmpstrn*_1.
16965 (define_peephole2
16966   [(parallel[
16967      (set (reg:CC FLAGS_REG)
16968           (if_then_else:CC (ne (match_operand 6 "register_operand")
16969                                (const_int 0))
16970             (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16971                         (mem:BLK (match_operand 5 "register_operand")))
16972             (const_int 0)))
16973      (use (match_operand:SI 3 "immediate_operand"))
16974      (use (reg:CC FLAGS_REG))
16975      (clobber (match_operand 0 "register_operand"))
16976      (clobber (match_operand 1 "register_operand"))
16977      (clobber (match_operand 2 "register_operand"))])
16978    (set (match_operand:QI 7 "register_operand")
16979         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16980    (set (match_operand:QI 8 "register_operand")
16981         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16982    (set (reg FLAGS_REG)
16983         (compare (match_dup 7) (match_dup 8)))
16984   ]
16985   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16986   [(parallel[
16987      (set (reg:CC FLAGS_REG)
16988           (if_then_else:CC (ne (match_dup 6)
16989                                (const_int 0))
16990             (compare:CC (mem:BLK (match_dup 4))
16991                         (mem:BLK (match_dup 5)))
16992             (const_int 0)))
16993      (use (match_dup 3))
16994      (use (reg:CC FLAGS_REG))
16995      (clobber (match_dup 0))
16996      (clobber (match_dup 1))
16997      (clobber (match_dup 2))])])
16999 ;; Conditional move instructions.
17001 (define_expand "mov<mode>cc"
17002   [(set (match_operand:SWIM 0 "register_operand")
17003         (if_then_else:SWIM (match_operand 1 "comparison_operator")
17004                            (match_operand:SWIM 2 "<general_operand>")
17005                            (match_operand:SWIM 3 "<general_operand>")))]
17006   ""
17007   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
17009 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17010 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17011 ;; So just document what we're doing explicitly.
17013 (define_expand "x86_mov<mode>cc_0_m1"
17014   [(parallel
17015     [(set (match_operand:SWI48 0 "register_operand")
17016           (if_then_else:SWI48
17017             (match_operator:SWI48 2 "ix86_carry_flag_operator"
17018              [(match_operand 1 "flags_reg_operand")
17019               (const_int 0)])
17020             (const_int -1)
17021             (const_int 0)))
17022      (clobber (reg:CC FLAGS_REG))])])
17024 (define_insn "*x86_mov<mode>cc_0_m1"
17025   [(set (match_operand:SWI48 0 "register_operand" "=r")
17026         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17027                              [(reg FLAGS_REG) (const_int 0)])
17028           (const_int -1)
17029           (const_int 0)))
17030    (clobber (reg:CC FLAGS_REG))]
17031   ""
17032   "sbb{<imodesuffix>}\t%0, %0"
17033   ; Since we don't have the proper number of operands for an alu insn,
17034   ; fill in all the blanks.
17035   [(set_attr "type" "alu")
17036    (set_attr "modrm_class" "op0")
17037    (set_attr "use_carry" "1")
17038    (set_attr "pent_pair" "pu")
17039    (set_attr "memory" "none")
17040    (set_attr "imm_disp" "false")
17041    (set_attr "mode" "<MODE>")
17042    (set_attr "length_immediate" "0")])
17044 (define_insn "*x86_mov<mode>cc_0_m1_se"
17045   [(set (match_operand:SWI48 0 "register_operand" "=r")
17046         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17047                              [(reg FLAGS_REG) (const_int 0)])
17048                             (const_int 1)
17049                             (const_int 0)))
17050    (clobber (reg:CC FLAGS_REG))]
17051   ""
17052   "sbb{<imodesuffix>}\t%0, %0"
17053   [(set_attr "type" "alu")
17054    (set_attr "modrm_class" "op0")
17055    (set_attr "use_carry" "1")
17056    (set_attr "pent_pair" "pu")
17057    (set_attr "memory" "none")
17058    (set_attr "imm_disp" "false")
17059    (set_attr "mode" "<MODE>")
17060    (set_attr "length_immediate" "0")])
17062 (define_insn "*x86_mov<mode>cc_0_m1_neg"
17063   [(set (match_operand:SWI48 0 "register_operand" "=r")
17064         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17065                     [(reg FLAGS_REG) (const_int 0)])))
17066    (clobber (reg:CC FLAGS_REG))]
17067   ""
17068   "sbb{<imodesuffix>}\t%0, %0"
17069   [(set_attr "type" "alu")
17070    (set_attr "modrm_class" "op0")
17071    (set_attr "use_carry" "1")
17072    (set_attr "pent_pair" "pu")
17073    (set_attr "memory" "none")
17074    (set_attr "imm_disp" "false")
17075    (set_attr "mode" "<MODE>")
17076    (set_attr "length_immediate" "0")])
17078 (define_insn "*mov<mode>cc_noc"
17079   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
17080         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17081                                [(reg FLAGS_REG) (const_int 0)])
17082           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
17083           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
17084   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17085   "@
17086    cmov%O2%C1\t{%2, %0|%0, %2}
17087    cmov%O2%c1\t{%3, %0|%0, %3}"
17088   [(set_attr "type" "icmov")
17089    (set_attr "mode" "<MODE>")])
17091 (define_insn "*movsicc_noc_zext"
17092   [(set (match_operand:DI 0 "register_operand" "=r,r")
17093         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17094                            [(reg FLAGS_REG) (const_int 0)])
17095           (zero_extend:DI
17096             (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
17097           (zero_extend:DI
17098             (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
17099   "TARGET_64BIT
17100    && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17101   "@
17102    cmov%O2%C1\t{%2, %k0|%k0, %2}
17103    cmov%O2%c1\t{%3, %k0|%k0, %3}"
17104   [(set_attr "type" "icmov")
17105    (set_attr "mode" "SI")])
17107 ;; Don't do conditional moves with memory inputs.  This splitter helps
17108 ;; register starved x86_32 by forcing inputs into registers before reload.
17109 (define_split
17110   [(set (match_operand:SWI248 0 "register_operand")
17111         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17112                                [(reg FLAGS_REG) (const_int 0)])
17113           (match_operand:SWI248 2 "nonimmediate_operand")
17114           (match_operand:SWI248 3 "nonimmediate_operand")))]
17115   "!TARGET_64BIT && TARGET_CMOVE
17116    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17117    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17118    && can_create_pseudo_p ()
17119    && optimize_insn_for_speed_p ()"
17120   [(set (match_dup 0)
17121         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17123   if (MEM_P (operands[2]))
17124     operands[2] = force_reg (<MODE>mode, operands[2]);
17125   if (MEM_P (operands[3]))
17126     operands[3] = force_reg (<MODE>mode, operands[3]);
17129 (define_insn "*movqicc_noc"
17130   [(set (match_operand:QI 0 "register_operand" "=r,r")
17131         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17132                            [(reg FLAGS_REG) (const_int 0)])
17133                       (match_operand:QI 2 "register_operand" "r,0")
17134                       (match_operand:QI 3 "register_operand" "0,r")))]
17135   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17136   "#"
17137   [(set_attr "type" "icmov")
17138    (set_attr "mode" "QI")])
17140 (define_split
17141   [(set (match_operand:SWI12 0 "register_operand")
17142         (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
17143                               [(reg FLAGS_REG) (const_int 0)])
17144                       (match_operand:SWI12 2 "register_operand")
17145                       (match_operand:SWI12 3 "register_operand")))]
17146   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
17147    && reload_completed"
17148   [(set (match_dup 0)
17149         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17151   operands[0] = gen_lowpart (SImode, operands[0]);
17152   operands[2] = gen_lowpart (SImode, operands[2]);
17153   operands[3] = gen_lowpart (SImode, operands[3]);
17156 ;; Don't do conditional moves with memory inputs
17157 (define_peephole2
17158   [(match_scratch:SWI248 4 "r")
17159    (set (match_operand:SWI248 0 "register_operand")
17160         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17161                                [(reg FLAGS_REG) (const_int 0)])
17162           (match_operand:SWI248 2 "nonimmediate_operand")
17163           (match_operand:SWI248 3 "nonimmediate_operand")))]
17164   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17165    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17166    && optimize_insn_for_speed_p ()"
17167   [(set (match_dup 4) (match_dup 5))
17168    (set (match_dup 0)
17169         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17171   if (MEM_P (operands[2]))
17172     {
17173       operands[5] = operands[2];
17174       operands[2] = operands[4];
17175     }
17176   else if (MEM_P (operands[3]))
17177     {
17178       operands[5] = operands[3];
17179       operands[3] = operands[4];
17180     }
17181   else
17182     gcc_unreachable ();
17185 (define_peephole2
17186   [(match_scratch:SI 4 "r")
17187    (set (match_operand:DI 0 "register_operand")
17188         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17189                            [(reg FLAGS_REG) (const_int 0)])
17190           (zero_extend:DI
17191             (match_operand:SI 2 "nonimmediate_operand"))
17192           (zero_extend:DI
17193             (match_operand:SI 3 "nonimmediate_operand"))))]
17194   "TARGET_64BIT
17195    && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17196    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17197    && optimize_insn_for_speed_p ()"
17198   [(set (match_dup 4) (match_dup 5))
17199    (set (match_dup 0)
17200         (if_then_else:DI (match_dup 1)
17201           (zero_extend:DI (match_dup 2))
17202           (zero_extend:DI (match_dup 3))))]
17204   if (MEM_P (operands[2]))
17205     {
17206       operands[5] = operands[2];
17207       operands[2] = operands[4];
17208     }
17209   else if (MEM_P (operands[3]))
17210     {
17211       operands[5] = operands[3];
17212       operands[3] = operands[4];
17213     }
17214   else
17215     gcc_unreachable ();
17218 (define_expand "mov<mode>cc"
17219   [(set (match_operand:X87MODEF 0 "register_operand")
17220         (if_then_else:X87MODEF
17221           (match_operand 1 "comparison_operator")
17222           (match_operand:X87MODEF 2 "register_operand")
17223           (match_operand:X87MODEF 3 "register_operand")))]
17224   "(TARGET_80387 && TARGET_CMOVE)
17225    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17226   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
17228 (define_insn "*movxfcc_1"
17229   [(set (match_operand:XF 0 "register_operand" "=f,f")
17230         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17231                                 [(reg FLAGS_REG) (const_int 0)])
17232                       (match_operand:XF 2 "register_operand" "f,0")
17233                       (match_operand:XF 3 "register_operand" "0,f")))]
17234   "TARGET_80387 && TARGET_CMOVE"
17235   "@
17236    fcmov%F1\t{%2, %0|%0, %2}
17237    fcmov%f1\t{%3, %0|%0, %3}"
17238   [(set_attr "type" "fcmov")
17239    (set_attr "mode" "XF")])
17241 (define_insn "*movdfcc_1"
17242   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
17243         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17244                                 [(reg FLAGS_REG) (const_int 0)])
17245                       (match_operand:DF 2 "nonimmediate_operand"
17246                                                "f ,0,rm,0 ,rm,0")
17247                       (match_operand:DF 3 "nonimmediate_operand"
17248                                                "0 ,f,0 ,rm,0, rm")))]
17249   "TARGET_80387 && TARGET_CMOVE
17250    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17251   "@
17252    fcmov%F1\t{%2, %0|%0, %2}
17253    fcmov%f1\t{%3, %0|%0, %3}
17254    #
17255    #
17256    cmov%O2%C1\t{%2, %0|%0, %2}
17257    cmov%O2%c1\t{%3, %0|%0, %3}"
17258   [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
17259    (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
17260    (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
17262 (define_split
17263   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
17264         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17265                                 [(reg FLAGS_REG) (const_int 0)])
17266                       (match_operand:DF 2 "nonimmediate_operand")
17267                       (match_operand:DF 3 "nonimmediate_operand")))]
17268   "!TARGET_64BIT && reload_completed"
17269   [(set (match_dup 2)
17270         (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
17271    (set (match_dup 3)
17272         (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
17274   split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
17275   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
17278 (define_insn "*movsfcc_1_387"
17279   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
17280         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17281                                 [(reg FLAGS_REG) (const_int 0)])
17282                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
17283                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
17284   "TARGET_80387 && TARGET_CMOVE
17285    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17286   "@
17287    fcmov%F1\t{%2, %0|%0, %2}
17288    fcmov%f1\t{%3, %0|%0, %3}
17289    cmov%O2%C1\t{%2, %0|%0, %2}
17290    cmov%O2%c1\t{%3, %0|%0, %3}"
17291   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17292    (set_attr "mode" "SF,SF,SI,SI")])
17294 ;; Don't do conditional moves with memory inputs.  This splitter helps
17295 ;; register starved x86_32 by forcing inputs into registers before reload.
17296 (define_split
17297   [(set (match_operand:MODEF 0 "register_operand")
17298         (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
17299                               [(reg FLAGS_REG) (const_int 0)])
17300           (match_operand:MODEF 2 "nonimmediate_operand")
17301           (match_operand:MODEF 3 "nonimmediate_operand")))]
17302   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17303    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17304    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17305    && can_create_pseudo_p ()
17306    && optimize_insn_for_speed_p ()"
17307   [(set (match_dup 0)
17308         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17310   if (MEM_P (operands[2]))
17311     operands[2] = force_reg (<MODE>mode, operands[2]);
17312   if (MEM_P (operands[3]))
17313     operands[3] = force_reg (<MODE>mode, operands[3]);
17316 ;; Don't do conditional moves with memory inputs
17317 (define_peephole2
17318   [(match_scratch:MODEF 4 "r")
17319    (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
17320         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
17321                               [(reg FLAGS_REG) (const_int 0)])
17322           (match_operand:MODEF 2 "nonimmediate_operand")
17323           (match_operand:MODEF 3 "nonimmediate_operand")))]
17324   "(<MODE>mode != DFmode || TARGET_64BIT)
17325    && TARGET_80387 && TARGET_CMOVE
17326    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17327    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17328    && optimize_insn_for_speed_p ()"
17329   [(set (match_dup 4) (match_dup 5))
17330    (set (match_dup 0)
17331         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17333   if (MEM_P (operands[2]))
17334     {
17335       operands[5] = operands[2];
17336       operands[2] = operands[4];
17337     }
17338   else if (MEM_P (operands[3]))
17339     {
17340       operands[5] = operands[3];
17341       operands[3] = operands[4];
17342     }
17343   else
17344     gcc_unreachable ();
17347 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
17348 ;; the scalar versions to have only XMM registers as operands.
17350 ;; XOP conditional move
17351 (define_insn "*xop_pcmov_<mode>"
17352   [(set (match_operand:MODEF 0 "register_operand" "=x")
17353         (if_then_else:MODEF
17354           (match_operand:MODEF 1 "register_operand" "x")
17355           (match_operand:MODEF 2 "register_operand" "x")
17356           (match_operand:MODEF 3 "register_operand" "x")))]
17357   "TARGET_XOP"
17358   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
17359   [(set_attr "type" "sse4arg")])
17361 ;; These versions of the min/max patterns are intentionally ignorant of
17362 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
17363 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
17364 ;; are undefined in this condition, we're certain this is correct.
17366 (define_insn "<code><mode>3"
17367   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17368         (smaxmin:MODEF
17369           (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
17370           (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
17371   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17372   "@
17373    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
17374    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17375   [(set_attr "isa" "noavx,avx")
17376    (set_attr "prefix" "orig,vex")
17377    (set_attr "type" "sseadd")
17378    (set_attr "mode" "<MODE>")])
17380 ;; These versions of the min/max patterns implement exactly the operations
17381 ;;   min = (op1 < op2 ? op1 : op2)
17382 ;;   max = (!(op1 < op2) ? op1 : op2)
17383 ;; Their operands are not commutative, and thus they may be used in the
17384 ;; presence of -0.0 and NaN.
17386 (define_int_iterator IEEE_MAXMIN
17387         [UNSPEC_IEEE_MAX
17388          UNSPEC_IEEE_MIN])
17390 (define_int_attr ieee_maxmin
17391         [(UNSPEC_IEEE_MAX "max")
17392          (UNSPEC_IEEE_MIN "min")])
17394 (define_insn "*ieee_s<ieee_maxmin><mode>3"
17395   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17396         (unspec:MODEF
17397           [(match_operand:MODEF 1 "register_operand" "0,v")
17398            (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
17399           IEEE_MAXMIN))]
17400   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17401   "@
17402    <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
17403    v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17404   [(set_attr "isa" "noavx,avx")
17405    (set_attr "prefix" "orig,maybe_evex")
17406    (set_attr "type" "sseadd")
17407    (set_attr "mode" "<MODE>")])
17409 ;; Make two stack loads independent:
17410 ;;   fld aa              fld aa
17411 ;;   fld %st(0)     ->   fld bb
17412 ;;   fmul bb             fmul %st(1), %st
17414 ;; Actually we only match the last two instructions for simplicity.
17415 (define_peephole2
17416   [(set (match_operand 0 "fp_register_operand")
17417         (match_operand 1 "fp_register_operand"))
17418    (set (match_dup 0)
17419         (match_operator 2 "binary_fp_operator"
17420            [(match_dup 0)
17421             (match_operand 3 "memory_operand")]))]
17422   "REGNO (operands[0]) != REGNO (operands[1])"
17423   [(set (match_dup 0) (match_dup 3))
17424    (set (match_dup 0) (match_dup 4))]
17426   ;; The % modifier is not operational anymore in peephole2's, so we have to
17427   ;; swap the operands manually in the case of addition and multiplication.
17429   rtx op0, op1;
17431   if (COMMUTATIVE_ARITH_P (operands[2]))
17432     op0 = operands[0], op1 = operands[1];
17433   else
17434     op0 = operands[1], op1 = operands[0];
17436   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
17437                                 GET_MODE (operands[2]),
17438                                 op0, op1);
17441 ;; Conditional addition patterns
17442 (define_expand "add<mode>cc"
17443   [(match_operand:SWI 0 "register_operand")
17444    (match_operand 1 "ordered_comparison_operator")
17445    (match_operand:SWI 2 "register_operand")
17446    (match_operand:SWI 3 "const_int_operand")]
17447   ""
17448   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
17450 ;; Misc patterns (?)
17452 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17453 ;; Otherwise there will be nothing to keep
17455 ;; [(set (reg ebp) (reg esp))]
17456 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17457 ;;  (clobber (eflags)]
17458 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17460 ;; in proper program order.
17462 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
17463   [(set (match_operand:P 0 "register_operand" "=r,r")
17464         (plus:P (match_operand:P 1 "register_operand" "0,r")
17465                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
17466    (clobber (reg:CC FLAGS_REG))
17467    (clobber (mem:BLK (scratch)))]
17468   ""
17470   switch (get_attr_type (insn))
17471     {
17472     case TYPE_IMOV:
17473       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
17475     case TYPE_ALU:
17476       gcc_assert (rtx_equal_p (operands[0], operands[1]));
17477       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
17478         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
17480       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
17482     default:
17483       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17484       return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
17485     }
17487   [(set (attr "type")
17488         (cond [(and (eq_attr "alternative" "0")
17489                     (not (match_test "TARGET_OPT_AGU")))
17490                  (const_string "alu")
17491                (match_operand:<MODE> 2 "const0_operand")
17492                  (const_string "imov")
17493               ]
17494               (const_string "lea")))
17495    (set (attr "length_immediate")
17496         (cond [(eq_attr "type" "imov")
17497                  (const_string "0")
17498                (and (eq_attr "type" "alu")
17499                     (match_operand 2 "const128_operand"))
17500                  (const_string "1")
17501               ]
17502               (const_string "*")))
17503    (set_attr "mode" "<MODE>")])
17505 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
17506   [(set (match_operand:P 0 "register_operand" "=r")
17507         (minus:P (match_operand:P 1 "register_operand" "0")
17508                  (match_operand:P 2 "register_operand" "r")))
17509    (clobber (reg:CC FLAGS_REG))
17510    (clobber (mem:BLK (scratch)))]
17511   ""
17512   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
17513   [(set_attr "type" "alu")
17514    (set_attr "mode" "<MODE>")])
17516 (define_insn "allocate_stack_worker_probe_<mode>"
17517   [(set (match_operand:P 0 "register_operand" "=a")
17518         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17519                             UNSPECV_STACK_PROBE))
17520    (clobber (reg:CC FLAGS_REG))]
17521   "ix86_target_stack_probe ()"
17522   "call\t___chkstk_ms"
17523   [(set_attr "type" "multi")
17524    (set_attr "length" "5")])
17526 (define_expand "allocate_stack"
17527   [(match_operand 0 "register_operand")
17528    (match_operand 1 "general_operand")]
17529   "ix86_target_stack_probe ()"
17531   rtx x;
17533 #ifndef CHECK_STACK_LIMIT
17534 #define CHECK_STACK_LIMIT 0
17535 #endif
17537   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17538       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17539     x = operands[1];
17540   else
17541     {
17542       rtx (*insn) (rtx, rtx);
17544       x = copy_to_mode_reg (Pmode, operands[1]);
17546       insn = (TARGET_64BIT
17547               ? gen_allocate_stack_worker_probe_di
17548               : gen_allocate_stack_worker_probe_si);
17550       emit_insn (insn (x, x));
17551     }
17553   x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
17554                            stack_pointer_rtx, 0, OPTAB_DIRECT);
17556   if (x != stack_pointer_rtx)
17557     emit_move_insn (stack_pointer_rtx, x);
17559   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17560   DONE;
17563 ;; Use IOR for stack probes, this is shorter.
17564 (define_expand "probe_stack"
17565   [(match_operand 0 "memory_operand")]
17566   ""
17568   rtx (*gen_ior3) (rtx, rtx, rtx);
17570   gen_ior3 = (GET_MODE (operands[0]) == DImode
17571               ? gen_iordi3 : gen_iorsi3);
17573   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
17574   DONE;
17577 (define_insn "adjust_stack_and_probe<mode>"
17578   [(set (match_operand:P 0 "register_operand" "=r")
17579         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17580                             UNSPECV_PROBE_STACK_RANGE))
17581    (set (reg:P SP_REG)
17582         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
17583    (clobber (reg:CC FLAGS_REG))
17584    (clobber (mem:BLK (scratch)))]
17585   ""
17586   "* return output_adjust_stack_and_probe (operands[0]);"
17587   [(set_attr "type" "multi")])
17589 (define_insn "probe_stack_range<mode>"
17590   [(set (match_operand:P 0 "register_operand" "=r")
17591         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
17592                             (match_operand:P 2 "const_int_operand" "n")]
17593                             UNSPECV_PROBE_STACK_RANGE))
17594    (clobber (reg:CC FLAGS_REG))]
17595   ""
17596   "* return output_probe_stack_range (operands[0], operands[2]);"
17597   [(set_attr "type" "multi")])
17599 (define_expand "builtin_setjmp_receiver"
17600   [(label_ref (match_operand 0))]
17601   "!TARGET_64BIT && flag_pic"
17603 #if TARGET_MACHO
17604   if (TARGET_MACHO)
17605     {
17606       rtx xops[3];
17607       rtx_code_label *label_rtx = gen_label_rtx ();
17608       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17609       xops[0] = xops[1] = pic_offset_table_rtx;
17610       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17611       ix86_expand_binary_operator (MINUS, SImode, xops);
17612     }
17613   else
17614 #endif
17615     emit_insn (gen_set_got (pic_offset_table_rtx));
17616   DONE;
17619 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17620 ;; Do not split instructions with mask registers.
17621 (define_split
17622   [(set (match_operand 0 "general_reg_operand")
17623         (match_operator 3 "promotable_binary_operator"
17624            [(match_operand 1 "general_reg_operand")
17625             (match_operand 2 "aligned_operand")]))
17626    (clobber (reg:CC FLAGS_REG))]
17627   "! TARGET_PARTIAL_REG_STALL && reload_completed
17628    && ((GET_MODE (operands[0]) == HImode
17629         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17630             /* ??? next two lines just !satisfies_constraint_K (...) */
17631             || !CONST_INT_P (operands[2])
17632             || satisfies_constraint_K (operands[2])))
17633        || (GET_MODE (operands[0]) == QImode
17634            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17635   [(parallel [(set (match_dup 0)
17636                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17637               (clobber (reg:CC FLAGS_REG))])]
17639   operands[0] = gen_lowpart (SImode, operands[0]);
17640   operands[1] = gen_lowpart (SImode, operands[1]);
17641   if (GET_CODE (operands[3]) != ASHIFT)
17642     operands[2] = gen_lowpart (SImode, operands[2]);
17643   operands[3] = shallow_copy_rtx (operands[3]);
17644   PUT_MODE (operands[3], SImode);
17647 ; Promote the QImode tests, as i386 has encoding of the AND
17648 ; instruction with 32-bit sign-extended immediate and thus the
17649 ; instruction size is unchanged, except in the %eax case for
17650 ; which it is increased by one byte, hence the ! optimize_size.
17651 (define_split
17652   [(set (match_operand 0 "flags_reg_operand")
17653         (match_operator 2 "compare_operator"
17654           [(and (match_operand 3 "aligned_operand")
17655                 (match_operand 4 "const_int_operand"))
17656            (const_int 0)]))
17657    (set (match_operand 1 "register_operand")
17658         (and (match_dup 3) (match_dup 4)))]
17659   "! TARGET_PARTIAL_REG_STALL && reload_completed
17660    && optimize_insn_for_speed_p ()
17661    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17662        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17663    /* Ensure that the operand will remain sign-extended immediate.  */
17664    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17665   [(parallel [(set (match_dup 0)
17666                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17667                                     (const_int 0)]))
17668               (set (match_dup 1)
17669                    (and:SI (match_dup 3) (match_dup 4)))])]
17671   operands[4]
17672     = gen_int_mode (INTVAL (operands[4])
17673                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17674   operands[1] = gen_lowpart (SImode, operands[1]);
17675   operands[3] = gen_lowpart (SImode, operands[3]);
17678 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17679 ; the TEST instruction with 32-bit sign-extended immediate and thus
17680 ; the instruction size would at least double, which is not what we
17681 ; want even with ! optimize_size.
17682 (define_split
17683   [(set (match_operand 0 "flags_reg_operand")
17684         (match_operator 1 "compare_operator"
17685           [(and (match_operand:HI 2 "aligned_operand")
17686                 (match_operand:HI 3 "const_int_operand"))
17687            (const_int 0)]))]
17688   "! TARGET_PARTIAL_REG_STALL && reload_completed
17689    && ! TARGET_FAST_PREFIX
17690    && optimize_insn_for_speed_p ()
17691    /* Ensure that the operand will remain sign-extended immediate.  */
17692    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17693   [(set (match_dup 0)
17694         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17695                          (const_int 0)]))]
17697   operands[3]
17698     = gen_int_mode (INTVAL (operands[3])
17699                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17700   operands[2] = gen_lowpart (SImode, operands[2]);
17703 (define_split
17704   [(set (match_operand 0 "register_operand")
17705         (neg (match_operand 1 "register_operand")))
17706    (clobber (reg:CC FLAGS_REG))]
17707   "! TARGET_PARTIAL_REG_STALL && reload_completed
17708    && (GET_MODE (operands[0]) == HImode
17709        || (GET_MODE (operands[0]) == QImode
17710            && (TARGET_PROMOTE_QImode
17711                || optimize_insn_for_size_p ())))"
17712   [(parallel [(set (match_dup 0)
17713                    (neg:SI (match_dup 1)))
17714               (clobber (reg:CC FLAGS_REG))])]
17716   operands[0] = gen_lowpart (SImode, operands[0]);
17717   operands[1] = gen_lowpart (SImode, operands[1]);
17720 ;; Do not split instructions with mask regs.
17721 (define_split
17722   [(set (match_operand 0 "general_reg_operand")
17723         (not (match_operand 1 "general_reg_operand")))]
17724   "! TARGET_PARTIAL_REG_STALL && reload_completed
17725    && (GET_MODE (operands[0]) == HImode
17726        || (GET_MODE (operands[0]) == QImode
17727            && (TARGET_PROMOTE_QImode
17728                || optimize_insn_for_size_p ())))"
17729   [(set (match_dup 0)
17730         (not:SI (match_dup 1)))]
17732   operands[0] = gen_lowpart (SImode, operands[0]);
17733   operands[1] = gen_lowpart (SImode, operands[1]);
17736 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
17737 ;; transform a complex memory operation into two memory to register operations.
17739 ;; Don't push memory operands
17740 (define_peephole2
17741   [(set (match_operand:SWI 0 "push_operand")
17742         (match_operand:SWI 1 "memory_operand"))
17743    (match_scratch:SWI 2 "<r>")]
17744   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17745    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17746   [(set (match_dup 2) (match_dup 1))
17747    (set (match_dup 0) (match_dup 2))])
17749 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17750 ;; SImode pushes.
17751 (define_peephole2
17752   [(set (match_operand:SF 0 "push_operand")
17753         (match_operand:SF 1 "memory_operand"))
17754    (match_scratch:SF 2 "r")]
17755   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17756    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17757   [(set (match_dup 2) (match_dup 1))
17758    (set (match_dup 0) (match_dup 2))])
17760 ;; Don't move an immediate directly to memory when the instruction
17761 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17762 (define_peephole2
17763   [(match_scratch:SWI124 1 "<r>")
17764    (set (match_operand:SWI124 0 "memory_operand")
17765         (const_int 0))]
17766   "optimize_insn_for_speed_p ()
17767    && ((<MODE>mode == HImode
17768        && TARGET_LCP_STALL)
17769        || (!TARGET_USE_MOV0
17770           && TARGET_SPLIT_LONG_MOVES
17771           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17772    && peep2_regno_dead_p (0, FLAGS_REG)"
17773   [(parallel [(set (match_dup 2) (const_int 0))
17774               (clobber (reg:CC FLAGS_REG))])
17775    (set (match_dup 0) (match_dup 1))]
17776   "operands[2] = gen_lowpart (SImode, operands[1]);")
17778 (define_peephole2
17779   [(match_scratch:SWI124 2 "<r>")
17780    (set (match_operand:SWI124 0 "memory_operand")
17781         (match_operand:SWI124 1 "immediate_operand"))]
17782   "optimize_insn_for_speed_p ()
17783    && ((<MODE>mode == HImode
17784        && TARGET_LCP_STALL)
17785        || (TARGET_SPLIT_LONG_MOVES
17786           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17787   [(set (match_dup 2) (match_dup 1))
17788    (set (match_dup 0) (match_dup 2))])
17790 ;; Don't compare memory with zero, load and use a test instead.
17791 (define_peephole2
17792   [(set (match_operand 0 "flags_reg_operand")
17793         (match_operator 1 "compare_operator"
17794           [(match_operand:SI 2 "memory_operand")
17795            (const_int 0)]))
17796    (match_scratch:SI 3 "r")]
17797   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17798   [(set (match_dup 3) (match_dup 2))
17799    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17801 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17802 ;; Don't split NOTs with a displacement operand, because resulting XOR
17803 ;; will not be pairable anyway.
17805 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17806 ;; represented using a modRM byte.  The XOR replacement is long decoded,
17807 ;; so this split helps here as well.
17809 ;; Note: Can't do this as a regular split because we can't get proper
17810 ;; lifetime information then.
17812 (define_peephole2
17813   [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
17814         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
17815   "optimize_insn_for_speed_p ()
17816    && ((TARGET_NOT_UNPAIRABLE
17817         && (!MEM_P (operands[0])
17818             || !memory_displacement_operand (operands[0], <MODE>mode)))
17819        || (TARGET_NOT_VECTORMODE
17820            && long_memory_operand (operands[0], <MODE>mode)))
17821    && peep2_regno_dead_p (0, FLAGS_REG)"
17822   [(parallel [(set (match_dup 0)
17823                    (xor:SWI124 (match_dup 1) (const_int -1)))
17824               (clobber (reg:CC FLAGS_REG))])])
17826 ;; Non pairable "test imm, reg" instructions can be translated to
17827 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17828 ;; byte opcode instead of two, have a short form for byte operands),
17829 ;; so do it for other CPUs as well.  Given that the value was dead,
17830 ;; this should not create any new dependencies.  Pass on the sub-word
17831 ;; versions if we're concerned about partial register stalls.
17833 (define_peephole2
17834   [(set (match_operand 0 "flags_reg_operand")
17835         (match_operator 1 "compare_operator"
17836           [(and:SI (match_operand:SI 2 "register_operand")
17837                    (match_operand:SI 3 "immediate_operand"))
17838            (const_int 0)]))]
17839   "ix86_match_ccmode (insn, CCNOmode)
17840    && (true_regnum (operands[2]) != AX_REG
17841        || satisfies_constraint_K (operands[3]))
17842    && peep2_reg_dead_p (1, operands[2])"
17843   [(parallel
17844      [(set (match_dup 0)
17845            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17846                             (const_int 0)]))
17847       (set (match_dup 2)
17848            (and:SI (match_dup 2) (match_dup 3)))])])
17850 ;; We don't need to handle HImode case, because it will be promoted to SImode
17851 ;; on ! TARGET_PARTIAL_REG_STALL
17853 (define_peephole2
17854   [(set (match_operand 0 "flags_reg_operand")
17855         (match_operator 1 "compare_operator"
17856           [(and:QI (match_operand:QI 2 "register_operand")
17857                    (match_operand:QI 3 "immediate_operand"))
17858            (const_int 0)]))]
17859   "! TARGET_PARTIAL_REG_STALL
17860    && ix86_match_ccmode (insn, CCNOmode)
17861    && true_regnum (operands[2]) != AX_REG
17862    && peep2_reg_dead_p (1, operands[2])"
17863   [(parallel
17864      [(set (match_dup 0)
17865            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17866                             (const_int 0)]))
17867       (set (match_dup 2)
17868            (and:QI (match_dup 2) (match_dup 3)))])])
17870 (define_peephole2
17871   [(set (match_operand 0 "flags_reg_operand")
17872         (match_operator 1 "compare_operator"
17873           [(and:SI
17874              (zero_extract:SI
17875                (match_operand 2 "QIreg_operand")
17876                (const_int 8)
17877                (const_int 8))
17878              (match_operand 3 "const_int_operand"))
17879            (const_int 0)]))]
17880   "! TARGET_PARTIAL_REG_STALL
17881    && ix86_match_ccmode (insn, CCNOmode)
17882    && true_regnum (operands[2]) != AX_REG
17883    && peep2_reg_dead_p (1, operands[2])"
17884   [(parallel [(set (match_dup 0)
17885                    (match_op_dup 1
17886                      [(and:SI
17887                         (zero_extract:SI
17888                           (match_dup 2)
17889                           (const_int 8)
17890                           (const_int 8))
17891                         (match_dup 3))
17892                       (const_int 0)]))
17893               (set (zero_extract:SI (match_dup 2)
17894                                     (const_int 8)
17895                                     (const_int 8))
17896                    (and:SI
17897                      (zero_extract:SI
17898                        (match_dup 2)
17899                        (const_int 8)
17900                        (const_int 8))
17901                      (match_dup 3)))])])
17903 ;; Don't do logical operations with memory inputs.
17904 (define_peephole2
17905   [(match_scratch:SI 2 "r")
17906    (parallel [(set (match_operand:SI 0 "register_operand")
17907                    (match_operator:SI 3 "arith_or_logical_operator"
17908                      [(match_dup 0)
17909                       (match_operand:SI 1 "memory_operand")]))
17910               (clobber (reg:CC FLAGS_REG))])]
17911   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17912   [(set (match_dup 2) (match_dup 1))
17913    (parallel [(set (match_dup 0)
17914                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17915               (clobber (reg:CC FLAGS_REG))])])
17917 (define_peephole2
17918   [(match_scratch:SI 2 "r")
17919    (parallel [(set (match_operand:SI 0 "register_operand")
17920                    (match_operator:SI 3 "arith_or_logical_operator"
17921                      [(match_operand:SI 1 "memory_operand")
17922                       (match_dup 0)]))
17923               (clobber (reg:CC FLAGS_REG))])]
17924   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17925   [(set (match_dup 2) (match_dup 1))
17926    (parallel [(set (match_dup 0)
17927                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17928               (clobber (reg:CC FLAGS_REG))])])
17930 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17931 ;; refers to the destination of the load!
17933 (define_peephole2
17934   [(set (match_operand:SI 0 "register_operand")
17935         (match_operand:SI 1 "register_operand"))
17936    (parallel [(set (match_dup 0)
17937                    (match_operator:SI 3 "commutative_operator"
17938                      [(match_dup 0)
17939                       (match_operand:SI 2 "memory_operand")]))
17940               (clobber (reg:CC FLAGS_REG))])]
17941   "REGNO (operands[0]) != REGNO (operands[1])
17942    && GENERAL_REGNO_P (REGNO (operands[0]))
17943    && GENERAL_REGNO_P (REGNO (operands[1]))"
17944   [(set (match_dup 0) (match_dup 4))
17945    (parallel [(set (match_dup 0)
17946                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17947               (clobber (reg:CC FLAGS_REG))])]
17948   "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);")
17950 (define_peephole2
17951   [(set (match_operand 0 "register_operand")
17952         (match_operand 1 "register_operand"))
17953    (set (match_dup 0)
17954                    (match_operator 3 "commutative_operator"
17955                      [(match_dup 0)
17956                       (match_operand 2 "memory_operand")]))]
17957   "REGNO (operands[0]) != REGNO (operands[1])
17958    && ((MMX_REGNO_P (REGNO (operands[0]))
17959         && MMX_REGNO_P (REGNO (operands[1]))) 
17960        || (SSE_REGNO_P (REGNO (operands[0]))
17961            && SSE_REGNO_P (REGNO (operands[1]))))"
17962   [(set (match_dup 0) (match_dup 2))
17963    (set (match_dup 0)
17964         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17966 ; Don't do logical operations with memory outputs
17968 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17969 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17970 ; the same decoder scheduling characteristics as the original.
17972 (define_peephole2
17973   [(match_scratch:SI 2 "r")
17974    (parallel [(set (match_operand:SI 0 "memory_operand")
17975                    (match_operator:SI 3 "arith_or_logical_operator"
17976                      [(match_dup 0)
17977                       (match_operand:SI 1 "nonmemory_operand")]))
17978               (clobber (reg:CC FLAGS_REG))])]
17979   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17980    /* Do not split stack checking probes.  */
17981    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17982   [(set (match_dup 2) (match_dup 0))
17983    (parallel [(set (match_dup 2)
17984                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17985               (clobber (reg:CC FLAGS_REG))])
17986    (set (match_dup 0) (match_dup 2))])
17988 (define_peephole2
17989   [(match_scratch:SI 2 "r")
17990    (parallel [(set (match_operand:SI 0 "memory_operand")
17991                    (match_operator:SI 3 "arith_or_logical_operator"
17992                      [(match_operand:SI 1 "nonmemory_operand")
17993                       (match_dup 0)]))
17994               (clobber (reg:CC FLAGS_REG))])]
17995   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17996    /* Do not split stack checking probes.  */
17997    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17998   [(set (match_dup 2) (match_dup 0))
17999    (parallel [(set (match_dup 2)
18000                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18001               (clobber (reg:CC FLAGS_REG))])
18002    (set (match_dup 0) (match_dup 2))])
18004 ;; Attempt to use arith or logical operations with memory outputs with
18005 ;; setting of flags.
18006 (define_peephole2
18007   [(set (match_operand:SWI 0 "register_operand")
18008         (match_operand:SWI 1 "memory_operand"))
18009    (parallel [(set (match_dup 0)
18010                    (match_operator:SWI 3 "plusminuslogic_operator"
18011                      [(match_dup 0)
18012                       (match_operand:SWI 2 "<nonmemory_operand>")]))
18013               (clobber (reg:CC FLAGS_REG))])
18014    (set (match_dup 1) (match_dup 0))
18015    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18016   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18017    && peep2_reg_dead_p (4, operands[0])
18018    && !reg_overlap_mentioned_p (operands[0], operands[1])
18019    && !reg_overlap_mentioned_p (operands[0], operands[2])
18020    && (<MODE>mode != QImode
18021        || immediate_operand (operands[2], QImode)
18022        || any_QIreg_operand (operands[2], QImode))
18023    && ix86_match_ccmode (peep2_next_insn (3),
18024                          (GET_CODE (operands[3]) == PLUS
18025                           || GET_CODE (operands[3]) == MINUS)
18026                          ? CCGOCmode : CCNOmode)"
18027   [(parallel [(set (match_dup 4) (match_dup 5))
18028               (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
18029                                                   (match_dup 2)]))])]
18031   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18032   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
18033                                 copy_rtx (operands[1]),
18034                                 copy_rtx (operands[2]));
18035   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
18036                                  operands[5], const0_rtx);
18039 (define_peephole2
18040   [(parallel [(set (match_operand:SWI 0 "register_operand")
18041                    (match_operator:SWI 2 "plusminuslogic_operator"
18042                      [(match_dup 0)
18043                       (match_operand:SWI 1 "memory_operand")]))
18044               (clobber (reg:CC FLAGS_REG))])
18045    (set (match_dup 1) (match_dup 0))
18046    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18047   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18048    && GET_CODE (operands[2]) != MINUS
18049    && peep2_reg_dead_p (3, operands[0])
18050    && !reg_overlap_mentioned_p (operands[0], operands[1])
18051    && ix86_match_ccmode (peep2_next_insn (2),
18052                          GET_CODE (operands[2]) == PLUS
18053                          ? CCGOCmode : CCNOmode)"
18054   [(parallel [(set (match_dup 3) (match_dup 4))
18055               (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
18056                                                   (match_dup 0)]))])]
18058   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
18059   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
18060                                 copy_rtx (operands[1]),
18061                                 copy_rtx (operands[0]));
18062   operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
18063                                  operands[4], const0_rtx);
18066 (define_peephole2
18067   [(set (match_operand:SWI12 0 "register_operand")
18068         (match_operand:SWI12 1 "memory_operand"))
18069    (parallel [(set (match_operand:SI 4 "register_operand")
18070                    (match_operator:SI 3 "plusminuslogic_operator"
18071                      [(match_dup 4)
18072                       (match_operand:SI 2 "nonmemory_operand")]))
18073               (clobber (reg:CC FLAGS_REG))])
18074    (set (match_dup 1) (match_dup 0))
18075    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18076   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18077    && REG_P (operands[0]) && REG_P (operands[4])
18078    && REGNO (operands[0]) == REGNO (operands[4])
18079    && peep2_reg_dead_p (4, operands[0])
18080    && (<MODE>mode != QImode
18081        || immediate_operand (operands[2], SImode)
18082        || any_QIreg_operand (operands[2], SImode))
18083    && !reg_overlap_mentioned_p (operands[0], operands[1])
18084    && !reg_overlap_mentioned_p (operands[0], operands[2])
18085    && ix86_match_ccmode (peep2_next_insn (3),
18086                          (GET_CODE (operands[3]) == PLUS
18087                           || GET_CODE (operands[3]) == MINUS)
18088                          ? CCGOCmode : CCNOmode)"
18089   [(parallel [(set (match_dup 4) (match_dup 5))
18090               (set (match_dup 1) (match_dup 6))])]
18092   operands[2] = gen_lowpart (<MODE>mode, operands[2]);
18093   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18094   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
18095                                 copy_rtx (operands[1]), operands[2]);
18096   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
18097                                  operands[5], const0_rtx);
18098   operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
18099                                 copy_rtx (operands[1]),
18100                                 copy_rtx (operands[2]));
18103 ;; Attempt to always use XOR for zeroing registers.
18104 (define_peephole2
18105   [(set (match_operand 0 "register_operand")
18106         (match_operand 1 "const0_operand"))]
18107   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
18108    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18109    && GENERAL_REGNO_P (REGNO (operands[0]))
18110    && peep2_regno_dead_p (0, FLAGS_REG)"
18111   [(parallel [(set (match_dup 0) (const_int 0))
18112               (clobber (reg:CC FLAGS_REG))])]
18113   "operands[0] = gen_lowpart (word_mode, operands[0]);")
18115 (define_peephole2
18116   [(set (strict_low_part (match_operand 0 "register_operand"))
18117         (const_int 0))]
18118   "(GET_MODE (operands[0]) == QImode
18119     || GET_MODE (operands[0]) == HImode)
18120    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18121    && peep2_regno_dead_p (0, FLAGS_REG)"
18122   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18123               (clobber (reg:CC FLAGS_REG))])])
18125 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
18126 (define_peephole2
18127   [(set (match_operand:SWI248 0 "register_operand")
18128         (const_int -1))]
18129   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
18130    && GENERAL_REGNO_P (REGNO (operands[0]))
18131    && peep2_regno_dead_p (0, FLAGS_REG)"
18132   [(parallel [(set (match_dup 0) (const_int -1))
18133               (clobber (reg:CC FLAGS_REG))])]
18135   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
18136     operands[0] = gen_lowpart (SImode, operands[0]);
18139 ;; Attempt to convert simple lea to add/shift.
18140 ;; These can be created by move expanders.
18141 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
18142 ;; relevant lea instructions were already split.
18144 (define_peephole2
18145   [(set (match_operand:SWI48 0 "register_operand")
18146         (plus:SWI48 (match_dup 0)
18147                     (match_operand:SWI48 1 "<nonmemory_operand>")))]
18148   "!TARGET_OPT_AGU
18149    && peep2_regno_dead_p (0, FLAGS_REG)"
18150   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18151               (clobber (reg:CC FLAGS_REG))])])
18153 (define_peephole2
18154   [(set (match_operand:SWI48 0 "register_operand")
18155         (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
18156                     (match_dup 0)))]
18157   "!TARGET_OPT_AGU
18158    && peep2_regno_dead_p (0, FLAGS_REG)"
18159   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18160               (clobber (reg:CC FLAGS_REG))])])
18162 (define_peephole2
18163   [(set (match_operand:DI 0 "register_operand")
18164         (zero_extend:DI
18165           (plus:SI (match_operand:SI 1 "register_operand")
18166                    (match_operand:SI 2 "nonmemory_operand"))))]
18167   "TARGET_64BIT && !TARGET_OPT_AGU
18168    && REGNO (operands[0]) == REGNO (operands[1])
18169    && peep2_regno_dead_p (0, FLAGS_REG)"
18170   [(parallel [(set (match_dup 0)
18171                    (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
18172               (clobber (reg:CC FLAGS_REG))])])
18174 (define_peephole2
18175   [(set (match_operand:DI 0 "register_operand")
18176         (zero_extend:DI
18177           (plus:SI (match_operand:SI 1 "nonmemory_operand")
18178                    (match_operand:SI 2 "register_operand"))))]
18179   "TARGET_64BIT && !TARGET_OPT_AGU
18180    && REGNO (operands[0]) == REGNO (operands[2])
18181    && peep2_regno_dead_p (0, FLAGS_REG)"
18182   [(parallel [(set (match_dup 0)
18183                    (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
18184               (clobber (reg:CC FLAGS_REG))])])
18186 (define_peephole2
18187   [(set (match_operand:SWI48 0 "register_operand")
18188         (mult:SWI48 (match_dup 0)
18189                     (match_operand:SWI48 1 "const_int_operand")))]
18190   "exact_log2 (INTVAL (operands[1])) >= 0
18191    && peep2_regno_dead_p (0, FLAGS_REG)"
18192   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
18193               (clobber (reg:CC FLAGS_REG))])]
18194   "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18196 (define_peephole2
18197   [(set (match_operand:DI 0 "register_operand")
18198         (zero_extend:DI
18199           (mult:SI (match_operand:SI 1 "register_operand")
18200                    (match_operand:SI 2 "const_int_operand"))))]
18201   "TARGET_64BIT
18202    && exact_log2 (INTVAL (operands[2])) >= 0
18203    && REGNO (operands[0]) == REGNO (operands[1])
18204    && peep2_regno_dead_p (0, FLAGS_REG)"
18205   [(parallel [(set (match_dup 0)
18206                    (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
18207               (clobber (reg:CC FLAGS_REG))])]
18208   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18210 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
18211 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
18212 ;; On many CPUs it is also faster, since special hardware to avoid esp
18213 ;; dependencies is present.
18215 ;; While some of these conversions may be done using splitters, we use
18216 ;; peepholes in order to allow combine_stack_adjustments pass to see
18217 ;; nonobfuscated RTL.
18219 ;; Convert prologue esp subtractions to push.
18220 ;; We need register to push.  In order to keep verify_flow_info happy we have
18221 ;; two choices
18222 ;; - use scratch and clobber it in order to avoid dependencies
18223 ;; - use already live register
18224 ;; We can't use the second way right now, since there is no reliable way how to
18225 ;; verify that given register is live.  First choice will also most likely in
18226 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
18227 ;; call clobbered registers are dead.  We may want to use base pointer as an
18228 ;; alternative when no register is available later.
18230 (define_peephole2
18231   [(match_scratch:W 1 "r")
18232    (parallel [(set (reg:P SP_REG)
18233                    (plus:P (reg:P SP_REG)
18234                            (match_operand:P 0 "const_int_operand")))
18235               (clobber (reg:CC FLAGS_REG))
18236               (clobber (mem:BLK (scratch)))])]
18237   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
18238    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
18239    && !ix86_using_red_zone ()"
18240   [(clobber (match_dup 1))
18241    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18242               (clobber (mem:BLK (scratch)))])])
18244 (define_peephole2
18245   [(match_scratch:W 1 "r")
18246    (parallel [(set (reg:P SP_REG)
18247                    (plus:P (reg:P SP_REG)
18248                            (match_operand:P 0 "const_int_operand")))
18249               (clobber (reg:CC FLAGS_REG))
18250               (clobber (mem:BLK (scratch)))])]
18251   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
18252    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
18253    && !ix86_using_red_zone ()"
18254   [(clobber (match_dup 1))
18255    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18256    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18257               (clobber (mem:BLK (scratch)))])])
18259 ;; Convert esp subtractions to push.
18260 (define_peephole2
18261   [(match_scratch:W 1 "r")
18262    (parallel [(set (reg:P SP_REG)
18263                    (plus:P (reg:P SP_REG)
18264                            (match_operand:P 0 "const_int_operand")))
18265               (clobber (reg:CC FLAGS_REG))])]
18266   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
18267    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
18268    && !ix86_using_red_zone ()"
18269   [(clobber (match_dup 1))
18270    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
18272 (define_peephole2
18273   [(match_scratch:W 1 "r")
18274    (parallel [(set (reg:P SP_REG)
18275                    (plus:P (reg:P SP_REG)
18276                            (match_operand:P 0 "const_int_operand")))
18277               (clobber (reg:CC FLAGS_REG))])]
18278   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
18279    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
18280    && !ix86_using_red_zone ()"
18281   [(clobber (match_dup 1))
18282    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18283    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
18285 ;; Convert epilogue deallocator to pop.
18286 (define_peephole2
18287   [(match_scratch:W 1 "r")
18288    (parallel [(set (reg:P SP_REG)
18289                    (plus:P (reg:P SP_REG)
18290                            (match_operand:P 0 "const_int_operand")))
18291               (clobber (reg:CC FLAGS_REG))
18292               (clobber (mem:BLK (scratch)))])]
18293   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
18294    && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
18295   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18296               (clobber (mem:BLK (scratch)))])])
18298 ;; Two pops case is tricky, since pop causes dependency
18299 ;; on destination register.  We use two registers if available.
18300 (define_peephole2
18301   [(match_scratch:W 1 "r")
18302    (match_scratch:W 2 "r")
18303    (parallel [(set (reg:P SP_REG)
18304                    (plus:P (reg:P SP_REG)
18305                            (match_operand:P 0 "const_int_operand")))
18306               (clobber (reg:CC FLAGS_REG))
18307               (clobber (mem:BLK (scratch)))])]
18308   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
18309    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18310   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18311               (clobber (mem:BLK (scratch)))])
18312    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
18314 (define_peephole2
18315   [(match_scratch:W 1 "r")
18316    (parallel [(set (reg:P SP_REG)
18317                    (plus:P (reg:P SP_REG)
18318                            (match_operand:P 0 "const_int_operand")))
18319               (clobber (reg:CC FLAGS_REG))
18320               (clobber (mem:BLK (scratch)))])]
18321   "optimize_insn_for_size_p ()
18322    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18323   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18324               (clobber (mem:BLK (scratch)))])
18325    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18327 ;; Convert esp additions to pop.
18328 (define_peephole2
18329   [(match_scratch:W 1 "r")
18330    (parallel [(set (reg:P SP_REG)
18331                    (plus:P (reg:P SP_REG)
18332                            (match_operand:P 0 "const_int_operand")))
18333               (clobber (reg:CC FLAGS_REG))])]
18334   "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
18335   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18337 ;; Two pops case is tricky, since pop causes dependency
18338 ;; on destination register.  We use two registers if available.
18339 (define_peephole2
18340   [(match_scratch:W 1 "r")
18341    (match_scratch:W 2 "r")
18342    (parallel [(set (reg:P SP_REG)
18343                    (plus:P (reg:P SP_REG)
18344                            (match_operand:P 0 "const_int_operand")))
18345               (clobber (reg:CC FLAGS_REG))])]
18346   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18347   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18348    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
18350 (define_peephole2
18351   [(match_scratch:W 1 "r")
18352    (parallel [(set (reg:P SP_REG)
18353                    (plus:P (reg:P SP_REG)
18354                            (match_operand:P 0 "const_int_operand")))
18355               (clobber (reg:CC FLAGS_REG))])]
18356   "optimize_insn_for_size_p ()
18357    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18358   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18359    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18361 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18362 ;; required and register dies.  Similarly for 128 to -128.
18363 (define_peephole2
18364   [(set (match_operand 0 "flags_reg_operand")
18365         (match_operator 1 "compare_operator"
18366           [(match_operand 2 "register_operand")
18367            (match_operand 3 "const_int_operand")]))]
18368   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
18369      && incdec_operand (operands[3], GET_MODE (operands[3])))
18370     || (!TARGET_FUSE_CMP_AND_BRANCH
18371         && INTVAL (operands[3]) == 128))
18372    && ix86_match_ccmode (insn, CCGCmode)
18373    && peep2_reg_dead_p (1, operands[2])"
18374   [(parallel [(set (match_dup 0)
18375                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
18376               (clobber (match_dup 2))])])
18378 ;; Convert imul by three, five and nine into lea
18379 (define_peephole2
18380   [(parallel
18381     [(set (match_operand:SWI48 0 "register_operand")
18382           (mult:SWI48 (match_operand:SWI48 1 "register_operand")
18383                       (match_operand:SWI48 2 "const359_operand")))
18384      (clobber (reg:CC FLAGS_REG))])]
18385   "!TARGET_PARTIAL_REG_STALL
18386    || <MODE>mode == SImode
18387    || optimize_function_for_size_p (cfun)"
18388   [(set (match_dup 0)
18389         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
18390                     (match_dup 1)))]
18391   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18393 (define_peephole2
18394   [(parallel
18395     [(set (match_operand:SWI48 0 "register_operand")
18396           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
18397                       (match_operand:SWI48 2 "const359_operand")))
18398      (clobber (reg:CC FLAGS_REG))])]
18399   "optimize_insn_for_speed_p ()
18400    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
18401   [(set (match_dup 0) (match_dup 1))
18402    (set (match_dup 0)
18403         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
18404                     (match_dup 0)))]
18405   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18407 ;; imul $32bit_imm, mem, reg is vector decoded, while
18408 ;; imul $32bit_imm, reg, reg is direct decoded.
18409 (define_peephole2
18410   [(match_scratch:SWI48 3 "r")
18411    (parallel [(set (match_operand:SWI48 0 "register_operand")
18412                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
18413                                (match_operand:SWI48 2 "immediate_operand")))
18414               (clobber (reg:CC FLAGS_REG))])]
18415   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18416    && !satisfies_constraint_K (operands[2])"
18417   [(set (match_dup 3) (match_dup 1))
18418    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
18419               (clobber (reg:CC FLAGS_REG))])])
18421 (define_peephole2
18422   [(match_scratch:SI 3 "r")
18423    (parallel [(set (match_operand:DI 0 "register_operand")
18424                    (zero_extend:DI
18425                      (mult:SI (match_operand:SI 1 "memory_operand")
18426                               (match_operand:SI 2 "immediate_operand"))))
18427               (clobber (reg:CC FLAGS_REG))])]
18428   "TARGET_64BIT
18429    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18430    && !satisfies_constraint_K (operands[2])"
18431   [(set (match_dup 3) (match_dup 1))
18432    (parallel [(set (match_dup 0)
18433                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18434               (clobber (reg:CC FLAGS_REG))])])
18436 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18437 ;; Convert it into imul reg, reg
18438 ;; It would be better to force assembler to encode instruction using long
18439 ;; immediate, but there is apparently no way to do so.
18440 (define_peephole2
18441   [(parallel [(set (match_operand:SWI248 0 "register_operand")
18442                    (mult:SWI248
18443                     (match_operand:SWI248 1 "nonimmediate_operand")
18444                     (match_operand:SWI248 2 "const_int_operand")))
18445               (clobber (reg:CC FLAGS_REG))])
18446    (match_scratch:SWI248 3 "r")]
18447   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18448    && satisfies_constraint_K (operands[2])"
18449   [(set (match_dup 3) (match_dup 2))
18450    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
18451               (clobber (reg:CC FLAGS_REG))])]
18453   if (!rtx_equal_p (operands[0], operands[1]))
18454     emit_move_insn (operands[0], operands[1]);
18457 ;; After splitting up read-modify operations, array accesses with memory
18458 ;; operands might end up in form:
18459 ;;  sall    $2, %eax
18460 ;;  movl    4(%esp), %edx
18461 ;;  addl    %edx, %eax
18462 ;; instead of pre-splitting:
18463 ;;  sall    $2, %eax
18464 ;;  addl    4(%esp), %eax
18465 ;; Turn it into:
18466 ;;  movl    4(%esp), %edx
18467 ;;  leal    (%edx,%eax,4), %eax
18469 (define_peephole2
18470   [(match_scratch:W 5 "r")
18471    (parallel [(set (match_operand 0 "register_operand")
18472                    (ashift (match_operand 1 "register_operand")
18473                            (match_operand 2 "const_int_operand")))
18474                (clobber (reg:CC FLAGS_REG))])
18475    (parallel [(set (match_operand 3 "register_operand")
18476                    (plus (match_dup 0)
18477                          (match_operand 4 "x86_64_general_operand")))
18478                    (clobber (reg:CC FLAGS_REG))])]
18479   "IN_RANGE (INTVAL (operands[2]), 1, 3)
18480    /* Validate MODE for lea.  */
18481    && ((!TARGET_PARTIAL_REG_STALL
18482         && (GET_MODE (operands[0]) == QImode
18483             || GET_MODE (operands[0]) == HImode))
18484        || GET_MODE (operands[0]) == SImode
18485        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18486    && (rtx_equal_p (operands[0], operands[3])
18487        || peep2_reg_dead_p (2, operands[0]))
18488    /* We reorder load and the shift.  */
18489    && !reg_overlap_mentioned_p (operands[0], operands[4])"
18490   [(set (match_dup 5) (match_dup 4))
18491    (set (match_dup 0) (match_dup 1))]
18493   machine_mode op1mode = GET_MODE (operands[1]);
18494   machine_mode mode = op1mode == DImode ? DImode : SImode;
18495   int scale = 1 << INTVAL (operands[2]);
18496   rtx index = gen_lowpart (word_mode, operands[1]);
18497   rtx base = gen_lowpart (word_mode, operands[5]);
18498   rtx dest = gen_lowpart (mode, operands[3]);
18500   operands[1] = gen_rtx_PLUS (word_mode, base,
18501                               gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
18502   if (mode != word_mode)
18503     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18505   operands[5] = base;
18506   if (op1mode != word_mode)
18507     operands[5] = gen_lowpart (op1mode, operands[5]);
18509   operands[0] = dest;
18512 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18513 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18514 ;; caught for use by garbage collectors and the like.  Using an insn that
18515 ;; maps to SIGILL makes it more likely the program will rightfully die.
18516 ;; Keeping with tradition, "6" is in honor of #UD.
18517 (define_insn "trap"
18518   [(trap_if (const_int 1) (const_int 6))]
18519   ""
18521 #ifdef HAVE_AS_IX86_UD2
18522   return "ud2";
18523 #else
18524   return ASM_SHORT "0x0b0f";
18525 #endif
18527   [(set_attr "length" "2")])
18529 (define_expand "prefetch"
18530   [(prefetch (match_operand 0 "address_operand")
18531              (match_operand:SI 1 "const_int_operand")
18532              (match_operand:SI 2 "const_int_operand"))]
18533   "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18535   bool write = INTVAL (operands[1]) != 0;
18536   int locality = INTVAL (operands[2]);
18538   gcc_assert (IN_RANGE (locality, 0, 3));
18540   /* Use 3dNOW prefetch in case we are asking for write prefetch not
18541      supported by SSE counterpart or the SSE prefetch is not available
18542      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
18543      of locality.  */
18544   if (TARGET_PREFETCHWT1 && write && locality <= 2)
18545     operands[2] = const2_rtx;
18546   else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
18547     operands[2] = GEN_INT (3);
18548   else
18549     operands[1] = const0_rtx;
18552 (define_insn "*prefetch_sse"
18553   [(prefetch (match_operand 0 "address_operand" "p")
18554              (const_int 0)
18555              (match_operand:SI 1 "const_int_operand"))]
18556   "TARGET_PREFETCH_SSE"
18558   static const char * const patterns[4] = {
18559    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18560   };
18562   int locality = INTVAL (operands[1]);
18563   gcc_assert (IN_RANGE (locality, 0, 3));
18565   return patterns[locality];
18567   [(set_attr "type" "sse")
18568    (set_attr "atom_sse_attr" "prefetch")
18569    (set (attr "length_address")
18570         (symbol_ref "memory_address_length (operands[0], false)"))
18571    (set_attr "memory" "none")])
18573 (define_insn "*prefetch_3dnow"
18574   [(prefetch (match_operand 0 "address_operand" "p")
18575              (match_operand:SI 1 "const_int_operand" "n")
18576              (const_int 3))]
18577   "TARGET_PRFCHW"
18579   if (INTVAL (operands[1]) == 0)
18580     return "prefetch\t%a0";
18581   else
18582     return "prefetchw\t%a0";
18584   [(set_attr "type" "mmx")
18585    (set (attr "length_address")
18586         (symbol_ref "memory_address_length (operands[0], false)"))
18587    (set_attr "memory" "none")])
18589 (define_insn "*prefetch_prefetchwt1"
18590   [(prefetch (match_operand 0 "address_operand" "p")
18591              (const_int 1)
18592              (const_int 2))]
18593   "TARGET_PREFETCHWT1"
18594   "prefetchwt1\t%a0";
18595   [(set_attr "type" "sse")
18596    (set (attr "length_address")
18597         (symbol_ref "memory_address_length (operands[0], false)"))
18598    (set_attr "memory" "none")])
18600 (define_expand "stack_protect_set"
18601   [(match_operand 0 "memory_operand")
18602    (match_operand 1 "memory_operand")]
18603   "TARGET_SSP_TLS_GUARD"
18605   rtx (*insn)(rtx, rtx);
18607 #ifdef TARGET_THREAD_SSP_OFFSET
18608   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18609   insn = (TARGET_LP64
18610           ? gen_stack_tls_protect_set_di
18611           : gen_stack_tls_protect_set_si);
18612 #else
18613   insn = (TARGET_LP64
18614           ? gen_stack_protect_set_di
18615           : gen_stack_protect_set_si);
18616 #endif
18618   emit_insn (insn (operands[0], operands[1]));
18619   DONE;
18622 (define_insn "stack_protect_set_<mode>"
18623   [(set (match_operand:PTR 0 "memory_operand" "=m")
18624         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
18625                     UNSPEC_SP_SET))
18626    (set (match_scratch:PTR 2 "=&r") (const_int 0))
18627    (clobber (reg:CC FLAGS_REG))]
18628   "TARGET_SSP_TLS_GUARD"
18629   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18630   [(set_attr "type" "multi")])
18632 (define_insn "stack_tls_protect_set_<mode>"
18633   [(set (match_operand:PTR 0 "memory_operand" "=m")
18634         (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
18635                     UNSPEC_SP_TLS_SET))
18636    (set (match_scratch:PTR 2 "=&r") (const_int 0))
18637    (clobber (reg:CC FLAGS_REG))]
18638   ""
18639   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18640   [(set_attr "type" "multi")])
18642 (define_expand "stack_protect_test"
18643   [(match_operand 0 "memory_operand")
18644    (match_operand 1 "memory_operand")
18645    (match_operand 2)]
18646   "TARGET_SSP_TLS_GUARD"
18648   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18650   rtx (*insn)(rtx, rtx, rtx);
18652 #ifdef TARGET_THREAD_SSP_OFFSET
18653   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18654   insn = (TARGET_LP64
18655           ? gen_stack_tls_protect_test_di
18656           : gen_stack_tls_protect_test_si);
18657 #else
18658   insn = (TARGET_LP64
18659           ? gen_stack_protect_test_di
18660           : gen_stack_protect_test_si);
18661 #endif
18663   emit_insn (insn (flags, operands[0], operands[1]));
18665   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18666                                   flags, const0_rtx, operands[2]));
18667   DONE;
18670 (define_insn "stack_protect_test_<mode>"
18671   [(set (match_operand:CCZ 0 "flags_reg_operand")
18672         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18673                      (match_operand:PTR 2 "memory_operand" "m")]
18674                     UNSPEC_SP_TEST))
18675    (clobber (match_scratch:PTR 3 "=&r"))]
18676   "TARGET_SSP_TLS_GUARD"
18677   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18678   [(set_attr "type" "multi")])
18680 (define_insn "stack_tls_protect_test_<mode>"
18681   [(set (match_operand:CCZ 0 "flags_reg_operand")
18682         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18683                      (match_operand:PTR 2 "const_int_operand" "i")]
18684                     UNSPEC_SP_TLS_TEST))
18685    (clobber (match_scratch:PTR 3 "=r"))]
18686   ""
18687   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
18688   [(set_attr "type" "multi")])
18690 (define_insn "sse4_2_crc32<mode>"
18691   [(set (match_operand:SI 0 "register_operand" "=r")
18692         (unspec:SI
18693           [(match_operand:SI 1 "register_operand" "0")
18694            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18695           UNSPEC_CRC32))]
18696   "TARGET_SSE4_2 || TARGET_CRC32"
18697   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18698   [(set_attr "type" "sselog1")
18699    (set_attr "prefix_rep" "1")
18700    (set_attr "prefix_extra" "1")
18701    (set (attr "prefix_data16")
18702      (if_then_else (match_operand:HI 2)
18703        (const_string "1")
18704        (const_string "*")))
18705    (set (attr "prefix_rex")
18706      (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18707        (const_string "1")
18708        (const_string "*")))
18709    (set_attr "mode" "SI")])
18711 (define_insn "sse4_2_crc32di"
18712   [(set (match_operand:DI 0 "register_operand" "=r")
18713         (unspec:DI
18714           [(match_operand:DI 1 "register_operand" "0")
18715            (match_operand:DI 2 "nonimmediate_operand" "rm")]
18716           UNSPEC_CRC32))]
18717   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18718   "crc32{q}\t{%2, %0|%0, %2}"
18719   [(set_attr "type" "sselog1")
18720    (set_attr "prefix_rep" "1")
18721    (set_attr "prefix_extra" "1")
18722    (set_attr "mode" "DI")])
18724 (define_insn "rdpmc"
18725   [(set (match_operand:DI 0 "register_operand" "=A")
18726         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18727                             UNSPECV_RDPMC))]
18728   "!TARGET_64BIT"
18729   "rdpmc"
18730   [(set_attr "type" "other")
18731    (set_attr "length" "2")])
18733 (define_insn "rdpmc_rex64"
18734   [(set (match_operand:DI 0 "register_operand" "=a")
18735         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18736                             UNSPECV_RDPMC))
18737    (set (match_operand:DI 1 "register_operand" "=d")
18738         (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18739   "TARGET_64BIT"
18740   "rdpmc"
18741   [(set_attr "type" "other")
18742    (set_attr "length" "2")])
18744 (define_insn "rdtsc"
18745   [(set (match_operand:DI 0 "register_operand" "=A")
18746         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18747   "!TARGET_64BIT"
18748   "rdtsc"
18749   [(set_attr "type" "other")
18750    (set_attr "length" "2")])
18752 (define_insn "rdtsc_rex64"
18753   [(set (match_operand:DI 0 "register_operand" "=a")
18754         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18755    (set (match_operand:DI 1 "register_operand" "=d")
18756         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18757   "TARGET_64BIT"
18758   "rdtsc"
18759   [(set_attr "type" "other")
18760    (set_attr "length" "2")])
18762 (define_insn "rdtscp"
18763   [(set (match_operand:DI 0 "register_operand" "=A")
18764         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18765    (set (match_operand:SI 1 "register_operand" "=c")
18766         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18767   "!TARGET_64BIT"
18768   "rdtscp"
18769   [(set_attr "type" "other")
18770    (set_attr "length" "3")])
18772 (define_insn "rdtscp_rex64"
18773   [(set (match_operand:DI 0 "register_operand" "=a")
18774         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18775    (set (match_operand:DI 1 "register_operand" "=d")
18776         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18777    (set (match_operand:SI 2 "register_operand" "=c")
18778         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18779   "TARGET_64BIT"
18780   "rdtscp"
18781   [(set_attr "type" "other")
18782    (set_attr "length" "3")])
18784 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18786 ;; FXSR, XSAVE and XSAVEOPT instructions
18788 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18790 (define_insn "fxsave"
18791   [(set (match_operand:BLK 0 "memory_operand" "=m")
18792         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18793   "TARGET_FXSR"
18794   "fxsave\t%0"
18795   [(set_attr "type" "other")
18796    (set_attr "memory" "store")
18797    (set (attr "length")
18798         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18800 (define_insn "fxsave64"
18801   [(set (match_operand:BLK 0 "memory_operand" "=m")
18802         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18803   "TARGET_64BIT && TARGET_FXSR"
18804   "fxsave64\t%0"
18805   [(set_attr "type" "other")
18806    (set_attr "memory" "store")
18807    (set (attr "length")
18808         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18810 (define_insn "fxrstor"
18811   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18812                     UNSPECV_FXRSTOR)]
18813   "TARGET_FXSR"
18814   "fxrstor\t%0"
18815   [(set_attr "type" "other")
18816    (set_attr "memory" "load")
18817    (set (attr "length")
18818         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18820 (define_insn "fxrstor64"
18821   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18822                     UNSPECV_FXRSTOR64)]
18823   "TARGET_64BIT && TARGET_FXSR"
18824   "fxrstor64\t%0"
18825   [(set_attr "type" "other")
18826    (set_attr "memory" "load")
18827    (set (attr "length")
18828         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18830 (define_int_iterator ANY_XSAVE
18831         [UNSPECV_XSAVE
18832          (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
18833          (UNSPECV_XSAVEC "TARGET_XSAVEC")
18834          (UNSPECV_XSAVES "TARGET_XSAVES")])
18836 (define_int_iterator ANY_XSAVE64
18837         [UNSPECV_XSAVE64
18838          (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
18839          (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
18840          (UNSPECV_XSAVES64 "TARGET_XSAVES")])
18842 (define_int_attr xsave
18843         [(UNSPECV_XSAVE "xsave")
18844          (UNSPECV_XSAVE64 "xsave64")
18845          (UNSPECV_XSAVEOPT "xsaveopt")
18846          (UNSPECV_XSAVEOPT64 "xsaveopt64")
18847          (UNSPECV_XSAVEC "xsavec")
18848          (UNSPECV_XSAVEC64 "xsavec64")
18849          (UNSPECV_XSAVES "xsaves")
18850          (UNSPECV_XSAVES64 "xsaves64")])
18852 (define_int_iterator ANY_XRSTOR
18853         [UNSPECV_XRSTOR
18854          (UNSPECV_XRSTORS "TARGET_XSAVES")])
18856 (define_int_iterator ANY_XRSTOR64
18857         [UNSPECV_XRSTOR64
18858          (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
18860 (define_int_attr xrstor
18861         [(UNSPECV_XRSTOR "xrstor")
18862          (UNSPECV_XRSTOR64 "xrstor")
18863          (UNSPECV_XRSTORS "xrstors")
18864          (UNSPECV_XRSTORS64 "xrstors")])
18866 (define_insn "<xsave>"
18867   [(set (match_operand:BLK 0 "memory_operand" "=m")
18868         (unspec_volatile:BLK
18869          [(match_operand:DI 1 "register_operand" "A")]
18870          ANY_XSAVE))]
18871   "!TARGET_64BIT && TARGET_XSAVE"
18872   "<xsave>\t%0"
18873   [(set_attr "type" "other")
18874    (set_attr "memory" "store")
18875    (set (attr "length")
18876         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18878 (define_insn "<xsave>_rex64"
18879   [(set (match_operand:BLK 0 "memory_operand" "=m")
18880         (unspec_volatile:BLK
18881          [(match_operand:SI 1 "register_operand" "a")
18882           (match_operand:SI 2 "register_operand" "d")]
18883          ANY_XSAVE))]
18884   "TARGET_64BIT && TARGET_XSAVE"
18885   "<xsave>\t%0"
18886   [(set_attr "type" "other")
18887    (set_attr "memory" "store")
18888    (set (attr "length")
18889         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18891 (define_insn "<xsave>"
18892   [(set (match_operand:BLK 0 "memory_operand" "=m")
18893         (unspec_volatile:BLK
18894          [(match_operand:SI 1 "register_operand" "a")
18895           (match_operand:SI 2 "register_operand" "d")]
18896          ANY_XSAVE64))]
18897   "TARGET_64BIT && TARGET_XSAVE"
18898   "<xsave>\t%0"
18899   [(set_attr "type" "other")
18900    (set_attr "memory" "store")
18901    (set (attr "length")
18902         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18904 (define_insn "<xrstor>"
18905    [(unspec_volatile:BLK
18906      [(match_operand:BLK 0 "memory_operand" "m")
18907       (match_operand:DI 1 "register_operand" "A")]
18908      ANY_XRSTOR)]
18909   "!TARGET_64BIT && TARGET_XSAVE"
18910   "<xrstor>\t%0"
18911   [(set_attr "type" "other")
18912    (set_attr "memory" "load")
18913    (set (attr "length")
18914         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18916 (define_insn "<xrstor>_rex64"
18917    [(unspec_volatile:BLK
18918      [(match_operand:BLK 0 "memory_operand" "m")
18919       (match_operand:SI 1 "register_operand" "a")
18920       (match_operand:SI 2 "register_operand" "d")]
18921      ANY_XRSTOR)]
18922   "TARGET_64BIT && TARGET_XSAVE"
18923   "<xrstor>\t%0"
18924   [(set_attr "type" "other")
18925    (set_attr "memory" "load")
18926    (set (attr "length")
18927         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18929 (define_insn "<xrstor>64"
18930    [(unspec_volatile:BLK
18931      [(match_operand:BLK 0 "memory_operand" "m")
18932       (match_operand:SI 1 "register_operand" "a")
18933       (match_operand:SI 2 "register_operand" "d")]
18934      ANY_XRSTOR64)]
18935   "TARGET_64BIT && TARGET_XSAVE"
18936   "<xrstor>64\t%0"
18937   [(set_attr "type" "other")
18938    (set_attr "memory" "load")
18939    (set (attr "length")
18940         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18942 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18944 ;; Floating-point instructions for atomic compound assignments
18946 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18948 ; Clobber all floating-point registers on environment save and restore
18949 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18950 (define_insn "fnstenv"
18951   [(set (match_operand:BLK 0 "memory_operand" "=m")
18952         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18953    (clobber (reg:HI FPCR_REG))
18954    (clobber (reg:XF ST0_REG))
18955    (clobber (reg:XF ST1_REG))
18956    (clobber (reg:XF ST2_REG))
18957    (clobber (reg:XF ST3_REG))
18958    (clobber (reg:XF ST4_REG))
18959    (clobber (reg:XF ST5_REG))
18960    (clobber (reg:XF ST6_REG))
18961    (clobber (reg:XF ST7_REG))]
18962   "TARGET_80387"
18963   "fnstenv\t%0"
18964   [(set_attr "type" "other")
18965    (set_attr "memory" "store")
18966    (set (attr "length")
18967         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18969 (define_insn "fldenv"
18970   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18971                     UNSPECV_FLDENV)
18972    (clobber (reg:CCFP FPSR_REG))
18973    (clobber (reg:HI FPCR_REG))
18974    (clobber (reg:XF ST0_REG))
18975    (clobber (reg:XF ST1_REG))
18976    (clobber (reg:XF ST2_REG))
18977    (clobber (reg:XF ST3_REG))
18978    (clobber (reg:XF ST4_REG))
18979    (clobber (reg:XF ST5_REG))
18980    (clobber (reg:XF ST6_REG))
18981    (clobber (reg:XF ST7_REG))]
18982   "TARGET_80387"
18983   "fldenv\t%0"
18984   [(set_attr "type" "other")
18985    (set_attr "memory" "load")
18986    (set (attr "length")
18987         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18989 (define_insn "fnstsw"
18990   [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
18991         (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18992   "TARGET_80387"
18993   "fnstsw\t%0"
18994   [(set_attr "type" "other,other")
18995    (set_attr "memory" "none,store")
18996    (set (attr "length")
18997         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18999 (define_insn "fnclex"
19000   [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
19001   "TARGET_80387"
19002   "fnclex"
19003   [(set_attr "type" "other")
19004    (set_attr "memory" "none")
19005    (set_attr "length" "2")])
19007 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19009 ;; LWP instructions
19011 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19013 (define_expand "lwp_llwpcb"
19014   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
19015                     UNSPECV_LLWP_INTRINSIC)]
19016   "TARGET_LWP")
19018 (define_insn "*lwp_llwpcb<mode>1"
19019   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
19020                     UNSPECV_LLWP_INTRINSIC)]
19021   "TARGET_LWP"
19022   "llwpcb\t%0"
19023   [(set_attr "type" "lwp")
19024    (set_attr "mode" "<MODE>")
19025    (set_attr "length" "5")])
19027 (define_expand "lwp_slwpcb"
19028   [(set (match_operand 0 "register_operand" "=r")
19029         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19030   "TARGET_LWP"
19032   rtx (*insn)(rtx);
19034   insn = (Pmode == DImode
19035           ? gen_lwp_slwpcbdi
19036           : gen_lwp_slwpcbsi);
19038   emit_insn (insn (operands[0]));
19039   DONE;
19042 (define_insn "lwp_slwpcb<mode>"
19043   [(set (match_operand:P 0 "register_operand" "=r")
19044         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19045   "TARGET_LWP"
19046   "slwpcb\t%0"
19047   [(set_attr "type" "lwp")
19048    (set_attr "mode" "<MODE>")
19049    (set_attr "length" "5")])
19051 (define_expand "lwp_lwpval<mode>3"
19052   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
19053                      (match_operand:SI 2 "nonimmediate_operand" "rm")
19054                      (match_operand:SI 3 "const_int_operand" "i")]
19055                     UNSPECV_LWPVAL_INTRINSIC)]
19056   "TARGET_LWP"
19057   ;; Avoid unused variable warning.
19058   "(void) operands[0];")
19060 (define_insn "*lwp_lwpval<mode>3_1"
19061   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
19062                      (match_operand:SI 1 "nonimmediate_operand" "rm")
19063                      (match_operand:SI 2 "const_int_operand" "i")]
19064                     UNSPECV_LWPVAL_INTRINSIC)]
19065   "TARGET_LWP"
19066   "lwpval\t{%2, %1, %0|%0, %1, %2}"
19067   [(set_attr "type" "lwp")
19068    (set_attr "mode" "<MODE>")
19069    (set (attr "length")
19070         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19072 (define_expand "lwp_lwpins<mode>3"
19073   [(set (reg:CCC FLAGS_REG)
19074         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
19075                               (match_operand:SI 2 "nonimmediate_operand" "rm")
19076                               (match_operand:SI 3 "const_int_operand" "i")]
19077                              UNSPECV_LWPINS_INTRINSIC))
19078    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
19079         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
19080   "TARGET_LWP")
19082 (define_insn "*lwp_lwpins<mode>3_1"
19083   [(set (reg:CCC FLAGS_REG)
19084         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
19085                               (match_operand:SI 1 "nonimmediate_operand" "rm")
19086                               (match_operand:SI 2 "const_int_operand" "i")]
19087                              UNSPECV_LWPINS_INTRINSIC))]
19088   "TARGET_LWP"
19089   "lwpins\t{%2, %1, %0|%0, %1, %2}"
19090   [(set_attr "type" "lwp")
19091    (set_attr "mode" "<MODE>")
19092    (set (attr "length")
19093         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19095 (define_int_iterator RDFSGSBASE
19096         [UNSPECV_RDFSBASE
19097          UNSPECV_RDGSBASE])
19099 (define_int_iterator WRFSGSBASE
19100         [UNSPECV_WRFSBASE
19101          UNSPECV_WRGSBASE])
19103 (define_int_attr fsgs
19104         [(UNSPECV_RDFSBASE "fs")
19105          (UNSPECV_RDGSBASE "gs")
19106          (UNSPECV_WRFSBASE "fs")
19107          (UNSPECV_WRGSBASE "gs")])
19109 (define_insn "rd<fsgs>base<mode>"
19110   [(set (match_operand:SWI48 0 "register_operand" "=r")
19111         (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
19112   "TARGET_64BIT && TARGET_FSGSBASE"
19113   "rd<fsgs>base\t%0"
19114   [(set_attr "type" "other")
19115    (set_attr "prefix_extra" "2")])
19117 (define_insn "wr<fsgs>base<mode>"
19118   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
19119                     WRFSGSBASE)]
19120   "TARGET_64BIT && TARGET_FSGSBASE"
19121   "wr<fsgs>base\t%0"
19122   [(set_attr "type" "other")
19123    (set_attr "prefix_extra" "2")])
19125 (define_insn "rdrand<mode>_1"
19126   [(set (match_operand:SWI248 0 "register_operand" "=r")
19127         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
19128    (set (reg:CCC FLAGS_REG)
19129         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
19130   "TARGET_RDRND"
19131   "rdrand\t%0"
19132   [(set_attr "type" "other")
19133    (set_attr "prefix_extra" "1")])
19135 (define_insn "rdseed<mode>_1"
19136   [(set (match_operand:SWI248 0 "register_operand" "=r")
19137         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
19138    (set (reg:CCC FLAGS_REG)
19139         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
19140   "TARGET_RDSEED"
19141   "rdseed\t%0"
19142   [(set_attr "type" "other")
19143    (set_attr "prefix_extra" "1")])
19145 (define_expand "pause"
19146   [(set (match_dup 0)
19147         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
19148   ""
19150   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
19151   MEM_VOLATILE_P (operands[0]) = 1;
19154 ;; Use "rep; nop", instead of "pause", to support older assemblers.
19155 ;; They have the same encoding.
19156 (define_insn "*pause"
19157   [(set (match_operand:BLK 0)
19158         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
19159   ""
19160   "rep%; nop"
19161   [(set_attr "length" "2")
19162    (set_attr "memory" "unknown")])
19164 (define_expand "xbegin"
19165   [(set (match_operand:SI 0 "register_operand")
19166         (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
19167   "TARGET_RTM"
19169   rtx_code_label *label = gen_label_rtx ();
19171   /* xbegin is emitted as jump_insn, so reload won't be able
19172      to reload its operand.  Force the value into AX hard register.  */
19173   rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
19174   emit_move_insn (ax_reg, constm1_rtx);
19176   emit_jump_insn (gen_xbegin_1 (ax_reg, label));
19178   emit_label (label);
19179   LABEL_NUSES (label) = 1;
19181   emit_move_insn (operands[0], ax_reg);
19183   DONE;
19186 (define_insn "xbegin_1"
19187   [(set (pc)
19188         (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
19189                           (const_int 0))
19190                       (label_ref (match_operand 1))
19191                       (pc)))
19192    (set (match_operand:SI 0 "register_operand" "+a")
19193         (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
19194   "TARGET_RTM"
19195   "xbegin\t%l1"
19196   [(set_attr "type" "other")
19197    (set_attr "length" "6")])
19199 (define_insn "xend"
19200   [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
19201   "TARGET_RTM"
19202   "xend"
19203   [(set_attr "type" "other")
19204    (set_attr "length" "3")])
19206 (define_insn "xabort"
19207   [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
19208                     UNSPECV_XABORT)]
19209   "TARGET_RTM"
19210   "xabort\t%0"
19211   [(set_attr "type" "other")
19212    (set_attr "length" "3")])
19214 (define_expand "xtest"
19215   [(set (match_operand:QI 0 "register_operand")
19216         (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
19217   "TARGET_RTM"
19219   emit_insn (gen_xtest_1 ());
19221   ix86_expand_setcc (operands[0], NE,
19222                      gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
19223   DONE;
19226 (define_insn "xtest_1"
19227   [(set (reg:CCZ FLAGS_REG)
19228         (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
19229   "TARGET_RTM"
19230   "xtest"
19231   [(set_attr "type" "other")
19232    (set_attr "length" "3")])
19234 (define_insn "pcommit"
19235   [(unspec_volatile [(const_int 0)] UNSPECV_PCOMMIT)]
19236   "TARGET_PCOMMIT"
19237   "pcommit"
19238   [(set_attr "type" "other")
19239    (set_attr "length" "4")])
19241 (define_insn "clwb"
19242   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
19243                    UNSPECV_CLWB)]
19244   "TARGET_CLWB"
19245   "clwb\t%a0"
19246   [(set_attr "type" "sse")
19247    (set_attr "atom_sse_attr" "fence")
19248    (set_attr "memory" "unknown")])
19250 (define_insn "clflushopt"
19251   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
19252                    UNSPECV_CLFLUSHOPT)]
19253   "TARGET_CLFLUSHOPT"
19254   "clflushopt\t%a0"
19255   [(set_attr "type" "sse")
19256    (set_attr "atom_sse_attr" "fence")
19257    (set_attr "memory" "unknown")])
19259 ;; MONITORX and MWAITX
19260 (define_insn "mwaitx"
19261   [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
19262                      (match_operand:SI 1 "register_operand" "a")
19263                      (match_operand:SI 2 "register_operand" "b")]
19264                    UNSPECV_MWAITX)]
19265   "TARGET_MWAITX"
19266 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
19267 ;; Since 32bit register operands are implicitly zero extended to 64bit,
19268 ;; we only need to set up 32bit registers.
19269   "mwaitx"
19270   [(set_attr "length" "3")])
19272 (define_insn "monitorx_<mode>"
19273   [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
19274                      (match_operand:SI 1 "register_operand" "c")
19275                      (match_operand:SI 2 "register_operand" "d")]
19276                    UNSPECV_MONITORX)]
19277   "TARGET_MWAITX"
19278 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
19279 ;; RCX and RDX are used.  Since 32bit register operands are implicitly
19280 ;; zero extended to 64bit, we only need to set up 32bit registers.
19281   "%^monitorx"
19282   [(set (attr "length")
19283      (symbol_ref ("(Pmode != word_mode) + 3")))])
19285 ;; CLZERO
19286 (define_insn "clzero_<mode>"
19287   [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
19288                    UNSPECV_CLZERO)]
19289   "TARGET_CLZERO"
19290   "clzero"
19291   [(set_attr "length" "3")
19292   (set_attr "memory" "unknown")])
19294 ;; MPX instructions
19296 (define_expand "<mode>_mk"
19297   [(set (match_operand:BND 0 "register_operand")
19298         (unspec:BND
19299           [(mem:<bnd_ptr>
19300            (match_par_dup 3
19301              [(match_operand:<bnd_ptr> 1 "register_operand")
19302               (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
19303           UNSPEC_BNDMK))]
19304   "TARGET_MPX"
19306   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
19307                                                   operands[2]),
19308                                 UNSPEC_BNDMK_ADDR);
19311 (define_insn "*<mode>_mk"
19312   [(set (match_operand:BND 0 "register_operand" "=w")
19313         (unspec:BND
19314           [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19315              [(unspec:<bnd_ptr>
19316                 [(match_operand:<bnd_ptr> 1 "register_operand" "r")
19317                  (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
19318                 UNSPEC_BNDMK_ADDR)])]
19319           UNSPEC_BNDMK))]
19320   "TARGET_MPX"
19321   "bndmk\t{%3, %0|%0, %3}"
19322   [(set_attr "type" "mpxmk")])
19324 (define_expand "mov<mode>"
19325   [(set (match_operand:BND 0 "general_operand")
19326         (match_operand:BND 1 "general_operand"))]
19327   "TARGET_MPX"
19328   "ix86_expand_move (<MODE>mode, operands); DONE;")
19330 (define_insn "*mov<mode>_internal_mpx"
19331   [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
19332         (match_operand:BND 1 "general_operand" "wm,w"))]
19333   "TARGET_MPX"
19334   "bndmov\t{%1, %0|%0, %1}"
19335   [(set_attr "type" "mpxmov")])
19337 (define_expand "<mode>_<bndcheck>"
19338   [(parallel
19339      [(unspec
19340         [(match_operand:BND 0 "register_operand")
19341          (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
19342       (set (match_dup 2)
19343            (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
19344   "TARGET_MPX"
19346   operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
19347   MEM_VOLATILE_P (operands[2]) = 1;
19350 (define_insn "*<mode>_<bndcheck>"
19351   [(unspec
19352      [(match_operand:BND 0 "register_operand" "w")
19353       (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
19354    (set (match_operand:BLK 2 "bnd_mem_operator")
19355         (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))]
19356   "TARGET_MPX"
19357   "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
19358   [(set_attr "type" "mpxchk")])
19360 (define_expand "<mode>_ldx"
19361   [(parallel
19362      [(set (match_operand:BND 0 "register_operand")
19363            (unspec:BND
19364              [(mem:<bnd_ptr>
19365                 (match_par_dup 3
19366                   [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
19367                    (match_operand:<bnd_ptr> 2 "register_operand")]))]
19368              UNSPEC_BNDLDX))
19369       (use (mem:BLK (match_dup 1)))])]
19370   "TARGET_MPX"
19372   /* Avoid registers which cannot be used as index.  */
19373   if (!index_register_operand (operands[2], Pmode))
19374     operands[2] = copy_addr_to_reg (operands[2]);
19376   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
19377                                                   operands[2]),
19378                                 UNSPEC_BNDLDX_ADDR);
19381 (define_insn "*<mode>_ldx"
19382   [(set (match_operand:BND 0 "register_operand" "=w")
19383         (unspec:BND
19384           [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19385              [(unspec:<bnd_ptr>
19386                 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
19387                  (match_operand:<bnd_ptr> 2 "register_operand" "l")]
19388                 UNSPEC_BNDLDX_ADDR)])]
19389           UNSPEC_BNDLDX))
19390    (use (mem:BLK (match_dup 1)))]
19391   "TARGET_MPX"
19392   "bndldx\t{%3, %0|%0, %3}"
19393   [(set_attr "type" "mpxld")])
19395 (define_expand "<mode>_stx"
19396   [(parallel
19397      [(unspec
19398         [(mem:<bnd_ptr>
19399            (match_par_dup 3
19400              [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
19401               (match_operand:<bnd_ptr> 1 "register_operand")]))
19402          (match_operand:BND 2 "register_operand")]
19403         UNSPEC_BNDSTX)
19404       (set (match_dup 4)
19405            (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
19406   "TARGET_MPX"
19408   /* Avoid registers which cannot be used as index.  */
19409   if (!index_register_operand (operands[1], Pmode))
19410     operands[1] = copy_addr_to_reg (operands[1]);
19412   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
19413                                                   operands[1]),
19414                                 UNSPEC_BNDLDX_ADDR);
19415   operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
19416   MEM_VOLATILE_P (operands[4]) = 1;
19419 (define_insn "*<mode>_stx"
19420   [(unspec
19421      [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19422         [(unspec:<bnd_ptr>
19423            [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
19424             (match_operand:<bnd_ptr> 1 "register_operand" "l")]
19425            UNSPEC_BNDLDX_ADDR)])
19426          (match_operand:BND 2 "register_operand" "w")]
19427         UNSPEC_BNDSTX)
19428    (set (match_operand:BLK 4 "bnd_mem_operator")
19429         (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))]
19430   "TARGET_MPX"
19431   "bndstx\t{%2, %3|%3, %2}"
19432   [(set_attr "type" "mpxst")])
19434 (define_insn "move_size_reloc_<mode>"
19435   [(set (match_operand:SWI48 0 "register_operand" "=r")
19436         (unspec:SWI48
19437           [(match_operand:SWI48 1 "symbol_operand")]
19438         UNSPEC_SIZEOF))]
19439   "TARGET_MPX"
19441   if (x86_64_immediate_size_operand (operands[1], VOIDmode))
19442     return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
19443   else
19444     return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
19446   [(set_attr "type" "imov")
19447    (set_attr "mode" "<MODE>")])
19449 ;; RDPKRU and WRPKRU
19451 (define_expand "rdpkru"
19452   [(parallel
19453      [(set (match_operand:SI 0 "register_operand")
19454            (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
19455       (set (match_dup 2) (const_int 0))])]
19456   "TARGET_PKU"
19458   operands[1] = force_reg (SImode, const0_rtx);
19459   operands[2] = gen_reg_rtx (SImode);
19462 (define_insn "*rdpkru"
19463   [(set (match_operand:SI 0 "register_operand" "=a")
19464         (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
19465                             UNSPECV_PKU))
19466    (set (match_operand:SI 1 "register_operand" "=d")
19467         (const_int 0))]
19468   "TARGET_PKU"
19469   "rdpkru"
19470   [(set_attr "type" "other")])
19472 (define_expand "wrpkru"
19473   [(unspec_volatile:SI
19474      [(match_operand:SI 0 "register_operand")
19475       (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
19476   "TARGET_PKU"
19478   operands[1] = force_reg (SImode, const0_rtx);
19479   operands[2] = force_reg (SImode, const0_rtx);
19482 (define_insn "*wrpkru"
19483   [(unspec_volatile:SI
19484      [(match_operand:SI 0 "register_operand" "a")
19485       (match_operand:SI 1 "register_operand" "d")
19486       (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
19487   "TARGET_PKU"
19488   "wrpkru"
19489   [(set_attr "type" "other")])
19491 (include "mmx.md")
19492 (include "sse.md")
19493 (include "sync.md")