predicates.md (any_QIreg_operand): Rename from q_regs_operand.
[official-gcc.git] / gcc / config / i386 / i386.md
blob7195882f03dd382053d297c18a0ba3279f434162
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2015 Free Software Foundation, Inc.
3 ;; Mostly by William Schelter.
4 ;; x86_64 support added by Jan Hubicka
5 ;;
6 ;; This file is part of GCC.
7 ;;
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
11 ;; any later version.
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3.  If not see
20 ;; <http://www.gnu.org/licenses/>.  */
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;; The special asm out single letter directives following a '%' are:
28 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
29 ;; C -- print opcode suffix for set/cmov insn.
30 ;; c -- like C, but print reversed condition
31 ;; F,f -- likewise, but for floating-point.
32 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
33 ;;      otherwise nothing
34 ;; R -- print the prefix for register names.
35 ;; z -- print the opcode suffix for the size of the current operand.
36 ;; Z -- likewise, with special suffixes for x87 instructions.
37 ;; * -- print a star (in certain assembler syntax)
38 ;; A -- print an absolute memory reference.
39 ;; E -- print address with DImode register names if TARGET_64BIT.
40 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
41 ;; s -- print a shift double count, followed by the assemblers argument
42 ;;      delimiter.
43 ;; b -- print the QImode name of the register for the indicated operand.
44 ;;      %b0 would print %al if operands[0] is reg 0.
45 ;; w --  likewise, print the HImode name of the register.
46 ;; k --  likewise, print the SImode name of the register.
47 ;; q --  likewise, print the DImode name of the register.
48 ;; x --  likewise, print the V4SFmode name of the register.
49 ;; t --  likewise, print the V8SFmode name of the register.
50 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
51 ;; y -- print "st(0)" instead of "st" as a register.
52 ;; d -- print duplicated register operand for AVX instruction.
53 ;; D -- print condition for SSE cmp instruction.
54 ;; P -- if PIC, print an @PLT suffix.
55 ;; p -- print raw symbol name.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; K -- print HLE lock prefix
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
64 ;; @ -- print a segment register of thread base pointer load
65 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
66 ;; ! -- print MPX prefix for jxx/call/ret instructions if required.
68 (define_c_enum "unspec" [
69   ;; Relocation specifiers
70   UNSPEC_GOT
71   UNSPEC_GOTOFF
72   UNSPEC_GOTPCREL
73   UNSPEC_GOTTPOFF
74   UNSPEC_TPOFF
75   UNSPEC_NTPOFF
76   UNSPEC_DTPOFF
77   UNSPEC_GOTNTPOFF
78   UNSPEC_INDNTPOFF
79   UNSPEC_PLTOFF
80   UNSPEC_MACHOPIC_OFFSET
81   UNSPEC_PCREL
82   UNSPEC_SIZEOF
84   ;; Prologue support
85   UNSPEC_STACK_ALLOC
86   UNSPEC_SET_GOT
87   UNSPEC_SET_RIP
88   UNSPEC_SET_GOT_OFFSET
89   UNSPEC_MEMORY_BLOCKAGE
90   UNSPEC_STACK_CHECK
92   ;; TLS support
93   UNSPEC_TP
94   UNSPEC_TLS_GD
95   UNSPEC_TLS_LD_BASE
96   UNSPEC_TLSDESC
97   UNSPEC_TLS_IE_SUN
99   ;; Other random patterns
100   UNSPEC_SCAS
101   UNSPEC_FNSTSW
102   UNSPEC_SAHF
103   UNSPEC_PARITY
104   UNSPEC_FSTCW
105   UNSPEC_ADD_CARRY
106   UNSPEC_FLDCW
107   UNSPEC_REP
108   UNSPEC_LD_MPIC        ; load_macho_picbase
109   UNSPEC_TRUNC_NOOP
110   UNSPEC_DIV_ALREADY_SPLIT
111   UNSPEC_PAUSE
112   UNSPEC_LEA_ADDR
113   UNSPEC_XBEGIN_ABORT
114   UNSPEC_STOS
115   UNSPEC_PEEPSIB
116   UNSPEC_INSN_FALSE_DEP
118   ;; For SSE/MMX support:
119   UNSPEC_FIX_NOTRUNC
120   UNSPEC_MASKMOV
121   UNSPEC_MOVMSK
122   UNSPEC_RCP
123   UNSPEC_RSQRT
124   UNSPEC_PSADBW
126   ;; Generic math support
127   UNSPEC_COPYSIGN
128   UNSPEC_IEEE_MIN       ; not commutative
129   UNSPEC_IEEE_MAX       ; not commutative
131   ;; x87 Floating point
132   UNSPEC_SIN
133   UNSPEC_COS
134   UNSPEC_FPATAN
135   UNSPEC_FYL2X
136   UNSPEC_FYL2XP1
137   UNSPEC_FRNDINT
138   UNSPEC_FIST
139   UNSPEC_F2XM1
140   UNSPEC_TAN
141   UNSPEC_FXAM
143   ;; x87 Rounding
144   UNSPEC_FRNDINT_FLOOR
145   UNSPEC_FRNDINT_CEIL
146   UNSPEC_FRNDINT_TRUNC
147   UNSPEC_FRNDINT_MASK_PM
148   UNSPEC_FIST_FLOOR
149   UNSPEC_FIST_CEIL
151   ;; x87 Double output FP
152   UNSPEC_SINCOS_COS
153   UNSPEC_SINCOS_SIN
154   UNSPEC_XTRACT_FRACT
155   UNSPEC_XTRACT_EXP
156   UNSPEC_FSCALE_FRACT
157   UNSPEC_FSCALE_EXP
158   UNSPEC_FPREM_F
159   UNSPEC_FPREM_U
160   UNSPEC_FPREM1_F
161   UNSPEC_FPREM1_U
163   UNSPEC_C2_FLAG
164   UNSPEC_FXAM_MEM
166   ;; SSP patterns
167   UNSPEC_SP_SET
168   UNSPEC_SP_TEST
169   UNSPEC_SP_TLS_SET
170   UNSPEC_SP_TLS_TEST
172   ;; For ROUND support
173   UNSPEC_ROUND
175   ;; For CRC32 support
176   UNSPEC_CRC32
178   ;; For BMI support
179   UNSPEC_BEXTR
181   ;; For BMI2 support
182   UNSPEC_PDEP
183   UNSPEC_PEXT
185   ;; For AVX512F support
186   UNSPEC_KMOV
188   UNSPEC_BNDMK
189   UNSPEC_BNDMK_ADDR
190   UNSPEC_BNDSTX
191   UNSPEC_BNDLDX
192   UNSPEC_BNDLDX_ADDR
193   UNSPEC_BNDCL
194   UNSPEC_BNDCU
195   UNSPEC_BNDCN
196   UNSPEC_MPX_FENCE
199 (define_c_enum "unspecv" [
200   UNSPECV_BLOCKAGE
201   UNSPECV_STACK_PROBE
202   UNSPECV_PROBE_STACK_RANGE
203   UNSPECV_ALIGN
204   UNSPECV_PROLOGUE_USE
205   UNSPECV_SPLIT_STACK_RETURN
206   UNSPECV_CLD
207   UNSPECV_NOPS
208   UNSPECV_RDTSC
209   UNSPECV_RDTSCP
210   UNSPECV_RDPMC
211   UNSPECV_LLWP_INTRINSIC
212   UNSPECV_SLWP_INTRINSIC
213   UNSPECV_LWPVAL_INTRINSIC
214   UNSPECV_LWPINS_INTRINSIC
215   UNSPECV_RDFSBASE
216   UNSPECV_RDGSBASE
217   UNSPECV_WRFSBASE
218   UNSPECV_WRGSBASE
219   UNSPECV_FXSAVE
220   UNSPECV_FXRSTOR
221   UNSPECV_FXSAVE64
222   UNSPECV_FXRSTOR64
223   UNSPECV_XSAVE
224   UNSPECV_XRSTOR
225   UNSPECV_XSAVE64
226   UNSPECV_XRSTOR64
227   UNSPECV_XSAVEOPT
228   UNSPECV_XSAVEOPT64
229   UNSPECV_XSAVES
230   UNSPECV_XRSTORS
231   UNSPECV_XSAVES64
232   UNSPECV_XRSTORS64
233   UNSPECV_XSAVEC
234   UNSPECV_XSAVEC64
236   ;; For atomic compound assignments.
237   UNSPECV_FNSTENV
238   UNSPECV_FLDENV
239   UNSPECV_FNSTSW
240   UNSPECV_FNCLEX
242   ;; For RDRAND support
243   UNSPECV_RDRAND
245   ;; For RDSEED support
246   UNSPECV_RDSEED
248   ;; For RTM support
249   UNSPECV_XBEGIN
250   UNSPECV_XEND
251   UNSPECV_XABORT
252   UNSPECV_XTEST
254   UNSPECV_NLGR
256   ;; For CLWB support
257   UNSPECV_CLWB
259   ;; For PCOMMIT support
260   UNSPECV_PCOMMIT
262   ;; For CLFLUSHOPT support
263   UNSPECV_CLFLUSHOPT
266 ;; Constants to represent rounding modes in the ROUND instruction
267 (define_constants
268   [(ROUND_FLOOR                 0x1)
269    (ROUND_CEIL                  0x2)
270    (ROUND_TRUNC                 0x3)
271    (ROUND_MXCSR                 0x4)
272    (ROUND_NO_EXC                0x8)
273   ])
275 ;; Constants to represent AVX512F embeded rounding
276 (define_constants
277   [(ROUND_NEAREST_INT                   0)
278    (ROUND_NEG_INF                       1)
279    (ROUND_POS_INF                       2)
280    (ROUND_ZERO                          3)
281    (NO_ROUND                            4)
282    (ROUND_SAE                           8)
283   ])
285 ;; Constants to represent pcomtrue/pcomfalse variants
286 (define_constants
287   [(PCOM_FALSE                  0)
288    (PCOM_TRUE                   1)
289    (COM_FALSE_S                 2)
290    (COM_FALSE_P                 3)
291    (COM_TRUE_S                  4)
292    (COM_TRUE_P                  5)
293   ])
295 ;; Constants used in the XOP pperm instruction
296 (define_constants
297   [(PPERM_SRC                   0x00)   /* copy source */
298    (PPERM_INVERT                0x20)   /* invert source */
299    (PPERM_REVERSE               0x40)   /* bit reverse source */
300    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
301    (PPERM_ZERO                  0x80)   /* all 0's */
302    (PPERM_ONES                  0xa0)   /* all 1's */
303    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
304    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
305    (PPERM_SRC1                  0x00)   /* use first source byte */
306    (PPERM_SRC2                  0x10)   /* use second source byte */
307    ])
309 ;; Registers by name.
310 (define_constants
311   [(AX_REG                       0)
312    (DX_REG                       1)
313    (CX_REG                       2)
314    (BX_REG                       3)
315    (SI_REG                       4)
316    (DI_REG                       5)
317    (BP_REG                       6)
318    (SP_REG                       7)
319    (ST0_REG                      8)
320    (ST1_REG                      9)
321    (ST2_REG                     10)
322    (ST3_REG                     11)
323    (ST4_REG                     12)
324    (ST5_REG                     13)
325    (ST6_REG                     14)
326    (ST7_REG                     15)
327    (FLAGS_REG                   17)
328    (FPSR_REG                    18)
329    (FPCR_REG                    19)
330    (XMM0_REG                    21)
331    (XMM1_REG                    22)
332    (XMM2_REG                    23)
333    (XMM3_REG                    24)
334    (XMM4_REG                    25)
335    (XMM5_REG                    26)
336    (XMM6_REG                    27)
337    (XMM7_REG                    28)
338    (MM0_REG                     29)
339    (MM1_REG                     30)
340    (MM2_REG                     31)
341    (MM3_REG                     32)
342    (MM4_REG                     33)
343    (MM5_REG                     34)
344    (MM6_REG                     35)
345    (MM7_REG                     36)
346    (R8_REG                      37)
347    (R9_REG                      38)
348    (R10_REG                     39)
349    (R11_REG                     40)
350    (R12_REG                     41)
351    (R13_REG                     42)
352    (R14_REG                     43)
353    (R15_REG                     44)
354    (XMM8_REG                    45)
355    (XMM9_REG                    46)
356    (XMM10_REG                   47)
357    (XMM11_REG                   48)
358    (XMM12_REG                   49)
359    (XMM13_REG                   50)
360    (XMM14_REG                   51)
361    (XMM15_REG                   52)
362    (XMM16_REG                   53)
363    (XMM17_REG                   54)
364    (XMM18_REG                   55)
365    (XMM19_REG                   56)
366    (XMM20_REG                   57)
367    (XMM21_REG                   58)
368    (XMM22_REG                   59)
369    (XMM23_REG                   60)
370    (XMM24_REG                   61)
371    (XMM25_REG                   62)
372    (XMM26_REG                   63)
373    (XMM27_REG                   64)
374    (XMM28_REG                   65)
375    (XMM29_REG                   66)
376    (XMM30_REG                   67)
377    (XMM31_REG                   68)
378    (MASK0_REG                   69)
379    (MASK1_REG                   70)
380    (MASK2_REG                   71)
381    (MASK3_REG                   72)
382    (MASK4_REG                   73)
383    (MASK5_REG                   74)
384    (MASK6_REG                   75)
385    (MASK7_REG                   76)
386    (BND0_REG                    77)
387    (BND1_REG                    78)
388   ])
390 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
391 ;; from i386.c.
393 ;; In C guard expressions, put expressions which may be compile-time
394 ;; constants first.  This allows for better optimization.  For
395 ;; example, write "TARGET_64BIT && reload_completed", not
396 ;; "reload_completed && TARGET_64BIT".
399 ;; Processor type.
400 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
401                     atom,slm,generic,amdfam10,bdver1,bdver2,bdver3,bdver4,
402                     btver2,knl"
403   (const (symbol_ref "ix86_schedule")))
405 ;; A basic instruction type.  Refinements due to arguments to be
406 ;; provided in other attributes.
407 (define_attr "type"
408   "other,multi,
409    alu,alu1,negnot,imov,imovx,lea,
410    incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
411    imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
412    push,pop,call,callv,leave,
413    str,bitmanip,
414    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
415    fxch,fistp,fisttp,frndint,
416    sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
417    ssemul,sseimul,ssediv,sselog,sselog1,
418    sseishft,sseishft1,ssecmp,ssecomi,
419    ssecvt,ssecvt1,sseicvt,sseins,
420    sseshuf,sseshuf1,ssemuladd,sse4arg,
421    lwp,mskmov,msklog,
422    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
423    mpxmov,mpxmk,mpxchk,mpxld,mpxst"
424   (const_string "other"))
426 ;; Main data type used by the insn
427 (define_attr "mode"
428   "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
429   V2DF,V2SF,V1DF,V8DF"
430   (const_string "unknown"))
432 ;; The CPU unit operations uses.
433 (define_attr "unit" "integer,i387,sse,mmx,unknown"
434   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
435                           fxch,fistp,fisttp,frndint")
436            (const_string "i387")
437          (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
438                           ssemul,sseimul,ssediv,sselog,sselog1,
439                           sseishft,sseishft1,ssecmp,ssecomi,
440                           ssecvt,ssecvt1,sseicvt,sseins,
441                           sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
442            (const_string "sse")
443          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
444            (const_string "mmx")
445          (eq_attr "type" "other")
446            (const_string "unknown")]
447          (const_string "integer")))
449 ;; The minimum required alignment of vector mode memory operands of the SSE
450 ;; (non-VEX/EVEX) instruction in bits, if it is different from
451 ;; GET_MODE_ALIGNMENT of the operand, otherwise 0.  If an instruction has
452 ;; multiple alternatives, this should be conservative maximum of those minimum
453 ;; required alignments.
454 (define_attr "ssememalign" "" (const_int 0))
456 ;; The (bounding maximum) length of an instruction immediate.
457 (define_attr "length_immediate" ""
458   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
459                           bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
460                           mpxld,mpxst")
461            (const_int 0)
462          (eq_attr "unit" "i387,sse,mmx")
463            (const_int 0)
464          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
465                           rotate,rotatex,rotate1,imul,icmp,push,pop")
466            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
467          (eq_attr "type" "imov,test")
468            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
469          (eq_attr "type" "call")
470            (if_then_else (match_operand 0 "constant_call_address_operand")
471              (const_int 4)
472              (const_int 0))
473          (eq_attr "type" "callv")
474            (if_then_else (match_operand 1 "constant_call_address_operand")
475              (const_int 4)
476              (const_int 0))
477          ;; We don't know the size before shorten_branches.  Expect
478          ;; the instruction to fit for better scheduling.
479          (eq_attr "type" "ibr")
480            (const_int 1)
481          ]
482          (symbol_ref "/* Update immediate_length and other attributes! */
483                       gcc_unreachable (),1")))
485 ;; The (bounding maximum) length of an instruction address.
486 (define_attr "length_address" ""
487   (cond [(eq_attr "type" "str,other,multi,fxch")
488            (const_int 0)
489          (and (eq_attr "type" "call")
490               (match_operand 0 "constant_call_address_operand"))
491              (const_int 0)
492          (and (eq_attr "type" "callv")
493               (match_operand 1 "constant_call_address_operand"))
494              (const_int 0)
495          ]
496          (symbol_ref "ix86_attr_length_address_default (insn)")))
498 ;; Set when length prefix is used.
499 (define_attr "prefix_data16" ""
500   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
501            (const_int 0)
502          (eq_attr "mode" "HI")
503            (const_int 1)
504          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
505            (const_int 1)
506         ]
507         (const_int 0)))
509 ;; Set when string REP prefix is used.
510 (define_attr "prefix_rep" ""
511   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
512            (const_int 0)
513          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
514            (const_int 1)
515          (and (eq_attr "type" "ibr,call,callv")
516               (match_test "ix86_bnd_prefixed_insn_p (insn)"))
517            (const_int 1)
518         ]
519         (const_int 0)))
521 ;; Set when 0f opcode prefix is used.
522 (define_attr "prefix_0f" ""
523   (if_then_else
524     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
525                           mpxmk,mpxmov,mpxchk,mpxld,mpxst")
526          (eq_attr "unit" "sse,mmx"))
527     (const_int 1)
528     (const_int 0)))
530 ;; Set when REX opcode prefix is used.
531 (define_attr "prefix_rex" ""
532   (cond [(not (match_test "TARGET_64BIT"))
533            (const_int 0)
534          (and (eq_attr "mode" "DI")
535               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
536                    (eq_attr "unit" "!mmx")))
537            (const_int 1)
538          (and (eq_attr "mode" "QI")
539               (match_test "x86_extended_QIreg_mentioned_p (insn)"))
540            (const_int 1)
541          (match_test "x86_extended_reg_mentioned_p (insn)")
542            (const_int 1)
543          (and (eq_attr "type" "imovx")
544               (match_operand:QI 1 "ext_QIreg_operand"))
545            (const_int 1)
546         ]
547         (const_int 0)))
549 ;; There are also additional prefixes in 3DNOW, SSSE3.
550 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
551 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
552 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
553 (define_attr "prefix_extra" ""
554   (cond [(eq_attr "type" "ssemuladd,sse4arg")
555            (const_int 2)
556          (eq_attr "type" "sseiadd1,ssecvt1")
557            (const_int 1)
558         ]
559         (const_int 0)))
561 ;; Prefix used: original, VEX or maybe VEX.
562 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
563   (cond [(eq_attr "mode" "OI,V8SF,V4DF")
564            (const_string "vex")
565          (eq_attr "mode" "XI,V16SF,V8DF")
566            (const_string "evex")
567         ]
568         (const_string "orig")))
570 ;; VEX W bit is used.
571 (define_attr "prefix_vex_w" "" (const_int 0))
573 ;; The length of VEX prefix
574 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
575 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
576 ;; still prefix_0f 1, with prefix_extra 1.
577 (define_attr "length_vex" ""
578   (if_then_else (and (eq_attr "prefix_0f" "1")
579                      (eq_attr "prefix_extra" "0"))
580     (if_then_else (eq_attr "prefix_vex_w" "1")
581       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
582       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
583     (if_then_else (eq_attr "prefix_vex_w" "1")
584       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
585       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
587 ;; 4-bytes evex prefix and 1 byte opcode.
588 (define_attr "length_evex" "" (const_int 5))
590 ;; Set when modrm byte is used.
591 (define_attr "modrm" ""
592   (cond [(eq_attr "type" "str,leave")
593            (const_int 0)
594          (eq_attr "unit" "i387")
595            (const_int 0)
596          (and (eq_attr "type" "incdec")
597               (and (not (match_test "TARGET_64BIT"))
598                    (ior (match_operand:SI 1 "register_operand")
599                         (match_operand:HI 1 "register_operand"))))
600            (const_int 0)
601          (and (eq_attr "type" "push")
602               (not (match_operand 1 "memory_operand")))
603            (const_int 0)
604          (and (eq_attr "type" "pop")
605               (not (match_operand 0 "memory_operand")))
606            (const_int 0)
607          (and (eq_attr "type" "imov")
608               (and (not (eq_attr "mode" "DI"))
609                    (ior (and (match_operand 0 "register_operand")
610                              (match_operand 1 "immediate_operand"))
611                         (ior (and (match_operand 0 "ax_reg_operand")
612                                   (match_operand 1 "memory_displacement_only_operand"))
613                              (and (match_operand 0 "memory_displacement_only_operand")
614                                   (match_operand 1 "ax_reg_operand"))))))
615            (const_int 0)
616          (and (eq_attr "type" "call")
617               (match_operand 0 "constant_call_address_operand"))
618              (const_int 0)
619          (and (eq_attr "type" "callv")
620               (match_operand 1 "constant_call_address_operand"))
621              (const_int 0)
622          (and (eq_attr "type" "alu,alu1,icmp,test")
623               (match_operand 0 "ax_reg_operand"))
624              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
625          ]
626          (const_int 1)))
628 ;; When this attribute is set, calculate total insn length from
629 ;; length_nobnd attribute, prefixed with eventual bnd prefix byte
630 (define_attr "length_nobnd" "" (const_int 0))
632 ;; The (bounding maximum) length of an instruction in bytes.
633 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
634 ;; Later we may want to split them and compute proper length as for
635 ;; other insns.
636 (define_attr "length" ""
637   (cond [(eq_attr "length_nobnd" "!0")
638            (plus (symbol_ref ("ix86_bnd_prefixed_insn_p (insn)"))
639                  (attr "length_nobnd"))
640          (eq_attr "type" "other,multi,fistp,frndint")
641            (const_int 16)
642          (eq_attr "type" "fcmp")
643            (const_int 4)
644          (eq_attr "unit" "i387")
645            (plus (const_int 2)
646                  (plus (attr "prefix_data16")
647                        (attr "length_address")))
648          (ior (eq_attr "prefix" "evex")
649               (and (ior (eq_attr "prefix" "maybe_evex")
650                         (eq_attr "prefix" "maybe_vex"))
651                    (match_test "TARGET_AVX512F")))
652            (plus (attr "length_evex")
653                  (plus (attr "length_immediate")
654                        (plus (attr "modrm")
655                              (attr "length_address"))))
656          (ior (eq_attr "prefix" "vex")
657               (and (ior (eq_attr "prefix" "maybe_vex")
658                         (eq_attr "prefix" "maybe_evex"))
659                    (match_test "TARGET_AVX")))
660            (plus (attr "length_vex")
661                  (plus (attr "length_immediate")
662                        (plus (attr "modrm")
663                              (attr "length_address"))))]
664          (plus (plus (attr "modrm")
665                      (plus (attr "prefix_0f")
666                            (plus (attr "prefix_rex")
667                                  (plus (attr "prefix_extra")
668                                        (const_int 1)))))
669                (plus (attr "prefix_rep")
670                      (plus (attr "prefix_data16")
671                            (plus (attr "length_immediate")
672                                  (attr "length_address")))))))
674 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
675 ;; `store' if there is a simple memory reference therein, or `unknown'
676 ;; if the instruction is complex.
678 (define_attr "memory" "none,load,store,both,unknown"
679   (cond [(eq_attr "type" "other,multi,str,lwp")
680            (const_string "unknown")
681          (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
682            (const_string "none")
683          (eq_attr "type" "fistp,leave")
684            (const_string "both")
685          (eq_attr "type" "frndint")
686            (const_string "load")
687          (eq_attr "type" "mpxld")
688            (const_string "load")
689          (eq_attr "type" "mpxst")
690            (const_string "store")
691          (eq_attr "type" "push")
692            (if_then_else (match_operand 1 "memory_operand")
693              (const_string "both")
694              (const_string "store"))
695          (eq_attr "type" "pop")
696            (if_then_else (match_operand 0 "memory_operand")
697              (const_string "both")
698              (const_string "load"))
699          (eq_attr "type" "setcc")
700            (if_then_else (match_operand 0 "memory_operand")
701              (const_string "store")
702              (const_string "none"))
703          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
704            (if_then_else (ior (match_operand 0 "memory_operand")
705                               (match_operand 1 "memory_operand"))
706              (const_string "load")
707              (const_string "none"))
708          (eq_attr "type" "ibr")
709            (if_then_else (match_operand 0 "memory_operand")
710              (const_string "load")
711              (const_string "none"))
712          (eq_attr "type" "call")
713            (if_then_else (match_operand 0 "constant_call_address_operand")
714              (const_string "none")
715              (const_string "load"))
716          (eq_attr "type" "callv")
717            (if_then_else (match_operand 1 "constant_call_address_operand")
718              (const_string "none")
719              (const_string "load"))
720          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
721               (match_operand 1 "memory_operand"))
722            (const_string "both")
723          (and (match_operand 0 "memory_operand")
724               (match_operand 1 "memory_operand"))
725            (const_string "both")
726          (match_operand 0 "memory_operand")
727            (const_string "store")
728          (match_operand 1 "memory_operand")
729            (const_string "load")
730          (and (eq_attr "type"
731                  "!alu1,negnot,ishift1,
732                    imov,imovx,icmp,test,bitmanip,
733                    fmov,fcmp,fsgn,
734                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
735                    sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
736                    mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
737               (match_operand 2 "memory_operand"))
738            (const_string "load")
739          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
740               (match_operand 3 "memory_operand"))
741            (const_string "load")
742         ]
743         (const_string "none")))
745 ;; Indicates if an instruction has both an immediate and a displacement.
747 (define_attr "imm_disp" "false,true,unknown"
748   (cond [(eq_attr "type" "other,multi")
749            (const_string "unknown")
750          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
751               (and (match_operand 0 "memory_displacement_operand")
752                    (match_operand 1 "immediate_operand")))
753            (const_string "true")
754          (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
755               (and (match_operand 0 "memory_displacement_operand")
756                    (match_operand 2 "immediate_operand")))
757            (const_string "true")
758         ]
759         (const_string "false")))
761 ;; Indicates if an FP operation has an integer source.
763 (define_attr "fp_int_src" "false,true"
764   (const_string "false"))
766 ;; Defines rounding mode of an FP operation.
768 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
769   (const_string "any"))
771 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
772 (define_attr "use_carry" "0,1" (const_string "0"))
774 ;; Define attribute to indicate unaligned ssemov insns
775 (define_attr "movu" "0,1" (const_string "0"))
777 ;; Used to control the "enabled" attribute on a per-instruction basis.
778 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
779                     sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
780                     avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
781                     fma_avx512f,avx512bw,noavx512bw,avx512dq,noavx512dq"
782   (const_string "base"))
784 (define_attr "enabled" ""
785   (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
786          (eq_attr "isa" "x64_sse4")
787            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
788          (eq_attr "isa" "x64_sse4_noavx")
789            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
790          (eq_attr "isa" "x64_avx")
791            (symbol_ref "TARGET_64BIT && TARGET_AVX")
792          (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
793          (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
794          (eq_attr "isa" "sse2_noavx")
795            (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
796          (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
797          (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
798          (eq_attr "isa" "sse4_noavx")
799            (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
800          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
801          (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
802          (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
803          (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
804          (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
805          (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
806          (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
807          (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
808          (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
809          (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
810          (eq_attr "isa" "fma_avx512f")
811            (symbol_ref "TARGET_FMA || TARGET_AVX512F")
812          (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
813          (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
814          (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
815          (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
816         ]
817         (const_int 1)))
819 (define_attr "preferred_for_size" "" (const_int 1))
820 (define_attr "preferred_for_speed" "" (const_int 1))
822 ;; Describe a user's asm statement.
823 (define_asm_attributes
824   [(set_attr "length" "128")
825    (set_attr "type" "multi")])
827 (define_code_iterator plusminus [plus minus])
829 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
831 (define_code_iterator multdiv [mult div])
833 ;; Base name for define_insn
834 (define_code_attr plusminus_insn
835   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
836    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
838 ;; Base name for insn mnemonic.
839 (define_code_attr plusminus_mnemonic
840   [(plus "add") (ss_plus "adds") (us_plus "addus")
841    (minus "sub") (ss_minus "subs") (us_minus "subus")])
842 (define_code_attr plusminus_carry_mnemonic
843   [(plus "adc") (minus "sbb")])
844 (define_code_attr multdiv_mnemonic
845   [(mult "mul") (div "div")])
847 ;; Mark commutative operators as such in constraints.
848 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
849                         (minus "") (ss_minus "") (us_minus "")])
851 ;; Mapping of max and min
852 (define_code_iterator maxmin [smax smin umax umin])
854 ;; Mapping of signed max and min
855 (define_code_iterator smaxmin [smax smin])
857 ;; Mapping of unsigned max and min
858 (define_code_iterator umaxmin [umax umin])
860 ;; Base name for integer and FP insn mnemonic
861 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
862                               (umax "maxu") (umin "minu")])
863 (define_code_attr maxmin_float [(smax "max") (smin "min")])
865 ;; Mapping of logic operators
866 (define_code_iterator any_logic [and ior xor])
867 (define_code_iterator any_or [ior xor])
868 (define_code_iterator fpint_logic [and xor])
870 ;; Base name for insn mnemonic.
871 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
873 ;; Mapping of logic-shift operators
874 (define_code_iterator any_lshift [ashift lshiftrt])
876 ;; Mapping of shift-right operators
877 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
879 ;; Mapping of all shift operators
880 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
882 ;; Base name for define_insn
883 (define_code_attr shift_insn
884   [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
886 ;; Base name for insn mnemonic.
887 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
888 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
890 ;; Mapping of rotate operators
891 (define_code_iterator any_rotate [rotate rotatert])
893 ;; Base name for define_insn
894 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
896 ;; Base name for insn mnemonic.
897 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
899 ;; Mapping of abs neg operators
900 (define_code_iterator absneg [abs neg])
902 ;; Base name for x87 insn mnemonic.
903 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
905 ;; Used in signed and unsigned widening multiplications.
906 (define_code_iterator any_extend [sign_extend zero_extend])
908 ;; Prefix for insn menmonic.
909 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
911 ;; Prefix for define_insn
912 (define_code_attr u [(sign_extend "") (zero_extend "u")])
913 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
914 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
916 ;; Used in signed and unsigned truncations.
917 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
918 ;; Instruction suffix for truncations.
919 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
921 ;; Used in signed and unsigned fix.
922 (define_code_iterator any_fix [fix unsigned_fix])
923 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
925 ;; Used in signed and unsigned float.
926 (define_code_iterator any_float [float unsigned_float])
927 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
929 ;; All integer modes.
930 (define_mode_iterator SWI1248x [QI HI SI DI])
932 ;; All integer modes with AVX512BW.
933 (define_mode_iterator SWI1248_AVX512BW
934   [QI HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
936 ;; All integer modes without QImode.
937 (define_mode_iterator SWI248x [HI SI DI])
939 ;; All integer modes without QImode and HImode.
940 (define_mode_iterator SWI48x [SI DI])
942 ;; All integer modes without SImode and DImode.
943 (define_mode_iterator SWI12 [QI HI])
945 ;; All integer modes without DImode.
946 (define_mode_iterator SWI124 [QI HI SI])
948 ;; All integer modes without QImode and DImode.
949 (define_mode_iterator SWI24 [HI SI])
951 ;; Single word integer modes.
952 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
954 ;; Single word integer modes without QImode.
955 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
957 ;; Single word integer modes without QImode and HImode.
958 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
960 ;; All math-dependant single and double word integer modes.
961 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
962                              (HI "TARGET_HIMODE_MATH")
963                              SI DI (TI "TARGET_64BIT")])
965 ;; Math-dependant single word integer modes.
966 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
967                             (HI "TARGET_HIMODE_MATH")
968                             SI (DI "TARGET_64BIT")])
970 ;; Math-dependant integer modes without DImode.
971 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
972                                (HI "TARGET_HIMODE_MATH")
973                                SI])
975 ;; Math-dependant single word integer modes without QImode.
976 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
977                                SI (DI "TARGET_64BIT")])
979 ;; Double word integer modes.
980 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
981                            (TI "TARGET_64BIT")])
983 ;; GET_MODE_SIZE for selected modes.  As GET_MODE_SIZE is not
984 ;; compile time constant, it is faster to use <MODE_SIZE> than
985 ;; GET_MODE_SIZE (<MODE>mode).  For XFmode which depends on
986 ;; command line options just use GET_MODE_SIZE macro.
987 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
988                              (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
989                              (V16QI "16") (V32QI "32") (V64QI "64")
990                              (V8HI "16") (V16HI "32") (V32HI "64")
991                              (V4SI "16") (V8SI "32") (V16SI "64")
992                              (V2DI "16") (V4DI "32") (V8DI "64")
993                              (V1TI "16") (V2TI "32") (V4TI "64")
994                              (V2DF "16") (V4DF "32") (V8DF "64")
995                              (V4SF "16") (V8SF "32") (V16SF "64")])
997 ;; Double word integer modes as mode attribute.
998 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
999 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1001 ;; Half mode for double word integer modes.
1002 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1003                             (DI "TARGET_64BIT")])
1005 ;; Bound modes.
1006 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1007                            (BND64 "TARGET_LP64")])
1009 ;; Pointer mode corresponding to bound mode.
1010 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
1012 ;; MPX check types
1013 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
1015 ;; Check name
1016 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
1017                            (UNSPEC_BNDCU "cu")
1018                            (UNSPEC_BNDCN "cn")])
1020 ;; Instruction suffix for integer modes.
1021 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1023 ;; Instruction suffix for masks.
1024 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1026 ;; Pointer size prefix for integer modes (Intel asm dialect)
1027 (define_mode_attr iptrsize [(QI "BYTE")
1028                             (HI "WORD")
1029                             (SI "DWORD")
1030                             (DI "QWORD")])
1032 ;; Register class for integer modes.
1033 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1035 ;; Immediate operand constraint for integer modes.
1036 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1038 ;; General operand constraint for word modes.
1039 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1041 ;; Immediate operand constraint for double integer modes.
1042 (define_mode_attr di [(SI "nF") (DI "e")])
1044 ;; Immediate operand constraint for shifts.
1045 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1047 ;; General operand predicate for integer modes.
1048 (define_mode_attr general_operand
1049         [(QI "general_operand")
1050          (HI "general_operand")
1051          (SI "x86_64_general_operand")
1052          (DI "x86_64_general_operand")
1053          (TI "x86_64_general_operand")])
1055 ;; General sign extend operand predicate for integer modes,
1056 ;; which disallows VOIDmode operands and thus it is suitable
1057 ;; for use inside sign_extend.
1058 (define_mode_attr general_sext_operand
1059         [(QI "sext_operand")
1060          (HI "sext_operand")
1061          (SI "x86_64_sext_operand")
1062          (DI "x86_64_sext_operand")])
1064 ;; General sign/zero extend operand predicate for integer modes.
1065 (define_mode_attr general_szext_operand
1066         [(QI "general_operand")
1067          (HI "general_operand")
1068          (SI "x86_64_szext_general_operand")
1069          (DI "x86_64_szext_general_operand")])
1071 ;; Immediate operand predicate for integer modes.
1072 (define_mode_attr immediate_operand
1073         [(QI "immediate_operand")
1074          (HI "immediate_operand")
1075          (SI "x86_64_immediate_operand")
1076          (DI "x86_64_immediate_operand")])
1078 ;; Nonmemory operand predicate for integer modes.
1079 (define_mode_attr nonmemory_operand
1080         [(QI "nonmemory_operand")
1081          (HI "nonmemory_operand")
1082          (SI "x86_64_nonmemory_operand")
1083          (DI "x86_64_nonmemory_operand")])
1085 ;; Operand predicate for shifts.
1086 (define_mode_attr shift_operand
1087         [(QI "nonimmediate_operand")
1088          (HI "nonimmediate_operand")
1089          (SI "nonimmediate_operand")
1090          (DI "shiftdi_operand")
1091          (TI "register_operand")])
1093 ;; Operand predicate for shift argument.
1094 (define_mode_attr shift_immediate_operand
1095         [(QI "const_1_to_31_operand")
1096          (HI "const_1_to_31_operand")
1097          (SI "const_1_to_31_operand")
1098          (DI "const_1_to_63_operand")])
1100 ;; Input operand predicate for arithmetic left shifts.
1101 (define_mode_attr ashl_input_operand
1102         [(QI "nonimmediate_operand")
1103          (HI "nonimmediate_operand")
1104          (SI "nonimmediate_operand")
1105          (DI "ashldi_input_operand")
1106          (TI "reg_or_pm1_operand")])
1108 ;; SSE and x87 SFmode and DFmode floating point modes
1109 (define_mode_iterator MODEF [SF DF])
1111 ;; All x87 floating point modes
1112 (define_mode_iterator X87MODEF [SF DF XF])
1114 ;; SSE instruction suffix for various modes
1115 (define_mode_attr ssemodesuffix
1116   [(SF "ss") (DF "sd")
1117    (V16SF "ps") (V8DF "pd")
1118    (V8SF "ps") (V4DF "pd")
1119    (V4SF "ps") (V2DF "pd")
1120    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1121    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1122    (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1124 ;; SSE vector suffix for floating point modes
1125 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1127 ;; SSE vector mode corresponding to a scalar mode
1128 (define_mode_attr ssevecmode
1129   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1130 (define_mode_attr ssevecmodelower
1131   [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1133 ;; Instruction suffix for REX 64bit operators.
1134 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1136 ;; This mode iterator allows :P to be used for patterns that operate on
1137 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
1138 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1140 ;; This mode iterator allows :W to be used for patterns that operate on
1141 ;; word_mode sized quantities.
1142 (define_mode_iterator W
1143   [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1145 ;; This mode iterator allows :PTR to be used for patterns that operate on
1146 ;; ptr_mode sized quantities.
1147 (define_mode_iterator PTR
1148   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1150 ;; Scheduling descriptions
1152 (include "pentium.md")
1153 (include "ppro.md")
1154 (include "k6.md")
1155 (include "athlon.md")
1156 (include "bdver1.md")
1157 (include "bdver3.md")
1158 (include "btver2.md")
1159 (include "geode.md")
1160 (include "atom.md")
1161 (include "slm.md")
1162 (include "core2.md")
1165 ;; Operand and operator predicates and constraints
1167 (include "predicates.md")
1168 (include "constraints.md")
1171 ;; Compare and branch/compare and store instructions.
1173 (define_expand "cbranch<mode>4"
1174   [(set (reg:CC FLAGS_REG)
1175         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1176                     (match_operand:SDWIM 2 "<general_operand>")))
1177    (set (pc) (if_then_else
1178                (match_operator 0 "ordered_comparison_operator"
1179                 [(reg:CC FLAGS_REG) (const_int 0)])
1180                (label_ref (match_operand 3))
1181                (pc)))]
1182   ""
1184   if (MEM_P (operands[1]) && MEM_P (operands[2]))
1185     operands[1] = force_reg (<MODE>mode, operands[1]);
1186   ix86_expand_branch (GET_CODE (operands[0]),
1187                       operands[1], operands[2], operands[3]);
1188   DONE;
1191 (define_expand "cstore<mode>4"
1192   [(set (reg:CC FLAGS_REG)
1193         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1194                     (match_operand:SWIM 3 "<general_operand>")))
1195    (set (match_operand:QI 0 "register_operand")
1196         (match_operator 1 "ordered_comparison_operator"
1197           [(reg:CC FLAGS_REG) (const_int 0)]))]
1198   ""
1200   if (MEM_P (operands[2]) && MEM_P (operands[3]))
1201     operands[2] = force_reg (<MODE>mode, operands[2]);
1202   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1203                      operands[2], operands[3]);
1204   DONE;
1207 (define_expand "cmp<mode>_1"
1208   [(set (reg:CC FLAGS_REG)
1209         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1210                     (match_operand:SWI48 1 "<general_operand>")))])
1212 (define_insn "*cmp<mode>_ccno_1"
1213   [(set (reg FLAGS_REG)
1214         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1215                  (match_operand:SWI 1 "const0_operand")))]
1216   "ix86_match_ccmode (insn, CCNOmode)"
1217   "@
1218    test{<imodesuffix>}\t%0, %0
1219    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1220   [(set_attr "type" "test,icmp")
1221    (set_attr "length_immediate" "0,1")
1222    (set_attr "mode" "<MODE>")])
1224 (define_insn "*cmp<mode>_1"
1225   [(set (reg FLAGS_REG)
1226         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1227                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1228   "ix86_match_ccmode (insn, CCmode)"
1229   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1230   [(set_attr "type" "icmp")
1231    (set_attr "mode" "<MODE>")])
1233 (define_insn "*cmp<mode>_minus_1"
1234   [(set (reg FLAGS_REG)
1235         (compare
1236           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1237                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1238           (const_int 0)))]
1239   "ix86_match_ccmode (insn, CCGOCmode)"
1240   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1241   [(set_attr "type" "icmp")
1242    (set_attr "mode" "<MODE>")])
1244 (define_insn "*cmpqi_ext_1"
1245   [(set (reg FLAGS_REG)
1246         (compare
1247           (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1248           (subreg:QI
1249             (zero_extract:SI
1250               (match_operand 1 "ext_register_operand" "Q,Q")
1251               (const_int 8)
1252               (const_int 8)) 0)))]
1253   "ix86_match_ccmode (insn, CCmode)"
1254   "cmp{b}\t{%h1, %0|%0, %h1}"
1255   [(set_attr "isa" "*,nox64")
1256    (set_attr "type" "icmp")
1257    (set_attr "mode" "QI")])
1259 (define_insn "*cmpqi_ext_2"
1260   [(set (reg FLAGS_REG)
1261         (compare
1262           (subreg:QI
1263             (zero_extract:SI
1264               (match_operand 0 "ext_register_operand" "Q")
1265               (const_int 8)
1266               (const_int 8)) 0)
1267           (match_operand:QI 1 "const0_operand")))]
1268   "ix86_match_ccmode (insn, CCNOmode)"
1269   "test{b}\t%h0, %h0"
1270   [(set_attr "type" "test")
1271    (set_attr "length_immediate" "0")
1272    (set_attr "mode" "QI")])
1274 (define_expand "cmpqi_ext_3"
1275   [(set (reg:CC FLAGS_REG)
1276         (compare:CC
1277           (subreg:QI
1278             (zero_extract:SI
1279               (match_operand 0 "ext_register_operand")
1280               (const_int 8)
1281               (const_int 8)) 0)
1282           (match_operand:QI 1 "const_int_operand")))])
1284 (define_insn "*cmpqi_ext_3"
1285   [(set (reg FLAGS_REG)
1286         (compare
1287           (subreg:QI
1288             (zero_extract:SI
1289               (match_operand 0 "ext_register_operand" "Q,Q")
1290               (const_int 8)
1291               (const_int 8)) 0)
1292           (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1293   "ix86_match_ccmode (insn, CCmode)"
1294   "cmp{b}\t{%1, %h0|%h0, %1}"
1295   [(set_attr "isa" "*,nox64")
1296    (set_attr "type" "icmp")
1297    (set_attr "modrm" "1")
1298    (set_attr "mode" "QI")])
1300 (define_insn "*cmpqi_ext_4"
1301   [(set (reg FLAGS_REG)
1302         (compare
1303           (subreg:QI
1304             (zero_extract:SI
1305               (match_operand 0 "ext_register_operand" "Q")
1306               (const_int 8)
1307               (const_int 8)) 0)
1308           (subreg:QI
1309             (zero_extract:SI
1310               (match_operand 1 "ext_register_operand" "Q")
1311               (const_int 8)
1312               (const_int 8)) 0)))]
1313   "ix86_match_ccmode (insn, CCmode)"
1314   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1315   [(set_attr "type" "icmp")
1316    (set_attr "mode" "QI")])
1318 ;; These implement float point compares.
1319 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1320 ;; which would allow mix and match FP modes on the compares.  Which is what
1321 ;; the old patterns did, but with many more of them.
1323 (define_expand "cbranchxf4"
1324   [(set (reg:CC FLAGS_REG)
1325         (compare:CC (match_operand:XF 1 "nonmemory_operand")
1326                     (match_operand:XF 2 "nonmemory_operand")))
1327    (set (pc) (if_then_else
1328               (match_operator 0 "ix86_fp_comparison_operator"
1329                [(reg:CC FLAGS_REG)
1330                 (const_int 0)])
1331               (label_ref (match_operand 3))
1332               (pc)))]
1333   "TARGET_80387"
1335   ix86_expand_branch (GET_CODE (operands[0]),
1336                       operands[1], operands[2], operands[3]);
1337   DONE;
1340 (define_expand "cstorexf4"
1341   [(set (reg:CC FLAGS_REG)
1342         (compare:CC (match_operand:XF 2 "nonmemory_operand")
1343                     (match_operand:XF 3 "nonmemory_operand")))
1344    (set (match_operand:QI 0 "register_operand")
1345               (match_operator 1 "ix86_fp_comparison_operator"
1346                [(reg:CC FLAGS_REG)
1347                 (const_int 0)]))]
1348   "TARGET_80387"
1350   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1351                      operands[2], operands[3]);
1352   DONE;
1355 (define_expand "cbranch<mode>4"
1356   [(set (reg:CC FLAGS_REG)
1357         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1358                     (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1359    (set (pc) (if_then_else
1360               (match_operator 0 "ix86_fp_comparison_operator"
1361                [(reg:CC FLAGS_REG)
1362                 (const_int 0)])
1363               (label_ref (match_operand 3))
1364               (pc)))]
1365   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1367   ix86_expand_branch (GET_CODE (operands[0]),
1368                       operands[1], operands[2], operands[3]);
1369   DONE;
1372 (define_expand "cstore<mode>4"
1373   [(set (reg:CC FLAGS_REG)
1374         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1375                     (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1376    (set (match_operand:QI 0 "register_operand")
1377               (match_operator 1 "ix86_fp_comparison_operator"
1378                [(reg:CC FLAGS_REG)
1379                 (const_int 0)]))]
1380   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1382   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1383                      operands[2], operands[3]);
1384   DONE;
1387 (define_expand "cbranchcc4"
1388   [(set (pc) (if_then_else
1389               (match_operator 0 "comparison_operator"
1390                [(match_operand 1 "flags_reg_operand")
1391                 (match_operand 2 "const0_operand")])
1392               (label_ref (match_operand 3))
1393               (pc)))]
1394   ""
1396   ix86_expand_branch (GET_CODE (operands[0]),
1397                       operands[1], operands[2], operands[3]);
1398   DONE;
1401 (define_expand "cstorecc4"
1402   [(set (match_operand:QI 0 "register_operand")
1403               (match_operator 1 "comparison_operator"
1404                [(match_operand 2 "flags_reg_operand")
1405                 (match_operand 3 "const0_operand")]))]
1406   ""
1408   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1409                      operands[2], operands[3]);
1410   DONE;
1414 ;; FP compares, step 1:
1415 ;; Set the FP condition codes.
1417 ;; CCFPmode     compare with exceptions
1418 ;; CCFPUmode    compare with no exceptions
1420 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1421 ;; used to manage the reg stack popping would not be preserved.
1423 (define_insn "*cmp<mode>_0_i387"
1424   [(set (match_operand:HI 0 "register_operand" "=a")
1425         (unspec:HI
1426           [(compare:CCFP
1427              (match_operand:X87MODEF 1 "register_operand" "f")
1428              (match_operand:X87MODEF 2 "const0_operand"))]
1429         UNSPEC_FNSTSW))]
1430   "TARGET_80387"
1431   "* return output_fp_compare (insn, operands, false, false);"
1432   [(set_attr "type" "multi")
1433    (set_attr "unit" "i387")
1434    (set_attr "mode" "<MODE>")])
1436 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1437   [(set (reg:CCFP FLAGS_REG)
1438         (compare:CCFP
1439           (match_operand:X87MODEF 1 "register_operand" "f")
1440           (match_operand:X87MODEF 2 "const0_operand")))
1441    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1442   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1443   "#"
1444   "&& reload_completed"
1445   [(set (match_dup 0)
1446         (unspec:HI
1447           [(compare:CCFP (match_dup 1)(match_dup 2))]
1448         UNSPEC_FNSTSW))
1449    (set (reg:CC FLAGS_REG)
1450         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1451   ""
1452   [(set_attr "type" "multi")
1453    (set_attr "unit" "i387")
1454    (set_attr "mode" "<MODE>")])
1456 (define_insn "*cmpxf_i387"
1457   [(set (match_operand:HI 0 "register_operand" "=a")
1458         (unspec:HI
1459           [(compare:CCFP
1460              (match_operand:XF 1 "register_operand" "f")
1461              (match_operand:XF 2 "register_operand" "f"))]
1462           UNSPEC_FNSTSW))]
1463   "TARGET_80387"
1464   "* return output_fp_compare (insn, operands, false, false);"
1465   [(set_attr "type" "multi")
1466    (set_attr "unit" "i387")
1467    (set_attr "mode" "XF")])
1469 (define_insn_and_split "*cmpxf_cc_i387"
1470   [(set (reg:CCFP FLAGS_REG)
1471         (compare:CCFP
1472           (match_operand:XF 1 "register_operand" "f")
1473           (match_operand:XF 2 "register_operand" "f")))
1474    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1475   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1476   "#"
1477   "&& reload_completed"
1478   [(set (match_dup 0)
1479         (unspec:HI
1480           [(compare:CCFP (match_dup 1)(match_dup 2))]
1481         UNSPEC_FNSTSW))
1482    (set (reg:CC FLAGS_REG)
1483         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1484   ""
1485   [(set_attr "type" "multi")
1486    (set_attr "unit" "i387")
1487    (set_attr "mode" "XF")])
1489 (define_insn "*cmp<mode>_i387"
1490   [(set (match_operand:HI 0 "register_operand" "=a")
1491         (unspec:HI
1492           [(compare:CCFP
1493              (match_operand:MODEF 1 "register_operand" "f")
1494              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1495           UNSPEC_FNSTSW))]
1496   "TARGET_80387"
1497   "* return output_fp_compare (insn, operands, false, false);"
1498   [(set_attr "type" "multi")
1499    (set_attr "unit" "i387")
1500    (set_attr "mode" "<MODE>")])
1502 (define_insn_and_split "*cmp<mode>_cc_i387"
1503   [(set (reg:CCFP FLAGS_REG)
1504         (compare:CCFP
1505           (match_operand:MODEF 1 "register_operand" "f")
1506           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1507    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1508   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1509   "#"
1510   "&& reload_completed"
1511   [(set (match_dup 0)
1512         (unspec:HI
1513           [(compare:CCFP (match_dup 1)(match_dup 2))]
1514         UNSPEC_FNSTSW))
1515    (set (reg:CC FLAGS_REG)
1516         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1517   ""
1518   [(set_attr "type" "multi")
1519    (set_attr "unit" "i387")
1520    (set_attr "mode" "<MODE>")])
1522 (define_insn "*cmpu<mode>_i387"
1523   [(set (match_operand:HI 0 "register_operand" "=a")
1524         (unspec:HI
1525           [(compare:CCFPU
1526              (match_operand:X87MODEF 1 "register_operand" "f")
1527              (match_operand:X87MODEF 2 "register_operand" "f"))]
1528           UNSPEC_FNSTSW))]
1529   "TARGET_80387"
1530   "* return output_fp_compare (insn, operands, false, true);"
1531   [(set_attr "type" "multi")
1532    (set_attr "unit" "i387")
1533    (set_attr "mode" "<MODE>")])
1535 (define_insn_and_split "*cmpu<mode>_cc_i387"
1536   [(set (reg:CCFPU FLAGS_REG)
1537         (compare:CCFPU
1538           (match_operand:X87MODEF 1 "register_operand" "f")
1539           (match_operand:X87MODEF 2 "register_operand" "f")))
1540    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1541   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1542   "#"
1543   "&& reload_completed"
1544   [(set (match_dup 0)
1545         (unspec:HI
1546           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1547         UNSPEC_FNSTSW))
1548    (set (reg:CC FLAGS_REG)
1549         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1550   ""
1551   [(set_attr "type" "multi")
1552    (set_attr "unit" "i387")
1553    (set_attr "mode" "<MODE>")])
1555 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1556   [(set (match_operand:HI 0 "register_operand" "=a")
1557         (unspec:HI
1558           [(compare:CCFP
1559              (match_operand:X87MODEF 1 "register_operand" "f")
1560              (match_operator:X87MODEF 3 "float_operator"
1561                [(match_operand:SWI24 2 "memory_operand" "m")]))]
1562           UNSPEC_FNSTSW))]
1563   "TARGET_80387
1564    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1565        || optimize_function_for_size_p (cfun))"
1566   "* return output_fp_compare (insn, operands, false, false);"
1567   [(set_attr "type" "multi")
1568    (set_attr "unit" "i387")
1569    (set_attr "fp_int_src" "true")
1570    (set_attr "mode" "<SWI24:MODE>")])
1572 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1573   [(set (reg:CCFP FLAGS_REG)
1574         (compare:CCFP
1575           (match_operand:X87MODEF 1 "register_operand" "f")
1576           (match_operator:X87MODEF 3 "float_operator"
1577             [(match_operand:SWI24 2 "memory_operand" "m")])))
1578    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1579   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1580    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1581        || optimize_function_for_size_p (cfun))"
1582   "#"
1583   "&& reload_completed"
1584   [(set (match_dup 0)
1585         (unspec:HI
1586           [(compare:CCFP
1587              (match_dup 1)
1588              (match_op_dup 3 [(match_dup 2)]))]
1589         UNSPEC_FNSTSW))
1590    (set (reg:CC FLAGS_REG)
1591         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1592   ""
1593   [(set_attr "type" "multi")
1594    (set_attr "unit" "i387")
1595    (set_attr "fp_int_src" "true")
1596    (set_attr "mode" "<SWI24:MODE>")])
1598 ;; FP compares, step 2
1599 ;; Move the fpsw to ax.
1601 (define_insn "x86_fnstsw_1"
1602   [(set (match_operand:HI 0 "register_operand" "=a")
1603         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1604   "TARGET_80387"
1605   "fnstsw\t%0"
1606   [(set_attr "length" "2")
1607    (set_attr "mode" "SI")
1608    (set_attr "unit" "i387")])
1610 ;; FP compares, step 3
1611 ;; Get ax into flags, general case.
1613 (define_insn "x86_sahf_1"
1614   [(set (reg:CC FLAGS_REG)
1615         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1616                    UNSPEC_SAHF))]
1617   "TARGET_SAHF"
1619 #ifndef HAVE_AS_IX86_SAHF
1620   if (TARGET_64BIT)
1621     return ASM_BYTE "0x9e";
1622   else
1623 #endif
1624   return "sahf";
1626   [(set_attr "length" "1")
1627    (set_attr "athlon_decode" "vector")
1628    (set_attr "amdfam10_decode" "direct")
1629    (set_attr "bdver1_decode" "direct")
1630    (set_attr "mode" "SI")])
1632 ;; Pentium Pro can do steps 1 through 3 in one go.
1633 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1634 ;; (these i387 instructions set flags directly)
1636 (define_mode_iterator FPCMP [CCFP CCFPU])
1637 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1639 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1640   [(set (reg:FPCMP FLAGS_REG)
1641         (compare:FPCMP
1642           (match_operand:MODEF 0 "register_operand" "f,x")
1643           (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1644   "TARGET_MIX_SSE_I387
1645    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1646   "* return output_fp_compare (insn, operands, true,
1647                                <FPCMP:MODE>mode == CCFPUmode);"
1648   [(set_attr "type" "fcmp,ssecomi")
1649    (set_attr "prefix" "orig,maybe_vex")
1650    (set_attr "mode" "<MODEF:MODE>")
1651    (set (attr "prefix_rep")
1652         (if_then_else (eq_attr "type" "ssecomi")
1653                       (const_string "0")
1654                       (const_string "*")))
1655    (set (attr "prefix_data16")
1656         (cond [(eq_attr "type" "fcmp")
1657                  (const_string "*")
1658                (eq_attr "mode" "DF")
1659                  (const_string "1")
1660               ]
1661               (const_string "0")))
1662    (set_attr "athlon_decode" "vector")
1663    (set_attr "amdfam10_decode" "direct")
1664    (set_attr "bdver1_decode" "double")])
1666 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1667   [(set (reg:FPCMP FLAGS_REG)
1668         (compare:FPCMP
1669           (match_operand:MODEF 0 "register_operand" "x")
1670           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1671   "TARGET_SSE_MATH
1672    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1673   "* return output_fp_compare (insn, operands, true,
1674                                <FPCMP:MODE>mode == CCFPUmode);"
1675   [(set_attr "type" "ssecomi")
1676    (set_attr "prefix" "maybe_vex")
1677    (set_attr "mode" "<MODEF:MODE>")
1678    (set_attr "prefix_rep" "0")
1679    (set (attr "prefix_data16")
1680         (if_then_else (eq_attr "mode" "DF")
1681                       (const_string "1")
1682                       (const_string "0")))
1683    (set_attr "athlon_decode" "vector")
1684    (set_attr "amdfam10_decode" "direct")
1685    (set_attr "bdver1_decode" "double")])
1687 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1688   [(set (reg:FPCMP FLAGS_REG)
1689         (compare:FPCMP
1690           (match_operand:X87MODEF 0 "register_operand" "f")
1691           (match_operand:X87MODEF 1 "register_operand" "f")))]
1692   "TARGET_80387 && TARGET_CMOVE
1693    && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1694   "* return output_fp_compare (insn, operands, true,
1695                                <FPCMP:MODE>mode == CCFPUmode);"
1696   [(set_attr "type" "fcmp")
1697    (set_attr "mode" "<X87MODEF:MODE>")
1698    (set_attr "athlon_decode" "vector")
1699    (set_attr "amdfam10_decode" "direct")
1700    (set_attr "bdver1_decode" "double")])
1702 ;; Push/pop instructions.
1704 (define_insn "*push<mode>2"
1705   [(set (match_operand:DWI 0 "push_operand" "=<")
1706         (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1707   ""
1708   "#"
1709   [(set_attr "type" "multi")
1710    (set_attr "mode" "<MODE>")])
1712 (define_split
1713   [(set (match_operand:TI 0 "push_operand")
1714         (match_operand:TI 1 "general_operand"))]
1715   "TARGET_64BIT && reload_completed
1716    && !SSE_REG_P (operands[1])"
1717   [(const_int 0)]
1718   "ix86_split_long_move (operands); DONE;")
1720 (define_insn "*pushdi2_rex64"
1721   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1722         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1723   "TARGET_64BIT"
1724   "@
1725    push{q}\t%1
1726    #"
1727   [(set_attr "type" "push,multi")
1728    (set_attr "mode" "DI")])
1730 ;; Convert impossible pushes of immediate to existing instructions.
1731 ;; First try to get scratch register and go through it.  In case this
1732 ;; fails, push sign extended lower part first and then overwrite
1733 ;; upper part by 32bit move.
1734 (define_peephole2
1735   [(match_scratch:DI 2 "r")
1736    (set (match_operand:DI 0 "push_operand")
1737         (match_operand:DI 1 "immediate_operand"))]
1738   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1739    && !x86_64_immediate_operand (operands[1], DImode)"
1740   [(set (match_dup 2) (match_dup 1))
1741    (set (match_dup 0) (match_dup 2))])
1743 ;; We need to define this as both peepholer and splitter for case
1744 ;; peephole2 pass is not run.
1745 ;; "&& 1" is needed to keep it from matching the previous pattern.
1746 (define_peephole2
1747   [(set (match_operand:DI 0 "push_operand")
1748         (match_operand:DI 1 "immediate_operand"))]
1749   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1750    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1751   [(set (match_dup 0) (match_dup 1))
1752    (set (match_dup 2) (match_dup 3))]
1754   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1756   operands[1] = gen_lowpart (DImode, operands[2]);
1757   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1758                                                    GEN_INT (4)));
1761 (define_split
1762   [(set (match_operand:DI 0 "push_operand")
1763         (match_operand:DI 1 "immediate_operand"))]
1764   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1765                     ? epilogue_completed : reload_completed)
1766    && !symbolic_operand (operands[1], DImode)
1767    && !x86_64_immediate_operand (operands[1], DImode)"
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 "general_operand"))]
1781   "!TARGET_64BIT && reload_completed
1782    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1783   [(const_int 0)]
1784   "ix86_split_long_move (operands); DONE;")
1786 (define_insn "*pushsi2"
1787   [(set (match_operand:SI 0 "push_operand" "=<")
1788         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1789   "!TARGET_64BIT"
1790   "push{l}\t%1"
1791   [(set_attr "type" "push")
1792    (set_attr "mode" "SI")])
1794 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1795 ;; "push a byte/word".  But actually we use pushl, which has the effect
1796 ;; of rounding the amount pushed up to a word.
1798 ;; For TARGET_64BIT we always round up to 8 bytes.
1799 (define_insn "*push<mode>2_rex64"
1800   [(set (match_operand:SWI124 0 "push_operand" "=X")
1801         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1802   "TARGET_64BIT"
1803   "push{q}\t%q1"
1804   [(set_attr "type" "push")
1805    (set_attr "mode" "DI")])
1807 (define_insn "*push<mode>2"
1808   [(set (match_operand:SWI12 0 "push_operand" "=X")
1809         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1810   "!TARGET_64BIT"
1811   "push{l}\t%k1"
1812   [(set_attr "type" "push")
1813    (set_attr "mode" "SI")])
1815 (define_insn "*push<mode>2_prologue"
1816   [(set (match_operand:W 0 "push_operand" "=<")
1817         (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1818    (clobber (mem:BLK (scratch)))]
1819   ""
1820   "push{<imodesuffix>}\t%1"
1821   [(set_attr "type" "push")
1822    (set_attr "mode" "<MODE>")])
1824 (define_insn "*pop<mode>1"
1825   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1826         (match_operand:W 1 "pop_operand" ">"))]
1827   ""
1828   "pop{<imodesuffix>}\t%0"
1829   [(set_attr "type" "pop")
1830    (set_attr "mode" "<MODE>")])
1832 (define_insn "*pop<mode>1_epilogue"
1833   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1834         (match_operand:W 1 "pop_operand" ">"))
1835    (clobber (mem:BLK (scratch)))]
1836   ""
1837   "pop{<imodesuffix>}\t%0"
1838   [(set_attr "type" "pop")
1839    (set_attr "mode" "<MODE>")])
1841 (define_insn "*pushfl<mode>2"
1842   [(set (match_operand:W 0 "push_operand" "=<")
1843         (match_operand:W 1 "flags_reg_operand"))]
1844   ""
1845   "pushf{<imodesuffix>}"
1846   [(set_attr "type" "push")
1847    (set_attr "mode" "<MODE>")])
1849 (define_insn "*popfl<mode>1"
1850   [(set (match_operand:W 0 "flags_reg_operand")
1851         (match_operand:W 1 "pop_operand" ">"))]
1852   ""
1853   "popf{<imodesuffix>}"
1854   [(set_attr "type" "pop")
1855    (set_attr "mode" "<MODE>")])
1858 ;; Move instructions.
1860 (define_expand "movxi"
1861   [(set (match_operand:XI 0 "nonimmediate_operand")
1862         (match_operand:XI 1 "general_operand"))]
1863   "TARGET_AVX512F"
1864   "ix86_expand_move (XImode, operands); DONE;")
1866 ;; Reload patterns to support multi-word load/store
1867 ;; with non-offsetable address.
1868 (define_expand "reload_noff_store"
1869   [(parallel [(match_operand 0 "memory_operand" "=m")
1870               (match_operand 1 "register_operand" "r")
1871               (match_operand:DI 2 "register_operand" "=&r")])]
1872   "TARGET_64BIT"
1874   rtx mem = operands[0];
1875   rtx addr = XEXP (mem, 0);
1877   emit_move_insn (operands[2], addr);
1878   mem = replace_equiv_address_nv (mem, operands[2]);
1880   emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
1881   DONE;
1884 (define_expand "reload_noff_load"
1885   [(parallel [(match_operand 0 "register_operand" "=r")
1886               (match_operand 1 "memory_operand" "m")
1887               (match_operand:DI 2 "register_operand" "=r")])]
1888   "TARGET_64BIT"
1890   rtx mem = operands[1];
1891   rtx addr = XEXP (mem, 0);
1893   emit_move_insn (operands[2], addr);
1894   mem = replace_equiv_address_nv (mem, operands[2]);
1896   emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
1897   DONE;
1900 (define_expand "movoi"
1901   [(set (match_operand:OI 0 "nonimmediate_operand")
1902         (match_operand:OI 1 "general_operand"))]
1903   "TARGET_AVX"
1904   "ix86_expand_move (OImode, operands); DONE;")
1906 (define_expand "movti"
1907   [(set (match_operand:TI 0 "nonimmediate_operand")
1908         (match_operand:TI 1 "nonimmediate_operand"))]
1909   "TARGET_64BIT || TARGET_SSE"
1911   if (TARGET_64BIT)
1912     ix86_expand_move (TImode, operands);
1913   else
1914     ix86_expand_vector_move (TImode, operands);
1915   DONE;
1918 ;; This expands to what emit_move_complex would generate if we didn't
1919 ;; have a movti pattern.  Having this avoids problems with reload on
1920 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1921 ;; to have around all the time.
1922 (define_expand "movcdi"
1923   [(set (match_operand:CDI 0 "nonimmediate_operand")
1924         (match_operand:CDI 1 "general_operand"))]
1925   ""
1927   if (push_operand (operands[0], CDImode))
1928     emit_move_complex_push (CDImode, operands[0], operands[1]);
1929   else
1930     emit_move_complex_parts (operands[0], operands[1]);
1931   DONE;
1934 (define_expand "mov<mode>"
1935   [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1936         (match_operand:SWI1248x 1 "general_operand"))]
1937   ""
1938   "ix86_expand_move (<MODE>mode, operands); DONE;")
1940 (define_insn "*mov<mode>_xor"
1941   [(set (match_operand:SWI48 0 "register_operand" "=r")
1942         (match_operand:SWI48 1 "const0_operand"))
1943    (clobber (reg:CC FLAGS_REG))]
1944   "reload_completed"
1945   "xor{l}\t%k0, %k0"
1946   [(set_attr "type" "alu1")
1947    (set_attr "mode" "SI")
1948    (set_attr "length_immediate" "0")])
1950 (define_insn "*mov<mode>_or"
1951   [(set (match_operand:SWI48 0 "register_operand" "=r")
1952         (match_operand:SWI48 1 "const_int_operand"))
1953    (clobber (reg:CC FLAGS_REG))]
1954   "reload_completed
1955    && operands[1] == constm1_rtx"
1956   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1957   [(set_attr "type" "alu1")
1958    (set_attr "mode" "<MODE>")
1959    (set_attr "length_immediate" "1")])
1961 (define_insn "*movxi_internal_avx512f"
1962   [(set (match_operand:XI 0 "nonimmediate_operand" "=x,x ,m")
1963         (match_operand:XI 1 "vector_move_operand"  "C ,xm,x"))]
1964   "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1966   switch (which_alternative)
1967     {
1968     case 0:
1969       return standard_sse_constant_opcode (insn, operands[1]);
1970     case 1:
1971     case 2:
1972       if (misaligned_operand (operands[0], XImode)
1973           || misaligned_operand (operands[1], XImode))
1974         return "vmovdqu32\t{%1, %0|%0, %1}";
1975       else
1976         return "vmovdqa32\t{%1, %0|%0, %1}";
1977     default:
1978       gcc_unreachable ();
1979     }
1981   [(set_attr "type" "sselog1,ssemov,ssemov")
1982    (set_attr "prefix" "evex")
1983    (set_attr "mode" "XI")])
1985 (define_insn "*movoi_internal_avx"
1986   [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,m")
1987         (match_operand:OI 1 "vector_move_operand"  "C ,vm,v"))]
1988   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1990   switch (get_attr_type (insn))
1991     {
1992     case TYPE_SSELOG1:
1993       return standard_sse_constant_opcode (insn, operands[1]);
1995     case TYPE_SSEMOV:
1996       if (misaligned_operand (operands[0], OImode)
1997           || misaligned_operand (operands[1], OImode))
1998         {
1999           if (get_attr_mode (insn) == MODE_V8SF)
2000             return "vmovups\t{%1, %0|%0, %1}";
2001           else if (get_attr_mode (insn) == MODE_XI)
2002             return "vmovdqu32\t{%1, %0|%0, %1}";
2003           else
2004             return "vmovdqu\t{%1, %0|%0, %1}";
2005         }
2006       else
2007         {
2008           if (get_attr_mode (insn) == MODE_V8SF)
2009             return "vmovaps\t{%1, %0|%0, %1}";
2010           else if (get_attr_mode (insn) == MODE_XI)
2011             return "vmovdqa32\t{%1, %0|%0, %1}";
2012           else
2013             return "vmovdqa\t{%1, %0|%0, %1}";
2014         }
2016     default:
2017       gcc_unreachable ();
2018     }
2020   [(set_attr "type" "sselog1,ssemov,ssemov")
2021    (set_attr "prefix" "vex")
2022    (set (attr "mode")
2023         (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2024                     (match_operand 1 "ext_sse_reg_operand"))
2025                  (const_string "XI")
2026                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2027                  (const_string "V8SF")
2028                (and (eq_attr "alternative" "2")
2029                     (match_test "TARGET_SSE_TYPELESS_STORES"))
2030                  (const_string "V8SF")
2031               ]
2032               (const_string "OI")))])
2034 (define_insn "*movti_internal"
2035   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,m")
2036         (match_operand:TI 1 "general_operand"      "riFo,re,C,vm,v"))]
2037   "(TARGET_64BIT || TARGET_SSE)
2038    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2040   switch (get_attr_type (insn))
2041     {
2042     case TYPE_MULTI:
2043       return "#";
2045     case TYPE_SSELOG1:
2046       return standard_sse_constant_opcode (insn, operands[1]);
2048     case TYPE_SSEMOV:
2049       /* TDmode values are passed as TImode on the stack.  Moving them
2050          to stack may result in unaligned memory access.  */
2051       if (misaligned_operand (operands[0], TImode)
2052           || misaligned_operand (operands[1], TImode))
2053         {
2054           if (get_attr_mode (insn) == MODE_V4SF)
2055             return "%vmovups\t{%1, %0|%0, %1}";
2056           else if (get_attr_mode (insn) == MODE_XI)
2057             return "vmovdqu32\t{%1, %0|%0, %1}";
2058           else
2059             return "%vmovdqu\t{%1, %0|%0, %1}";
2060         }
2061       else
2062         {
2063           if (get_attr_mode (insn) == MODE_V4SF)
2064             return "%vmovaps\t{%1, %0|%0, %1}";
2065           else if (get_attr_mode (insn) == MODE_XI)
2066             return "vmovdqa32\t{%1, %0|%0, %1}";
2067           else
2068             return "%vmovdqa\t{%1, %0|%0, %1}";
2069         }
2071     default:
2072       gcc_unreachable ();
2073     }
2075   [(set_attr "isa" "x64,x64,*,*,*")
2076    (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
2077    (set (attr "prefix")
2078      (if_then_else (eq_attr "type" "sselog1,ssemov")
2079        (const_string "maybe_vex")
2080        (const_string "orig")))
2081    (set (attr "mode")
2082         (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2083                     (match_operand 1 "ext_sse_reg_operand"))
2084                  (const_string "XI")
2085                (eq_attr "alternative" "0,1")
2086                  (const_string "DI")
2087                (ior (not (match_test "TARGET_SSE2"))
2088                     (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2089                  (const_string "V4SF")
2090                (and (eq_attr "alternative" "4")
2091                     (match_test "TARGET_SSE_TYPELESS_STORES"))
2092                  (const_string "V4SF")
2093                (match_test "TARGET_AVX")
2094                  (const_string "TI")
2095                (match_test "optimize_function_for_size_p (cfun)")
2096                  (const_string "V4SF")
2097                ]
2098                (const_string "TI")))])
2100 (define_split
2101   [(set (match_operand:TI 0 "nonimmediate_operand")
2102         (match_operand:TI 1 "general_operand"))]
2103   "reload_completed
2104    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
2105   [(const_int 0)]
2106   "ix86_split_long_move (operands); DONE;")
2108 (define_insn "*movdi_internal"
2109   [(set (match_operand:DI 0 "nonimmediate_operand"
2110     "=r  ,o  ,r,r  ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,?r ,?r,?*Yi,?*Ym,?*Yi,*k,*k ,*r ,*m")
2111         (match_operand:DI 1 "general_operand"
2112     "riFo,riF,Z,rem,i,re,C ,*y,m  ,*y,*Yn,r   ,C ,*v,m ,*v,*Yj,*v,r   ,*Yj ,*Yn ,*r ,*km,*k,*k"))]
2113   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2115   switch (get_attr_type (insn))
2116     {
2117     case TYPE_MSKMOV:
2118       return "kmovq\t{%1, %0|%0, %1}";
2120     case TYPE_MULTI:
2121       return "#";
2123     case TYPE_MMX:
2124       return "pxor\t%0, %0";
2126     case TYPE_MMXMOV:
2127       /* Handle broken assemblers that require movd instead of movq.  */
2128       if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2129           && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2130         return "movd\t{%1, %0|%0, %1}";
2131       return "movq\t{%1, %0|%0, %1}";
2133     case TYPE_SSELOG1:
2134       if (GENERAL_REG_P (operands[0]))
2135         return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2137       return standard_sse_constant_opcode (insn, operands[1]);
2139     case TYPE_SSEMOV:
2140       switch (get_attr_mode (insn))
2141         {
2142         case MODE_DI:
2143           /* Handle broken assemblers that require movd instead of movq.  */
2144           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2145               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2146             return "%vmovd\t{%1, %0|%0, %1}";
2147           return "%vmovq\t{%1, %0|%0, %1}";
2148         case MODE_TI:
2149           return "%vmovdqa\t{%1, %0|%0, %1}";
2150         case MODE_XI:
2151           return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2153         case MODE_V2SF:
2154           gcc_assert (!TARGET_AVX);
2155           return "movlps\t{%1, %0|%0, %1}";
2156         case MODE_V4SF:
2157           return "%vmovaps\t{%1, %0|%0, %1}";
2159         default:
2160           gcc_unreachable ();
2161         }
2163     case TYPE_SSECVT:
2164       if (SSE_REG_P (operands[0]))
2165         return "movq2dq\t{%1, %0|%0, %1}";
2166       else
2167         return "movdq2q\t{%1, %0|%0, %1}";
2169     case TYPE_LEA:
2170       return "lea{q}\t{%E1, %0|%0, %E1}";
2172     case TYPE_IMOV:
2173       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2174       if (get_attr_mode (insn) == MODE_SI)
2175         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2176       else if (which_alternative == 4)
2177         return "movabs{q}\t{%1, %0|%0, %1}";
2178       else if (ix86_use_lea_for_mov (insn, operands))
2179         return "lea{q}\t{%E1, %0|%0, %E1}";
2180       else
2181         return "mov{q}\t{%1, %0|%0, %1}";
2183     default:
2184       gcc_unreachable ();
2185     }
2187   [(set (attr "isa")
2188      (cond [(eq_attr "alternative" "0,1")
2189               (const_string "nox64")
2190             (eq_attr "alternative" "2,3,4,5,10,11,16,18,21,23")
2191               (const_string "x64")
2192             (eq_attr "alternative" "17")
2193               (const_string "x64_sse4")
2194            ]
2195            (const_string "*")))
2196    (set (attr "type")
2197      (cond [(eq_attr "alternative" "0,1")
2198               (const_string "multi")
2199             (eq_attr "alternative" "6")
2200               (const_string "mmx")
2201             (eq_attr "alternative" "7,8,9,10,11")
2202               (const_string "mmxmov")
2203             (eq_attr "alternative" "12,17")
2204               (const_string "sselog1")
2205             (eq_attr "alternative" "13,14,15,16,18")
2206               (const_string "ssemov")
2207             (eq_attr "alternative" "19,20")
2208               (const_string "ssecvt")
2209             (eq_attr "alternative" "21,22,23,24")
2210               (const_string "mskmov")
2211             (and (match_operand 0 "register_operand")
2212                  (match_operand 1 "pic_32bit_operand"))
2213               (const_string "lea")
2214            ]
2215            (const_string "imov")))
2216    (set (attr "modrm")
2217      (if_then_else
2218        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2219          (const_string "0")
2220          (const_string "*")))
2221    (set (attr "length_immediate")
2222      (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2223               (const_string "8")
2224             (eq_attr "alternative" "17")
2225               (const_string "1")
2226            ]
2227            (const_string "*")))
2228    (set (attr "prefix_rex")
2229      (if_then_else (eq_attr "alternative" "10,11,16,17,18")
2230        (const_string "1")
2231        (const_string "*")))
2232    (set (attr "prefix_extra")
2233      (if_then_else (eq_attr "alternative" "17")
2234        (const_string "1")
2235        (const_string "*")))
2236    (set (attr "prefix")
2237      (if_then_else (eq_attr "type" "sselog1,ssemov")
2238        (const_string "maybe_vex")
2239        (const_string "orig")))
2240    (set (attr "prefix_data16")
2241      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2242        (const_string "1")
2243        (const_string "*")))
2244    (set (attr "mode")
2245      (cond [(eq_attr "alternative" "2")
2246               (const_string "SI")
2247             (eq_attr "alternative" "12,13")
2248               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2249                           (match_operand 1 "ext_sse_reg_operand"))
2250                        (const_string "XI")
2251                      (ior (not (match_test "TARGET_SSE2"))
2252                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2253                        (const_string "V4SF")
2254                      (match_test "TARGET_AVX")
2255                        (const_string "TI")
2256                      (match_test "optimize_function_for_size_p (cfun)")
2257                        (const_string "V4SF")
2258                     ]
2259                     (const_string "TI"))
2261             (and (eq_attr "alternative" "14,15")
2262                  (not (match_test "TARGET_SSE2")))
2263               (const_string "V2SF")
2264             (eq_attr "alternative" "17")
2265               (const_string "TI")
2266            ]
2267            (const_string "DI")))])
2269 (define_split
2270   [(set (match_operand:DI 0 "nonimmediate_operand")
2271         (match_operand:DI 1 "general_operand"))]
2272   "!TARGET_64BIT && reload_completed
2273    && !(MMX_REG_P (operands[0])
2274         || SSE_REG_P (operands[0])
2275         || MASK_REG_P (operands[0]))
2276    && !(MMX_REG_P (operands[1])
2277         || SSE_REG_P (operands[1])
2278         || MASK_REG_P (operands[1]))"
2279   [(const_int 0)]
2280   "ix86_split_long_move (operands); DONE;")
2282 (define_insn "*movsi_internal"
2283   [(set (match_operand:SI 0 "nonimmediate_operand"
2284                         "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi,*k  ,*rm")
2285         (match_operand:SI 1 "general_operand"
2286                         "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r   ,*krm,*k"))]
2287   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2289   switch (get_attr_type (insn))
2290     {
2291     case TYPE_SSELOG1:
2292       if (GENERAL_REG_P (operands[0]))
2293         return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2295       return standard_sse_constant_opcode (insn, operands[1]);
2297     case TYPE_MSKMOV:
2298       return "kmovd\t{%1, %0|%0, %1}";
2300     case TYPE_SSEMOV:
2301       switch (get_attr_mode (insn))
2302         {
2303         case MODE_SI:
2304           return "%vmovd\t{%1, %0|%0, %1}";
2305         case MODE_TI:
2306           return "%vmovdqa\t{%1, %0|%0, %1}";
2307         case MODE_XI:
2308           return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2310         case MODE_V4SF:
2311           return "%vmovaps\t{%1, %0|%0, %1}";
2313         case MODE_SF:
2314           gcc_assert (!TARGET_AVX);
2315           return "movss\t{%1, %0|%0, %1}";
2317         default:
2318           gcc_unreachable ();
2319         }
2321     case TYPE_MMX:
2322       return "pxor\t%0, %0";
2324     case TYPE_MMXMOV:
2325       switch (get_attr_mode (insn))
2326         {
2327         case MODE_DI:
2328           return "movq\t{%1, %0|%0, %1}";
2329         case MODE_SI:
2330           return "movd\t{%1, %0|%0, %1}";
2332         default:
2333           gcc_unreachable ();
2334         }
2336     case TYPE_LEA:
2337       return "lea{l}\t{%E1, %0|%0, %E1}";
2339     case TYPE_IMOV:
2340       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2341       if (ix86_use_lea_for_mov (insn, operands))
2342         return "lea{l}\t{%E1, %0|%0, %E1}";
2343       else
2344         return "mov{l}\t{%1, %0|%0, %1}";
2346     default:
2347       gcc_unreachable ();
2348     }
2350   [(set (attr "isa")
2351      (if_then_else (eq_attr "alternative" "11")
2352        (const_string "sse4")
2353        (const_string "*")))
2354    (set (attr "type")
2355      (cond [(eq_attr "alternative" "2")
2356               (const_string "mmx")
2357             (eq_attr "alternative" "3,4,5")
2358               (const_string "mmxmov")
2359             (eq_attr "alternative" "6,11")
2360               (const_string "sselog1")
2361             (eq_attr "alternative" "7,8,9,10,12")
2362               (const_string "ssemov")
2363             (eq_attr "alternative" "13,14")
2364               (const_string "mskmov")
2365             (and (match_operand 0 "register_operand")
2366                  (match_operand 1 "pic_32bit_operand"))
2367               (const_string "lea")
2368            ]
2369            (const_string "imov")))
2370    (set (attr "length_immediate")
2371      (if_then_else (eq_attr "alternative" "11")
2372        (const_string "1")
2373        (const_string "*")))
2374    (set (attr "prefix_extra")
2375      (if_then_else (eq_attr "alternative" "11")
2376        (const_string "1")
2377        (const_string "*")))
2378    (set (attr "prefix")
2379      (if_then_else (eq_attr "type" "sselog1,ssemov")
2380        (const_string "maybe_vex")
2381        (const_string "orig")))
2382    (set (attr "prefix_data16")
2383      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2384        (const_string "1")
2385        (const_string "*")))
2386    (set (attr "mode")
2387      (cond [(eq_attr "alternative" "2,3")
2388               (const_string "DI")
2389             (eq_attr "alternative" "6,7")
2390               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2391                           (match_operand 1 "ext_sse_reg_operand"))
2392                        (const_string "XI")
2393                      (ior (not (match_test "TARGET_SSE2"))
2394                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2395                        (const_string "V4SF")
2396                      (match_test "TARGET_AVX")
2397                        (const_string "TI")
2398                      (match_test "optimize_function_for_size_p (cfun)")
2399                        (const_string "V4SF")
2400                     ]
2401                     (const_string "TI"))
2403             (and (eq_attr "alternative" "8,9")
2404                  (not (match_test "TARGET_SSE2")))
2405               (const_string "SF")
2406             (eq_attr "alternative" "11")
2407               (const_string "TI")
2408            ]
2409            (const_string "SI")))])
2411 (define_insn "kmovw"
2412   [(set (match_operand:HI 0 "nonimmediate_operand" "=k,k")
2413         (unspec:HI
2414           [(match_operand:HI 1 "nonimmediate_operand" "rm,k")]
2415           UNSPEC_KMOV))]
2416   "!(MEM_P (operands[0]) && MEM_P (operands[1])) && TARGET_AVX512F"
2417   "@
2418    kmovw\t{%k1, %0|%0, %k1}
2419    kmovw\t{%1, %0|%0, %1}";
2420   [(set_attr "mode" "HI")
2421    (set_attr "type" "mskmov")
2422    (set_attr "prefix" "vex")])
2425 (define_insn "*movhi_internal"
2426   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k,rm")
2427         (match_operand:HI 1 "general_operand"      "r ,rn,rm,rn,rm,k,k"))]
2428   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2430   switch (get_attr_type (insn))
2431     {
2432     case TYPE_IMOVX:
2433       /* movzwl is faster than movw on p2 due to partial word stalls,
2434          though not as fast as an aligned movl.  */
2435       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2437     case TYPE_MSKMOV:
2438       switch (which_alternative)
2439         {
2440         case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2441         case 5: return "kmovw\t{%1, %0|%0, %1}";
2442         case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2443         default: gcc_unreachable ();
2444         }
2446     default:
2447       if (get_attr_mode (insn) == MODE_SI)
2448         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2449       else
2450         return "mov{w}\t{%1, %0|%0, %1}";
2451     }
2453   [(set (attr "type")
2454      (cond [(eq_attr "alternative" "4,5,6")
2455               (const_string "mskmov")
2456             (match_test "optimize_function_for_size_p (cfun)")
2457               (const_string "imov")
2458             (and (eq_attr "alternative" "0")
2459                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2460                       (not (match_test "TARGET_HIMODE_MATH"))))
2461               (const_string "imov")
2462             (and (eq_attr "alternative" "1,2")
2463                  (match_operand:HI 1 "aligned_operand"))
2464               (const_string "imov")
2465             (and (match_test "TARGET_MOVX")
2466                  (eq_attr "alternative" "0,2"))
2467               (const_string "imovx")
2468            ]
2469            (const_string "imov")))
2470     (set (attr "prefix")
2471       (if_then_else (eq_attr "alternative" "4,5,6")
2472         (const_string "vex")
2473         (const_string "orig")))
2474     (set (attr "mode")
2475       (cond [(eq_attr "type" "imovx")
2476                (const_string "SI")
2477              (and (eq_attr "alternative" "1,2")
2478                   (match_operand:HI 1 "aligned_operand"))
2479                (const_string "SI")
2480              (and (eq_attr "alternative" "0")
2481                   (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2482                        (not (match_test "TARGET_HIMODE_MATH"))))
2483                (const_string "SI")
2484             ]
2485             (const_string "HI")))])
2487 ;; Situation is quite tricky about when to choose full sized (SImode) move
2488 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2489 ;; partial register dependency machines (such as AMD Athlon), where QImode
2490 ;; moves issue extra dependency and for partial register stalls machines
2491 ;; that don't use QImode patterns (and QImode move cause stall on the next
2492 ;; instruction).
2494 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2495 ;; register stall machines with, where we use QImode instructions, since
2496 ;; partial register stall can be caused there.  Then we use movzx.
2498 (define_insn "*movqi_internal"
2499   [(set (match_operand:QI 0 "nonimmediate_operand"
2500                         "=q,q ,q ,r,r ,?r,m ,k,k,r ,m,k")
2501         (match_operand:QI 1 "general_operand"
2502                         "q ,qn,qm,q,rn,qm,qn,r ,k,k,k,m"))]
2503   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2505   switch (get_attr_type (insn))
2506     {
2507     case TYPE_IMOVX:
2508       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2509       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2511     case TYPE_MSKMOV:
2512       switch (which_alternative)
2513         {
2514         case 7: return TARGET_AVX512DQ ? "kmovb\t{%k1, %0|%0, %k1}"
2515                                        : "kmovw\t{%k1, %0|%0, %k1}";
2516         case 8: return TARGET_AVX512DQ ? "kmovb\t{%1, %0|%0, %1}"
2517                                        : "kmovw\t{%1, %0|%0, %1}";
2518         case 9: return TARGET_AVX512DQ ? "kmovb\t{%1, %k0|%k0, %1}"
2519                                        : "kmovw\t{%1, %k0|%k0, %1}";
2520         case 10:
2521         case 11:
2522           gcc_assert (TARGET_AVX512DQ);
2523           return "kmovb\t{%1, %0|%0, %1}";
2524         default: gcc_unreachable ();
2525         }
2527     default:
2528       if (get_attr_mode (insn) == MODE_SI)
2529         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2530       else
2531         return "mov{b}\t{%1, %0|%0, %1}";
2532     }
2534   [(set_attr "isa" "*,*,*,*,*,*,*,*,*,*,avx512dq,avx512dq")
2535    (set (attr "type")
2536      (cond [(eq_attr "alternative" "7,8,9,10,11")
2537               (const_string "mskmov")
2538             (and (eq_attr "alternative" "5")
2539                  (not (match_operand:QI 1 "aligned_operand")))
2540               (const_string "imovx")
2541             (match_test "optimize_function_for_size_p (cfun)")
2542               (const_string "imov")
2543             (and (eq_attr "alternative" "3")
2544                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2545                       (not (match_test "TARGET_QIMODE_MATH"))))
2546               (const_string "imov")
2547             (eq_attr "alternative" "3,5")
2548               (const_string "imovx")
2549             (and (match_test "TARGET_MOVX")
2550                  (eq_attr "alternative" "2"))
2551               (const_string "imovx")
2552            ]
2553            (const_string "imov")))
2554    (set (attr "prefix")
2555      (if_then_else (eq_attr "alternative" "7,8,9")
2556        (const_string "vex")
2557        (const_string "orig")))
2558    (set (attr "mode")
2559       (cond [(eq_attr "alternative" "3,4,5")
2560                (const_string "SI")
2561              (eq_attr "alternative" "6")
2562                (const_string "QI")
2563              (eq_attr "type" "imovx")
2564                (const_string "SI")
2565              (and (eq_attr "type" "imov")
2566                   (and (eq_attr "alternative" "0,1")
2567                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2568                             (and (not (match_test "optimize_function_for_size_p (cfun)"))
2569                                  (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2570                (const_string "SI")
2571              ;; Avoid partial register stalls when not using QImode arithmetic
2572              (and (eq_attr "type" "imov")
2573                   (and (eq_attr "alternative" "0,1")
2574                        (and (match_test "TARGET_PARTIAL_REG_STALL")
2575                             (not (match_test "TARGET_QIMODE_MATH")))))
2576                (const_string "SI")
2577            ]
2578            (const_string "QI")))])
2580 ;; Stores and loads of ax to arbitrary constant address.
2581 ;; We fake an second form of instruction to force reload to load address
2582 ;; into register when rax is not available
2583 (define_insn "*movabs<mode>_1"
2584   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2585         (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2586   "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2587   "@
2588    movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2589    mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2590   [(set_attr "type" "imov")
2591    (set_attr "modrm" "0,*")
2592    (set_attr "length_address" "8,0")
2593    (set_attr "length_immediate" "0,*")
2594    (set_attr "memory" "store")
2595    (set_attr "mode" "<MODE>")])
2597 (define_insn "*movabs<mode>_2"
2598   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2599         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2600   "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2601   "@
2602    movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2603    mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2604   [(set_attr "type" "imov")
2605    (set_attr "modrm" "0,*")
2606    (set_attr "length_address" "8,0")
2607    (set_attr "length_immediate" "0")
2608    (set_attr "memory" "load")
2609    (set_attr "mode" "<MODE>")])
2611 (define_insn "*swap<mode>"
2612   [(set (match_operand:SWI48 0 "register_operand" "+r")
2613         (match_operand:SWI48 1 "register_operand" "+r"))
2614    (set (match_dup 1)
2615         (match_dup 0))]
2616   ""
2617   "xchg{<imodesuffix>}\t%1, %0"
2618   [(set_attr "type" "imov")
2619    (set_attr "mode" "<MODE>")
2620    (set_attr "pent_pair" "np")
2621    (set_attr "athlon_decode" "vector")
2622    (set_attr "amdfam10_decode" "double")
2623    (set_attr "bdver1_decode" "double")])
2625 (define_insn "*swap<mode>_1"
2626   [(set (match_operand:SWI12 0 "register_operand" "+r")
2627         (match_operand:SWI12 1 "register_operand" "+r"))
2628    (set (match_dup 1)
2629         (match_dup 0))]
2630   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2631   "xchg{l}\t%k1, %k0"
2632   [(set_attr "type" "imov")
2633    (set_attr "mode" "SI")
2634    (set_attr "pent_pair" "np")
2635    (set_attr "athlon_decode" "vector")
2636    (set_attr "amdfam10_decode" "double")
2637    (set_attr "bdver1_decode" "double")])
2639 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2640 ;; is disabled for AMDFAM10
2641 (define_insn "*swap<mode>_2"
2642   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2643         (match_operand:SWI12 1 "register_operand" "+<r>"))
2644    (set (match_dup 1)
2645         (match_dup 0))]
2646   "TARGET_PARTIAL_REG_STALL"
2647   "xchg{<imodesuffix>}\t%1, %0"
2648   [(set_attr "type" "imov")
2649    (set_attr "mode" "<MODE>")
2650    (set_attr "pent_pair" "np")
2651    (set_attr "athlon_decode" "vector")])
2653 (define_expand "movstrict<mode>"
2654   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2655         (match_operand:SWI12 1 "general_operand"))]
2656   ""
2658   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2659     FAIL;
2660   if (GET_CODE (operands[0]) == SUBREG
2661       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2662     FAIL;
2663   /* Don't generate memory->memory moves, go through a register */
2664   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2665     operands[1] = force_reg (<MODE>mode, operands[1]);
2668 (define_insn "*movstrict<mode>_1"
2669   [(set (strict_low_part
2670           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2671         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2672   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2673    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2674   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2675   [(set_attr "type" "imov")
2676    (set_attr "mode" "<MODE>")])
2678 (define_insn "*movstrict<mode>_xor"
2679   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2680         (match_operand:SWI12 1 "const0_operand"))
2681    (clobber (reg:CC FLAGS_REG))]
2682   "reload_completed"
2683   "xor{<imodesuffix>}\t%0, %0"
2684   [(set_attr "type" "alu1")
2685    (set_attr "mode" "<MODE>")
2686    (set_attr "length_immediate" "0")])
2688 (define_insn "*mov<mode>_extv_1"
2689   [(set (match_operand:SWI24 0 "register_operand" "=R")
2690         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2691                             (const_int 8)
2692                             (const_int 8)))]
2693   ""
2694   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2695   [(set_attr "type" "imovx")
2696    (set_attr "mode" "SI")])
2698 (define_insn "*movqi_extv_1"
2699   [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2700         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2701                          (const_int 8)
2702                          (const_int 8)))]
2703   ""
2705   switch (get_attr_type (insn))
2706     {
2707     case TYPE_IMOVX:
2708       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2709     default:
2710       return "mov{b}\t{%h1, %0|%0, %h1}";
2711     }
2713   [(set_attr "isa" "*,*,nox64")
2714    (set (attr "type")
2715      (if_then_else (and (match_operand:QI 0 "register_operand")
2716                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2717                              (match_test "TARGET_MOVX")))
2718         (const_string "imovx")
2719         (const_string "imov")))
2720    (set (attr "mode")
2721      (if_then_else (eq_attr "type" "imovx")
2722         (const_string "SI")
2723         (const_string "QI")))])
2725 (define_insn "*mov<mode>_extzv_1"
2726   [(set (match_operand:SWI48 0 "register_operand" "=R")
2727         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2728                             (const_int 8)
2729                             (const_int 8)))]
2730   ""
2731   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2732   [(set_attr "type" "imovx")
2733    (set_attr "mode" "SI")])
2735 (define_insn "*movqi_extzv_2"
2736   [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2737         (subreg:QI
2738           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2739                            (const_int 8)
2740                            (const_int 8)) 0))]
2741   ""
2743   switch (get_attr_type (insn))
2744     {
2745     case TYPE_IMOVX:
2746       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2747     default:
2748       return "mov{b}\t{%h1, %0|%0, %h1}";
2749     }
2751   [(set_attr "isa" "*,*,nox64")
2752    (set (attr "type")
2753      (if_then_else (and (match_operand:QI 0 "register_operand")
2754                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2755                              (match_test "TARGET_MOVX")))
2756         (const_string "imovx")
2757         (const_string "imov")))
2758    (set (attr "mode")
2759      (if_then_else (eq_attr "type" "imovx")
2760         (const_string "SI")
2761         (const_string "QI")))])
2763 (define_insn "mov<mode>_insv_1"
2764   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2765                              (const_int 8)
2766                              (const_int 8))
2767         (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2768   ""
2770   if (CONST_INT_P (operands[1]))
2771     operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2772   return "mov{b}\t{%b1, %h0|%h0, %b1}";
2774   [(set_attr "isa" "*,nox64")
2775    (set_attr "type" "imov")
2776    (set_attr "mode" "QI")])
2778 (define_insn "*movqi_insv_2"
2779   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2780                          (const_int 8)
2781                          (const_int 8))
2782         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2783                      (const_int 8)))]
2784   ""
2785   "mov{b}\t{%h1, %h0|%h0, %h1}"
2786   [(set_attr "type" "imov")
2787    (set_attr "mode" "QI")])
2789 ;; Floating point push instructions.
2791 (define_insn "*pushtf"
2792   [(set (match_operand:TF 0 "push_operand" "=<,<")
2793         (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2794   "TARGET_64BIT || TARGET_SSE"
2796   /* This insn should be already split before reg-stack.  */
2797   gcc_unreachable ();
2799   [(set_attr "isa" "*,x64")
2800    (set_attr "type" "multi")
2801    (set_attr "unit" "sse,*")
2802    (set_attr "mode" "TF,DI")])
2804 ;; %%% Kill this when call knows how to work this out.
2805 (define_split
2806   [(set (match_operand:TF 0 "push_operand")
2807         (match_operand:TF 1 "sse_reg_operand"))]
2808   "TARGET_SSE && reload_completed"
2809   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2810    (set (match_dup 0) (match_dup 1))]
2812   /* Preserve memory attributes. */
2813   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2816 (define_insn "*pushxf"
2817   [(set (match_operand:XF 0 "push_operand" "=<,<,<,<")
2818         (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF"))]
2819   ""
2821   /* This insn should be already split before reg-stack.  */
2822   gcc_unreachable ();
2824   [(set_attr "type" "multi")
2825    (set_attr "unit" "i387,*,*,*")
2826    (set (attr "mode")
2827         (cond [(eq_attr "alternative" "1,2,3")
2828                  (if_then_else (match_test "TARGET_64BIT")
2829                    (const_string "DI")
2830                    (const_string "SI"))
2831               ]
2832               (const_string "XF")))
2833    (set (attr "preferred_for_size")
2834      (cond [(eq_attr "alternative" "1")
2835               (symbol_ref "false")]
2836            (symbol_ref "true")))])
2838 ;; %%% Kill this when call knows how to work this out.
2839 (define_split
2840   [(set (match_operand:XF 0 "push_operand")
2841         (match_operand:XF 1 "fp_register_operand"))]
2842   "reload_completed"
2843   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2844    (set (match_dup 0) (match_dup 1))]
2846   operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
2847   /* Preserve memory attributes. */
2848   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2851 (define_insn "*pushdf"
2852   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
2853         (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmF,x"))]
2854   ""
2856   /* This insn should be already split before reg-stack.  */
2857   gcc_unreachable ();
2859   [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
2860    (set_attr "type" "multi")
2861    (set_attr "unit" "i387,*,*,*,*,sse")
2862    (set_attr "mode" "DF,SI,SI,SI,DI,DF")
2863    (set (attr "preferred_for_size")
2864      (cond [(eq_attr "alternative" "1")
2865               (symbol_ref "false")]
2866            (symbol_ref "true")))
2867    (set (attr "preferred_for_speed")
2868      (cond [(eq_attr "alternative" "1")
2869               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
2870            (symbol_ref "true")))])
2871    
2872 ;; %%% Kill this when call knows how to work this out.
2873 (define_split
2874   [(set (match_operand:DF 0 "push_operand")
2875         (match_operand:DF 1 "any_fp_register_operand"))]
2876   "reload_completed"
2877   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2878    (set (match_dup 0) (match_dup 1))]
2880   /* Preserve memory attributes. */
2881   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2884 (define_insn "*pushsf_rex64"
2885   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2886         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2887   "TARGET_64BIT"
2889   /* Anything else should be already split before reg-stack.  */
2890   gcc_assert (which_alternative == 1);
2891   return "push{q}\t%q1";
2893   [(set_attr "type" "multi,push,multi")
2894    (set_attr "unit" "i387,*,*")
2895    (set_attr "mode" "SF,DI,SF")])
2897 (define_insn "*pushsf"
2898   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2899         (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2900   "!TARGET_64BIT"
2902   /* Anything else should be already split before reg-stack.  */
2903   gcc_assert (which_alternative == 1);
2904   return "push{l}\t%1";
2906   [(set_attr "type" "multi,push,multi")
2907    (set_attr "unit" "i387,*,*")
2908    (set_attr "mode" "SF,SI,SF")])
2910 ;; %%% Kill this when call knows how to work this out.
2911 (define_split
2912   [(set (match_operand:SF 0 "push_operand")
2913         (match_operand:SF 1 "any_fp_register_operand"))]
2914   "reload_completed"
2915   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2916    (set (match_dup 0) (match_dup 1))]
2918   rtx op = XEXP (operands[0], 0);
2919   if (GET_CODE (op) == PRE_DEC)
2920     {
2921       gcc_assert (!TARGET_64BIT);
2922       op = GEN_INT (-4);
2923     }
2924   else
2925     {
2926       op = XEXP (XEXP (op, 1), 1);
2927       gcc_assert (CONST_INT_P (op));
2928     }
2929   operands[2] = op;
2930   /* Preserve memory attributes. */
2931   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2934 (define_split
2935   [(set (match_operand:SF 0 "push_operand")
2936         (match_operand:SF 1 "memory_operand"))]
2937   "reload_completed
2938    && (operands[2] = find_constant_src (insn))"
2939   [(set (match_dup 0) (match_dup 2))])
2941 (define_split
2942   [(set (match_operand 0 "push_operand")
2943         (match_operand 1 "general_operand"))]
2944   "reload_completed
2945    && (GET_MODE (operands[0]) == TFmode
2946        || GET_MODE (operands[0]) == XFmode
2947        || GET_MODE (operands[0]) == DFmode)
2948    && !ANY_FP_REG_P (operands[1])"
2949   [(const_int 0)]
2950   "ix86_split_long_move (operands); DONE;")
2952 ;; Floating point move instructions.
2954 (define_expand "movtf"
2955   [(set (match_operand:TF 0 "nonimmediate_operand")
2956         (match_operand:TF 1 "nonimmediate_operand"))]
2957   "TARGET_64BIT || TARGET_SSE"
2958   "ix86_expand_move (TFmode, operands); DONE;")
2960 (define_expand "mov<mode>"
2961   [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2962         (match_operand:X87MODEF 1 "general_operand"))]
2963   ""
2964   "ix86_expand_move (<MODE>mode, operands); DONE;")
2966 (define_insn "*movtf_internal"
2967   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2968         (match_operand:TF 1 "general_operand"      "C ,xm,x,*roF,*rC"))]
2969   "(TARGET_64BIT || TARGET_SSE)
2970    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2971    && (!can_create_pseudo_p ()
2972        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2973        || GET_CODE (operands[1]) != CONST_DOUBLE
2974        || (optimize_function_for_size_p (cfun)
2975            && standard_sse_constant_p (operands[1])
2976            && !memory_operand (operands[0], TFmode))
2977        || (!TARGET_MEMORY_MISMATCH_STALL
2978            && memory_operand (operands[0], TFmode)))"
2980   switch (get_attr_type (insn))
2981     {
2982     case TYPE_SSELOG1:
2983       return standard_sse_constant_opcode (insn, operands[1]);
2985     case TYPE_SSEMOV:
2986       /* Handle misaligned load/store since we
2987          don't have movmisaligntf pattern. */
2988       if (misaligned_operand (operands[0], TFmode)
2989           || misaligned_operand (operands[1], TFmode))
2990         {
2991           if (get_attr_mode (insn) == MODE_V4SF)
2992             return "%vmovups\t{%1, %0|%0, %1}";
2993           else
2994             return "%vmovdqu\t{%1, %0|%0, %1}";
2995         }
2996       else
2997         {
2998           if (get_attr_mode (insn) == MODE_V4SF)
2999             return "%vmovaps\t{%1, %0|%0, %1}";
3000           else
3001             return "%vmovdqa\t{%1, %0|%0, %1}";
3002         }
3004     case TYPE_MULTI:
3005         return "#";
3007     default:
3008       gcc_unreachable ();
3009     }
3011   [(set_attr "isa" "*,*,*,x64,x64")
3012    (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3013    (set (attr "prefix")
3014      (if_then_else (eq_attr "type" "sselog1,ssemov")
3015        (const_string "maybe_vex")
3016        (const_string "orig")))
3017    (set (attr "mode")
3018         (cond [(eq_attr "alternative" "3,4")
3019                  (const_string "DI")
3020                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3021                  (const_string "V4SF")
3022                (and (eq_attr "alternative" "2")
3023                     (match_test "TARGET_SSE_TYPELESS_STORES"))
3024                  (const_string "V4SF")
3025                (match_test "TARGET_AVX")
3026                  (const_string "TI")
3027                (ior (not (match_test "TARGET_SSE2"))
3028                     (match_test "optimize_function_for_size_p (cfun)"))
3029                  (const_string "V4SF")
3030                ]
3031                (const_string "TI")))])
3033 ;; Possible store forwarding (partial memory) stall
3034 ;; in alternatives 4, 6, 7 and 8.
3035 (define_insn "*movxf_internal"
3036   [(set (match_operand:XF 0 "nonimmediate_operand"
3037          "=f,m,f,?r ,!o,?*r ,!o,!o,!o")
3038         (match_operand:XF 1 "general_operand"
3039          "fm,f,G,roF,r , *roF,*r,F ,C"))]
3040   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3041    && (!can_create_pseudo_p ()
3042        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3043        || GET_CODE (operands[1]) != CONST_DOUBLE
3044        || (optimize_function_for_size_p (cfun)
3045            && standard_80387_constant_p (operands[1]) > 0
3046            && !memory_operand (operands[0], XFmode))
3047        || (!TARGET_MEMORY_MISMATCH_STALL
3048            && memory_operand (operands[0], XFmode)))"
3050   switch (get_attr_type (insn))
3051     {
3052     case TYPE_FMOV:
3053       if (which_alternative == 2)
3054         return standard_80387_constant_opcode (operands[1]);
3055       return output_387_reg_move (insn, operands);
3057     case TYPE_MULTI:
3058       return "#";
3060     default:
3061       gcc_unreachable ();
3062     }
3064   [(set (attr "isa")
3065         (cond [(eq_attr "alternative" "7")
3066                  (const_string "nox64")
3067                (eq_attr "alternative" "8")
3068                  (const_string "x64")
3069               ]
3070               (const_string "*")))
3071    (set (attr "type")
3072         (cond [(eq_attr "alternative" "3,4,5,6,7,8")
3073                  (const_string "multi")
3074               ]
3075               (const_string "fmov")))
3076    (set (attr "mode")
3077         (cond [(eq_attr "alternative" "3,4,5,6,7,8")
3078                  (if_then_else (match_test "TARGET_64BIT")
3079                    (const_string "DI")
3080                    (const_string "SI"))
3081               ]
3082               (const_string "XF")))
3083    (set (attr "preferred_for_size")
3084      (cond [(eq_attr "alternative" "3,4")
3085               (symbol_ref "false")]
3086            (symbol_ref "true")))])
3087    
3088 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3089 (define_insn "*movdf_internal"
3090   [(set (match_operand:DF 0 "nonimmediate_operand"
3091     "=Yf*f,m   ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi")
3092         (match_operand:DF 1 "general_operand"
3093     "Yf*fm,Yf*f,G   ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))]
3094   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3095    && (!can_create_pseudo_p ()
3096        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3097        || GET_CODE (operands[1]) != CONST_DOUBLE
3098        || (optimize_function_for_size_p (cfun)
3099            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3100                 && standard_80387_constant_p (operands[1]) > 0)
3101                || (TARGET_SSE2 && TARGET_SSE_MATH
3102                    && standard_sse_constant_p (operands[1])))
3103            && !memory_operand (operands[0], DFmode))
3104        || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3105            && memory_operand (operands[0], DFmode)))"
3107   switch (get_attr_type (insn))
3108     {
3109     case TYPE_FMOV:
3110       if (which_alternative == 2)
3111         return standard_80387_constant_opcode (operands[1]);
3112       return output_387_reg_move (insn, operands);
3114     case TYPE_MULTI:
3115       return "#";
3117     case TYPE_IMOV:
3118       if (get_attr_mode (insn) == MODE_SI)
3119         return "mov{l}\t{%1, %k0|%k0, %1}";
3120       else if (which_alternative == 11)
3121         return "movabs{q}\t{%1, %0|%0, %1}";
3122       else
3123         return "mov{q}\t{%1, %0|%0, %1}";
3125     case TYPE_SSELOG1:
3126       return standard_sse_constant_opcode (insn, operands[1]);
3128     case TYPE_SSEMOV:
3129       switch (get_attr_mode (insn))
3130         {
3131         case MODE_DF:
3132           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3133             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3134           return "%vmovsd\t{%1, %0|%0, %1}";
3136         case MODE_V4SF:
3137           return "%vmovaps\t{%1, %0|%0, %1}";
3138         case MODE_V8DF:
3139           return "vmovapd\t{%g1, %g0|%g0, %g1}";
3140         case MODE_V2DF:
3141           return "%vmovapd\t{%1, %0|%0, %1}";
3143         case MODE_V2SF:
3144           gcc_assert (!TARGET_AVX);
3145           return "movlps\t{%1, %0|%0, %1}";
3146         case MODE_V1DF:
3147           gcc_assert (!TARGET_AVX);
3148           return "movlpd\t{%1, %0|%0, %1}";
3150         case MODE_DI:
3151           /* Handle broken assemblers that require movd instead of movq.  */
3152           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3153               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3154             return "%vmovd\t{%1, %0|%0, %1}";
3155           return "%vmovq\t{%1, %0|%0, %1}";
3157         default:
3158           gcc_unreachable ();
3159         }
3161     default:
3162       gcc_unreachable ();
3163     }
3165   [(set (attr "isa")
3166         (cond [(eq_attr "alternative" "3,4,5,6,7")
3167                  (const_string "nox64")
3168                (eq_attr "alternative" "8,9,10,11,20,21")
3169                  (const_string "x64")
3170                (eq_attr "alternative" "12,13,14,15")
3171                  (const_string "sse2")
3172               ]
3173               (const_string "*")))
3174    (set (attr "type")
3175         (cond [(eq_attr "alternative" "0,1,2")
3176                  (const_string "fmov")
3177                (eq_attr "alternative" "3,4,5,6,7")
3178                  (const_string "multi")
3179                (eq_attr "alternative" "8,9,10,11")
3180                  (const_string "imov")
3181                (eq_attr "alternative" "12,16")
3182                  (const_string "sselog1")
3183               ]
3184               (const_string "ssemov")))
3185    (set (attr "modrm")
3186      (if_then_else (eq_attr "alternative" "11")
3187        (const_string "0")
3188        (const_string "*")))
3189    (set (attr "length_immediate")
3190      (if_then_else (eq_attr "alternative" "11")
3191        (const_string "8")
3192        (const_string "*")))
3193    (set (attr "prefix")
3194      (if_then_else (eq_attr "type" "sselog1,ssemov")
3195        (const_string "maybe_vex")
3196        (const_string "orig")))
3197    (set (attr "prefix_data16")
3198      (if_then_else
3199        (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3200             (eq_attr "mode" "V1DF"))
3201        (const_string "1")
3202        (const_string "*")))
3203    (set (attr "mode")
3204         (cond [(eq_attr "alternative" "3,4,5,6,7,10")
3205                  (const_string "SI")
3206                (eq_attr "alternative" "8,9,11,20,21")
3207                  (const_string "DI")
3209                /* xorps is one byte shorter for non-AVX targets.  */
3210                (eq_attr "alternative" "12,16")
3211                  (cond [(not (match_test "TARGET_SSE2"))
3212                           (const_string "V4SF")
3213                         (match_test "TARGET_AVX512F")
3214                           (const_string "XI")
3215                         (match_test "TARGET_AVX")
3216                           (const_string "V2DF")
3217                         (match_test "optimize_function_for_size_p (cfun)")
3218                           (const_string "V4SF")
3219                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3220                           (const_string "TI")
3221                        ]
3222                        (const_string "V2DF"))
3224                /* For architectures resolving dependencies on
3225                   whole SSE registers use movapd to break dependency
3226                   chains, otherwise use short move to avoid extra work.  */
3228                /* movaps is one byte shorter for non-AVX targets.  */
3229                (eq_attr "alternative" "13,17")
3230                  (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3231                              (match_operand 1 "ext_sse_reg_operand"))
3232                           (const_string "V8DF")
3233                         (ior (not (match_test "TARGET_SSE2"))
3234                              (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3235                           (const_string "V4SF")
3236                         (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3237                           (const_string "V2DF")
3238                         (match_test "TARGET_AVX")
3239                           (const_string "DF")
3240                         (match_test "optimize_function_for_size_p (cfun)")
3241                           (const_string "V4SF")
3242                        ]
3243                        (const_string "DF"))
3245                /* For architectures resolving dependencies on register
3246                   parts we may avoid extra work to zero out upper part
3247                   of register.  */
3248                (eq_attr "alternative" "14,18")
3249                  (cond [(not (match_test "TARGET_SSE2"))
3250                           (const_string "V2SF")
3251                         (match_test "TARGET_AVX")
3252                           (const_string "DF")
3253                         (match_test "TARGET_SSE_SPLIT_REGS")
3254                           (const_string "V1DF")
3255                        ]
3256                        (const_string "DF"))
3258                (and (eq_attr "alternative" "15,19")
3259                     (not (match_test "TARGET_SSE2")))
3260                  (const_string "V2SF")
3261               ]
3262               (const_string "DF")))
3263    (set (attr "preferred_for_size")
3264      (cond [(eq_attr "alternative" "3,4")
3265               (symbol_ref "false")]
3266            (symbol_ref "true")))
3267    (set (attr "preferred_for_speed")
3268      (cond [(eq_attr "alternative" "3,4")
3269               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3270            (symbol_ref "true")))])
3272 (define_insn "*movsf_internal"
3273   [(set (match_operand:SF 0 "nonimmediate_operand"
3274           "=Yf*f,m   ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
3275         (match_operand:SF 1 "general_operand"
3276           "Yf*fm,Yf*f,G   ,rmF,rF,C,v,m,v,Yj,r  ,*y ,m  ,*y,*Yn,r"))]
3277   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3278    && (!can_create_pseudo_p ()
3279        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3280        || GET_CODE (operands[1]) != CONST_DOUBLE
3281        || (optimize_function_for_size_p (cfun)
3282            && ((!TARGET_SSE_MATH
3283                 && standard_80387_constant_p (operands[1]) > 0)
3284                || (TARGET_SSE_MATH
3285                    && standard_sse_constant_p (operands[1]))))
3286        || memory_operand (operands[0], SFmode))"
3288   switch (get_attr_type (insn))
3289     {
3290     case TYPE_FMOV:
3291       if (which_alternative == 2)
3292         return standard_80387_constant_opcode (operands[1]);
3293       return output_387_reg_move (insn, operands);
3295     case TYPE_IMOV:
3296       return "mov{l}\t{%1, %0|%0, %1}";
3298     case TYPE_SSELOG1:
3299       return standard_sse_constant_opcode (insn, operands[1]);
3301     case TYPE_SSEMOV:
3302       switch (get_attr_mode (insn))
3303         {
3304         case MODE_SF:
3305           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3306             return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3307           return "%vmovss\t{%1, %0|%0, %1}";
3309         case MODE_V16SF:
3310           return "vmovaps\t{%g1, %g0|%g0, %g1}";
3311         case MODE_V4SF:
3312           return "%vmovaps\t{%1, %0|%0, %1}";
3314         case MODE_SI:
3315           return "%vmovd\t{%1, %0|%0, %1}";
3317         default:
3318           gcc_unreachable ();
3319         }
3321     case TYPE_MMXMOV:
3322       switch (get_attr_mode (insn))
3323         {
3324         case MODE_DI:
3325           return "movq\t{%1, %0|%0, %1}";
3326         case MODE_SI:
3327           return "movd\t{%1, %0|%0, %1}";
3329         default:
3330           gcc_unreachable ();
3331         }
3333     default:
3334       gcc_unreachable ();
3335     }
3337   [(set (attr "type")
3338         (cond [(eq_attr "alternative" "0,1,2")
3339                  (const_string "fmov")
3340                (eq_attr "alternative" "3,4")
3341                  (const_string "imov")
3342                (eq_attr "alternative" "5")
3343                  (const_string "sselog1")
3344                (eq_attr "alternative" "11,12,13,14,15")
3345                  (const_string "mmxmov")
3346               ]
3347               (const_string "ssemov")))
3348    (set (attr "prefix")
3349      (if_then_else (eq_attr "type" "sselog1,ssemov")
3350        (const_string "maybe_vex")
3351        (const_string "orig")))
3352    (set (attr "prefix_data16")
3353      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3354        (const_string "1")
3355        (const_string "*")))
3356    (set (attr "mode")
3357         (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15")
3358                  (const_string "SI")
3359                (eq_attr "alternative" "11")
3360                  (const_string "DI")
3361                (eq_attr "alternative" "5")
3362                  (cond [(not (match_test "TARGET_SSE2"))
3363                           (const_string "V4SF")
3364                         (match_test "TARGET_AVX512F")
3365                           (const_string "V16SF")
3366                         (match_test "TARGET_AVX")
3367                           (const_string "V4SF")
3368                         (match_test "optimize_function_for_size_p (cfun)")
3369                           (const_string "V4SF")
3370                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3371                           (const_string "TI")
3372                        ]
3373                        (const_string "V4SF"))
3375                /* For architectures resolving dependencies on
3376                   whole SSE registers use APS move to break dependency
3377                   chains, otherwise use short move to avoid extra work.
3379                   Do the same for architectures resolving dependencies on
3380                   the parts.  While in DF mode it is better to always handle
3381                   just register parts, the SF mode is different due to lack
3382                   of instructions to load just part of the register.  It is
3383                   better to maintain the whole registers in single format
3384                   to avoid problems on using packed logical operations.  */
3385                (eq_attr "alternative" "6")
3386                  (cond [(ior  (match_operand 0 "ext_sse_reg_operand")
3387                               (match_operand 1 "ext_sse_reg_operand"))
3388                           (const_string "V16SF")
3389                         (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3390                              (match_test "TARGET_SSE_SPLIT_REGS"))
3391                           (const_string "V4SF")
3392                        ]
3393                        (const_string "SF"))
3394               ]
3395               (const_string "SF")))])
3397 (define_split
3398   [(set (match_operand 0 "any_fp_register_operand")
3399         (match_operand 1 "memory_operand"))]
3400   "reload_completed
3401    && (GET_MODE (operands[0]) == TFmode
3402        || GET_MODE (operands[0]) == XFmode
3403        || GET_MODE (operands[0]) == DFmode
3404        || GET_MODE (operands[0]) == SFmode)
3405    && (operands[2] = find_constant_src (insn))"
3406   [(set (match_dup 0) (match_dup 2))]
3408   rtx c = operands[2];
3409   int r = REGNO (operands[0]);
3411   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3412       || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3413     FAIL;
3416 (define_split
3417   [(set (match_operand 0 "any_fp_register_operand")
3418         (float_extend (match_operand 1 "memory_operand")))]
3419   "reload_completed
3420    && (GET_MODE (operands[0]) == TFmode
3421        || GET_MODE (operands[0]) == XFmode
3422        || GET_MODE (operands[0]) == DFmode)
3423    && (operands[2] = find_constant_src (insn))"
3424   [(set (match_dup 0) (match_dup 2))]
3426   rtx c = operands[2];
3427   int r = REGNO (operands[0]);
3429   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3430       || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3431     FAIL;
3434 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3435 (define_split
3436   [(set (match_operand:X87MODEF 0 "fp_register_operand")
3437         (match_operand:X87MODEF 1 "immediate_operand"))]
3438   "reload_completed
3439    && (standard_80387_constant_p (operands[1]) == 8
3440        || standard_80387_constant_p (operands[1]) == 9)"
3441   [(set (match_dup 0)(match_dup 1))
3442    (set (match_dup 0)
3443         (neg:X87MODEF (match_dup 0)))]
3445   REAL_VALUE_TYPE r;
3447   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3448   if (real_isnegzero (&r))
3449     operands[1] = CONST0_RTX (<MODE>mode);
3450   else
3451     operands[1] = CONST1_RTX (<MODE>mode);
3454 (define_split
3455   [(set (match_operand 0 "nonimmediate_operand")
3456         (match_operand 1 "general_operand"))]
3457   "reload_completed
3458    && (GET_MODE (operands[0]) == TFmode
3459        || GET_MODE (operands[0]) == XFmode
3460        || GET_MODE (operands[0]) == DFmode)
3461    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3462   [(const_int 0)]
3463   "ix86_split_long_move (operands); DONE;")
3465 (define_insn "swapxf"
3466   [(set (match_operand:XF 0 "register_operand" "+f")
3467         (match_operand:XF 1 "register_operand" "+f"))
3468    (set (match_dup 1)
3469         (match_dup 0))]
3470   "TARGET_80387"
3472   if (STACK_TOP_P (operands[0]))
3473     return "fxch\t%1";
3474   else
3475     return "fxch\t%0";
3477   [(set_attr "type" "fxch")
3478    (set_attr "mode" "XF")])
3480 (define_insn "*swap<mode>"
3481   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3482         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3483    (set (match_dup 1)
3484         (match_dup 0))]
3485   "TARGET_80387 || reload_completed"
3487   if (STACK_TOP_P (operands[0]))
3488     return "fxch\t%1";
3489   else
3490     return "fxch\t%0";
3492   [(set_attr "type" "fxch")
3493    (set_attr "mode" "<MODE>")])
3495 ;; Zero extension instructions
3497 (define_expand "zero_extendsidi2"
3498   [(set (match_operand:DI 0 "nonimmediate_operand")
3499         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3501 (define_insn "*zero_extendsidi2"
3502   [(set (match_operand:DI 0 "nonimmediate_operand"
3503                         "=r,?r,?o,r   ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3504         (zero_extend:DI
3505          (match_operand:SI 1 "x86_64_zext_operand"
3506                         "0 ,rm,r ,rmWz,0,r   ,m   ,*Yj,*x,r   ,m")))]
3507   ""
3509   switch (get_attr_type (insn))
3510     {
3511     case TYPE_IMOVX:
3512       if (ix86_use_lea_for_mov (insn, operands))
3513         return "lea{l}\t{%E1, %k0|%k0, %E1}";
3514       else
3515         return "mov{l}\t{%1, %k0|%k0, %1}";
3517     case TYPE_MULTI:
3518       return "#";
3520     case TYPE_MMXMOV:
3521       return "movd\t{%1, %0|%0, %1}";
3523     case TYPE_SSELOG1:
3524       return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3526     case TYPE_SSEMOV:
3527       if (GENERAL_REG_P (operands[0]))
3528         return "%vmovd\t{%1, %k0|%k0, %1}";
3530       return "%vmovd\t{%1, %0|%0, %1}";
3532     default:
3533       gcc_unreachable ();
3534     }
3536   [(set (attr "isa")
3537      (cond [(eq_attr "alternative" "0,1,2")
3538               (const_string "nox64")
3539             (eq_attr "alternative" "3,7")
3540               (const_string "x64")
3541             (eq_attr "alternative" "8")
3542               (const_string "x64_sse4")
3543             (eq_attr "alternative" "10")
3544               (const_string "sse2")
3545            ]
3546            (const_string "*")))
3547    (set (attr "type")
3548      (cond [(eq_attr "alternative" "0,1,2,4")
3549               (const_string "multi")
3550             (eq_attr "alternative" "5,6")
3551               (const_string "mmxmov")
3552             (eq_attr "alternative" "7,9,10")
3553               (const_string "ssemov")
3554             (eq_attr "alternative" "8")
3555               (const_string "sselog1")
3556            ]
3557            (const_string "imovx")))
3558    (set (attr "prefix_extra")
3559      (if_then_else (eq_attr "alternative" "8")
3560        (const_string "1")
3561        (const_string "*")))
3562    (set (attr "length_immediate")
3563      (if_then_else (eq_attr "alternative" "8")
3564        (const_string "1")
3565        (const_string "*")))
3566    (set (attr "prefix")
3567      (if_then_else (eq_attr "type" "ssemov,sselog1")
3568        (const_string "maybe_vex")
3569        (const_string "orig")))
3570    (set (attr "prefix_0f")
3571      (if_then_else (eq_attr "type" "imovx")
3572        (const_string "0")
3573        (const_string "*")))
3574    (set (attr "mode")
3575      (cond [(eq_attr "alternative" "5,6")
3576               (const_string "DI")
3577             (eq_attr "alternative" "7,8,9")
3578               (const_string "TI")
3579            ]
3580            (const_string "SI")))])
3582 (define_split
3583   [(set (match_operand:DI 0 "memory_operand")
3584         (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3585   "reload_completed"
3586   [(set (match_dup 4) (const_int 0))]
3587   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3589 (define_split
3590   [(set (match_operand:DI 0 "register_operand")
3591         (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3592   "!TARGET_64BIT && reload_completed
3593    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3594    && true_regnum (operands[0]) == true_regnum (operands[1])"
3595   [(set (match_dup 4) (const_int 0))]
3596   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3598 (define_split
3599   [(set (match_operand:DI 0 "nonimmediate_operand")
3600         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3601   "!TARGET_64BIT && reload_completed
3602    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3603    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3604   [(set (match_dup 3) (match_dup 1))
3605    (set (match_dup 4) (const_int 0))]
3606   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3608 (define_insn "zero_extend<mode>di2"
3609   [(set (match_operand:DI 0 "register_operand" "=r")
3610         (zero_extend:DI
3611          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3612   "TARGET_64BIT"
3613   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3614   [(set_attr "type" "imovx")
3615    (set_attr "mode" "SI")])
3617 (define_expand "zero_extend<mode>si2"
3618   [(set (match_operand:SI 0 "register_operand")
3619         (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3620   ""
3622   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3623     {
3624       operands[1] = force_reg (<MODE>mode, operands[1]);
3625       emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3626       DONE;
3627     }
3630 (define_insn_and_split "zero_extend<mode>si2_and"
3631   [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3632         (zero_extend:SI
3633           (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3634    (clobber (reg:CC FLAGS_REG))]
3635   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3636   "#"
3637   "&& reload_completed"
3638   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3639               (clobber (reg:CC FLAGS_REG))])]
3641   if (true_regnum (operands[0]) != true_regnum (operands[1]))
3642     {
3643       ix86_expand_clear (operands[0]);
3645       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3646       emit_insn (gen_movstrict<mode>
3647                   (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3648       DONE;
3649     }
3651   operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3653   [(set_attr "type" "alu1")
3654    (set_attr "mode" "SI")])
3656 (define_insn "*zero_extend<mode>si2"
3657   [(set (match_operand:SI 0 "register_operand" "=r")
3658         (zero_extend:SI
3659           (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3660   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3661   "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3662   [(set_attr "type" "imovx")
3663    (set_attr "mode" "SI")])
3665 (define_expand "zero_extendqihi2"
3666   [(set (match_operand:HI 0 "register_operand")
3667         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3668   ""
3670   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3671     {
3672       operands[1] = force_reg (QImode, operands[1]);
3673       emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3674       DONE;
3675     }
3678 (define_insn_and_split "zero_extendqihi2_and"
3679   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3680         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3681    (clobber (reg:CC FLAGS_REG))]
3682   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3683   "#"
3684   "&& reload_completed"
3685   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3686               (clobber (reg:CC FLAGS_REG))])]
3688   if (true_regnum (operands[0]) != true_regnum (operands[1]))
3689     {
3690       ix86_expand_clear (operands[0]);
3692       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3693       emit_insn (gen_movstrictqi
3694                   (gen_lowpart (QImode, operands[0]), operands[1]));
3695       DONE;
3696     }
3698   operands[0] = gen_lowpart (SImode, operands[0]);
3700   [(set_attr "type" "alu1")
3701    (set_attr "mode" "SI")])
3703 ; zero extend to SImode to avoid partial register stalls
3704 (define_insn "*zero_extendqihi2"
3705   [(set (match_operand:HI 0 "register_operand" "=r")
3706         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3707   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3708   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3709   [(set_attr "type" "imovx")
3710    (set_attr "mode" "SI")])
3712 ;; Sign extension instructions
3714 (define_expand "extendsidi2"
3715   [(set (match_operand:DI 0 "register_operand")
3716         (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3717   ""
3719   if (!TARGET_64BIT)
3720     {
3721       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3722       DONE;
3723     }
3726 (define_insn "*extendsidi2_rex64"
3727   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3728         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3729   "TARGET_64BIT"
3730   "@
3731    {cltq|cdqe}
3732    movs{lq|x}\t{%1, %0|%0, %1}"
3733   [(set_attr "type" "imovx")
3734    (set_attr "mode" "DI")
3735    (set_attr "prefix_0f" "0")
3736    (set_attr "modrm" "0,1")])
3738 (define_insn "extendsidi2_1"
3739   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3740         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3741    (clobber (reg:CC FLAGS_REG))
3742    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3743   "!TARGET_64BIT"
3744   "#")
3746 ;; Split the memory case.  If the source register doesn't die, it will stay
3747 ;; this way, if it does die, following peephole2s take care of it.
3748 (define_split
3749   [(set (match_operand:DI 0 "memory_operand")
3750         (sign_extend:DI (match_operand:SI 1 "register_operand")))
3751    (clobber (reg:CC FLAGS_REG))
3752    (clobber (match_operand:SI 2 "register_operand"))]
3753   "reload_completed"
3754   [(const_int 0)]
3756   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3758   emit_move_insn (operands[3], operands[1]);
3760   /* Generate a cltd if possible and doing so it profitable.  */
3761   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3762       && true_regnum (operands[1]) == AX_REG
3763       && true_regnum (operands[2]) == DX_REG)
3764     {
3765       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3766     }
3767   else
3768     {
3769       emit_move_insn (operands[2], operands[1]);
3770       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3771     }
3772   emit_move_insn (operands[4], operands[2]);
3773   DONE;
3776 ;; Peepholes for the case where the source register does die, after
3777 ;; being split with the above splitter.
3778 (define_peephole2
3779   [(set (match_operand:SI 0 "memory_operand")
3780         (match_operand:SI 1 "register_operand"))
3781    (set (match_operand:SI 2 "register_operand") (match_dup 1))
3782    (parallel [(set (match_dup 2)
3783                    (ashiftrt:SI (match_dup 2) (const_int 31)))
3784                (clobber (reg:CC FLAGS_REG))])
3785    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3786   "REGNO (operands[1]) != REGNO (operands[2])
3787    && peep2_reg_dead_p (2, operands[1])
3788    && peep2_reg_dead_p (4, operands[2])
3789    && !reg_mentioned_p (operands[2], operands[3])"
3790   [(set (match_dup 0) (match_dup 1))
3791    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3792               (clobber (reg:CC FLAGS_REG))])
3793    (set (match_dup 3) (match_dup 1))])
3795 (define_peephole2
3796   [(set (match_operand:SI 0 "memory_operand")
3797         (match_operand:SI 1 "register_operand"))
3798    (parallel [(set (match_operand:SI 2 "register_operand")
3799                    (ashiftrt:SI (match_dup 1) (const_int 31)))
3800                (clobber (reg:CC FLAGS_REG))])
3801    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3802   "/* cltd is shorter than sarl $31, %eax */
3803    !optimize_function_for_size_p (cfun)
3804    && true_regnum (operands[1]) == AX_REG
3805    && true_regnum (operands[2]) == DX_REG
3806    && peep2_reg_dead_p (2, operands[1])
3807    && peep2_reg_dead_p (3, operands[2])
3808    && !reg_mentioned_p (operands[2], operands[3])"
3809   [(set (match_dup 0) (match_dup 1))
3810    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3811               (clobber (reg:CC FLAGS_REG))])
3812    (set (match_dup 3) (match_dup 1))])
3814 ;; Extend to register case.  Optimize case where source and destination
3815 ;; registers match and cases where we can use cltd.
3816 (define_split
3817   [(set (match_operand:DI 0 "register_operand")
3818         (sign_extend:DI (match_operand:SI 1 "register_operand")))
3819    (clobber (reg:CC FLAGS_REG))
3820    (clobber (match_scratch:SI 2))]
3821   "reload_completed"
3822   [(const_int 0)]
3824   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3826   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3827     emit_move_insn (operands[3], operands[1]);
3829   /* Generate a cltd if possible and doing so it profitable.  */
3830   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3831       && true_regnum (operands[3]) == AX_REG
3832       && true_regnum (operands[4]) == DX_REG)
3833     {
3834       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3835       DONE;
3836     }
3838   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3839     emit_move_insn (operands[4], operands[1]);
3841   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3842   DONE;
3845 (define_insn "extend<mode>di2"
3846   [(set (match_operand:DI 0 "register_operand" "=r")
3847         (sign_extend:DI
3848          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3849   "TARGET_64BIT"
3850   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3851   [(set_attr "type" "imovx")
3852    (set_attr "mode" "DI")])
3854 (define_insn "extendhisi2"
3855   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3856         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3857   ""
3859   switch (get_attr_prefix_0f (insn))
3860     {
3861     case 0:
3862       return "{cwtl|cwde}";
3863     default:
3864       return "movs{wl|x}\t{%1, %0|%0, %1}";
3865     }
3867   [(set_attr "type" "imovx")
3868    (set_attr "mode" "SI")
3869    (set (attr "prefix_0f")
3870      ;; movsx is short decodable while cwtl is vector decoded.
3871      (if_then_else (and (eq_attr "cpu" "!k6")
3872                         (eq_attr "alternative" "0"))
3873         (const_string "0")
3874         (const_string "1")))
3875    (set (attr "modrm")
3876      (if_then_else (eq_attr "prefix_0f" "0")
3877         (const_string "0")
3878         (const_string "1")))])
3880 (define_insn "*extendhisi2_zext"
3881   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3882         (zero_extend:DI
3883          (sign_extend:SI
3884           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3885   "TARGET_64BIT"
3887   switch (get_attr_prefix_0f (insn))
3888     {
3889     case 0:
3890       return "{cwtl|cwde}";
3891     default:
3892       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3893     }
3895   [(set_attr "type" "imovx")
3896    (set_attr "mode" "SI")
3897    (set (attr "prefix_0f")
3898      ;; movsx is short decodable while cwtl is vector decoded.
3899      (if_then_else (and (eq_attr "cpu" "!k6")
3900                         (eq_attr "alternative" "0"))
3901         (const_string "0")
3902         (const_string "1")))
3903    (set (attr "modrm")
3904      (if_then_else (eq_attr "prefix_0f" "0")
3905         (const_string "0")
3906         (const_string "1")))])
3908 (define_insn "extendqisi2"
3909   [(set (match_operand:SI 0 "register_operand" "=r")
3910         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3911   ""
3912   "movs{bl|x}\t{%1, %0|%0, %1}"
3913    [(set_attr "type" "imovx")
3914     (set_attr "mode" "SI")])
3916 (define_insn "*extendqisi2_zext"
3917   [(set (match_operand:DI 0 "register_operand" "=r")
3918         (zero_extend:DI
3919           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3920   "TARGET_64BIT"
3921   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3922    [(set_attr "type" "imovx")
3923     (set_attr "mode" "SI")])
3925 (define_insn "extendqihi2"
3926   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3927         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3928   ""
3930   switch (get_attr_prefix_0f (insn))
3931     {
3932     case 0:
3933       return "{cbtw|cbw}";
3934     default:
3935       return "movs{bw|x}\t{%1, %0|%0, %1}";
3936     }
3938   [(set_attr "type" "imovx")
3939    (set_attr "mode" "HI")
3940    (set (attr "prefix_0f")
3941      ;; movsx is short decodable while cwtl is vector decoded.
3942      (if_then_else (and (eq_attr "cpu" "!k6")
3943                         (eq_attr "alternative" "0"))
3944         (const_string "0")
3945         (const_string "1")))
3946    (set (attr "modrm")
3947      (if_then_else (eq_attr "prefix_0f" "0")
3948         (const_string "0")
3949         (const_string "1")))])
3951 ;; Conversions between float and double.
3953 ;; These are all no-ops in the model used for the 80387.
3954 ;; So just emit moves.
3956 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3957 (define_split
3958   [(set (match_operand:DF 0 "push_operand")
3959         (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3960   "reload_completed"
3961   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3962    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3964 (define_split
3965   [(set (match_operand:XF 0 "push_operand")
3966         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3967   "reload_completed"
3968   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3969    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3970   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3972 (define_expand "extendsfdf2"
3973   [(set (match_operand:DF 0 "nonimmediate_operand")
3974         (float_extend:DF (match_operand:SF 1 "general_operand")))]
3975   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3977   /* ??? Needed for compress_float_constant since all fp constants
3978      are TARGET_LEGITIMATE_CONSTANT_P.  */
3979   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3980     {
3981       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3982           && standard_80387_constant_p (operands[1]) > 0)
3983         {
3984           operands[1] = simplify_const_unary_operation
3985             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3986           emit_move_insn_1 (operands[0], operands[1]);
3987           DONE;
3988         }
3989       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3990     }
3993 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3994    cvtss2sd:
3995       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3996       cvtps2pd xmm2,xmm1
3997    We do the conversion post reload to avoid producing of 128bit spills
3998    that might lead to ICE on 32bit target.  The sequence unlikely combine
3999    anyway.  */
4000 (define_split
4001   [(set (match_operand:DF 0 "register_operand")
4002         (float_extend:DF
4003           (match_operand:SF 1 "nonimmediate_operand")))]
4004   "TARGET_USE_VECTOR_FP_CONVERTS
4005    && optimize_insn_for_speed_p ()
4006    && reload_completed && SSE_REG_P (operands[0])"
4007    [(set (match_dup 2)
4008          (float_extend:V2DF
4009            (vec_select:V2SF
4010              (match_dup 3)
4011              (parallel [(const_int 0) (const_int 1)]))))]
4013   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4014   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4015   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4016      Try to avoid move when unpacking can be done in source.  */
4017   if (REG_P (operands[1]))
4018     {
4019       /* If it is unsafe to overwrite upper half of source, we need
4020          to move to destination and unpack there.  */
4021       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4022            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4023           && true_regnum (operands[0]) != true_regnum (operands[1]))
4024         {
4025           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4026           emit_move_insn (tmp, operands[1]);
4027         }
4028       else
4029         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4030       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4031                                              operands[3]));
4032     }
4033   else
4034     emit_insn (gen_vec_setv4sf_0 (operands[3],
4035                                   CONST0_RTX (V4SFmode), operands[1]));
4038 ;; It's more profitable to split and then extend in the same register.
4039 (define_peephole2
4040   [(set (match_operand:DF 0 "register_operand")
4041         (float_extend:DF
4042           (match_operand:SF 1 "memory_operand")))]
4043   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4044    && optimize_insn_for_speed_p ()
4045    && SSE_REG_P (operands[0])"
4046   [(set (match_dup 2) (match_dup 1))
4047    (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4048   "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
4050 (define_insn "*extendsfdf2_mixed"
4051   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4052         (float_extend:DF
4053           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4054   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4056   switch (which_alternative)
4057     {
4058     case 0:
4059     case 1:
4060       return output_387_reg_move (insn, operands);
4062     case 2:
4063       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4065     default:
4066       gcc_unreachable ();
4067     }
4069   [(set_attr "type" "fmov,fmov,ssecvt")
4070    (set_attr "prefix" "orig,orig,maybe_vex")
4071    (set_attr "mode" "SF,XF,DF")])
4073 (define_insn "*extendsfdf2_sse"
4074   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4075         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4076   "TARGET_SSE2 && TARGET_SSE_MATH"
4077   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4078   [(set_attr "type" "ssecvt")
4079    (set_attr "prefix" "maybe_vex")
4080    (set_attr "mode" "DF")])
4082 (define_insn "*extendsfdf2_i387"
4083   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4084         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4085   "TARGET_80387"
4086   "* return output_387_reg_move (insn, operands);"
4087   [(set_attr "type" "fmov")
4088    (set_attr "mode" "SF,XF")])
4090 (define_expand "extend<mode>xf2"
4091   [(set (match_operand:XF 0 "nonimmediate_operand")
4092         (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4093   "TARGET_80387"
4095   /* ??? Needed for compress_float_constant since all fp constants
4096      are TARGET_LEGITIMATE_CONSTANT_P.  */
4097   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4098     {
4099       if (standard_80387_constant_p (operands[1]) > 0)
4100         {
4101           operands[1] = simplify_const_unary_operation
4102             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4103           emit_move_insn_1 (operands[0], operands[1]);
4104           DONE;
4105         }
4106       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4107     }
4110 (define_insn "*extend<mode>xf2_i387"
4111   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4112         (float_extend:XF
4113           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4114   "TARGET_80387"
4115   "* return output_387_reg_move (insn, operands);"
4116   [(set_attr "type" "fmov")
4117    (set_attr "mode" "<MODE>,XF")])
4119 ;; %%% This seems bad bad news.
4120 ;; This cannot output into an f-reg because there is no way to be sure
4121 ;; of truncating in that case.  Otherwise this is just like a simple move
4122 ;; insn.  So we pretend we can output to a reg in order to get better
4123 ;; register preferencing, but we really use a stack slot.
4125 ;; Conversion from DFmode to SFmode.
4127 (define_expand "truncdfsf2"
4128   [(set (match_operand:SF 0 "nonimmediate_operand")
4129         (float_truncate:SF
4130           (match_operand:DF 1 "nonimmediate_operand")))]
4131   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4133   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4134     ;
4135   else if (flag_unsafe_math_optimizations)
4136     ;
4137   else
4138     {
4139       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4140       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4141       DONE;
4142     }
4145 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4146    cvtsd2ss:
4147       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4148       cvtpd2ps xmm2,xmm1
4149    We do the conversion post reload to avoid producing of 128bit spills
4150    that might lead to ICE on 32bit target.  The sequence unlikely combine
4151    anyway.  */
4152 (define_split
4153   [(set (match_operand:SF 0 "register_operand")
4154         (float_truncate:SF
4155           (match_operand:DF 1 "nonimmediate_operand")))]
4156   "TARGET_USE_VECTOR_FP_CONVERTS
4157    && optimize_insn_for_speed_p ()
4158    && reload_completed && SSE_REG_P (operands[0])"
4159    [(set (match_dup 2)
4160          (vec_concat:V4SF
4161            (float_truncate:V2SF
4162              (match_dup 4))
4163            (match_dup 3)))]
4165   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4166   operands[3] = CONST0_RTX (V2SFmode);
4167   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4168   /* Use movsd for loading from memory, unpcklpd for registers.
4169      Try to avoid move when unpacking can be done in source, or SSE3
4170      movddup is available.  */
4171   if (REG_P (operands[1]))
4172     {
4173       if (!TARGET_SSE3
4174           && true_regnum (operands[0]) != true_regnum (operands[1])
4175           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4176               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4177         {
4178           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4179           emit_move_insn (tmp, operands[1]);
4180           operands[1] = tmp;
4181         }
4182       else if (!TARGET_SSE3)
4183         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4184       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4185     }
4186   else
4187     emit_insn (gen_sse2_loadlpd (operands[4],
4188                                  CONST0_RTX (V2DFmode), operands[1]));
4191 ;; It's more profitable to split and then extend in the same register.
4192 (define_peephole2
4193   [(set (match_operand:SF 0 "register_operand")
4194         (float_truncate:SF
4195           (match_operand:DF 1 "memory_operand")))]
4196   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4197    && optimize_insn_for_speed_p ()
4198    && SSE_REG_P (operands[0])"
4199   [(set (match_dup 2) (match_dup 1))
4200    (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4201   "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
4203 (define_expand "truncdfsf2_with_temp"
4204   [(parallel [(set (match_operand:SF 0)
4205                    (float_truncate:SF (match_operand:DF 1)))
4206               (clobber (match_operand:SF 2))])])
4208 (define_insn "*truncdfsf_fast_mixed"
4209   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4210         (float_truncate:SF
4211           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4212   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4214   switch (which_alternative)
4215     {
4216     case 0:
4217       return output_387_reg_move (insn, operands);
4218     case 1:
4219       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4220     default:
4221       gcc_unreachable ();
4222     }
4224   [(set_attr "type" "fmov,ssecvt")
4225    (set_attr "prefix" "orig,maybe_vex")
4226    (set_attr "mode" "SF")])
4228 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4229 ;; because nothing we do here is unsafe.
4230 (define_insn "*truncdfsf_fast_sse"
4231   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4232         (float_truncate:SF
4233           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4234   "TARGET_SSE2 && TARGET_SSE_MATH"
4235   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4236   [(set_attr "type" "ssecvt")
4237    (set_attr "prefix" "maybe_vex")
4238    (set_attr "mode" "SF")])
4240 (define_insn "*truncdfsf_fast_i387"
4241   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4242         (float_truncate:SF
4243           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4244   "TARGET_80387 && flag_unsafe_math_optimizations"
4245   "* return output_387_reg_move (insn, operands);"
4246   [(set_attr "type" "fmov")
4247    (set_attr "mode" "SF")])
4249 (define_insn "*truncdfsf_mixed"
4250   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,x ,?f,?x,?*r")
4251         (float_truncate:SF
4252           (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4253    (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
4254   "TARGET_MIX_SSE_I387"
4256   switch (which_alternative)
4257     {
4258     case 0:
4259       return output_387_reg_move (insn, operands);
4260     case 1:
4261       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4263     default:
4264       return "#";
4265     }
4267   [(set_attr "isa" "*,sse2,*,*,*")
4268    (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4269    (set_attr "unit" "*,*,i387,i387,i387")
4270    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4271    (set_attr "mode" "SF")])
4273 (define_insn "*truncdfsf_i387"
4274   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4275         (float_truncate:SF
4276           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4277    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4278   "TARGET_80387"
4280   switch (which_alternative)
4281     {
4282     case 0:
4283       return output_387_reg_move (insn, operands);
4285     default:
4286       return "#";
4287     }
4289   [(set_attr "type" "fmov,multi,multi,multi")
4290    (set_attr "unit" "*,i387,i387,i387")
4291    (set_attr "mode" "SF")])
4293 (define_insn "*truncdfsf2_i387_1"
4294   [(set (match_operand:SF 0 "memory_operand" "=m")
4295         (float_truncate:SF
4296           (match_operand:DF 1 "register_operand" "f")))]
4297   "TARGET_80387
4298    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4299    && !TARGET_MIX_SSE_I387"
4300   "* return output_387_reg_move (insn, operands);"
4301   [(set_attr "type" "fmov")
4302    (set_attr "mode" "SF")])
4304 (define_split
4305   [(set (match_operand:SF 0 "register_operand")
4306         (float_truncate:SF
4307          (match_operand:DF 1 "fp_register_operand")))
4308    (clobber (match_operand 2))]
4309   "reload_completed"
4310   [(set (match_dup 2) (match_dup 1))
4311    (set (match_dup 0) (match_dup 2))]
4312   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4314 ;; Conversion from XFmode to {SF,DF}mode
4316 (define_expand "truncxf<mode>2"
4317   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4318                    (float_truncate:MODEF
4319                      (match_operand:XF 1 "register_operand")))
4320               (clobber (match_dup 2))])]
4321   "TARGET_80387"
4323   if (flag_unsafe_math_optimizations)
4324     {
4325       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4326       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4327       if (reg != operands[0])
4328         emit_move_insn (operands[0], reg);
4329       DONE;
4330     }
4331   else
4332     operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4335 (define_insn "*truncxfsf2_mixed"
4336   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4337         (float_truncate:SF
4338           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4339    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4340   "TARGET_80387"
4342   gcc_assert (!which_alternative);
4343   return output_387_reg_move (insn, operands);
4345   [(set_attr "type" "fmov,multi,multi,multi")
4346    (set_attr "unit" "*,i387,i387,i387")
4347    (set_attr "mode" "SF")])
4349 (define_insn "*truncxfdf2_mixed"
4350   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4351         (float_truncate:DF
4352           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4353    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4354   "TARGET_80387"
4356   gcc_assert (!which_alternative);
4357   return output_387_reg_move (insn, operands);
4359   [(set_attr "isa" "*,*,sse2,*")
4360    (set_attr "type" "fmov,multi,multi,multi")
4361    (set_attr "unit" "*,i387,i387,i387")
4362    (set_attr "mode" "DF")])
4364 (define_insn "truncxf<mode>2_i387_noop"
4365   [(set (match_operand:MODEF 0 "register_operand" "=f")
4366         (float_truncate:MODEF
4367           (match_operand:XF 1 "register_operand" "f")))]
4368   "TARGET_80387 && flag_unsafe_math_optimizations"
4369   "* return output_387_reg_move (insn, operands);"
4370   [(set_attr "type" "fmov")
4371    (set_attr "mode" "<MODE>")])
4373 (define_insn "*truncxf<mode>2_i387"
4374   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4375         (float_truncate:MODEF
4376           (match_operand:XF 1 "register_operand" "f")))]
4377   "TARGET_80387"
4378   "* return output_387_reg_move (insn, operands);"
4379   [(set_attr "type" "fmov")
4380    (set_attr "mode" "<MODE>")])
4382 (define_split
4383   [(set (match_operand:MODEF 0 "register_operand")
4384         (float_truncate:MODEF
4385           (match_operand:XF 1 "register_operand")))
4386    (clobber (match_operand:MODEF 2 "memory_operand"))]
4387   "TARGET_80387 && reload_completed"
4388   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4389    (set (match_dup 0) (match_dup 2))])
4391 (define_split
4392   [(set (match_operand:MODEF 0 "memory_operand")
4393         (float_truncate:MODEF
4394           (match_operand:XF 1 "register_operand")))
4395    (clobber (match_operand:MODEF 2 "memory_operand"))]
4396   "TARGET_80387"
4397   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4399 ;; Signed conversion to DImode.
4401 (define_expand "fix_truncxfdi2"
4402   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4403                    (fix:DI (match_operand:XF 1 "register_operand")))
4404               (clobber (reg:CC FLAGS_REG))])]
4405   "TARGET_80387"
4407   if (TARGET_FISTTP)
4408    {
4409      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4410      DONE;
4411    }
4414 (define_expand "fix_trunc<mode>di2"
4415   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4416                    (fix:DI (match_operand:MODEF 1 "register_operand")))
4417               (clobber (reg:CC FLAGS_REG))])]
4418   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4420   if (TARGET_FISTTP
4421       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4422    {
4423      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4424      DONE;
4425    }
4426   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4427    {
4428      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4429      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4430      if (out != operands[0])
4431         emit_move_insn (operands[0], out);
4432      DONE;
4433    }
4436 ;; Signed conversion to SImode.
4438 (define_expand "fix_truncxfsi2"
4439   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4440                    (fix:SI (match_operand:XF 1 "register_operand")))
4441               (clobber (reg:CC FLAGS_REG))])]
4442   "TARGET_80387"
4444   if (TARGET_FISTTP)
4445    {
4446      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4447      DONE;
4448    }
4451 (define_expand "fix_trunc<mode>si2"
4452   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4453                    (fix:SI (match_operand:MODEF 1 "register_operand")))
4454               (clobber (reg:CC FLAGS_REG))])]
4455   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4457   if (TARGET_FISTTP
4458       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4459    {
4460      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4461      DONE;
4462    }
4463   if (SSE_FLOAT_MODE_P (<MODE>mode))
4464    {
4465      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4466      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4467      if (out != operands[0])
4468         emit_move_insn (operands[0], out);
4469      DONE;
4470    }
4473 ;; Signed conversion to HImode.
4475 (define_expand "fix_trunc<mode>hi2"
4476   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4477                    (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4478               (clobber (reg:CC FLAGS_REG))])]
4479   "TARGET_80387
4480    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4482   if (TARGET_FISTTP)
4483    {
4484      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4485      DONE;
4486    }
4489 ;; Unsigned conversion to SImode.
4491 (define_expand "fixuns_trunc<mode>si2"
4492   [(parallel
4493     [(set (match_operand:SI 0 "register_operand")
4494           (unsigned_fix:SI
4495             (match_operand:MODEF 1 "nonimmediate_operand")))
4496      (use (match_dup 2))
4497      (clobber (match_scratch:<ssevecmode> 3))
4498      (clobber (match_scratch:<ssevecmode> 4))])]
4499   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4501   machine_mode mode = <MODE>mode;
4502   machine_mode vecmode = <ssevecmode>mode;
4503   REAL_VALUE_TYPE TWO31r;
4504   rtx two31;
4506   if (optimize_insn_for_size_p ())
4507     FAIL;
4509   real_ldexp (&TWO31r, &dconst1, 31);
4510   two31 = const_double_from_real_value (TWO31r, mode);
4511   two31 = ix86_build_const_vector (vecmode, true, two31);
4512   operands[2] = force_reg (vecmode, two31);
4515 (define_insn_and_split "*fixuns_trunc<mode>_1"
4516   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4517         (unsigned_fix:SI
4518           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4519    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4520    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4521    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4522   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4523    && optimize_function_for_speed_p (cfun)"
4524   "#"
4525   "&& reload_completed"
4526   [(const_int 0)]
4528   ix86_split_convert_uns_si_sse (operands);
4529   DONE;
4532 ;; Unsigned conversion to HImode.
4533 ;; Without these patterns, we'll try the unsigned SI conversion which
4534 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4536 (define_expand "fixuns_trunc<mode>hi2"
4537   [(set (match_dup 2)
4538         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4539    (set (match_operand:HI 0 "nonimmediate_operand")
4540         (subreg:HI (match_dup 2) 0))]
4541   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4542   "operands[2] = gen_reg_rtx (SImode);")
4544 ;; When SSE is available, it is always faster to use it!
4545 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4546   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4547         (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4548   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4549    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4550   "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4551   [(set_attr "type" "sseicvt")
4552    (set_attr "prefix" "maybe_vex")
4553    (set (attr "prefix_rex")
4554         (if_then_else
4555           (match_test "<SWI48:MODE>mode == DImode")
4556           (const_string "1")
4557           (const_string "*")))
4558    (set_attr "mode" "<MODEF:MODE>")
4559    (set_attr "athlon_decode" "double,vector")
4560    (set_attr "amdfam10_decode" "double,double")
4561    (set_attr "bdver1_decode" "double,double")])
4563 ;; Avoid vector decoded forms of the instruction.
4564 (define_peephole2
4565   [(match_scratch:MODEF 2 "x")
4566    (set (match_operand:SWI48 0 "register_operand")
4567         (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4568   "TARGET_AVOID_VECTOR_DECODE
4569    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4570    && optimize_insn_for_speed_p ()"
4571   [(set (match_dup 2) (match_dup 1))
4572    (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4574 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4575   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4576         (fix:SWI248x (match_operand 1 "register_operand")))]
4577   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4578    && TARGET_FISTTP
4579    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4580          && (TARGET_64BIT || <MODE>mode != DImode))
4581         && TARGET_SSE_MATH)
4582    && can_create_pseudo_p ()"
4583   "#"
4584   "&& 1"
4585   [(const_int 0)]
4587   if (memory_operand (operands[0], VOIDmode))
4588     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4589   else
4590     {
4591       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4592       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4593                                                             operands[1],
4594                                                             operands[2]));
4595     }
4596   DONE;
4598   [(set_attr "type" "fisttp")
4599    (set_attr "mode" "<MODE>")])
4601 (define_insn "fix_trunc<mode>_i387_fisttp"
4602   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4603         (fix:SWI248x (match_operand 1 "register_operand" "f")))
4604    (clobber (match_scratch:XF 2 "=&1f"))]
4605   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4606    && TARGET_FISTTP
4607    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4608          && (TARGET_64BIT || <MODE>mode != DImode))
4609         && TARGET_SSE_MATH)"
4610   "* return output_fix_trunc (insn, operands, true);"
4611   [(set_attr "type" "fisttp")
4612    (set_attr "mode" "<MODE>")])
4614 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4615   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4616         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4617    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4618    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4619   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4620    && TARGET_FISTTP
4621    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4622         && (TARGET_64BIT || <MODE>mode != DImode))
4623         && TARGET_SSE_MATH)"
4624   "#"
4625   [(set_attr "type" "fisttp")
4626    (set_attr "mode" "<MODE>")])
4628 (define_split
4629   [(set (match_operand:SWI248x 0 "register_operand")
4630         (fix:SWI248x (match_operand 1 "register_operand")))
4631    (clobber (match_operand:SWI248x 2 "memory_operand"))
4632    (clobber (match_scratch 3))]
4633   "reload_completed"
4634   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4635               (clobber (match_dup 3))])
4636    (set (match_dup 0) (match_dup 2))])
4638 (define_split
4639   [(set (match_operand:SWI248x 0 "memory_operand")
4640         (fix:SWI248x (match_operand 1 "register_operand")))
4641    (clobber (match_operand:SWI248x 2 "memory_operand"))
4642    (clobber (match_scratch 3))]
4643   "reload_completed"
4644   [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4645               (clobber (match_dup 3))])])
4647 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4648 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4649 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4650 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4651 ;; function in i386.c.
4652 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4653   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4654         (fix:SWI248x (match_operand 1 "register_operand")))
4655    (clobber (reg:CC FLAGS_REG))]
4656   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4657    && !TARGET_FISTTP
4658    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4659          && (TARGET_64BIT || <MODE>mode != DImode))
4660    && can_create_pseudo_p ()"
4661   "#"
4662   "&& 1"
4663   [(const_int 0)]
4665   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4667   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4668   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4669   if (memory_operand (operands[0], VOIDmode))
4670     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4671                                          operands[2], operands[3]));
4672   else
4673     {
4674       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4675       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4676                                                      operands[2], operands[3],
4677                                                      operands[4]));
4678     }
4679   DONE;
4681   [(set_attr "type" "fistp")
4682    (set_attr "i387_cw" "trunc")
4683    (set_attr "mode" "<MODE>")])
4685 (define_insn "fix_truncdi_i387"
4686   [(set (match_operand:DI 0 "memory_operand" "=m")
4687         (fix:DI (match_operand 1 "register_operand" "f")))
4688    (use (match_operand:HI 2 "memory_operand" "m"))
4689    (use (match_operand:HI 3 "memory_operand" "m"))
4690    (clobber (match_scratch:XF 4 "=&1f"))]
4691   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4692    && !TARGET_FISTTP
4693    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4694   "* return output_fix_trunc (insn, operands, false);"
4695   [(set_attr "type" "fistp")
4696    (set_attr "i387_cw" "trunc")
4697    (set_attr "mode" "DI")])
4699 (define_insn "fix_truncdi_i387_with_temp"
4700   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4701         (fix:DI (match_operand 1 "register_operand" "f,f")))
4702    (use (match_operand:HI 2 "memory_operand" "m,m"))
4703    (use (match_operand:HI 3 "memory_operand" "m,m"))
4704    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4705    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4706   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4707    && !TARGET_FISTTP
4708    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4709   "#"
4710   [(set_attr "type" "fistp")
4711    (set_attr "i387_cw" "trunc")
4712    (set_attr "mode" "DI")])
4714 (define_split
4715   [(set (match_operand:DI 0 "register_operand")
4716         (fix:DI (match_operand 1 "register_operand")))
4717    (use (match_operand:HI 2 "memory_operand"))
4718    (use (match_operand:HI 3 "memory_operand"))
4719    (clobber (match_operand:DI 4 "memory_operand"))
4720    (clobber (match_scratch 5))]
4721   "reload_completed"
4722   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4723               (use (match_dup 2))
4724               (use (match_dup 3))
4725               (clobber (match_dup 5))])
4726    (set (match_dup 0) (match_dup 4))])
4728 (define_split
4729   [(set (match_operand:DI 0 "memory_operand")
4730         (fix:DI (match_operand 1 "register_operand")))
4731    (use (match_operand:HI 2 "memory_operand"))
4732    (use (match_operand:HI 3 "memory_operand"))
4733    (clobber (match_operand:DI 4 "memory_operand"))
4734    (clobber (match_scratch 5))]
4735   "reload_completed"
4736   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4737               (use (match_dup 2))
4738               (use (match_dup 3))
4739               (clobber (match_dup 5))])])
4741 (define_insn "fix_trunc<mode>_i387"
4742   [(set (match_operand:SWI24 0 "memory_operand" "=m")
4743         (fix:SWI24 (match_operand 1 "register_operand" "f")))
4744    (use (match_operand:HI 2 "memory_operand" "m"))
4745    (use (match_operand:HI 3 "memory_operand" "m"))]
4746   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4747    && !TARGET_FISTTP
4748    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4749   "* return output_fix_trunc (insn, operands, false);"
4750   [(set_attr "type" "fistp")
4751    (set_attr "i387_cw" "trunc")
4752    (set_attr "mode" "<MODE>")])
4754 (define_insn "fix_trunc<mode>_i387_with_temp"
4755   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4756         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4757    (use (match_operand:HI 2 "memory_operand" "m,m"))
4758    (use (match_operand:HI 3 "memory_operand" "m,m"))
4759    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4760   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4761    && !TARGET_FISTTP
4762    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4763   "#"
4764   [(set_attr "type" "fistp")
4765    (set_attr "i387_cw" "trunc")
4766    (set_attr "mode" "<MODE>")])
4768 (define_split
4769   [(set (match_operand:SWI24 0 "register_operand")
4770         (fix:SWI24 (match_operand 1 "register_operand")))
4771    (use (match_operand:HI 2 "memory_operand"))
4772    (use (match_operand:HI 3 "memory_operand"))
4773    (clobber (match_operand:SWI24 4 "memory_operand"))]
4774   "reload_completed"
4775   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4776               (use (match_dup 2))
4777               (use (match_dup 3))])
4778    (set (match_dup 0) (match_dup 4))])
4780 (define_split
4781   [(set (match_operand:SWI24 0 "memory_operand")
4782         (fix:SWI24 (match_operand 1 "register_operand")))
4783    (use (match_operand:HI 2 "memory_operand"))
4784    (use (match_operand:HI 3 "memory_operand"))
4785    (clobber (match_operand:SWI24 4 "memory_operand"))]
4786   "reload_completed"
4787   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4788               (use (match_dup 2))
4789               (use (match_dup 3))])])
4791 (define_insn "x86_fnstcw_1"
4792   [(set (match_operand:HI 0 "memory_operand" "=m")
4793         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4794   "TARGET_80387"
4795   "fnstcw\t%0"
4796   [(set (attr "length")
4797         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4798    (set_attr "mode" "HI")
4799    (set_attr "unit" "i387")
4800    (set_attr "bdver1_decode" "vector")])
4802 (define_insn "x86_fldcw_1"
4803   [(set (reg:HI FPCR_REG)
4804         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4805   "TARGET_80387"
4806   "fldcw\t%0"
4807   [(set (attr "length")
4808         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4809    (set_attr "mode" "HI")
4810    (set_attr "unit" "i387")
4811    (set_attr "athlon_decode" "vector")
4812    (set_attr "amdfam10_decode" "vector")
4813    (set_attr "bdver1_decode" "vector")])
4815 ;; Conversion between fixed point and floating point.
4817 ;; Even though we only accept memory inputs, the backend _really_
4818 ;; wants to be able to do this between registers.  Thankfully, LRA
4819 ;; will fix this up for us during register allocation.
4821 (define_insn "floathi<mode>2"
4822   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4823         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
4824   "TARGET_80387
4825    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4826        || TARGET_MIX_SSE_I387)"
4827   "fild%Z1\t%1"
4828   [(set_attr "type" "fmov")
4829    (set_attr "mode" "<MODE>")
4830    (set_attr "fp_int_src" "true")])
4832 (define_insn "float<SWI48x:mode>xf2"
4833   [(set (match_operand:XF 0 "register_operand" "=f")
4834         (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4835   "TARGET_80387"
4836   "fild%Z1\t%1"
4837   [(set_attr "type" "fmov")
4838    (set_attr "mode" "XF")
4839    (set_attr "fp_int_src" "true")])
4841 (define_expand "float<SWI48:mode><MODEF:mode>2"
4842   [(set (match_operand:MODEF 0 "register_operand")
4843         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4844   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
4846   if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
4847       && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
4848     {
4849       rtx reg = gen_reg_rtx (XFmode);
4850       rtx (*insn)(rtx, rtx);
4852       emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
4854       if (<MODEF:MODE>mode == SFmode)
4855         insn = gen_truncxfsf2;
4856       else if (<MODEF:MODE>mode == DFmode)
4857         insn = gen_truncxfdf2;
4858       else
4859         gcc_unreachable ();
4861       emit_insn (insn (operands[0], reg));
4862       DONE;
4863     }
4866 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse"
4867   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4868         (float:MODEF
4869           (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4870   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4871   "@
4872    fild%Z1\t%1
4873    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4874    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4875   [(set_attr "type" "fmov,sseicvt,sseicvt")
4876    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4877    (set_attr "mode" "<MODEF:MODE>")
4878    (set (attr "prefix_rex")
4879      (if_then_else
4880        (and (eq_attr "prefix" "maybe_vex")
4881             (match_test "<SWI48:MODE>mode == DImode"))
4882        (const_string "1")
4883        (const_string "*")))
4884    (set_attr "unit" "i387,*,*")
4885    (set_attr "athlon_decode" "*,double,direct")
4886    (set_attr "amdfam10_decode" "*,vector,double")
4887    (set_attr "bdver1_decode" "*,double,direct")
4888    (set_attr "fp_int_src" "true")
4889    (set (attr "enabled")
4890      (cond [(eq_attr "alternative" "0")
4891               (symbol_ref "TARGET_MIX_SSE_I387
4892                            && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
4893                                                 <SWI48:MODE>mode)")
4894            ]
4895            (symbol_ref "true")))
4896    (set (attr "preferred_for_speed")
4897      (cond [(eq_attr "alternative" "1")
4898               (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
4899            (symbol_ref "true")))])
4901 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
4902   [(set (match_operand:MODEF 0 "register_operand" "=f")
4903         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4904   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
4905   "fild%Z1\t%1"
4906   [(set_attr "type" "fmov")
4907    (set_attr "mode" "<MODEF:MODE>")
4908    (set_attr "fp_int_src" "true")])
4910 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
4911 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
4912 ;; alternative in sse2_loadld.
4913 (define_split
4914   [(set (match_operand:MODEF 0 "register_operand")
4915         (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
4916   "TARGET_SSE2 && TARGET_SSE_MATH
4917    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4918    && reload_completed && SSE_REG_P (operands[0])
4919    && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)"
4920   [(const_int 0)]
4922   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4923                                      <MODE>mode, 0);
4924   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4926   emit_insn (gen_sse2_loadld (operands[4],
4927                               CONST0_RTX (V4SImode), operands[1]));
4929   if (<ssevecmode>mode == V4SFmode)
4930     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4931   else
4932     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4933   DONE;
4936 ;; Avoid partial SSE register dependency stalls
4937 (define_split
4938   [(set (match_operand:MODEF 0 "register_operand")
4939         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4940   "TARGET_SSE2 && TARGET_SSE_MATH
4941    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4942    && optimize_function_for_speed_p (cfun)
4943    && reload_completed && SSE_REG_P (operands[0])"
4944   [(const_int 0)]
4946   const machine_mode vmode = <MODEF:ssevecmode>mode;
4947   const machine_mode mode = <MODEF:MODE>mode;
4948   rtx t, op0 = simplify_gen_subreg (vmode, operands[0], mode, 0);
4950   emit_move_insn (op0, CONST0_RTX (vmode));
4952   t = gen_rtx_FLOAT (mode, operands[1]);
4953   t = gen_rtx_VEC_DUPLICATE (vmode, t);
4954   t = gen_rtx_VEC_MERGE (vmode, t, op0, const1_rtx);
4955   emit_insn (gen_rtx_SET (VOIDmode, op0, t));
4956   DONE;
4959 ;; Break partial reg stall for cvtsd2ss.
4961 (define_peephole2
4962   [(set (match_operand:SF 0 "register_operand")
4963         (float_truncate:SF
4964           (match_operand:DF 1 "nonimmediate_operand")))]
4965   "TARGET_SSE2 && TARGET_SSE_MATH
4966    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4967    && optimize_function_for_speed_p (cfun)
4968    && SSE_REG_P (operands[0])
4969    && (!SSE_REG_P (operands[1])
4970        || REGNO (operands[0]) != REGNO (operands[1]))"
4971   [(set (match_dup 0)
4972         (vec_merge:V4SF
4973           (vec_duplicate:V4SF
4974             (float_truncate:V2SF
4975               (match_dup 1)))
4976           (match_dup 0)
4977           (const_int 1)))]
4979   operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
4980                                      SFmode, 0);
4981   operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
4982                                      DFmode, 0);
4983   emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
4986 ;; Break partial reg stall for cvtss2sd.
4988 (define_peephole2
4989   [(set (match_operand:DF 0 "register_operand")
4990         (float_extend:DF
4991           (match_operand:SF 1 "nonimmediate_operand")))]
4992   "TARGET_SSE2 && TARGET_SSE_MATH
4993    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4994    && optimize_function_for_speed_p (cfun)
4995    && SSE_REG_P (operands[0])
4996    && (!SSE_REG_P (operands[1])
4997        || REGNO (operands[0]) != REGNO (operands[1]))"
4998   [(set (match_dup 0)
4999         (vec_merge:V2DF
5000           (float_extend:V2DF
5001             (vec_select:V2SF
5002               (match_dup 1)
5003               (parallel [(const_int 0) (const_int 1)])))
5004           (match_dup 0)
5005           (const_int 1)))]
5007   operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
5008                                      DFmode, 0);
5009   operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
5010                                      SFmode, 0);
5011   emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5014 ;; Avoid store forwarding (partial memory) stall penalty
5015 ;; by passing DImode value through XMM registers.  */
5017 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5018   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5019         (float:X87MODEF
5020           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5021    (clobber (match_scratch:V4SI 3 "=X,x"))
5022    (clobber (match_scratch:V4SI 4 "=X,x"))
5023    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5024   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5025    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5026    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5027   "#"
5028   [(set_attr "type" "multi")
5029    (set_attr "mode" "<X87MODEF:MODE>")
5030    (set_attr "unit" "i387")
5031    (set_attr "fp_int_src" "true")])
5033 (define_split
5034   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5035         (float:X87MODEF (match_operand:DI 1 "register_operand")))
5036    (clobber (match_scratch:V4SI 3))
5037    (clobber (match_scratch:V4SI 4))
5038    (clobber (match_operand:DI 2 "memory_operand"))]
5039   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5040    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5041    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5042    && reload_completed"
5043   [(set (match_dup 2) (match_dup 3))
5044    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5046   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5047      Assemble the 64-bit DImode value in an xmm register.  */
5048   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5049                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5050   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5051                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5052   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5053                                          operands[4]));
5055   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5058 (define_split
5059   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5060         (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5061    (clobber (match_scratch:V4SI 3))
5062    (clobber (match_scratch:V4SI 4))
5063    (clobber (match_operand:DI 2 "memory_operand"))]
5064   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5065    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5066    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5067    && reload_completed"
5068   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5070 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5071   [(set (match_operand:MODEF 0 "register_operand")
5072         (unsigned_float:MODEF
5073           (match_operand:SWI12 1 "nonimmediate_operand")))]
5074   "!TARGET_64BIT
5075    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5077   operands[1] = convert_to_mode (SImode, operands[1], 1);
5078   emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5079   DONE;
5082 ;; Avoid store forwarding (partial memory) stall penalty by extending
5083 ;; SImode value to DImode through XMM register instead of pushing two
5084 ;; SImode values to stack. Also note that fild loads from memory only.
5086 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5087   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5088         (unsigned_float:X87MODEF
5089           (match_operand:SI 1 "nonimmediate_operand" "rm")))
5090    (clobber (match_scratch:DI 3 "=x"))
5091    (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5092   "!TARGET_64BIT
5093    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5094    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5095   "#"
5096   "&& reload_completed"
5097   [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5098    (set (match_dup 2) (match_dup 3))
5099    (set (match_dup 0)
5100         (float:X87MODEF (match_dup 2)))]
5101   ""
5102   [(set_attr "type" "multi")
5103    (set_attr "mode" "<MODE>")])
5105 (define_expand "floatunssi<mode>2"
5106   [(parallel
5107      [(set (match_operand:X87MODEF 0 "register_operand")
5108            (unsigned_float:X87MODEF
5109              (match_operand:SI 1 "nonimmediate_operand")))
5110       (clobber (match_scratch:DI 3))
5111       (clobber (match_dup 2))])]
5112   "!TARGET_64BIT
5113    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5114         && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5115        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5117   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5118     {
5119       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5120       DONE;
5121     }
5122   else
5123     operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5126 (define_expand "floatunsdisf2"
5127   [(use (match_operand:SF 0 "register_operand"))
5128    (use (match_operand:DI 1 "nonimmediate_operand"))]
5129   "TARGET_64BIT && TARGET_SSE_MATH"
5130   "x86_emit_floatuns (operands); DONE;")
5132 (define_expand "floatunsdidf2"
5133   [(use (match_operand:DF 0 "register_operand"))
5134    (use (match_operand:DI 1 "nonimmediate_operand"))]
5135   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5136    && TARGET_SSE2 && TARGET_SSE_MATH"
5138   if (TARGET_64BIT)
5139     x86_emit_floatuns (operands);
5140   else
5141     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5142   DONE;
5145 ;; Load effective address instructions
5147 (define_insn_and_split "*lea<mode>"
5148   [(set (match_operand:SWI48 0 "register_operand" "=r")
5149         (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5150   ""
5152   if (SImode_address_operand (operands[1], VOIDmode))
5153     {
5154       gcc_assert (TARGET_64BIT);
5155       return "lea{l}\t{%E1, %k0|%k0, %E1}";
5156     }
5157   else 
5158     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5160   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5161   [(const_int 0)]
5163   machine_mode mode = <MODE>mode;
5164   rtx pat;
5166   /* ix86_avoid_lea_for_addr re-recognizes insn and may
5167      change operands[] array behind our back.  */
5168   pat = PATTERN (curr_insn);
5170   operands[0] = SET_DEST (pat);
5171   operands[1] = SET_SRC (pat);
5173   /* Emit all operations in SImode for zero-extended addresses.  */
5174   if (SImode_address_operand (operands[1], VOIDmode))
5175     mode = SImode;
5177   ix86_split_lea_for_addr (curr_insn, operands, mode);
5179   /* Zero-extend return register to DImode for zero-extended addresses.  */
5180   if (mode != <MODE>mode)
5181     emit_insn (gen_zero_extendsidi2
5182                (operands[0], gen_lowpart (mode, operands[0])));
5184   DONE;
5186   [(set_attr "type" "lea")
5187    (set (attr "mode")
5188      (if_then_else
5189        (match_operand 1 "SImode_address_operand")
5190        (const_string "SI")
5191        (const_string "<MODE>")))])
5193 ;; Add instructions
5195 (define_expand "add<mode>3"
5196   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5197         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5198                     (match_operand:SDWIM 2 "<general_operand>")))]
5199   ""
5200   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5202 (define_insn_and_split "*add<dwi>3_doubleword"
5203   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5204         (plus:<DWI>
5205           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5206           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5207    (clobber (reg:CC FLAGS_REG))]
5208   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5209   "#"
5210   "reload_completed"
5211   [(parallel [(set (reg:CC FLAGS_REG)
5212                    (unspec:CC [(match_dup 1) (match_dup 2)]
5213                               UNSPEC_ADD_CARRY))
5214               (set (match_dup 0)
5215                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5216    (parallel [(set (match_dup 3)
5217                    (plus:DWIH
5218                      (match_dup 4)
5219                      (plus:DWIH
5220                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5221                        (match_dup 5))))
5222               (clobber (reg:CC FLAGS_REG))])]
5223   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5225 (define_insn "*add<mode>3_cc"
5226   [(set (reg:CC FLAGS_REG)
5227         (unspec:CC
5228           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5229            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5230           UNSPEC_ADD_CARRY))
5231    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5232         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5233   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5234   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5235   [(set_attr "type" "alu")
5236    (set_attr "mode" "<MODE>")])
5238 (define_insn "addqi3_cc"
5239   [(set (reg:CC FLAGS_REG)
5240         (unspec:CC
5241           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5242            (match_operand:QI 2 "general_operand" "qn,qm")]
5243           UNSPEC_ADD_CARRY))
5244    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5245         (plus:QI (match_dup 1) (match_dup 2)))]
5246   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5247   "add{b}\t{%2, %0|%0, %2}"
5248   [(set_attr "type" "alu")
5249    (set_attr "mode" "QI")])
5251 (define_insn "*add<mode>_1"
5252   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5253         (plus:SWI48
5254           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5255           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5256    (clobber (reg:CC FLAGS_REG))]
5257   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5259   switch (get_attr_type (insn))
5260     {
5261     case TYPE_LEA:
5262       return "#";
5264     case TYPE_INCDEC:
5265       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5266       if (operands[2] == const1_rtx)
5267         return "inc{<imodesuffix>}\t%0";
5268       else
5269         {
5270           gcc_assert (operands[2] == constm1_rtx);
5271           return "dec{<imodesuffix>}\t%0";
5272         }
5274     default:
5275       /* For most processors, ADD is faster than LEA.  This alternative
5276          was added to use ADD as much as possible.  */
5277       if (which_alternative == 2)
5278         std::swap (operands[1], operands[2]);
5279         
5280       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5281       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5282         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5284       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5285     }
5287   [(set (attr "type")
5288      (cond [(eq_attr "alternative" "3")
5289               (const_string "lea")
5290             (match_operand:SWI48 2 "incdec_operand")
5291               (const_string "incdec")
5292            ]
5293            (const_string "alu")))
5294    (set (attr "length_immediate")
5295       (if_then_else
5296         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5297         (const_string "1")
5298         (const_string "*")))
5299    (set_attr "mode" "<MODE>")])
5301 ;; It may seem that nonimmediate operand is proper one for operand 1.
5302 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5303 ;; we take care in ix86_binary_operator_ok to not allow two memory
5304 ;; operands so proper swapping will be done in reload.  This allow
5305 ;; patterns constructed from addsi_1 to match.
5307 (define_insn "addsi_1_zext"
5308   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5309         (zero_extend:DI
5310           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5311                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5312    (clobber (reg:CC FLAGS_REG))]
5313   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5315   switch (get_attr_type (insn))
5316     {
5317     case TYPE_LEA:
5318       return "#";
5320     case TYPE_INCDEC:
5321       if (operands[2] == const1_rtx)
5322         return "inc{l}\t%k0";
5323       else
5324         {
5325           gcc_assert (operands[2] == constm1_rtx);
5326           return "dec{l}\t%k0";
5327         }
5329     default:
5330       /* For most processors, ADD is faster than LEA.  This alternative
5331          was added to use ADD as much as possible.  */
5332       if (which_alternative == 1)
5333         std::swap (operands[1], operands[2]);
5335       if (x86_maybe_negate_const_int (&operands[2], SImode))
5336         return "sub{l}\t{%2, %k0|%k0, %2}";
5338       return "add{l}\t{%2, %k0|%k0, %2}";
5339     }
5341   [(set (attr "type")
5342      (cond [(eq_attr "alternative" "2")
5343               (const_string "lea")
5344             (match_operand:SI 2 "incdec_operand")
5345               (const_string "incdec")
5346            ]
5347            (const_string "alu")))
5348    (set (attr "length_immediate")
5349       (if_then_else
5350         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5351         (const_string "1")
5352         (const_string "*")))
5353    (set_attr "mode" "SI")])
5355 (define_insn "*addhi_1"
5356   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5357         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5358                  (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5359    (clobber (reg:CC FLAGS_REG))]
5360   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5362   switch (get_attr_type (insn))
5363     {
5364     case TYPE_LEA:
5365       return "#";
5367     case TYPE_INCDEC:
5368       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5369       if (operands[2] == const1_rtx)
5370         return "inc{w}\t%0";
5371       else
5372         {
5373           gcc_assert (operands[2] == constm1_rtx);
5374           return "dec{w}\t%0";
5375         }
5377     default:
5378       /* For most processors, ADD is faster than LEA.  This alternative
5379          was added to use ADD as much as possible.  */
5380       if (which_alternative == 2)
5381         std::swap (operands[1], operands[2]);
5383       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5384       if (x86_maybe_negate_const_int (&operands[2], HImode))
5385         return "sub{w}\t{%2, %0|%0, %2}";
5387       return "add{w}\t{%2, %0|%0, %2}";
5388     }
5390   [(set (attr "type")
5391      (cond [(eq_attr "alternative" "3")
5392               (const_string "lea")
5393             (match_operand:HI 2 "incdec_operand")
5394               (const_string "incdec")
5395            ]
5396            (const_string "alu")))
5397    (set (attr "length_immediate")
5398       (if_then_else
5399         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5400         (const_string "1")
5401         (const_string "*")))
5402    (set_attr "mode" "HI,HI,HI,SI")])
5404 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5405 (define_insn "*addqi_1"
5406   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5407         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5408                  (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5409    (clobber (reg:CC FLAGS_REG))]
5410   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5412   bool widen = (which_alternative == 3 || which_alternative == 4);
5414   switch (get_attr_type (insn))
5415     {
5416     case TYPE_LEA:
5417       return "#";
5419     case TYPE_INCDEC:
5420       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5421       if (operands[2] == const1_rtx)
5422         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5423       else
5424         {
5425           gcc_assert (operands[2] == constm1_rtx);
5426           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5427         }
5429     default:
5430       /* For most processors, ADD is faster than LEA.  These alternatives
5431          were added to use ADD as much as possible.  */
5432       if (which_alternative == 2 || which_alternative == 4)
5433         std::swap (operands[1], operands[2]);
5435       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5436       if (x86_maybe_negate_const_int (&operands[2], QImode))
5437         {
5438           if (widen)
5439             return "sub{l}\t{%2, %k0|%k0, %2}";
5440           else
5441             return "sub{b}\t{%2, %0|%0, %2}";
5442         }
5443       if (widen)
5444         return "add{l}\t{%k2, %k0|%k0, %k2}";
5445       else
5446         return "add{b}\t{%2, %0|%0, %2}";
5447     }
5449   [(set (attr "type")
5450      (cond [(eq_attr "alternative" "5")
5451               (const_string "lea")
5452             (match_operand:QI 2 "incdec_operand")
5453               (const_string "incdec")
5454            ]
5455            (const_string "alu")))
5456    (set (attr "length_immediate")
5457       (if_then_else
5458         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5459         (const_string "1")
5460         (const_string "*")))
5461    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5463 (define_insn "*addqi_1_slp"
5464   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5465         (plus:QI (match_dup 0)
5466                  (match_operand:QI 1 "general_operand" "qn,qm")))
5467    (clobber (reg:CC FLAGS_REG))]
5468   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5469    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5471   switch (get_attr_type (insn))
5472     {
5473     case TYPE_INCDEC:
5474       if (operands[1] == const1_rtx)
5475         return "inc{b}\t%0";
5476       else
5477         {
5478           gcc_assert (operands[1] == constm1_rtx);
5479           return "dec{b}\t%0";
5480         }
5482     default:
5483       if (x86_maybe_negate_const_int (&operands[1], QImode))
5484         return "sub{b}\t{%1, %0|%0, %1}";
5486       return "add{b}\t{%1, %0|%0, %1}";
5487     }
5489   [(set (attr "type")
5490      (if_then_else (match_operand:QI 1 "incdec_operand")
5491         (const_string "incdec")
5492         (const_string "alu1")))
5493    (set (attr "memory")
5494      (if_then_else (match_operand 1 "memory_operand")
5495         (const_string "load")
5496         (const_string "none")))
5497    (set_attr "mode" "QI")])
5499 ;; Split non destructive adds if we cannot use lea.
5500 (define_split
5501   [(set (match_operand:SWI48 0 "register_operand")
5502         (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5503                     (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5504    (clobber (reg:CC FLAGS_REG))]
5505   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5506   [(set (match_dup 0) (match_dup 1))
5507    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5508               (clobber (reg:CC FLAGS_REG))])])
5510 ;; Convert add to the lea pattern to avoid flags dependency.
5511 (define_split
5512   [(set (match_operand:SWI 0 "register_operand")
5513         (plus:SWI (match_operand:SWI 1 "register_operand")
5514                   (match_operand:SWI 2 "<nonmemory_operand>")))
5515    (clobber (reg:CC FLAGS_REG))]
5516   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5517   [(const_int 0)]
5519   machine_mode mode = <MODE>mode;
5520   rtx pat;
5522   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
5523     { 
5524       mode = SImode; 
5525       operands[0] = gen_lowpart (mode, operands[0]);
5526       operands[1] = gen_lowpart (mode, operands[1]);
5527       operands[2] = gen_lowpart (mode, operands[2]);
5528     }
5530   pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5532   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5533   DONE;
5536 ;; Split non destructive adds if we cannot use lea.
5537 (define_split
5538   [(set (match_operand:DI 0 "register_operand")
5539         (zero_extend:DI
5540           (plus:SI (match_operand:SI 1 "register_operand")
5541                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5542    (clobber (reg:CC FLAGS_REG))]
5543   "TARGET_64BIT
5544    && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5545   [(set (match_dup 3) (match_dup 1))
5546    (parallel [(set (match_dup 0)
5547                    (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5548               (clobber (reg:CC FLAGS_REG))])]
5549   "operands[3] = gen_lowpart (SImode, operands[0]);")
5551 ;; Convert add to the lea pattern to avoid flags dependency.
5552 (define_split
5553   [(set (match_operand:DI 0 "register_operand")
5554         (zero_extend:DI
5555           (plus:SI (match_operand:SI 1 "register_operand")
5556                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5557    (clobber (reg:CC FLAGS_REG))]
5558   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5559   [(set (match_dup 0)
5560         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5562 (define_insn "*add<mode>_2"
5563   [(set (reg FLAGS_REG)
5564         (compare
5565           (plus:SWI
5566             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5567             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5568           (const_int 0)))
5569    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5570         (plus:SWI (match_dup 1) (match_dup 2)))]
5571   "ix86_match_ccmode (insn, CCGOCmode)
5572    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5574   switch (get_attr_type (insn))
5575     {
5576     case TYPE_INCDEC:
5577       if (operands[2] == const1_rtx)
5578         return "inc{<imodesuffix>}\t%0";
5579       else
5580         {
5581           gcc_assert (operands[2] == constm1_rtx);
5582           return "dec{<imodesuffix>}\t%0";
5583         }
5585     default:
5586       if (which_alternative == 2)
5587         std::swap (operands[1], operands[2]);
5588         
5589       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5590       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5591         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5593       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5594     }
5596   [(set (attr "type")
5597      (if_then_else (match_operand:SWI 2 "incdec_operand")
5598         (const_string "incdec")
5599         (const_string "alu")))
5600    (set (attr "length_immediate")
5601       (if_then_else
5602         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5603         (const_string "1")
5604         (const_string "*")))
5605    (set_attr "mode" "<MODE>")])
5607 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5608 (define_insn "*addsi_2_zext"
5609   [(set (reg FLAGS_REG)
5610         (compare
5611           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5612                    (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5613           (const_int 0)))
5614    (set (match_operand:DI 0 "register_operand" "=r,r")
5615         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5616   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5617    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5619   switch (get_attr_type (insn))
5620     {
5621     case TYPE_INCDEC:
5622       if (operands[2] == const1_rtx)
5623         return "inc{l}\t%k0";
5624       else
5625         {
5626           gcc_assert (operands[2] == constm1_rtx);
5627           return "dec{l}\t%k0";
5628         }
5630     default:
5631       if (which_alternative == 1)
5632         std::swap (operands[1], operands[2]);
5634       if (x86_maybe_negate_const_int (&operands[2], SImode))
5635         return "sub{l}\t{%2, %k0|%k0, %2}";
5637       return "add{l}\t{%2, %k0|%k0, %2}";
5638     }
5640   [(set (attr "type")
5641      (if_then_else (match_operand:SI 2 "incdec_operand")
5642         (const_string "incdec")
5643         (const_string "alu")))
5644    (set (attr "length_immediate")
5645       (if_then_else
5646         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5647         (const_string "1")
5648         (const_string "*")))
5649    (set_attr "mode" "SI")])
5651 (define_insn "*add<mode>_3"
5652   [(set (reg FLAGS_REG)
5653         (compare
5654           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5655           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5656    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5657   "ix86_match_ccmode (insn, CCZmode)
5658    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5660   switch (get_attr_type (insn))
5661     {
5662     case TYPE_INCDEC:
5663       if (operands[2] == const1_rtx)
5664         return "inc{<imodesuffix>}\t%0";
5665       else
5666         {
5667           gcc_assert (operands[2] == constm1_rtx);
5668           return "dec{<imodesuffix>}\t%0";
5669         }
5671     default:
5672       if (which_alternative == 1)
5673         std::swap (operands[1], operands[2]);
5675       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5676       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5677         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5679       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5680     }
5682   [(set (attr "type")
5683      (if_then_else (match_operand:SWI 2 "incdec_operand")
5684         (const_string "incdec")
5685         (const_string "alu")))
5686    (set (attr "length_immediate")
5687       (if_then_else
5688         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5689         (const_string "1")
5690         (const_string "*")))
5691    (set_attr "mode" "<MODE>")])
5693 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5694 (define_insn "*addsi_3_zext"
5695   [(set (reg FLAGS_REG)
5696         (compare
5697           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5698           (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5699    (set (match_operand:DI 0 "register_operand" "=r,r")
5700         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5701   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5702    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5704   switch (get_attr_type (insn))
5705     {
5706     case TYPE_INCDEC:
5707       if (operands[2] == const1_rtx)
5708         return "inc{l}\t%k0";
5709       else
5710         {
5711           gcc_assert (operands[2] == constm1_rtx);
5712           return "dec{l}\t%k0";
5713         }
5715     default:
5716       if (which_alternative == 1)
5717         std::swap (operands[1], operands[2]);
5719       if (x86_maybe_negate_const_int (&operands[2], SImode))
5720         return "sub{l}\t{%2, %k0|%k0, %2}";
5722       return "add{l}\t{%2, %k0|%k0, %2}";
5723     }
5725   [(set (attr "type")
5726      (if_then_else (match_operand:SI 2 "incdec_operand")
5727         (const_string "incdec")
5728         (const_string "alu")))
5729    (set (attr "length_immediate")
5730       (if_then_else
5731         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5732         (const_string "1")
5733         (const_string "*")))
5734    (set_attr "mode" "SI")])
5736 ; For comparisons against 1, -1 and 128, we may generate better code
5737 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5738 ; is matched then.  We can't accept general immediate, because for
5739 ; case of overflows,  the result is messed up.
5740 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5741 ; only for comparisons not depending on it.
5743 (define_insn "*adddi_4"
5744   [(set (reg FLAGS_REG)
5745         (compare
5746           (match_operand:DI 1 "nonimmediate_operand" "0")
5747           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5748    (clobber (match_scratch:DI 0 "=rm"))]
5749   "TARGET_64BIT
5750    && ix86_match_ccmode (insn, CCGCmode)"
5752   switch (get_attr_type (insn))
5753     {
5754     case TYPE_INCDEC:
5755       if (operands[2] == constm1_rtx)
5756         return "inc{q}\t%0";
5757       else
5758         {
5759           gcc_assert (operands[2] == const1_rtx);
5760           return "dec{q}\t%0";
5761         }
5763     default:
5764       if (x86_maybe_negate_const_int (&operands[2], DImode))
5765         return "add{q}\t{%2, %0|%0, %2}";
5767       return "sub{q}\t{%2, %0|%0, %2}";
5768     }
5770   [(set (attr "type")
5771      (if_then_else (match_operand:DI 2 "incdec_operand")
5772         (const_string "incdec")
5773         (const_string "alu")))
5774    (set (attr "length_immediate")
5775       (if_then_else
5776         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5777         (const_string "1")
5778         (const_string "*")))
5779    (set_attr "mode" "DI")])
5781 ; For comparisons against 1, -1 and 128, we may generate better code
5782 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5783 ; is matched then.  We can't accept general immediate, because for
5784 ; case of overflows,  the result is messed up.
5785 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5786 ; only for comparisons not depending on it.
5788 (define_insn "*add<mode>_4"
5789   [(set (reg FLAGS_REG)
5790         (compare
5791           (match_operand:SWI124 1 "nonimmediate_operand" "0")
5792           (match_operand:SWI124 2 "const_int_operand" "n")))
5793    (clobber (match_scratch:SWI124 0 "=<r>m"))]
5794   "ix86_match_ccmode (insn, CCGCmode)"
5796   switch (get_attr_type (insn))
5797     {
5798     case TYPE_INCDEC:
5799       if (operands[2] == constm1_rtx)
5800         return "inc{<imodesuffix>}\t%0";
5801       else
5802         {
5803           gcc_assert (operands[2] == const1_rtx);
5804           return "dec{<imodesuffix>}\t%0";
5805         }
5807     default:
5808       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5809         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5811       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5812     }
5814   [(set (attr "type")
5815      (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5816         (const_string "incdec")
5817         (const_string "alu")))
5818    (set (attr "length_immediate")
5819       (if_then_else
5820         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5821         (const_string "1")
5822         (const_string "*")))
5823    (set_attr "mode" "<MODE>")])
5825 (define_insn "*add<mode>_5"
5826   [(set (reg FLAGS_REG)
5827         (compare
5828           (plus:SWI
5829             (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5830             (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5831           (const_int 0)))
5832    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5833   "ix86_match_ccmode (insn, CCGOCmode)
5834    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5836   switch (get_attr_type (insn))
5837     {
5838     case TYPE_INCDEC:
5839       if (operands[2] == const1_rtx)
5840         return "inc{<imodesuffix>}\t%0";
5841       else
5842         {
5843           gcc_assert (operands[2] == constm1_rtx);
5844           return "dec{<imodesuffix>}\t%0";
5845         }
5847     default:
5848       if (which_alternative == 1)
5849         std::swap (operands[1], operands[2]);
5851       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5852       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5853         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5855       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5856     }
5858   [(set (attr "type")
5859      (if_then_else (match_operand:SWI 2 "incdec_operand")
5860         (const_string "incdec")
5861         (const_string "alu")))
5862    (set (attr "length_immediate")
5863       (if_then_else
5864         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5865         (const_string "1")
5866         (const_string "*")))
5867    (set_attr "mode" "<MODE>")])
5869 (define_insn "addqi_ext_1"
5870   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
5871                          (const_int 8)
5872                          (const_int 8))
5873         (plus:SI
5874           (zero_extract:SI
5875             (match_operand 1 "ext_register_operand" "0,0")
5876             (const_int 8)
5877             (const_int 8))
5878           (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
5879    (clobber (reg:CC FLAGS_REG))]
5880   ""
5882   switch (get_attr_type (insn))
5883     {
5884     case TYPE_INCDEC:
5885       if (operands[2] == const1_rtx)
5886         return "inc{b}\t%h0";
5887       else
5888         {
5889           gcc_assert (operands[2] == constm1_rtx);
5890           return "dec{b}\t%h0";
5891         }
5893     default:
5894       return "add{b}\t{%2, %h0|%h0, %2}";
5895     }
5897   [(set_attr "isa" "*,nox64")
5898    (set (attr "type")
5899      (if_then_else (match_operand:QI 2 "incdec_operand")
5900         (const_string "incdec")
5901         (const_string "alu")))
5902    (set_attr "modrm" "1")
5903    (set_attr "mode" "QI")])
5905 (define_insn "*addqi_ext_2"
5906   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5907                          (const_int 8)
5908                          (const_int 8))
5909         (plus:SI
5910           (zero_extract:SI
5911             (match_operand 1 "ext_register_operand" "%0")
5912             (const_int 8)
5913             (const_int 8))
5914           (zero_extract:SI
5915             (match_operand 2 "ext_register_operand" "Q")
5916             (const_int 8)
5917             (const_int 8))))
5918    (clobber (reg:CC FLAGS_REG))]
5919   ""
5920   "add{b}\t{%h2, %h0|%h0, %h2}"
5921   [(set_attr "type" "alu")
5922    (set_attr "mode" "QI")])
5924 ;; Add with jump on overflow.
5925 (define_expand "addv<mode>4"
5926   [(parallel [(set (reg:CCO FLAGS_REG)
5927                    (eq:CCO (plus:<DWI>
5928                               (sign_extend:<DWI>
5929                                  (match_operand:SWI 1 "nonimmediate_operand"))
5930                               (match_dup 4))
5931                            (sign_extend:<DWI>
5932                               (plus:SWI (match_dup 1)
5933                                         (match_operand:SWI 2
5934                                            "<general_operand>")))))
5935               (set (match_operand:SWI 0 "register_operand")
5936                    (plus:SWI (match_dup 1) (match_dup 2)))])
5937    (set (pc) (if_then_else
5938                (eq (reg:CCO FLAGS_REG) (const_int 0))
5939                (label_ref (match_operand 3))
5940                (pc)))]
5941   ""
5943   ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
5944   if (CONST_INT_P (operands[2]))
5945     operands[4] = operands[2];
5946   else
5947     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
5950 (define_insn "*addv<mode>4"
5951   [(set (reg:CCO FLAGS_REG)
5952         (eq:CCO (plus:<DWI>
5953                    (sign_extend:<DWI>
5954                       (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
5955                    (sign_extend:<DWI>
5956                       (match_operand:SWI 2 "<general_sext_operand>"
5957                                            "<r>mWe,<r>We")))
5958                 (sign_extend:<DWI>
5959                    (plus:SWI (match_dup 1) (match_dup 2)))))
5960    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5961         (plus:SWI (match_dup 1) (match_dup 2)))]
5962   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5963   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5964   [(set_attr "type" "alu")
5965    (set_attr "mode" "<MODE>")])
5967 (define_insn "*addv<mode>4_1"
5968   [(set (reg:CCO FLAGS_REG)
5969         (eq:CCO (plus:<DWI>
5970                    (sign_extend:<DWI>
5971                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
5972                    (match_operand:<DWI> 3 "const_int_operand" "i"))
5973                 (sign_extend:<DWI>
5974                    (plus:SWI (match_dup 1)
5975                              (match_operand:SWI 2 "x86_64_immediate_operand"
5976                                                   "<i>")))))
5977    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
5978         (plus:SWI (match_dup 1) (match_dup 2)))]
5979   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
5980    && CONST_INT_P (operands[2])
5981    && INTVAL (operands[2]) == INTVAL (operands[3])"
5982   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5983   [(set_attr "type" "alu")
5984    (set_attr "mode" "<MODE>")
5985    (set (attr "length_immediate")
5986         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
5987                   (const_string "1")
5988                (match_test "<MODE_SIZE> == 8")
5989                   (const_string "4")]
5990               (const_string "<MODE_SIZE>")))])
5992 ;; The lea patterns for modes less than 32 bits need to be matched by
5993 ;; several insns converted to real lea by splitters.
5995 (define_insn_and_split "*lea_general_1"
5996   [(set (match_operand 0 "register_operand" "=r")
5997         (plus (plus (match_operand 1 "index_register_operand" "l")
5998                     (match_operand 2 "register_operand" "r"))
5999               (match_operand 3 "immediate_operand" "i")))]
6000   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6001    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6002    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6003    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6004    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6005        || GET_MODE (operands[3]) == VOIDmode)"
6006   "#"
6007   "&& reload_completed"
6008   [(const_int 0)]
6010   machine_mode mode = SImode;
6011   rtx pat;
6013   operands[0] = gen_lowpart (mode, operands[0]);
6014   operands[1] = gen_lowpart (mode, operands[1]);
6015   operands[2] = gen_lowpart (mode, operands[2]);
6016   operands[3] = gen_lowpart (mode, operands[3]);
6018   pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6019                       operands[3]);
6021   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6022   DONE;
6024   [(set_attr "type" "lea")
6025    (set_attr "mode" "SI")])
6027 (define_insn_and_split "*lea_general_2"
6028   [(set (match_operand 0 "register_operand" "=r")
6029         (plus (mult (match_operand 1 "index_register_operand" "l")
6030                     (match_operand 2 "const248_operand" "n"))
6031               (match_operand 3 "nonmemory_operand" "ri")))]
6032   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6033    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6034    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6035    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6036        || GET_MODE (operands[3]) == VOIDmode)"
6037   "#"
6038   "&& reload_completed"
6039   [(const_int 0)]
6041   machine_mode mode = SImode;
6042   rtx pat;
6044   operands[0] = gen_lowpart (mode, operands[0]);
6045   operands[1] = gen_lowpart (mode, operands[1]);
6046   operands[3] = gen_lowpart (mode, operands[3]);
6048   pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6049                       operands[3]);
6051   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6052   DONE;
6054   [(set_attr "type" "lea")
6055    (set_attr "mode" "SI")])
6057 (define_insn_and_split "*lea_general_3"
6058   [(set (match_operand 0 "register_operand" "=r")
6059         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6060                           (match_operand 2 "const248_operand" "n"))
6061                     (match_operand 3 "register_operand" "r"))
6062               (match_operand 4 "immediate_operand" "i")))]
6063   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6064    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6065    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6066    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6067   "#"
6068   "&& reload_completed"
6069   [(const_int 0)]
6071   machine_mode mode = SImode;
6072   rtx pat;
6074   operands[0] = gen_lowpart (mode, operands[0]);
6075   operands[1] = gen_lowpart (mode, operands[1]);
6076   operands[3] = gen_lowpart (mode, operands[3]);
6077   operands[4] = gen_lowpart (mode, operands[4]);
6079   pat = gen_rtx_PLUS (mode,
6080                       gen_rtx_PLUS (mode,
6081                                     gen_rtx_MULT (mode, operands[1],
6082                                                         operands[2]),
6083                                     operands[3]),
6084                       operands[4]);
6086   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6087   DONE;
6089   [(set_attr "type" "lea")
6090    (set_attr "mode" "SI")])
6092 (define_insn_and_split "*lea_general_4"
6093   [(set (match_operand 0 "register_operand" "=r")
6094         (any_or (ashift
6095                   (match_operand 1 "index_register_operand" "l")
6096                   (match_operand 2 "const_int_operand" "n"))
6097                 (match_operand 3 "const_int_operand" "n")))]
6098   "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6099       && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6100     || GET_MODE (operands[0]) == SImode
6101     || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6102    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6103    && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6104    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6105        < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6106   "#"
6107   "&& reload_completed"
6108   [(const_int 0)]
6110   machine_mode mode = GET_MODE (operands[0]);
6111   rtx pat;
6113   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6114     { 
6115       mode = SImode; 
6116       operands[0] = gen_lowpart (mode, operands[0]);
6117       operands[1] = gen_lowpart (mode, operands[1]);
6118     }
6120   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6122   pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6123                        INTVAL (operands[3]));
6125   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6126   DONE;
6128   [(set_attr "type" "lea")
6129    (set (attr "mode")
6130       (if_then_else (match_operand:DI 0)
6131         (const_string "DI")
6132         (const_string "SI")))])
6134 ;; Subtract instructions
6136 (define_expand "sub<mode>3"
6137   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6138         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6139                      (match_operand:SDWIM 2 "<general_operand>")))]
6140   ""
6141   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6143 (define_insn_and_split "*sub<dwi>3_doubleword"
6144   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6145         (minus:<DWI>
6146           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6147           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6148    (clobber (reg:CC FLAGS_REG))]
6149   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6150   "#"
6151   "reload_completed"
6152   [(parallel [(set (reg:CC FLAGS_REG)
6153                    (compare:CC (match_dup 1) (match_dup 2)))
6154               (set (match_dup 0)
6155                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6156    (parallel [(set (match_dup 3)
6157                    (minus:DWIH
6158                      (match_dup 4)
6159                      (plus:DWIH
6160                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6161                        (match_dup 5))))
6162               (clobber (reg:CC FLAGS_REG))])]
6163   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6165 (define_insn "*sub<mode>_1"
6166   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6167         (minus:SWI
6168           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6169           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6170    (clobber (reg:CC FLAGS_REG))]
6171   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6172   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6173   [(set_attr "type" "alu")
6174    (set_attr "mode" "<MODE>")])
6176 (define_insn "*subsi_1_zext"
6177   [(set (match_operand:DI 0 "register_operand" "=r")
6178         (zero_extend:DI
6179           (minus:SI (match_operand:SI 1 "register_operand" "0")
6180                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6181    (clobber (reg:CC FLAGS_REG))]
6182   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6183   "sub{l}\t{%2, %k0|%k0, %2}"
6184   [(set_attr "type" "alu")
6185    (set_attr "mode" "SI")])
6187 (define_insn "*subqi_1_slp"
6188   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6189         (minus:QI (match_dup 0)
6190                   (match_operand:QI 1 "general_operand" "qn,qm")))
6191    (clobber (reg:CC FLAGS_REG))]
6192   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6193    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6194   "sub{b}\t{%1, %0|%0, %1}"
6195   [(set_attr "type" "alu1")
6196    (set_attr "mode" "QI")])
6198 (define_insn "*sub<mode>_2"
6199   [(set (reg FLAGS_REG)
6200         (compare
6201           (minus:SWI
6202             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6203             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6204           (const_int 0)))
6205    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6206         (minus:SWI (match_dup 1) (match_dup 2)))]
6207   "ix86_match_ccmode (insn, CCGOCmode)
6208    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6209   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6210   [(set_attr "type" "alu")
6211    (set_attr "mode" "<MODE>")])
6213 (define_insn "*subsi_2_zext"
6214   [(set (reg FLAGS_REG)
6215         (compare
6216           (minus:SI (match_operand:SI 1 "register_operand" "0")
6217                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6218           (const_int 0)))
6219    (set (match_operand:DI 0 "register_operand" "=r")
6220         (zero_extend:DI
6221           (minus:SI (match_dup 1)
6222                     (match_dup 2))))]
6223   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6224    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6225   "sub{l}\t{%2, %k0|%k0, %2}"
6226   [(set_attr "type" "alu")
6227    (set_attr "mode" "SI")])
6229 ;; Subtract with jump on overflow.
6230 (define_expand "subv<mode>4"
6231   [(parallel [(set (reg:CCO FLAGS_REG)
6232                    (eq:CCO (minus:<DWI>
6233                               (sign_extend:<DWI>
6234                                  (match_operand:SWI 1 "nonimmediate_operand"))
6235                               (match_dup 4))
6236                            (sign_extend:<DWI>
6237                               (minus:SWI (match_dup 1)
6238                                          (match_operand:SWI 2
6239                                             "<general_operand>")))))
6240               (set (match_operand:SWI 0 "register_operand")
6241                    (minus:SWI (match_dup 1) (match_dup 2)))])
6242    (set (pc) (if_then_else
6243                (eq (reg:CCO FLAGS_REG) (const_int 0))
6244                (label_ref (match_operand 3))
6245                (pc)))]
6246   ""
6248   ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6249   if (CONST_INT_P (operands[2]))
6250     operands[4] = operands[2];
6251   else
6252     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6255 (define_insn "*subv<mode>4"
6256   [(set (reg:CCO FLAGS_REG)
6257         (eq:CCO (minus:<DWI>
6258                    (sign_extend:<DWI>
6259                       (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6260                    (sign_extend:<DWI>
6261                       (match_operand:SWI 2 "<general_sext_operand>"
6262                                            "<r>We,<r>m")))
6263                 (sign_extend:<DWI>
6264                    (minus:SWI (match_dup 1) (match_dup 2)))))
6265    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6266         (minus:SWI (match_dup 1) (match_dup 2)))]
6267   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6268   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6269   [(set_attr "type" "alu")
6270    (set_attr "mode" "<MODE>")])
6272 (define_insn "*subv<mode>4_1"
6273   [(set (reg:CCO FLAGS_REG)
6274         (eq:CCO (minus:<DWI>
6275                    (sign_extend:<DWI>
6276                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
6277                    (match_operand:<DWI> 3 "const_int_operand" "i"))
6278                 (sign_extend:<DWI>
6279                    (minus:SWI (match_dup 1)
6280                               (match_operand:SWI 2 "x86_64_immediate_operand"
6281                                                    "<i>")))))
6282    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6283         (minus:SWI (match_dup 1) (match_dup 2)))]
6284   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6285    && CONST_INT_P (operands[2])
6286    && INTVAL (operands[2]) == INTVAL (operands[3])"
6287   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6288   [(set_attr "type" "alu")
6289    (set_attr "mode" "<MODE>")
6290    (set (attr "length_immediate")
6291         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6292                   (const_string "1")
6293                (match_test "<MODE_SIZE> == 8")
6294                   (const_string "4")]
6295               (const_string "<MODE_SIZE>")))])
6297 (define_insn "*sub<mode>_3"
6298   [(set (reg FLAGS_REG)
6299         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6300                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6301    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6302         (minus:SWI (match_dup 1) (match_dup 2)))]
6303   "ix86_match_ccmode (insn, CCmode)
6304    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6305   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6306   [(set_attr "type" "alu")
6307    (set_attr "mode" "<MODE>")])
6309 (define_insn "*subsi_3_zext"
6310   [(set (reg FLAGS_REG)
6311         (compare (match_operand:SI 1 "register_operand" "0")
6312                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6313    (set (match_operand:DI 0 "register_operand" "=r")
6314         (zero_extend:DI
6315           (minus:SI (match_dup 1)
6316                     (match_dup 2))))]
6317   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6318    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6319   "sub{l}\t{%2, %1|%1, %2}"
6320   [(set_attr "type" "alu")
6321    (set_attr "mode" "SI")])
6323 ;; Add with carry and subtract with borrow
6325 (define_expand "<plusminus_insn><mode>3_carry"
6326   [(parallel
6327     [(set (match_operand:SWI 0 "nonimmediate_operand")
6328           (plusminus:SWI
6329             (match_operand:SWI 1 "nonimmediate_operand")
6330             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6331                        [(match_operand 3 "flags_reg_operand")
6332                         (const_int 0)])
6333                       (match_operand:SWI 2 "<general_operand>"))))
6334      (clobber (reg:CC FLAGS_REG))])]
6335   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6337 (define_insn "*<plusminus_insn><mode>3_carry"
6338   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6339         (plusminus:SWI
6340           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6341           (plus:SWI
6342             (match_operator 3 "ix86_carry_flag_operator"
6343              [(reg FLAGS_REG) (const_int 0)])
6344             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6345    (clobber (reg:CC FLAGS_REG))]
6346   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6347   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6348   [(set_attr "type" "alu")
6349    (set_attr "use_carry" "1")
6350    (set_attr "pent_pair" "pu")
6351    (set_attr "mode" "<MODE>")])
6353 (define_insn "*addsi3_carry_zext"
6354   [(set (match_operand:DI 0 "register_operand" "=r")
6355         (zero_extend:DI
6356           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6357                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6358                              [(reg FLAGS_REG) (const_int 0)])
6359                             (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6360    (clobber (reg:CC FLAGS_REG))]
6361   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6362   "adc{l}\t{%2, %k0|%k0, %2}"
6363   [(set_attr "type" "alu")
6364    (set_attr "use_carry" "1")
6365    (set_attr "pent_pair" "pu")
6366    (set_attr "mode" "SI")])
6368 (define_insn "*subsi3_carry_zext"
6369   [(set (match_operand:DI 0 "register_operand" "=r")
6370         (zero_extend:DI
6371           (minus:SI (match_operand:SI 1 "register_operand" "0")
6372                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6373                               [(reg FLAGS_REG) (const_int 0)])
6374                              (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6375    (clobber (reg:CC FLAGS_REG))]
6376   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6377   "sbb{l}\t{%2, %k0|%k0, %2}"
6378   [(set_attr "type" "alu")
6379    (set_attr "pent_pair" "pu")
6380    (set_attr "mode" "SI")])
6382 ;; ADCX instruction
6384 (define_insn "adcx<mode>3"
6385   [(set (reg:CCC FLAGS_REG)
6386         (compare:CCC
6387           (plus:SWI48
6388             (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6389             (plus:SWI48
6390               (match_operator 4 "ix86_carry_flag_operator"
6391                [(match_operand 3 "flags_reg_operand") (const_int 0)])
6392               (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6393           (const_int 0)))
6394    (set (match_operand:SWI48 0 "register_operand" "=r")
6395         (plus:SWI48 (match_dup 1)
6396                     (plus:SWI48 (match_op_dup 4
6397                                  [(match_dup 3) (const_int 0)])
6398                                 (match_dup 2))))]
6399   "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6400   "adcx\t{%2, %0|%0, %2}"
6401   [(set_attr "type" "alu")
6402    (set_attr "use_carry" "1")
6403    (set_attr "mode" "<MODE>")])
6405 ;; Overflow setting add instructions
6407 (define_insn "*add<mode>3_cconly_overflow"
6408   [(set (reg:CCC FLAGS_REG)
6409         (compare:CCC
6410           (plus:SWI
6411             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6412             (match_operand:SWI 2 "<general_operand>" "<g>"))
6413           (match_dup 1)))
6414    (clobber (match_scratch:SWI 0 "=<r>"))]
6415   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6416   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6417   [(set_attr "type" "alu")
6418    (set_attr "mode" "<MODE>")])
6420 (define_insn "*add<mode>3_cc_overflow"
6421   [(set (reg:CCC FLAGS_REG)
6422         (compare:CCC
6423             (plus:SWI
6424                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6425                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6426             (match_dup 1)))
6427    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6428         (plus:SWI (match_dup 1) (match_dup 2)))]
6429   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6430   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6431   [(set_attr "type" "alu")
6432    (set_attr "mode" "<MODE>")])
6434 (define_insn "*addsi3_zext_cc_overflow"
6435   [(set (reg:CCC FLAGS_REG)
6436         (compare:CCC
6437           (plus:SI
6438             (match_operand:SI 1 "nonimmediate_operand" "%0")
6439             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6440           (match_dup 1)))
6441    (set (match_operand:DI 0 "register_operand" "=r")
6442         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6443   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6444   "add{l}\t{%2, %k0|%k0, %2}"
6445   [(set_attr "type" "alu")
6446    (set_attr "mode" "SI")])
6448 ;; The patterns that match these are at the end of this file.
6450 (define_expand "<plusminus_insn>xf3"
6451   [(set (match_operand:XF 0 "register_operand")
6452         (plusminus:XF
6453           (match_operand:XF 1 "register_operand")
6454           (match_operand:XF 2 "register_operand")))]
6455   "TARGET_80387")
6457 (define_expand "<plusminus_insn><mode>3"
6458   [(set (match_operand:MODEF 0 "register_operand")
6459         (plusminus:MODEF
6460           (match_operand:MODEF 1 "register_operand")
6461           (match_operand:MODEF 2 "nonimmediate_operand")))]
6462   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6463     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6465 ;; Multiply instructions
6467 (define_expand "mul<mode>3"
6468   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6469                    (mult:SWIM248
6470                      (match_operand:SWIM248 1 "register_operand")
6471                      (match_operand:SWIM248 2 "<general_operand>")))
6472               (clobber (reg:CC FLAGS_REG))])])
6474 (define_expand "mulqi3"
6475   [(parallel [(set (match_operand:QI 0 "register_operand")
6476                    (mult:QI
6477                      (match_operand:QI 1 "register_operand")
6478                      (match_operand:QI 2 "nonimmediate_operand")))
6479               (clobber (reg:CC FLAGS_REG))])]
6480   "TARGET_QIMODE_MATH")
6482 ;; On AMDFAM10
6483 ;; IMUL reg32/64, reg32/64, imm8        Direct
6484 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6485 ;; IMUL reg32/64, reg32/64, imm32       Direct
6486 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6487 ;; IMUL reg32/64, reg32/64              Direct
6488 ;; IMUL reg32/64, mem32/64              Direct
6490 ;; On BDVER1, all above IMULs use DirectPath
6492 (define_insn "*mul<mode>3_1"
6493   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6494         (mult:SWI48
6495           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6496           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6497    (clobber (reg:CC FLAGS_REG))]
6498   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6499   "@
6500    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6501    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6502    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6503   [(set_attr "type" "imul")
6504    (set_attr "prefix_0f" "0,0,1")
6505    (set (attr "athlon_decode")
6506         (cond [(eq_attr "cpu" "athlon")
6507                   (const_string "vector")
6508                (eq_attr "alternative" "1")
6509                   (const_string "vector")
6510                (and (eq_attr "alternative" "2")
6511                     (match_operand 1 "memory_operand"))
6512                   (const_string "vector")]
6513               (const_string "direct")))
6514    (set (attr "amdfam10_decode")
6515         (cond [(and (eq_attr "alternative" "0,1")
6516                     (match_operand 1 "memory_operand"))
6517                   (const_string "vector")]
6518               (const_string "direct")))
6519    (set_attr "bdver1_decode" "direct")
6520    (set_attr "mode" "<MODE>")])
6522 (define_insn "*mulsi3_1_zext"
6523   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6524         (zero_extend:DI
6525           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6526                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6527    (clobber (reg:CC FLAGS_REG))]
6528   "TARGET_64BIT
6529    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6530   "@
6531    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6532    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6533    imul{l}\t{%2, %k0|%k0, %2}"
6534   [(set_attr "type" "imul")
6535    (set_attr "prefix_0f" "0,0,1")
6536    (set (attr "athlon_decode")
6537         (cond [(eq_attr "cpu" "athlon")
6538                   (const_string "vector")
6539                (eq_attr "alternative" "1")
6540                   (const_string "vector")
6541                (and (eq_attr "alternative" "2")
6542                     (match_operand 1 "memory_operand"))
6543                   (const_string "vector")]
6544               (const_string "direct")))
6545    (set (attr "amdfam10_decode")
6546         (cond [(and (eq_attr "alternative" "0,1")
6547                     (match_operand 1 "memory_operand"))
6548                   (const_string "vector")]
6549               (const_string "direct")))
6550    (set_attr "bdver1_decode" "direct")
6551    (set_attr "mode" "SI")])
6553 ;; On AMDFAM10
6554 ;; IMUL reg16, reg16, imm8      VectorPath
6555 ;; IMUL reg16, mem16, imm8      VectorPath
6556 ;; IMUL reg16, reg16, imm16     VectorPath
6557 ;; IMUL reg16, mem16, imm16     VectorPath
6558 ;; IMUL reg16, reg16            Direct
6559 ;; IMUL reg16, mem16            Direct
6561 ;; On BDVER1, all HI MULs use DoublePath
6563 (define_insn "*mulhi3_1"
6564   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6565         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6566                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6567    (clobber (reg:CC FLAGS_REG))]
6568   "TARGET_HIMODE_MATH
6569    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6570   "@
6571    imul{w}\t{%2, %1, %0|%0, %1, %2}
6572    imul{w}\t{%2, %1, %0|%0, %1, %2}
6573    imul{w}\t{%2, %0|%0, %2}"
6574   [(set_attr "type" "imul")
6575    (set_attr "prefix_0f" "0,0,1")
6576    (set (attr "athlon_decode")
6577         (cond [(eq_attr "cpu" "athlon")
6578                   (const_string "vector")
6579                (eq_attr "alternative" "1,2")
6580                   (const_string "vector")]
6581               (const_string "direct")))
6582    (set (attr "amdfam10_decode")
6583         (cond [(eq_attr "alternative" "0,1")
6584                   (const_string "vector")]
6585               (const_string "direct")))
6586    (set_attr "bdver1_decode" "double")
6587    (set_attr "mode" "HI")])
6589 ;;On AMDFAM10 and BDVER1
6590 ;; MUL reg8     Direct
6591 ;; MUL mem8     Direct
6593 (define_insn "*mulqi3_1"
6594   [(set (match_operand:QI 0 "register_operand" "=a")
6595         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6596                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6597    (clobber (reg:CC FLAGS_REG))]
6598   "TARGET_QIMODE_MATH
6599    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6600   "mul{b}\t%2"
6601   [(set_attr "type" "imul")
6602    (set_attr "length_immediate" "0")
6603    (set (attr "athlon_decode")
6604      (if_then_else (eq_attr "cpu" "athlon")
6605         (const_string "vector")
6606         (const_string "direct")))
6607    (set_attr "amdfam10_decode" "direct")
6608    (set_attr "bdver1_decode" "direct")
6609    (set_attr "mode" "QI")])
6611 ;; Multiply with jump on overflow.
6612 (define_expand "mulv<mode>4"
6613   [(parallel [(set (reg:CCO FLAGS_REG)
6614                    (eq:CCO (mult:<DWI>
6615                               (sign_extend:<DWI>
6616                                  (match_operand:SWI48 1 "register_operand"))
6617                               (match_dup 4))
6618                            (sign_extend:<DWI>
6619                               (mult:SWI48 (match_dup 1)
6620                                           (match_operand:SWI48 2
6621                                              "<general_operand>")))))
6622               (set (match_operand:SWI48 0 "register_operand")
6623                    (mult:SWI48 (match_dup 1) (match_dup 2)))])
6624    (set (pc) (if_then_else
6625                (eq (reg:CCO FLAGS_REG) (const_int 0))
6626                (label_ref (match_operand 3))
6627                (pc)))]
6628   ""
6630   if (CONST_INT_P (operands[2]))
6631     operands[4] = operands[2];
6632   else
6633     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6636 (define_insn "*mulv<mode>4"
6637   [(set (reg:CCO FLAGS_REG)
6638         (eq:CCO (mult:<DWI>
6639                    (sign_extend:<DWI>
6640                       (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6641                    (sign_extend:<DWI>
6642                       (match_operand:SWI48 2 "<general_sext_operand>"
6643                                              "We,mr")))
6644                 (sign_extend:<DWI>
6645                    (mult:SWI48 (match_dup 1) (match_dup 2)))))
6646    (set (match_operand:SWI48 0 "register_operand" "=r,r")
6647         (mult:SWI48 (match_dup 1) (match_dup 2)))]
6648   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6649   "@
6650    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6651    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6652   [(set_attr "type" "imul")
6653    (set_attr "prefix_0f" "0,1")
6654    (set (attr "athlon_decode")
6655         (cond [(eq_attr "cpu" "athlon")
6656                   (const_string "vector")
6657                (eq_attr "alternative" "0")
6658                   (const_string "vector")
6659                (and (eq_attr "alternative" "1")
6660                     (match_operand 1 "memory_operand"))
6661                   (const_string "vector")]
6662               (const_string "direct")))
6663    (set (attr "amdfam10_decode")
6664         (cond [(and (eq_attr "alternative" "1")
6665                     (match_operand 1 "memory_operand"))
6666                   (const_string "vector")]
6667               (const_string "direct")))
6668    (set_attr "bdver1_decode" "direct")
6669    (set_attr "mode" "<MODE>")])
6671 (define_insn "*mulv<mode>4_1"
6672   [(set (reg:CCO FLAGS_REG)
6673         (eq:CCO (mult:<DWI>
6674                    (sign_extend:<DWI>
6675                       (match_operand:SWI48 1 "nonimmediate_operand" "rm,rm"))
6676                    (match_operand:<DWI> 3 "const_int_operand" "K,i"))
6677                 (sign_extend:<DWI>
6678                    (mult:SWI48 (match_dup 1)
6679                                (match_operand:SWI 2 "x86_64_immediate_operand"
6680                                                     "K,<i>")))))
6681    (set (match_operand:SWI48 0 "register_operand" "=r,r")
6682         (mult:SWI48 (match_dup 1) (match_dup 2)))]
6683   "!(MEM_P (operands[1]) && MEM_P (operands[2]))
6684    && CONST_INT_P (operands[2])
6685    && INTVAL (operands[2]) == INTVAL (operands[3])"
6686   "@
6687    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6688    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6689   [(set_attr "type" "imul")
6690    (set (attr "athlon_decode")
6691         (cond [(eq_attr "cpu" "athlon")
6692                   (const_string "vector")
6693                (eq_attr "alternative" "1")
6694                   (const_string "vector")]
6695               (const_string "direct")))
6696    (set (attr "amdfam10_decode")
6697         (cond [(match_operand 1 "memory_operand")
6698                   (const_string "vector")]
6699               (const_string "direct")))
6700    (set_attr "bdver1_decode" "direct")
6701    (set_attr "mode" "<MODE>")
6702    (set (attr "length_immediate")
6703         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6704                   (const_string "1")
6705                (match_test "<MODE_SIZE> == 8")
6706                   (const_string "4")]
6707               (const_string "<MODE_SIZE>")))])
6709 (define_expand "umulv<mode>4"
6710   [(parallel [(set (reg:CCO FLAGS_REG)
6711                    (eq:CCO (mult:<DWI>
6712                               (zero_extend:<DWI>
6713                                  (match_operand:SWI48 1
6714                                                       "nonimmediate_operand"))
6715                               (zero_extend:<DWI>
6716                                  (match_operand:SWI48 2
6717                                                       "nonimmediate_operand")))
6718                            (zero_extend:<DWI>
6719                               (mult:SWI48 (match_dup 1) (match_dup 2)))))
6720               (set (match_operand:SWI48 0 "register_operand")
6721                    (mult:SWI48 (match_dup 1) (match_dup 2)))
6722               (clobber (match_scratch:SWI48 4))])
6723    (set (pc) (if_then_else
6724                (eq (reg:CCO FLAGS_REG) (const_int 0))
6725                (label_ref (match_operand 3))
6726                (pc)))]
6727   ""
6729   if (MEM_P (operands[1]) && MEM_P (operands[2]))
6730     operands[1] = force_reg (<MODE>mode, operands[1]);
6733 (define_insn "*umulv<mode>4"
6734   [(set (reg:CCO FLAGS_REG)
6735         (eq:CCO (mult:<DWI>
6736                    (zero_extend:<DWI>
6737                       (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6738                    (zero_extend:<DWI>
6739                       (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6740                 (zero_extend:<DWI>
6741                    (mult:SWI48 (match_dup 1) (match_dup 2)))))
6742    (set (match_operand:SWI48 0 "register_operand" "=a")
6743         (mult:SWI48 (match_dup 1) (match_dup 2)))
6744    (clobber (match_scratch:SWI48 3 "=d"))]
6745   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6746   "mul{<imodesuffix>}\t%2"
6747   [(set_attr "type" "imul")
6748    (set_attr "length_immediate" "0")
6749    (set (attr "athlon_decode")
6750      (if_then_else (eq_attr "cpu" "athlon")
6751        (const_string "vector")
6752        (const_string "double")))
6753    (set_attr "amdfam10_decode" "double")
6754    (set_attr "bdver1_decode" "direct")
6755    (set_attr "mode" "<MODE>")])
6757 (define_expand "<u>mulvqi4"
6758   [(parallel [(set (reg:CCO FLAGS_REG)
6759                    (eq:CCO (mult:HI
6760                               (any_extend:HI
6761                                  (match_operand:QI 1 "nonimmediate_operand"))
6762                               (any_extend:HI
6763                                  (match_operand:QI 2 "nonimmediate_operand")))
6764                            (any_extend:HI
6765                               (mult:QI (match_dup 1) (match_dup 2)))))
6766               (set (match_operand:QI 0 "register_operand")
6767                    (mult:QI (match_dup 1) (match_dup 2)))])
6768    (set (pc) (if_then_else
6769                (eq (reg:CCO FLAGS_REG) (const_int 0))
6770                (label_ref (match_operand 3))
6771                (pc)))]
6772   "TARGET_QIMODE_MATH"
6774   if (MEM_P (operands[1]) && MEM_P (operands[2]))
6775     operands[1] = force_reg (QImode, operands[1]);
6778 (define_insn "*<u>mulvqi4"
6779   [(set (reg:CCO FLAGS_REG)
6780         (eq:CCO (mult:HI
6781                    (any_extend:HI
6782                       (match_operand:QI 1 "nonimmediate_operand" "%0"))
6783                    (any_extend:HI
6784                       (match_operand:QI 2 "nonimmediate_operand" "qm")))
6785                 (any_extend:HI
6786                    (mult:QI (match_dup 1) (match_dup 2)))))
6787    (set (match_operand:QI 0 "register_operand" "=a")
6788         (mult:QI (match_dup 1) (match_dup 2)))]
6789   "TARGET_QIMODE_MATH
6790    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6791   "<sgnprefix>mul{b}\t%2"
6792   [(set_attr "type" "imul")
6793    (set_attr "length_immediate" "0")
6794    (set (attr "athlon_decode")
6795      (if_then_else (eq_attr "cpu" "athlon")
6796         (const_string "vector")
6797         (const_string "direct")))
6798    (set_attr "amdfam10_decode" "direct")
6799    (set_attr "bdver1_decode" "direct")
6800    (set_attr "mode" "QI")])
6802 (define_expand "<u>mul<mode><dwi>3"
6803   [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6804                    (mult:<DWI>
6805                      (any_extend:<DWI>
6806                        (match_operand:DWIH 1 "nonimmediate_operand"))
6807                      (any_extend:<DWI>
6808                        (match_operand:DWIH 2 "register_operand"))))
6809               (clobber (reg:CC FLAGS_REG))])])
6811 (define_expand "<u>mulqihi3"
6812   [(parallel [(set (match_operand:HI 0 "register_operand")
6813                    (mult:HI
6814                      (any_extend:HI
6815                        (match_operand:QI 1 "nonimmediate_operand"))
6816                      (any_extend:HI
6817                        (match_operand:QI 2 "register_operand"))))
6818               (clobber (reg:CC FLAGS_REG))])]
6819   "TARGET_QIMODE_MATH")
6821 (define_insn "*bmi2_umul<mode><dwi>3_1"
6822   [(set (match_operand:DWIH 0 "register_operand" "=r")
6823         (mult:DWIH
6824           (match_operand:DWIH 2 "nonimmediate_operand" "%d")
6825           (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
6826    (set (match_operand:DWIH 1 "register_operand" "=r")
6827         (truncate:DWIH
6828           (lshiftrt:<DWI>
6829             (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
6830                         (zero_extend:<DWI> (match_dup 3)))
6831             (match_operand:QI 4 "const_int_operand" "n"))))]
6832   "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
6833    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6834   "mulx\t{%3, %0, %1|%1, %0, %3}"
6835   [(set_attr "type" "imulx")
6836    (set_attr "prefix" "vex")
6837    (set_attr "mode" "<MODE>")])
6839 (define_insn "*umul<mode><dwi>3_1"
6840   [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6841         (mult:<DWI>
6842           (zero_extend:<DWI>
6843             (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6844           (zero_extend:<DWI>
6845             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6846    (clobber (reg:CC FLAGS_REG))]
6847   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6848   "@
6849    #
6850    mul{<imodesuffix>}\t%2"
6851   [(set_attr "isa" "bmi2,*")
6852    (set_attr "type" "imulx,imul")
6853    (set_attr "length_immediate" "*,0")
6854    (set (attr "athlon_decode")
6855         (cond [(eq_attr "alternative" "1")
6856                  (if_then_else (eq_attr "cpu" "athlon")
6857                    (const_string "vector")
6858                    (const_string "double"))]
6859               (const_string "*")))
6860    (set_attr "amdfam10_decode" "*,double")
6861    (set_attr "bdver1_decode" "*,direct")
6862    (set_attr "prefix" "vex,orig")
6863    (set_attr "mode" "<MODE>")])
6865 ;; Convert mul to the mulx pattern to avoid flags dependency.
6866 (define_split
6867  [(set (match_operand:<DWI> 0 "register_operand")
6868        (mult:<DWI>
6869          (zero_extend:<DWI>
6870            (match_operand:DWIH 1 "register_operand"))
6871          (zero_extend:<DWI>
6872            (match_operand:DWIH 2 "nonimmediate_operand"))))
6873   (clobber (reg:CC FLAGS_REG))]
6874  "TARGET_BMI2 && reload_completed
6875   && true_regnum (operands[1]) == DX_REG"
6876   [(parallel [(set (match_dup 3)
6877                    (mult:DWIH (match_dup 1) (match_dup 2)))
6878               (set (match_dup 4)
6879                    (truncate:DWIH
6880                      (lshiftrt:<DWI>
6881                        (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6882                                    (zero_extend:<DWI> (match_dup 2)))
6883                        (match_dup 5))))])]
6885   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6887   operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
6890 (define_insn "*mul<mode><dwi>3_1"
6891   [(set (match_operand:<DWI> 0 "register_operand" "=A")
6892         (mult:<DWI>
6893           (sign_extend:<DWI>
6894             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6895           (sign_extend:<DWI>
6896             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6897    (clobber (reg:CC FLAGS_REG))]
6898   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6899   "imul{<imodesuffix>}\t%2"
6900   [(set_attr "type" "imul")
6901    (set_attr "length_immediate" "0")
6902    (set (attr "athlon_decode")
6903      (if_then_else (eq_attr "cpu" "athlon")
6904         (const_string "vector")
6905         (const_string "double")))
6906    (set_attr "amdfam10_decode" "double")
6907    (set_attr "bdver1_decode" "direct")
6908    (set_attr "mode" "<MODE>")])
6910 (define_insn "*<u>mulqihi3_1"
6911   [(set (match_operand:HI 0 "register_operand" "=a")
6912         (mult:HI
6913           (any_extend:HI
6914             (match_operand:QI 1 "nonimmediate_operand" "%0"))
6915           (any_extend:HI
6916             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6917    (clobber (reg:CC FLAGS_REG))]
6918   "TARGET_QIMODE_MATH
6919    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6920   "<sgnprefix>mul{b}\t%2"
6921   [(set_attr "type" "imul")
6922    (set_attr "length_immediate" "0")
6923    (set (attr "athlon_decode")
6924      (if_then_else (eq_attr "cpu" "athlon")
6925         (const_string "vector")
6926         (const_string "direct")))
6927    (set_attr "amdfam10_decode" "direct")
6928    (set_attr "bdver1_decode" "direct")
6929    (set_attr "mode" "QI")])
6931 (define_expand "<s>mul<mode>3_highpart"
6932   [(parallel [(set (match_operand:SWI48 0 "register_operand")
6933                    (truncate:SWI48
6934                      (lshiftrt:<DWI>
6935                        (mult:<DWI>
6936                          (any_extend:<DWI>
6937                            (match_operand:SWI48 1 "nonimmediate_operand"))
6938                          (any_extend:<DWI>
6939                            (match_operand:SWI48 2 "register_operand")))
6940                        (match_dup 4))))
6941               (clobber (match_scratch:SWI48 3))
6942               (clobber (reg:CC FLAGS_REG))])]
6943   ""
6944   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6946 (define_insn "*<s>muldi3_highpart_1"
6947   [(set (match_operand:DI 0 "register_operand" "=d")
6948         (truncate:DI
6949           (lshiftrt:TI
6950             (mult:TI
6951               (any_extend:TI
6952                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6953               (any_extend:TI
6954                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6955             (const_int 64))))
6956    (clobber (match_scratch:DI 3 "=1"))
6957    (clobber (reg:CC FLAGS_REG))]
6958   "TARGET_64BIT
6959    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6960   "<sgnprefix>mul{q}\t%2"
6961   [(set_attr "type" "imul")
6962    (set_attr "length_immediate" "0")
6963    (set (attr "athlon_decode")
6964      (if_then_else (eq_attr "cpu" "athlon")
6965         (const_string "vector")
6966         (const_string "double")))
6967    (set_attr "amdfam10_decode" "double")
6968    (set_attr "bdver1_decode" "direct")
6969    (set_attr "mode" "DI")])
6971 (define_insn "*<s>mulsi3_highpart_1"
6972   [(set (match_operand:SI 0 "register_operand" "=d")
6973         (truncate:SI
6974           (lshiftrt:DI
6975             (mult:DI
6976               (any_extend:DI
6977                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6978               (any_extend:DI
6979                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6980             (const_int 32))))
6981    (clobber (match_scratch:SI 3 "=1"))
6982    (clobber (reg:CC FLAGS_REG))]
6983   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6984   "<sgnprefix>mul{l}\t%2"
6985   [(set_attr "type" "imul")
6986    (set_attr "length_immediate" "0")
6987    (set (attr "athlon_decode")
6988      (if_then_else (eq_attr "cpu" "athlon")
6989         (const_string "vector")
6990         (const_string "double")))
6991    (set_attr "amdfam10_decode" "double")
6992    (set_attr "bdver1_decode" "direct")
6993    (set_attr "mode" "SI")])
6995 (define_insn "*<s>mulsi3_highpart_zext"
6996   [(set (match_operand:DI 0 "register_operand" "=d")
6997         (zero_extend:DI (truncate:SI
6998           (lshiftrt:DI
6999             (mult:DI (any_extend:DI
7000                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7001                      (any_extend:DI
7002                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7003             (const_int 32)))))
7004    (clobber (match_scratch:SI 3 "=1"))
7005    (clobber (reg:CC FLAGS_REG))]
7006   "TARGET_64BIT
7007    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7008   "<sgnprefix>mul{l}\t%2"
7009   [(set_attr "type" "imul")
7010    (set_attr "length_immediate" "0")
7011    (set (attr "athlon_decode")
7012      (if_then_else (eq_attr "cpu" "athlon")
7013         (const_string "vector")
7014         (const_string "double")))
7015    (set_attr "amdfam10_decode" "double")
7016    (set_attr "bdver1_decode" "direct")
7017    (set_attr "mode" "SI")])
7019 ;; The patterns that match these are at the end of this file.
7021 (define_expand "mulxf3"
7022   [(set (match_operand:XF 0 "register_operand")
7023         (mult:XF (match_operand:XF 1 "register_operand")
7024                  (match_operand:XF 2 "register_operand")))]
7025   "TARGET_80387")
7027 (define_expand "mul<mode>3"
7028   [(set (match_operand:MODEF 0 "register_operand")
7029         (mult:MODEF (match_operand:MODEF 1 "register_operand")
7030                     (match_operand:MODEF 2 "nonimmediate_operand")))]
7031   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7032     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7034 ;; Divide instructions
7036 ;; The patterns that match these are at the end of this file.
7038 (define_expand "divxf3"
7039   [(set (match_operand:XF 0 "register_operand")
7040         (div:XF (match_operand:XF 1 "register_operand")
7041                 (match_operand:XF 2 "register_operand")))]
7042   "TARGET_80387")
7044 (define_expand "divdf3"
7045   [(set (match_operand:DF 0 "register_operand")
7046         (div:DF (match_operand:DF 1 "register_operand")
7047                 (match_operand:DF 2 "nonimmediate_operand")))]
7048    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7049     || (TARGET_SSE2 && TARGET_SSE_MATH)")
7051 (define_expand "divsf3"
7052   [(set (match_operand:SF 0 "register_operand")
7053         (div:SF (match_operand:SF 1 "register_operand")
7054                 (match_operand:SF 2 "nonimmediate_operand")))]
7055   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7056     || TARGET_SSE_MATH"
7058   if (TARGET_SSE_MATH
7059       && TARGET_RECIP_DIV
7060       && optimize_insn_for_speed_p ()
7061       && flag_finite_math_only && !flag_trapping_math
7062       && flag_unsafe_math_optimizations)
7063     {
7064       ix86_emit_swdivsf (operands[0], operands[1],
7065                          operands[2], SFmode);
7066       DONE;
7067     }
7070 ;; Divmod instructions.
7072 (define_expand "divmod<mode>4"
7073   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7074                    (div:SWIM248
7075                      (match_operand:SWIM248 1 "register_operand")
7076                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7077               (set (match_operand:SWIM248 3 "register_operand")
7078                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7079               (clobber (reg:CC FLAGS_REG))])])
7081 ;; Split with 8bit unsigned divide:
7082 ;;      if (dividend an divisor are in [0-255])
7083 ;;         use 8bit unsigned integer divide
7084 ;;       else
7085 ;;         use original integer divide
7086 (define_split
7087   [(set (match_operand:SWI48 0 "register_operand")
7088         (div:SWI48 (match_operand:SWI48 2 "register_operand")
7089                     (match_operand:SWI48 3 "nonimmediate_operand")))
7090    (set (match_operand:SWI48 1 "register_operand")
7091         (mod:SWI48 (match_dup 2) (match_dup 3)))
7092    (clobber (reg:CC FLAGS_REG))]
7093   "TARGET_USE_8BIT_IDIV
7094    && TARGET_QIMODE_MATH
7095    && can_create_pseudo_p ()
7096    && !optimize_insn_for_size_p ()"
7097   [(const_int 0)]
7098   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7100 (define_insn_and_split "divmod<mode>4_1"
7101   [(set (match_operand:SWI48 0 "register_operand" "=a")
7102         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7103                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7104    (set (match_operand:SWI48 1 "register_operand" "=&d")
7105         (mod:SWI48 (match_dup 2) (match_dup 3)))
7106    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7107    (clobber (reg:CC FLAGS_REG))]
7108   ""
7109   "#"
7110   "reload_completed"
7111   [(parallel [(set (match_dup 1)
7112                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7113               (clobber (reg:CC FLAGS_REG))])
7114    (parallel [(set (match_dup 0)
7115                    (div:SWI48 (match_dup 2) (match_dup 3)))
7116               (set (match_dup 1)
7117                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7118               (use (match_dup 1))
7119               (clobber (reg:CC FLAGS_REG))])]
7121   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7123   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7124     operands[4] = operands[2];
7125   else
7126     {
7127       /* Avoid use of cltd in favor of a mov+shift.  */
7128       emit_move_insn (operands[1], operands[2]);
7129       operands[4] = operands[1];
7130     }
7132   [(set_attr "type" "multi")
7133    (set_attr "mode" "<MODE>")])
7135 (define_insn_and_split "*divmod<mode>4"
7136   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7137         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7138                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7139    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7140         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7141    (clobber (reg:CC FLAGS_REG))]
7142   ""
7143   "#"
7144   "reload_completed"
7145   [(parallel [(set (match_dup 1)
7146                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7147               (clobber (reg:CC FLAGS_REG))])
7148    (parallel [(set (match_dup 0)
7149                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7150               (set (match_dup 1)
7151                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7152               (use (match_dup 1))
7153               (clobber (reg:CC FLAGS_REG))])]
7155   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7157   if (<MODE>mode != HImode
7158       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7159     operands[4] = operands[2];
7160   else
7161     {
7162       /* Avoid use of cltd in favor of a mov+shift.  */
7163       emit_move_insn (operands[1], operands[2]);
7164       operands[4] = operands[1];
7165     }
7167   [(set_attr "type" "multi")
7168    (set_attr "mode" "<MODE>")])
7170 (define_insn "*divmod<mode>4_noext"
7171   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7172         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7173                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7174    (set (match_operand:SWIM248 1 "register_operand" "=d")
7175         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7176    (use (match_operand:SWIM248 4 "register_operand" "1"))
7177    (clobber (reg:CC FLAGS_REG))]
7178   ""
7179   "idiv{<imodesuffix>}\t%3"
7180   [(set_attr "type" "idiv")
7181    (set_attr "mode" "<MODE>")])
7183 (define_expand "divmodqi4"
7184   [(parallel [(set (match_operand:QI 0 "register_operand")
7185                    (div:QI
7186                      (match_operand:QI 1 "register_operand")
7187                      (match_operand:QI 2 "nonimmediate_operand")))
7188               (set (match_operand:QI 3 "register_operand")
7189                    (mod:QI (match_dup 1) (match_dup 2)))
7190               (clobber (reg:CC FLAGS_REG))])]
7191   "TARGET_QIMODE_MATH"
7193   rtx div, mod, insn;
7194   rtx tmp0, tmp1;
7195   
7196   tmp0 = gen_reg_rtx (HImode);
7197   tmp1 = gen_reg_rtx (HImode);
7199   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7200      in AX.  */
7201   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7202   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7204   /* Extract remainder from AH.  */
7205   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7206   insn = emit_move_insn (operands[3], tmp1);
7208   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7209   set_unique_reg_note (insn, REG_EQUAL, mod);
7211   /* Extract quotient from AL.  */
7212   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7214   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7215   set_unique_reg_note (insn, REG_EQUAL, div);
7217   DONE;
7220 ;; Divide AX by r/m8, with result stored in
7221 ;; AL <- Quotient
7222 ;; AH <- Remainder
7223 ;; Change div/mod to HImode and extend the second argument to HImode
7224 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7225 ;; combine may fail.
7226 (define_insn "divmodhiqi3"
7227   [(set (match_operand:HI 0 "register_operand" "=a")
7228         (ior:HI
7229           (ashift:HI
7230             (zero_extend:HI
7231               (truncate:QI
7232                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7233                         (sign_extend:HI
7234                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7235             (const_int 8))
7236           (zero_extend:HI
7237             (truncate:QI
7238               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7239    (clobber (reg:CC FLAGS_REG))]
7240   "TARGET_QIMODE_MATH"
7241   "idiv{b}\t%2"
7242   [(set_attr "type" "idiv")
7243    (set_attr "mode" "QI")])
7245 (define_expand "udivmod<mode>4"
7246   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7247                    (udiv:SWIM248
7248                      (match_operand:SWIM248 1 "register_operand")
7249                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7250               (set (match_operand:SWIM248 3 "register_operand")
7251                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7252               (clobber (reg:CC FLAGS_REG))])])
7254 ;; Split with 8bit unsigned divide:
7255 ;;      if (dividend an divisor are in [0-255])
7256 ;;         use 8bit unsigned integer divide
7257 ;;       else
7258 ;;         use original integer divide
7259 (define_split
7260   [(set (match_operand:SWI48 0 "register_operand")
7261         (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7262                     (match_operand:SWI48 3 "nonimmediate_operand")))
7263    (set (match_operand:SWI48 1 "register_operand")
7264         (umod:SWI48 (match_dup 2) (match_dup 3)))
7265    (clobber (reg:CC FLAGS_REG))]
7266   "TARGET_USE_8BIT_IDIV
7267    && TARGET_QIMODE_MATH
7268    && can_create_pseudo_p ()
7269    && !optimize_insn_for_size_p ()"
7270   [(const_int 0)]
7271   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7273 (define_insn_and_split "udivmod<mode>4_1"
7274   [(set (match_operand:SWI48 0 "register_operand" "=a")
7275         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7276                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7277    (set (match_operand:SWI48 1 "register_operand" "=&d")
7278         (umod:SWI48 (match_dup 2) (match_dup 3)))
7279    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7280    (clobber (reg:CC FLAGS_REG))]
7281   ""
7282   "#"
7283   "reload_completed"
7284   [(set (match_dup 1) (const_int 0))
7285    (parallel [(set (match_dup 0)
7286                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7287               (set (match_dup 1)
7288                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7289               (use (match_dup 1))
7290               (clobber (reg:CC FLAGS_REG))])]
7291   ""
7292   [(set_attr "type" "multi")
7293    (set_attr "mode" "<MODE>")])
7295 (define_insn_and_split "*udivmod<mode>4"
7296   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7297         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7298                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7299    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7300         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7301    (clobber (reg:CC FLAGS_REG))]
7302   ""
7303   "#"
7304   "reload_completed"
7305   [(set (match_dup 1) (const_int 0))
7306    (parallel [(set (match_dup 0)
7307                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7308               (set (match_dup 1)
7309                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7310               (use (match_dup 1))
7311               (clobber (reg:CC FLAGS_REG))])]
7312   ""
7313   [(set_attr "type" "multi")
7314    (set_attr "mode" "<MODE>")])
7316 ;; Optimize division or modulo by constant power of 2, if the constant
7317 ;; materializes only after expansion.
7318 (define_insn_and_split "*udivmod<mode>4_pow2"
7319   [(set (match_operand:SWI48 0 "register_operand" "=r")
7320         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7321                     (match_operand:SWI48 3 "const_int_operand" "n")))
7322    (set (match_operand:SWI48 1 "register_operand" "=r")
7323         (umod:SWI48 (match_dup 2) (match_dup 3)))
7324    (clobber (reg:CC FLAGS_REG))]
7325   "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
7326    && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
7327   "#"
7328   "&& 1"
7329   [(set (match_dup 1) (match_dup 2))
7330    (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
7331               (clobber (reg:CC FLAGS_REG))])
7332    (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
7333               (clobber (reg:CC FLAGS_REG))])]
7335   int v = exact_log2 (UINTVAL (operands[3]));
7336   operands[4] = GEN_INT (v);
7337   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7339   [(set_attr "type" "multi")
7340    (set_attr "mode" "<MODE>")])
7342 (define_insn "*udivmod<mode>4_noext"
7343   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7344         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7345                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7346    (set (match_operand:SWIM248 1 "register_operand" "=d")
7347         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7348    (use (match_operand:SWIM248 4 "register_operand" "1"))
7349    (clobber (reg:CC FLAGS_REG))]
7350   ""
7351   "div{<imodesuffix>}\t%3"
7352   [(set_attr "type" "idiv")
7353    (set_attr "mode" "<MODE>")])
7355 (define_expand "udivmodqi4"
7356   [(parallel [(set (match_operand:QI 0 "register_operand")
7357                    (udiv:QI
7358                      (match_operand:QI 1 "register_operand")
7359                      (match_operand:QI 2 "nonimmediate_operand")))
7360               (set (match_operand:QI 3 "register_operand")
7361                    (umod:QI (match_dup 1) (match_dup 2)))
7362               (clobber (reg:CC FLAGS_REG))])]
7363   "TARGET_QIMODE_MATH"
7365   rtx div, mod, insn;
7366   rtx tmp0, tmp1;
7367   
7368   tmp0 = gen_reg_rtx (HImode);
7369   tmp1 = gen_reg_rtx (HImode);
7371   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7372      in AX.  */
7373   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7374   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7376   /* Extract remainder from AH.  */
7377   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7378   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7379   insn = emit_move_insn (operands[3], tmp1);
7381   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7382   set_unique_reg_note (insn, REG_EQUAL, mod);
7384   /* Extract quotient from AL.  */
7385   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7387   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7388   set_unique_reg_note (insn, REG_EQUAL, div);
7390   DONE;
7393 (define_insn "udivmodhiqi3"
7394   [(set (match_operand:HI 0 "register_operand" "=a")
7395         (ior:HI
7396           (ashift:HI
7397             (zero_extend:HI
7398               (truncate:QI
7399                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7400                         (zero_extend:HI
7401                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7402             (const_int 8))
7403           (zero_extend:HI
7404             (truncate:QI
7405               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7406    (clobber (reg:CC FLAGS_REG))]
7407   "TARGET_QIMODE_MATH"
7408   "div{b}\t%2"
7409   [(set_attr "type" "idiv")
7410    (set_attr "mode" "QI")])
7412 ;; We cannot use div/idiv for double division, because it causes
7413 ;; "division by zero" on the overflow and that's not what we expect
7414 ;; from truncate.  Because true (non truncating) double division is
7415 ;; never generated, we can't create this insn anyway.
7417 ;(define_insn ""
7418 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7419 ;       (truncate:SI
7420 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7421 ;                  (zero_extend:DI
7422 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7423 ;   (set (match_operand:SI 3 "register_operand" "=d")
7424 ;       (truncate:SI
7425 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7426 ;   (clobber (reg:CC FLAGS_REG))]
7427 ;  ""
7428 ;  "div{l}\t{%2, %0|%0, %2}"
7429 ;  [(set_attr "type" "idiv")])
7431 ;;- Logical AND instructions
7433 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7434 ;; Note that this excludes ah.
7436 (define_expand "testsi_ccno_1"
7437   [(set (reg:CCNO FLAGS_REG)
7438         (compare:CCNO
7439           (and:SI (match_operand:SI 0 "nonimmediate_operand")
7440                   (match_operand:SI 1 "x86_64_nonmemory_operand"))
7441           (const_int 0)))])
7443 (define_expand "testqi_ccz_1"
7444   [(set (reg:CCZ FLAGS_REG)
7445         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7446                              (match_operand:QI 1 "nonmemory_operand"))
7447                  (const_int 0)))])
7449 (define_expand "testdi_ccno_1"
7450   [(set (reg:CCNO FLAGS_REG)
7451         (compare:CCNO
7452           (and:DI (match_operand:DI 0 "nonimmediate_operand")
7453                   (match_operand:DI 1 "x86_64_szext_general_operand"))
7454           (const_int 0)))]
7455   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7457 (define_insn "*testdi_1"
7458   [(set (reg FLAGS_REG)
7459         (compare
7460          (and:DI
7461           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7462           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7463          (const_int 0)))]
7464   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7465    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7466   "@
7467    test{l}\t{%k1, %k0|%k0, %k1}
7468    test{l}\t{%k1, %k0|%k0, %k1}
7469    test{q}\t{%1, %0|%0, %1}
7470    test{q}\t{%1, %0|%0, %1}
7471    test{q}\t{%1, %0|%0, %1}"
7472   [(set_attr "type" "test")
7473    (set_attr "modrm" "0,1,0,1,1")
7474    (set_attr "mode" "SI,SI,DI,DI,DI")])
7476 (define_insn "*testqi_1_maybe_si"
7477   [(set (reg FLAGS_REG)
7478         (compare
7479           (and:QI
7480             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7481             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7482           (const_int 0)))]
7483    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7484     && ix86_match_ccmode (insn,
7485                          CONST_INT_P (operands[1])
7486                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7488   if (which_alternative == 3)
7489     {
7490       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7491         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7492       return "test{l}\t{%1, %k0|%k0, %1}";
7493     }
7494   return "test{b}\t{%1, %0|%0, %1}";
7496   [(set_attr "type" "test")
7497    (set_attr "modrm" "0,1,1,1")
7498    (set_attr "mode" "QI,QI,QI,SI")
7499    (set_attr "pent_pair" "uv,np,uv,np")])
7501 (define_insn "*test<mode>_1"
7502   [(set (reg FLAGS_REG)
7503         (compare
7504          (and:SWI124
7505           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7506           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7507          (const_int 0)))]
7508   "ix86_match_ccmode (insn, CCNOmode)
7509    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7510   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7511   [(set_attr "type" "test")
7512    (set_attr "modrm" "0,1,1")
7513    (set_attr "mode" "<MODE>")
7514    (set_attr "pent_pair" "uv,np,uv")])
7516 (define_expand "testqi_ext_ccno_0"
7517   [(set (reg:CCNO FLAGS_REG)
7518         (compare:CCNO
7519           (and:SI
7520             (zero_extract:SI
7521               (match_operand 0 "ext_register_operand")
7522               (const_int 8)
7523               (const_int 8))
7524             (match_operand 1 "const_int_operand"))
7525           (const_int 0)))])
7527 (define_insn "*testqi_ext_0"
7528   [(set (reg FLAGS_REG)
7529         (compare
7530           (and:SI
7531             (zero_extract:SI
7532               (match_operand 0 "ext_register_operand" "Q")
7533               (const_int 8)
7534               (const_int 8))
7535             (match_operand 1 "const_int_operand" "n"))
7536           (const_int 0)))]
7537   "ix86_match_ccmode (insn, CCNOmode)"
7538   "test{b}\t{%1, %h0|%h0, %1}"
7539   [(set_attr "type" "test")
7540    (set_attr "mode" "QI")
7541    (set_attr "length_immediate" "1")
7542    (set_attr "modrm" "1")
7543    (set_attr "pent_pair" "np")])
7545 (define_insn "*testqi_ext_1"
7546   [(set (reg FLAGS_REG)
7547         (compare
7548           (and:SI
7549             (zero_extract:SI
7550               (match_operand 0 "ext_register_operand" "Q,Q")
7551               (const_int 8)
7552               (const_int 8))
7553             (zero_extend:SI
7554               (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7555           (const_int 0)))]
7556   "ix86_match_ccmode (insn, CCNOmode)"
7557   "test{b}\t{%1, %h0|%h0, %1}"
7558   [(set_attr "isa" "*,nox64")
7559    (set_attr "type" "test")
7560    (set_attr "mode" "QI")])
7562 (define_insn "*testqi_ext_2"
7563   [(set (reg FLAGS_REG)
7564         (compare
7565           (and:SI
7566             (zero_extract:SI
7567               (match_operand 0 "ext_register_operand" "Q")
7568               (const_int 8)
7569               (const_int 8))
7570             (zero_extract:SI
7571               (match_operand 1 "ext_register_operand" "Q")
7572               (const_int 8)
7573               (const_int 8)))
7574           (const_int 0)))]
7575   "ix86_match_ccmode (insn, CCNOmode)"
7576   "test{b}\t{%h1, %h0|%h0, %h1}"
7577   [(set_attr "type" "test")
7578    (set_attr "mode" "QI")])
7580 ;; Combine likes to form bit extractions for some tests.  Humor it.
7581 (define_insn "*testqi_ext_3"
7582   [(set (reg FLAGS_REG)
7583         (compare (zero_extract:SWI48
7584                    (match_operand 0 "nonimmediate_operand" "rm")
7585                    (match_operand:SWI48 1 "const_int_operand")
7586                    (match_operand:SWI48 2 "const_int_operand"))
7587                  (const_int 0)))]
7588   "ix86_match_ccmode (insn, CCNOmode)
7589    && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7590        || GET_MODE (operands[0]) == SImode
7591        || GET_MODE (operands[0]) == HImode
7592        || GET_MODE (operands[0]) == QImode)
7593    /* Ensure that resulting mask is zero or sign extended operand.  */
7594    && INTVAL (operands[2]) >= 0
7595    && ((INTVAL (operands[1]) > 0
7596         && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7597        || (<MODE>mode == DImode
7598            && INTVAL (operands[1]) > 32
7599            && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7600   "#")
7602 (define_split
7603   [(set (match_operand 0 "flags_reg_operand")
7604         (match_operator 1 "compare_operator"
7605           [(zero_extract
7606              (match_operand 2 "nonimmediate_operand")
7607              (match_operand 3 "const_int_operand")
7608              (match_operand 4 "const_int_operand"))
7609            (const_int 0)]))]
7610   "ix86_match_ccmode (insn, CCNOmode)"
7611   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7613   rtx val = operands[2];
7614   HOST_WIDE_INT len = INTVAL (operands[3]);
7615   HOST_WIDE_INT pos = INTVAL (operands[4]);
7616   HOST_WIDE_INT mask;
7617   machine_mode mode, submode;
7619   mode = GET_MODE (val);
7620   if (MEM_P (val))
7621     {
7622       /* ??? Combine likes to put non-volatile mem extractions in QImode
7623          no matter the size of the test.  So find a mode that works.  */
7624       if (! MEM_VOLATILE_P (val))
7625         {
7626           mode = smallest_mode_for_size (pos + len, MODE_INT);
7627           val = adjust_address (val, mode, 0);
7628         }
7629     }
7630   else if (GET_CODE (val) == SUBREG
7631            && (submode = GET_MODE (SUBREG_REG (val)),
7632                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7633            && pos + len <= GET_MODE_BITSIZE (submode)
7634            && GET_MODE_CLASS (submode) == MODE_INT)
7635     {
7636       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7637       mode = submode;
7638       val = SUBREG_REG (val);
7639     }
7640   else if (mode == HImode && pos + len <= 8)
7641     {
7642       /* Small HImode tests can be converted to QImode.  */
7643       mode = QImode;
7644       val = gen_lowpart (QImode, val);
7645     }
7647   if (len == HOST_BITS_PER_WIDE_INT)
7648     mask = -1;
7649   else
7650     mask = ((HOST_WIDE_INT)1 << len) - 1;
7651   mask <<= pos;
7653   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7656 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7657 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7658 ;; this is relatively important trick.
7659 ;; Do the conversion only post-reload to avoid limiting of the register class
7660 ;; to QI regs.
7661 (define_split
7662   [(set (match_operand 0 "flags_reg_operand")
7663         (match_operator 1 "compare_operator"
7664           [(and (match_operand 2 "QIreg_operand")
7665                 (match_operand 3 "const_int_operand"))
7666            (const_int 0)]))]
7667    "reload_completed
7668     && GET_MODE (operands[2]) != QImode
7669     && ((ix86_match_ccmode (insn, CCZmode)
7670          && !(INTVAL (operands[3]) & ~(255 << 8)))
7671         || (ix86_match_ccmode (insn, CCNOmode)
7672             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7673   [(set (match_dup 0)
7674         (match_op_dup 1
7675           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7676                    (match_dup 3))
7677            (const_int 0)]))]
7679   operands[2] = gen_lowpart (SImode, operands[2]);
7680   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7683 (define_split
7684   [(set (match_operand 0 "flags_reg_operand")
7685         (match_operator 1 "compare_operator"
7686           [(and (match_operand 2 "nonimmediate_operand")
7687                 (match_operand 3 "const_int_operand"))
7688            (const_int 0)]))]
7689    "reload_completed
7690     && GET_MODE (operands[2]) != QImode
7691     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7692     && ((ix86_match_ccmode (insn, CCZmode)
7693          && !(INTVAL (operands[3]) & ~255))
7694         || (ix86_match_ccmode (insn, CCNOmode)
7695             && !(INTVAL (operands[3]) & ~127)))"
7696   [(set (match_dup 0)
7697         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7698                          (const_int 0)]))]
7700   operands[2] = gen_lowpart (QImode, operands[2]);
7701   operands[3] = gen_lowpart (QImode, operands[3]);
7704 (define_split
7705   [(set (match_operand:SWI1248x 0 "mask_reg_operand")
7706         (any_logic:SWI1248x (match_operand:SWI1248x 1 "mask_reg_operand")
7707                             (match_operand:SWI1248x 2 "mask_reg_operand")))
7708    (clobber (reg:CC FLAGS_REG))]
7709   "TARGET_AVX512F && reload_completed"
7710   [(set (match_dup 0)
7711         (any_logic:SWI1248x (match_dup 1)
7712                             (match_dup 2)))])
7714 (define_insn "*k<logic><mode>"
7715   [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand" "=k")
7716         (any_logic:SWI1248_AVX512BW (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand" "k")
7717                           (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand" "k")))]
7718   "TARGET_AVX512F"
7719   {
7720     if (!TARGET_AVX512DQ && <MODE>mode == QImode)
7721       return "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7722     else
7723       return "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
7724   }
7725   [(set_attr "mode" "<MODE>")
7726    (set_attr "type" "msklog")
7727    (set_attr "prefix" "vex")])
7729 ;; %%% This used to optimize known byte-wide and operations to memory,
7730 ;; and sometimes to QImode registers.  If this is considered useful,
7731 ;; it should be done with splitters.
7733 (define_expand "and<mode>3"
7734   [(set (match_operand:SWIM 0 "nonimmediate_operand")
7735         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7736                   (match_operand:SWIM 2 "<general_szext_operand>")))]
7737   ""
7739   machine_mode mode = <MODE>mode;
7740   rtx (*insn) (rtx, rtx);
7742   if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7743     {
7744       HOST_WIDE_INT ival = INTVAL (operands[2]);
7746       if (ival == (HOST_WIDE_INT) 0xffffffff)
7747         mode = SImode;
7748       else if (ival == 0xffff)
7749         mode = HImode;
7750       else if (ival == 0xff)
7751         mode = QImode;
7752       }
7754   if (mode == <MODE>mode)
7755     {
7756       ix86_expand_binary_operator (AND, <MODE>mode, operands);
7757       DONE;
7758     }
7760   if (<MODE>mode == DImode)
7761     insn = (mode == SImode)
7762            ? gen_zero_extendsidi2
7763            : (mode == HImode)
7764            ? gen_zero_extendhidi2
7765            : gen_zero_extendqidi2;
7766   else if (<MODE>mode == SImode)
7767     insn = (mode == HImode)
7768            ? gen_zero_extendhisi2
7769            : gen_zero_extendqisi2;
7770   else if (<MODE>mode == HImode)
7771     insn = gen_zero_extendqihi2;
7772   else
7773     gcc_unreachable ();
7775   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7776   DONE;
7779 (define_insn "*anddi_1"
7780   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,!k")
7781         (and:DI
7782          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
7783          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L,k")))
7784    (clobber (reg:CC FLAGS_REG))]
7785   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7787   switch (get_attr_type (insn))
7788     {
7789     case TYPE_IMOVX:
7790       return "#";
7792     case TYPE_MSKLOG:
7793       return "kandq\t{%2, %1, %0|%0, %1, %2}";
7795     default:
7796       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7797       if (get_attr_mode (insn) == MODE_SI)
7798         return "and{l}\t{%k2, %k0|%k0, %k2}";
7799       else
7800         return "and{q}\t{%2, %0|%0, %2}";
7801     }
7803   [(set_attr "type" "alu,alu,alu,imovx,msklog")
7804    (set_attr "length_immediate" "*,*,*,0,0")
7805    (set (attr "prefix_rex")
7806      (if_then_else
7807        (and (eq_attr "type" "imovx")
7808             (and (match_test "INTVAL (operands[2]) == 0xff")
7809                  (match_operand 1 "ext_QIreg_operand")))
7810        (const_string "1")
7811        (const_string "*")))
7812    (set_attr "mode" "SI,DI,DI,SI,DI")])
7814 (define_insn "*andsi_1"
7815   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7816         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm,k")
7817                 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L,k")))
7818    (clobber (reg:CC FLAGS_REG))]
7819   "ix86_binary_operator_ok (AND, SImode, operands)"
7821   switch (get_attr_type (insn))
7822     {
7823     case TYPE_IMOVX:
7824       return "#";
7826     case TYPE_MSKLOG:
7827       return "kandd\t{%2, %1, %0|%0, %1, %2}";
7829     default:
7830       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7831       return "and{l}\t{%2, %0|%0, %2}";
7832     }
7834   [(set_attr "type" "alu,alu,imovx,msklog")
7835    (set (attr "prefix_rex")
7836      (if_then_else
7837        (and (eq_attr "type" "imovx")
7838             (and (match_test "INTVAL (operands[2]) == 0xff")
7839                  (match_operand 1 "ext_QIreg_operand")))
7840        (const_string "1")
7841        (const_string "*")))
7842    (set_attr "length_immediate" "*,*,0,0")
7843    (set_attr "mode" "SI")])
7845 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7846 (define_insn "*andsi_1_zext"
7847   [(set (match_operand:DI 0 "register_operand" "=r")
7848         (zero_extend:DI
7849           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7850                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7851    (clobber (reg:CC FLAGS_REG))]
7852   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7853   "and{l}\t{%2, %k0|%k0, %2}"
7854   [(set_attr "type" "alu")
7855    (set_attr "mode" "SI")])
7857 (define_insn "*andhi_1"
7858   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7859         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k")
7860                 (match_operand:HI 2 "general_operand" "rn,rm,L,k")))
7861    (clobber (reg:CC FLAGS_REG))]
7862   "ix86_binary_operator_ok (AND, HImode, operands)"
7864   switch (get_attr_type (insn))
7865     {
7866     case TYPE_IMOVX:
7867       return "#";
7869     case TYPE_MSKLOG:
7870       return "kandw\t{%2, %1, %0|%0, %1, %2}";
7872     default:
7873       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7874       return "and{w}\t{%2, %0|%0, %2}";
7875     }
7877   [(set_attr "type" "alu,alu,imovx,msklog")
7878    (set_attr "length_immediate" "*,*,0,*")
7879    (set (attr "prefix_rex")
7880      (if_then_else
7881        (and (eq_attr "type" "imovx")
7882             (match_operand 1 "ext_QIreg_operand"))
7883        (const_string "1")
7884        (const_string "*")))
7885    (set_attr "mode" "HI,HI,SI,HI")])
7887 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7888 (define_insn "*andqi_1"
7889   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
7890         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
7891                 (match_operand:QI 2 "general_operand" "qn,qmn,rn,k")))
7892    (clobber (reg:CC FLAGS_REG))]
7893   "ix86_binary_operator_ok (AND, QImode, operands)"
7895   switch (which_alternative)
7896     {
7897     case 0:
7898     case 1:
7899       return "and{b}\t{%2, %0|%0, %2}";
7900     case 2:
7901       return "and{l}\t{%k2, %k0|%k0, %k2}";
7902     case 3:
7903       return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}"
7904                              : "kandw\t{%2, %1, %0|%0, %1, %2}";
7905     default:
7906       gcc_unreachable ();
7907     }
7909   [(set_attr "type" "alu,alu,alu,msklog")
7910    (set_attr "mode" "QI,QI,SI,HI")])
7912 (define_insn "*andqi_1_slp"
7913   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7914         (and:QI (match_dup 0)
7915                 (match_operand:QI 1 "general_operand" "qn,qmn")))
7916    (clobber (reg:CC FLAGS_REG))]
7917   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7918    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7919   "and{b}\t{%1, %0|%0, %1}"
7920   [(set_attr "type" "alu1")
7921    (set_attr "mode" "QI")])
7923 (define_insn "kandn<mode>"
7924   [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k")
7925         (and:SWI12
7926           (not:SWI12
7927             (match_operand:SWI12 1 "register_operand" "r,0,k"))
7928           (match_operand:SWI12 2 "register_operand" "r,r,k")))
7929    (clobber (reg:CC FLAGS_REG))]
7930   "TARGET_AVX512F"
7932   switch (which_alternative)
7933     {
7934     case 0:
7935       return "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}";
7936     case 1:
7937       return "#";
7938     case 2:
7939       if (TARGET_AVX512DQ && <MODE>mode == QImode)
7940         return "kandnb\t{%2, %1, %0|%0, %1, %2}";
7941       else
7942         return "kandnw\t{%2, %1, %0|%0, %1, %2}";
7943     default:
7944       gcc_unreachable ();
7945     }
7947   [(set_attr "isa" "bmi,*,avx512f")
7948    (set_attr "type" "bitmanip,*,msklog")
7949    (set_attr "prefix" "*,*,vex")
7950    (set_attr "btver2_decode" "direct,*,*")
7951    (set_attr "mode" "<MODE>")])
7953 (define_split
7954   [(set (match_operand:SWI12 0 "general_reg_operand")
7955         (and:SWI12
7956           (not:SWI12
7957             (match_dup 0))
7958           (match_operand:SWI12 1 "general_reg_operand")))
7959    (clobber (reg:CC FLAGS_REG))]
7960   "TARGET_AVX512F && !TARGET_BMI && reload_completed"
7961   [(set (match_dup 0)
7962         (not:HI (match_dup 0)))
7963    (parallel [(set (match_dup 0)
7964                    (and:HI (match_dup 0)
7965                            (match_dup 1)))
7966               (clobber (reg:CC FLAGS_REG))])])
7968 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7969 (define_split
7970   [(set (match_operand:DI 0 "register_operand")
7971         (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7972                 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7973    (clobber (reg:CC FLAGS_REG))]
7974   "TARGET_64BIT"
7975   [(parallel [(set (match_dup 0)
7976                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7977               (clobber (reg:CC FLAGS_REG))])]
7978   "operands[2] = gen_lowpart (SImode, operands[2]);")
7980 (define_split
7981   [(set (match_operand:SWI248 0 "register_operand")
7982         (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7983                     (match_operand:SWI248 2 "const_int_operand")))
7984    (clobber (reg:CC FLAGS_REG))]
7985   "reload_completed
7986    && true_regnum (operands[0]) != true_regnum (operands[1])"
7987   [(const_int 0)]
7989   HOST_WIDE_INT ival = INTVAL (operands[2]);
7990   machine_mode mode;
7991   rtx (*insn) (rtx, rtx);
7993   if (ival == (HOST_WIDE_INT) 0xffffffff)
7994     mode = SImode;
7995   else if (ival == 0xffff)
7996     mode = HImode;
7997   else
7998     {
7999       gcc_assert (ival == 0xff);
8000       mode = QImode;
8001     }
8003   if (<MODE>mode == DImode)
8004     insn = (mode == SImode)
8005            ? gen_zero_extendsidi2
8006            : (mode == HImode)
8007            ? gen_zero_extendhidi2
8008            : gen_zero_extendqidi2;
8009   else
8010     {
8011       if (<MODE>mode != SImode)
8012         /* Zero extend to SImode to avoid partial register stalls.  */
8013         operands[0] = gen_lowpart (SImode, operands[0]);
8015       insn = (mode == HImode)
8016              ? gen_zero_extendhisi2
8017              : gen_zero_extendqisi2;
8018     }
8019   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8020   DONE;
8023 (define_split
8024   [(set (match_operand:SWI48 0 "register_operand")
8025         (and:SWI48 (match_dup 0)
8026                    (const_int -65536)))
8027    (clobber (reg:CC FLAGS_REG))]
8028   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8029     || optimize_function_for_size_p (cfun)"
8030   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8031   "operands[1] = gen_lowpart (HImode, operands[0]);")
8033 (define_split
8034   [(set (match_operand:SWI248 0 "any_QIreg_operand")
8035         (and:SWI248 (match_dup 0)
8036                     (const_int -256)))
8037    (clobber (reg:CC FLAGS_REG))]
8038   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8039    && reload_completed"
8040   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8041   "operands[1] = gen_lowpart (QImode, operands[0]);")
8043 (define_split
8044   [(set (match_operand:SWI248 0 "QIreg_operand")
8045         (and:SWI248 (match_dup 0)
8046                     (const_int -65281)))
8047    (clobber (reg:CC FLAGS_REG))]
8048   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8049    && reload_completed"
8050   [(parallel [(set (zero_extract:SI (match_dup 0)
8051                                     (const_int 8)
8052                                     (const_int 8))
8053                    (xor:SI
8054                      (zero_extract:SI (match_dup 0)
8055                                       (const_int 8)
8056                                       (const_int 8))
8057                      (zero_extract:SI (match_dup 0)
8058                                       (const_int 8)
8059                                       (const_int 8))))
8060               (clobber (reg:CC FLAGS_REG))])]
8061   "operands[0] = gen_lowpart (SImode, operands[0]);")
8063 (define_insn "*anddi_2"
8064   [(set (reg FLAGS_REG)
8065         (compare
8066          (and:DI
8067           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8068           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8069          (const_int 0)))
8070    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8071         (and:DI (match_dup 1) (match_dup 2)))]
8072   "TARGET_64BIT
8073    && ix86_match_ccmode
8074         (insn,
8075          /* If we are going to emit andl instead of andq, and the operands[2]
8076             constant might have the SImode sign bit set, make sure the sign
8077             flag isn't tested, because the instruction will set the sign flag
8078             based on bit 31 rather than bit 63.  If it isn't CONST_INT,
8079             conservatively assume it might have bit 31 set.  */
8080          (satisfies_constraint_Z (operands[2])
8081           && (!CONST_INT_P (operands[2])
8082               || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8083          ? CCZmode : CCNOmode)
8084    && ix86_binary_operator_ok (AND, DImode, operands)"
8085   "@
8086    and{l}\t{%k2, %k0|%k0, %k2}
8087    and{q}\t{%2, %0|%0, %2}
8088    and{q}\t{%2, %0|%0, %2}"
8089   [(set_attr "type" "alu")
8090    (set_attr "mode" "SI,DI,DI")])
8092 (define_insn "*andqi_2_maybe_si"
8093   [(set (reg FLAGS_REG)
8094         (compare (and:QI
8095                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8096                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8097                  (const_int 0)))
8098    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8099         (and:QI (match_dup 1) (match_dup 2)))]
8100   "ix86_binary_operator_ok (AND, QImode, operands)
8101    && ix86_match_ccmode (insn,
8102                          CONST_INT_P (operands[2])
8103                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8105   if (which_alternative == 2)
8106     {
8107       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8108         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8109       return "and{l}\t{%2, %k0|%k0, %2}";
8110     }
8111   return "and{b}\t{%2, %0|%0, %2}";
8113   [(set_attr "type" "alu")
8114    (set_attr "mode" "QI,QI,SI")])
8116 (define_insn "*and<mode>_2"
8117   [(set (reg FLAGS_REG)
8118         (compare (and:SWI124
8119                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8120                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8121                  (const_int 0)))
8122    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8123         (and:SWI124 (match_dup 1) (match_dup 2)))]
8124   "ix86_match_ccmode (insn, CCNOmode)
8125    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8126   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8127   [(set_attr "type" "alu")
8128    (set_attr "mode" "<MODE>")])
8130 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8131 (define_insn "*andsi_2_zext"
8132   [(set (reg FLAGS_REG)
8133         (compare (and:SI
8134                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8135                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
8136                  (const_int 0)))
8137    (set (match_operand:DI 0 "register_operand" "=r")
8138         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8139   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8140    && ix86_binary_operator_ok (AND, SImode, operands)"
8141   "and{l}\t{%2, %k0|%k0, %2}"
8142   [(set_attr "type" "alu")
8143    (set_attr "mode" "SI")])
8145 (define_insn "*andqi_2_slp"
8146   [(set (reg FLAGS_REG)
8147         (compare (and:QI
8148                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8149                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8150                  (const_int 0)))
8151    (set (strict_low_part (match_dup 0))
8152         (and:QI (match_dup 0) (match_dup 1)))]
8153   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8154    && ix86_match_ccmode (insn, CCNOmode)
8155    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8156   "and{b}\t{%1, %0|%0, %1}"
8157   [(set_attr "type" "alu1")
8158    (set_attr "mode" "QI")])
8160 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8161 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8162 ;; for a QImode operand, which of course failed.
8163 (define_insn "andqi_ext_0"
8164   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8165                          (const_int 8)
8166                          (const_int 8))
8167         (and:SI
8168           (zero_extract:SI
8169             (match_operand 1 "ext_register_operand" "0")
8170             (const_int 8)
8171             (const_int 8))
8172           (match_operand 2 "const_int_operand" "n")))
8173    (clobber (reg:CC FLAGS_REG))]
8174   ""
8175   "and{b}\t{%2, %h0|%h0, %2}"
8176   [(set_attr "type" "alu")
8177    (set_attr "length_immediate" "1")
8178    (set_attr "modrm" "1")
8179    (set_attr "mode" "QI")])
8181 ;; Generated by peephole translating test to and.  This shows up
8182 ;; often in fp comparisons.
8183 (define_insn "*andqi_ext_0_cc"
8184   [(set (reg FLAGS_REG)
8185         (compare
8186           (and:SI
8187             (zero_extract:SI
8188               (match_operand 1 "ext_register_operand" "0")
8189               (const_int 8)
8190               (const_int 8))
8191             (match_operand 2 "const_int_operand" "n"))
8192           (const_int 0)))
8193    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8194                          (const_int 8)
8195                          (const_int 8))
8196         (and:SI
8197           (zero_extract:SI
8198             (match_dup 1)
8199             (const_int 8)
8200             (const_int 8))
8201           (match_dup 2)))]
8202   "ix86_match_ccmode (insn, CCNOmode)"
8203   "and{b}\t{%2, %h0|%h0, %2}"
8204   [(set_attr "type" "alu")
8205    (set_attr "length_immediate" "1")
8206    (set_attr "modrm" "1")
8207    (set_attr "mode" "QI")])
8209 (define_insn "*andqi_ext_1"
8210   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8211                          (const_int 8)
8212                          (const_int 8))
8213         (and:SI
8214           (zero_extract:SI
8215             (match_operand 1 "ext_register_operand" "0,0")
8216             (const_int 8)
8217             (const_int 8))
8218           (zero_extend:SI
8219             (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8220    (clobber (reg:CC FLAGS_REG))]
8221   ""
8222   "and{b}\t{%2, %h0|%h0, %2}"
8223   [(set_attr "isa" "*,nox64")
8224    (set_attr "type" "alu")
8225    (set_attr "length_immediate" "0")
8226    (set_attr "mode" "QI")])
8228 (define_insn "*andqi_ext_2"
8229   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8230                          (const_int 8)
8231                          (const_int 8))
8232         (and:SI
8233           (zero_extract:SI
8234             (match_operand 1 "ext_register_operand" "%0")
8235             (const_int 8)
8236             (const_int 8))
8237           (zero_extract:SI
8238             (match_operand 2 "ext_register_operand" "Q")
8239             (const_int 8)
8240             (const_int 8))))
8241    (clobber (reg:CC FLAGS_REG))]
8242   ""
8243   "and{b}\t{%h2, %h0|%h0, %h2}"
8244   [(set_attr "type" "alu")
8245    (set_attr "length_immediate" "0")
8246    (set_attr "mode" "QI")])
8248 ;; Convert wide AND instructions with immediate operand to shorter QImode
8249 ;; equivalents when possible.
8250 ;; Don't do the splitting with memory operands, since it introduces risk
8251 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8252 ;; for size, but that can (should?) be handled by generic code instead.
8253 (define_split
8254   [(set (match_operand 0 "QIreg_operand")
8255         (and (match_operand 1 "register_operand")
8256              (match_operand 2 "const_int_operand")))
8257    (clobber (reg:CC FLAGS_REG))]
8258    "reload_completed
8259     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8260     && !(~INTVAL (operands[2]) & ~(255 << 8))
8261     && GET_MODE (operands[0]) != QImode"
8262   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8263                    (and:SI (zero_extract:SI (match_dup 1)
8264                                             (const_int 8) (const_int 8))
8265                            (match_dup 2)))
8266               (clobber (reg:CC FLAGS_REG))])]
8268   operands[0] = gen_lowpart (SImode, operands[0]);
8269   operands[1] = gen_lowpart (SImode, operands[1]);
8270   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8273 ;; Since AND can be encoded with sign extended immediate, this is only
8274 ;; profitable when 7th bit is not set.
8275 (define_split
8276   [(set (match_operand 0 "any_QIreg_operand")
8277         (and (match_operand 1 "general_operand")
8278              (match_operand 2 "const_int_operand")))
8279    (clobber (reg:CC FLAGS_REG))]
8280    "reload_completed
8281     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8282     && !(~INTVAL (operands[2]) & ~255)
8283     && !(INTVAL (operands[2]) & 128)
8284     && GET_MODE (operands[0]) != QImode"
8285   [(parallel [(set (strict_low_part (match_dup 0))
8286                    (and:QI (match_dup 1)
8287                            (match_dup 2)))
8288               (clobber (reg:CC FLAGS_REG))])]
8290   operands[0] = gen_lowpart (QImode, operands[0]);
8291   operands[1] = gen_lowpart (QImode, operands[1]);
8292   operands[2] = gen_lowpart (QImode, operands[2]);
8295 ;; Logical inclusive and exclusive OR instructions
8297 ;; %%% This used to optimize known byte-wide and operations to memory.
8298 ;; If this is considered useful, it should be done with splitters.
8300 (define_expand "<code><mode>3"
8301   [(set (match_operand:SWIM 0 "nonimmediate_operand")
8302         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8303                      (match_operand:SWIM 2 "<general_operand>")))]
8304   ""
8305   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8307 (define_insn "*<code><mode>_1"
8308   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,k")
8309         (any_or:SWI48
8310          (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,k")
8311          (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,k")))
8312    (clobber (reg:CC FLAGS_REG))]
8313   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8314   "@
8315    <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8316    <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8317    k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8318   [(set_attr "type" "alu,alu,msklog")
8319    (set_attr "mode" "<MODE>")])
8321 (define_insn "*<code>hi_1"
8322   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
8323         (any_or:HI
8324          (match_operand:HI 1 "nonimmediate_operand" "%0,0,k")
8325          (match_operand:HI 2 "general_operand" "<g>,r<i>,k")))
8326    (clobber (reg:CC FLAGS_REG))]
8327   "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8328   "@
8329   <logic>{w}\t{%2, %0|%0, %2}
8330   <logic>{w}\t{%2, %0|%0, %2}
8331   k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8332   [(set_attr "type" "alu,alu,msklog")
8333    (set_attr "mode" "HI")])
8335 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8336 (define_insn "*<code>qi_1"
8337   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
8338         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8339                    (match_operand:QI 2 "general_operand" "qmn,qn,rn,k")))
8340    (clobber (reg:CC FLAGS_REG))]
8341   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8342   "@
8343    <logic>{b}\t{%2, %0|%0, %2}
8344    <logic>{b}\t{%2, %0|%0, %2}
8345    <logic>{l}\t{%k2, %k0|%k0, %k2}
8346    k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8347   [(set_attr "type" "alu,alu,alu,msklog")
8348    (set_attr "mode" "QI,QI,SI,HI")])
8350 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8351 (define_insn "*<code>si_1_zext"
8352   [(set (match_operand:DI 0 "register_operand" "=r")
8353         (zero_extend:DI
8354          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8355                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8356    (clobber (reg:CC FLAGS_REG))]
8357   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8358   "<logic>{l}\t{%2, %k0|%k0, %2}"
8359   [(set_attr "type" "alu")
8360    (set_attr "mode" "SI")])
8362 (define_insn "*<code>si_1_zext_imm"
8363   [(set (match_operand:DI 0 "register_operand" "=r")
8364         (any_or:DI
8365          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8366          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8367    (clobber (reg:CC FLAGS_REG))]
8368   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8369   "<logic>{l}\t{%2, %k0|%k0, %2}"
8370   [(set_attr "type" "alu")
8371    (set_attr "mode" "SI")])
8373 (define_insn "*<code>qi_1_slp"
8374   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8375         (any_or:QI (match_dup 0)
8376                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8377    (clobber (reg:CC FLAGS_REG))]
8378   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8379    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8380   "<logic>{b}\t{%1, %0|%0, %1}"
8381   [(set_attr "type" "alu1")
8382    (set_attr "mode" "QI")])
8384 (define_insn "*<code><mode>_2"
8385   [(set (reg FLAGS_REG)
8386         (compare (any_or:SWI
8387                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8388                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8389                  (const_int 0)))
8390    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8391         (any_or:SWI (match_dup 1) (match_dup 2)))]
8392   "ix86_match_ccmode (insn, CCNOmode)
8393    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8394   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8395   [(set_attr "type" "alu")
8396    (set_attr "mode" "<MODE>")])
8398 (define_insn "kxnor<mode>"
8399   [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
8400         (not:SWI12
8401           (xor:SWI12
8402             (match_operand:SWI12 1 "register_operand" "0,k")
8403             (match_operand:SWI12 2 "register_operand" "r,k"))))
8404    (clobber (reg:CC FLAGS_REG))]
8405   "TARGET_AVX512F"
8407   if (which_alternative == 1 && <MODE>mode == QImode && TARGET_AVX512DQ)
8408     return "kxnorb\t{%2, %1, %0|%0, %1, %2}";
8409   return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
8411   [(set_attr "type" "*,msklog")
8412    (set_attr "prefix" "*,vex")
8413    (set_attr "mode" "<MODE>")])
8415 (define_insn "kxnor<mode>"
8416   [(set (match_operand:SWI48x 0 "register_operand" "=r,!k")
8417         (not:SWI48x
8418           (xor:SWI48x
8419             (match_operand:SWI48x 1 "register_operand" "0,k")
8420             (match_operand:SWI48x 2 "register_operand" "r,k"))))
8421    (clobber (reg:CC FLAGS_REG))]
8422   "TARGET_AVX512BW"
8423   "@
8424    #
8425    kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8426   [(set_attr "type" "*,msklog")
8427    (set_attr "prefix" "*,vex")
8428    (set_attr "mode" "<MODE>")])
8430 (define_split
8431   [(set (match_operand:SWI1248x 0 "general_reg_operand")
8432         (not:SWI1248x
8433           (xor:SWI1248x
8434             (match_dup 0)
8435             (match_operand:SWI1248x 1 "general_reg_operand"))))
8436    (clobber (reg:CC FLAGS_REG))]
8437   "TARGET_AVX512F && reload_completed"
8438    [(parallel [(set (match_dup 0)
8439                     (xor:HI (match_dup 0)
8440                             (match_dup 1)))
8441                (clobber (reg:CC FLAGS_REG))])
8442     (set (match_dup 0)
8443          (not:HI (match_dup 0)))])
8445 ;;There are kortrest[bdq] but no intrinsics for them.
8446 ;;We probably don't need to implement them.
8447 (define_insn "kortestzhi"
8448   [(set (reg:CCZ FLAGS_REG)
8449         (compare:CCZ
8450           (ior:HI
8451             (match_operand:HI 0 "register_operand" "k")
8452             (match_operand:HI 1 "register_operand" "k"))
8453           (const_int 0)))]
8454   "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8455   "kortestw\t{%1, %0|%0, %1}"
8456   [(set_attr "mode" "HI")
8457    (set_attr "type" "msklog")
8458    (set_attr "prefix" "vex")])
8460 (define_insn "kortestchi"
8461   [(set (reg:CCC FLAGS_REG)
8462         (compare:CCC
8463           (ior:HI
8464             (match_operand:HI 0 "register_operand" "k")
8465             (match_operand:HI 1 "register_operand" "k"))
8466           (const_int -1)))]
8467   "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8468   "kortestw\t{%1, %0|%0, %1}"
8469   [(set_attr "mode" "HI")
8470    (set_attr "type" "msklog")
8471    (set_attr "prefix" "vex")])
8473 (define_insn "kunpckhi"
8474   [(set (match_operand:HI 0 "register_operand" "=k")
8475         (ior:HI
8476           (ashift:HI
8477             (match_operand:HI 1 "register_operand" "k")
8478             (const_int 8))
8479           (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
8480   "TARGET_AVX512F"
8481   "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8482   [(set_attr "mode" "HI")
8483    (set_attr "type" "msklog")
8484    (set_attr "prefix" "vex")])
8486 (define_insn "kunpcksi"
8487   [(set (match_operand:SI 0 "register_operand" "=k")
8488         (ior:SI
8489           (ashift:SI
8490             (match_operand:SI 1 "register_operand" "k")
8491             (const_int 16))
8492           (zero_extend:SI (subreg:HI (match_operand:SI 2 "register_operand" "k") 0))))]
8493   "TARGET_AVX512BW"
8494   "kunpckwd\t{%2, %1, %0|%0, %1, %2}"
8495   [(set_attr "mode" "SI")])
8497 (define_insn "kunpckdi"
8498   [(set (match_operand:DI 0 "register_operand" "=k")
8499         (ior:DI
8500           (ashift:DI
8501             (match_operand:DI 1 "register_operand" "k")
8502             (const_int 32))
8503           (zero_extend:DI (subreg:SI (match_operand:DI 2 "register_operand" "k") 0))))]
8504   "TARGET_AVX512BW"
8505   "kunpckdq\t{%2, %1, %0|%0, %1, %2}"
8506   [(set_attr "mode" "DI")])
8508 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8509 ;; ??? Special case for immediate operand is missing - it is tricky.
8510 (define_insn "*<code>si_2_zext"
8511   [(set (reg FLAGS_REG)
8512         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8513                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
8514                  (const_int 0)))
8515    (set (match_operand:DI 0 "register_operand" "=r")
8516         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8517   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8518    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8519   "<logic>{l}\t{%2, %k0|%k0, %2}"
8520   [(set_attr "type" "alu")
8521    (set_attr "mode" "SI")])
8523 (define_insn "*<code>si_2_zext_imm"
8524   [(set (reg FLAGS_REG)
8525         (compare (any_or:SI
8526                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8527                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8528                  (const_int 0)))
8529    (set (match_operand:DI 0 "register_operand" "=r")
8530         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8531   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8532    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8533   "<logic>{l}\t{%2, %k0|%k0, %2}"
8534   [(set_attr "type" "alu")
8535    (set_attr "mode" "SI")])
8537 (define_insn "*<code>qi_2_slp"
8538   [(set (reg FLAGS_REG)
8539         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8540                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8541                  (const_int 0)))
8542    (set (strict_low_part (match_dup 0))
8543         (any_or:QI (match_dup 0) (match_dup 1)))]
8544   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8545    && ix86_match_ccmode (insn, CCNOmode)
8546    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8547   "<logic>{b}\t{%1, %0|%0, %1}"
8548   [(set_attr "type" "alu1")
8549    (set_attr "mode" "QI")])
8551 (define_insn "*<code><mode>_3"
8552   [(set (reg FLAGS_REG)
8553         (compare (any_or:SWI
8554                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8555                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8556                  (const_int 0)))
8557    (clobber (match_scratch:SWI 0 "=<r>"))]
8558   "ix86_match_ccmode (insn, CCNOmode)
8559    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8560   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8561   [(set_attr "type" "alu")
8562    (set_attr "mode" "<MODE>")])
8564 (define_insn "*<code>qi_ext_0"
8565   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8566                          (const_int 8)
8567                          (const_int 8))
8568         (any_or:SI
8569           (zero_extract:SI
8570             (match_operand 1 "ext_register_operand" "0")
8571             (const_int 8)
8572             (const_int 8))
8573           (match_operand 2 "const_int_operand" "n")))
8574    (clobber (reg:CC FLAGS_REG))]
8575   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8576   "<logic>{b}\t{%2, %h0|%h0, %2}"
8577   [(set_attr "type" "alu")
8578    (set_attr "length_immediate" "1")
8579    (set_attr "modrm" "1")
8580    (set_attr "mode" "QI")])
8582 (define_insn "*<code>qi_ext_1"
8583   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8584                          (const_int 8)
8585                          (const_int 8))
8586         (any_or:SI
8587           (zero_extract:SI
8588             (match_operand 1 "ext_register_operand" "0,0")
8589             (const_int 8)
8590             (const_int 8))
8591           (zero_extend:SI
8592             (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8593    (clobber (reg:CC FLAGS_REG))]
8594   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8595   "<logic>{b}\t{%2, %h0|%h0, %2}"
8596   [(set_attr "isa" "*,nox64")
8597    (set_attr "type" "alu")
8598    (set_attr "length_immediate" "0")
8599    (set_attr "mode" "QI")])
8601 (define_insn "*<code>qi_ext_2"
8602   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8603                          (const_int 8)
8604                          (const_int 8))
8605         (any_or:SI
8606           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8607                            (const_int 8)
8608                            (const_int 8))
8609           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8610                            (const_int 8)
8611                            (const_int 8))))
8612    (clobber (reg:CC FLAGS_REG))]
8613   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8614   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8615   [(set_attr "type" "alu")
8616    (set_attr "length_immediate" "0")
8617    (set_attr "mode" "QI")])
8619 (define_split
8620   [(set (match_operand 0 "QIreg_operand")
8621         (any_or (match_operand 1 "register_operand")
8622                 (match_operand 2 "const_int_operand")))
8623    (clobber (reg:CC FLAGS_REG))]
8624    "reload_completed
8625     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8626     && !(INTVAL (operands[2]) & ~(255 << 8))
8627     && GET_MODE (operands[0]) != QImode"
8628   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8629                    (any_or:SI (zero_extract:SI (match_dup 1)
8630                                                (const_int 8) (const_int 8))
8631                               (match_dup 2)))
8632               (clobber (reg:CC FLAGS_REG))])]
8634   operands[0] = gen_lowpart (SImode, operands[0]);
8635   operands[1] = gen_lowpart (SImode, operands[1]);
8636   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8639 ;; Since OR can be encoded with sign extended immediate, this is only
8640 ;; profitable when 7th bit is set.
8641 (define_split
8642   [(set (match_operand 0 "any_QIreg_operand")
8643         (any_or (match_operand 1 "general_operand")
8644                 (match_operand 2 "const_int_operand")))
8645    (clobber (reg:CC FLAGS_REG))]
8646    "reload_completed
8647     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8648     && !(INTVAL (operands[2]) & ~255)
8649     && (INTVAL (operands[2]) & 128)
8650     && GET_MODE (operands[0]) != QImode"
8651   [(parallel [(set (strict_low_part (match_dup 0))
8652                    (any_or:QI (match_dup 1)
8653                               (match_dup 2)))
8654               (clobber (reg:CC FLAGS_REG))])]
8656   operands[0] = gen_lowpart (QImode, operands[0]);
8657   operands[1] = gen_lowpart (QImode, operands[1]);
8658   operands[2] = gen_lowpart (QImode, operands[2]);
8661 (define_expand "xorqi_cc_ext_1"
8662   [(parallel [
8663      (set (reg:CCNO FLAGS_REG)
8664           (compare:CCNO
8665             (xor:SI
8666               (zero_extract:SI
8667                 (match_operand 1 "ext_register_operand")
8668                 (const_int 8)
8669                 (const_int 8))
8670               (match_operand:QI 2 "const_int_operand"))
8671             (const_int 0)))
8672      (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8673                            (const_int 8)
8674                            (const_int 8))
8675           (xor:SI
8676             (zero_extract:SI
8677              (match_dup 1)
8678              (const_int 8)
8679              (const_int 8))
8680             (match_dup 2)))])])
8682 (define_insn "*xorqi_cc_ext_1"
8683   [(set (reg FLAGS_REG)
8684         (compare
8685           (xor:SI
8686             (zero_extract:SI
8687               (match_operand 1 "ext_register_operand" "0,0")
8688               (const_int 8)
8689               (const_int 8))
8690             (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8691           (const_int 0)))
8692    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8693                          (const_int 8)
8694                          (const_int 8))
8695         (xor:SI
8696           (zero_extract:SI
8697            (match_dup 1)
8698            (const_int 8)
8699            (const_int 8))
8700           (match_dup 2)))]
8701   "ix86_match_ccmode (insn, CCNOmode)"
8702   "xor{b}\t{%2, %h0|%h0, %2}"
8703   [(set_attr "isa" "*,nox64")
8704    (set_attr "type" "alu")
8705    (set_attr "modrm" "1")
8706    (set_attr "mode" "QI")])
8708 ;; Negation instructions
8710 (define_expand "neg<mode>2"
8711   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8712         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8713   ""
8714   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8716 (define_insn_and_split "*neg<dwi>2_doubleword"
8717   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8718         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8719    (clobber (reg:CC FLAGS_REG))]
8720   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8721   "#"
8722   "reload_completed"
8723   [(parallel
8724     [(set (reg:CCZ FLAGS_REG)
8725           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8726      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8727    (parallel
8728     [(set (match_dup 2)
8729           (plus:DWIH (match_dup 3)
8730                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8731                                 (const_int 0))))
8732      (clobber (reg:CC FLAGS_REG))])
8733    (parallel
8734     [(set (match_dup 2)
8735           (neg:DWIH (match_dup 2)))
8736      (clobber (reg:CC FLAGS_REG))])]
8737   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8739 (define_insn "*neg<mode>2_1"
8740   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8741         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8742    (clobber (reg:CC FLAGS_REG))]
8743   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8744   "neg{<imodesuffix>}\t%0"
8745   [(set_attr "type" "negnot")
8746    (set_attr "mode" "<MODE>")])
8748 ;; Combine is quite creative about this pattern.
8749 (define_insn "*negsi2_1_zext"
8750   [(set (match_operand:DI 0 "register_operand" "=r")
8751         (lshiftrt:DI
8752           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8753                              (const_int 32)))
8754         (const_int 32)))
8755    (clobber (reg:CC FLAGS_REG))]
8756   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8757   "neg{l}\t%k0"
8758   [(set_attr "type" "negnot")
8759    (set_attr "mode" "SI")])
8761 ;; The problem with neg is that it does not perform (compare x 0),
8762 ;; it really performs (compare 0 x), which leaves us with the zero
8763 ;; flag being the only useful item.
8765 (define_insn "*neg<mode>2_cmpz"
8766   [(set (reg:CCZ FLAGS_REG)
8767         (compare:CCZ
8768           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8769                    (const_int 0)))
8770    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8771         (neg:SWI (match_dup 1)))]
8772   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8773   "neg{<imodesuffix>}\t%0"
8774   [(set_attr "type" "negnot")
8775    (set_attr "mode" "<MODE>")])
8777 (define_insn "*negsi2_cmpz_zext"
8778   [(set (reg:CCZ FLAGS_REG)
8779         (compare:CCZ
8780           (lshiftrt:DI
8781             (neg:DI (ashift:DI
8782                       (match_operand:DI 1 "register_operand" "0")
8783                       (const_int 32)))
8784             (const_int 32))
8785           (const_int 0)))
8786    (set (match_operand:DI 0 "register_operand" "=r")
8787         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8788                                         (const_int 32)))
8789                      (const_int 32)))]
8790   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8791   "neg{l}\t%k0"
8792   [(set_attr "type" "negnot")
8793    (set_attr "mode" "SI")])
8795 ;; Negate with jump on overflow.
8796 (define_expand "negv<mode>3"
8797   [(parallel [(set (reg:CCO FLAGS_REG)
8798                    (ne:CCO (match_operand:SWI 1 "register_operand")
8799                            (match_dup 3)))
8800               (set (match_operand:SWI 0 "register_operand")
8801                    (neg:SWI (match_dup 1)))])
8802    (set (pc) (if_then_else
8803                (eq (reg:CCO FLAGS_REG) (const_int 0))
8804                (label_ref (match_operand 2))
8805                (pc)))]
8806   ""
8808   operands[3]
8809     = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
8810                     <MODE>mode);
8813 (define_insn "*negv<mode>3"
8814   [(set (reg:CCO FLAGS_REG)
8815         (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
8816                 (match_operand:SWI 2 "const_int_operand")))
8817    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8818         (neg:SWI (match_dup 1)))]
8819   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
8820    && mode_signbit_p (<MODE>mode, operands[2])"
8821   "neg{<imodesuffix>}\t%0"
8822   [(set_attr "type" "negnot")
8823    (set_attr "mode" "<MODE>")])
8825 ;; Changing of sign for FP values is doable using integer unit too.
8827 (define_expand "<code><mode>2"
8828   [(set (match_operand:X87MODEF 0 "register_operand")
8829         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8830   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8831   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8833 (define_insn "*absneg<mode>2_mixed"
8834   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8835         (match_operator:MODEF 3 "absneg_operator"
8836           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8837    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8838    (clobber (reg:CC FLAGS_REG))]
8839   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8840   "#")
8842 (define_insn "*absneg<mode>2_sse"
8843   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8844         (match_operator:MODEF 3 "absneg_operator"
8845           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8846    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8847    (clobber (reg:CC FLAGS_REG))]
8848   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8849   "#")
8851 (define_insn "*absneg<mode>2_i387"
8852   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8853         (match_operator:X87MODEF 3 "absneg_operator"
8854           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8855    (use (match_operand 2))
8856    (clobber (reg:CC FLAGS_REG))]
8857   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8858   "#")
8860 (define_expand "<code>tf2"
8861   [(set (match_operand:TF 0 "register_operand")
8862         (absneg:TF (match_operand:TF 1 "register_operand")))]
8863   "TARGET_SSE"
8864   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8866 (define_insn "*absnegtf2_sse"
8867   [(set (match_operand:TF 0 "register_operand" "=x,x")
8868         (match_operator:TF 3 "absneg_operator"
8869           [(match_operand:TF 1 "register_operand" "0,x")]))
8870    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8871    (clobber (reg:CC FLAGS_REG))]
8872   "TARGET_SSE"
8873   "#")
8875 ;; Splitters for fp abs and neg.
8877 (define_split
8878   [(set (match_operand 0 "fp_register_operand")
8879         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8880    (use (match_operand 2))
8881    (clobber (reg:CC FLAGS_REG))]
8882   "reload_completed"
8883   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8885 (define_split
8886   [(set (match_operand 0 "register_operand")
8887         (match_operator 3 "absneg_operator"
8888           [(match_operand 1 "register_operand")]))
8889    (use (match_operand 2 "nonimmediate_operand"))
8890    (clobber (reg:CC FLAGS_REG))]
8891   "reload_completed && SSE_REG_P (operands[0])"
8892   [(set (match_dup 0) (match_dup 3))]
8894   machine_mode mode = GET_MODE (operands[0]);
8895   machine_mode vmode = GET_MODE (operands[2]);
8896   rtx tmp;
8898   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8899   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8900   if (operands_match_p (operands[0], operands[2]))
8901     std::swap (operands[1], operands[2]);
8902   if (GET_CODE (operands[3]) == ABS)
8903     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8904   else
8905     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8906   operands[3] = tmp;
8909 (define_split
8910   [(set (match_operand:SF 0 "register_operand")
8911         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8912    (use (match_operand:V4SF 2))
8913    (clobber (reg:CC FLAGS_REG))]
8914   "reload_completed"
8915   [(parallel [(set (match_dup 0) (match_dup 1))
8916               (clobber (reg:CC FLAGS_REG))])]
8918   rtx tmp;
8919   operands[0] = gen_lowpart (SImode, operands[0]);
8920   if (GET_CODE (operands[1]) == ABS)
8921     {
8922       tmp = gen_int_mode (0x7fffffff, SImode);
8923       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8924     }
8925   else
8926     {
8927       tmp = gen_int_mode (0x80000000, SImode);
8928       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8929     }
8930   operands[1] = tmp;
8933 (define_split
8934   [(set (match_operand:DF 0 "register_operand")
8935         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8936    (use (match_operand 2))
8937    (clobber (reg:CC FLAGS_REG))]
8938   "reload_completed"
8939   [(parallel [(set (match_dup 0) (match_dup 1))
8940               (clobber (reg:CC FLAGS_REG))])]
8942   rtx tmp;
8943   if (TARGET_64BIT)
8944     {
8945       tmp = gen_lowpart (DImode, operands[0]);
8946       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8947       operands[0] = tmp;
8949       if (GET_CODE (operands[1]) == ABS)
8950         tmp = const0_rtx;
8951       else
8952         tmp = gen_rtx_NOT (DImode, tmp);
8953     }
8954   else
8955     {
8956       operands[0] = gen_highpart (SImode, operands[0]);
8957       if (GET_CODE (operands[1]) == ABS)
8958         {
8959           tmp = gen_int_mode (0x7fffffff, SImode);
8960           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8961         }
8962       else
8963         {
8964           tmp = gen_int_mode (0x80000000, SImode);
8965           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8966         }
8967     }
8968   operands[1] = tmp;
8971 (define_split
8972   [(set (match_operand:XF 0 "register_operand")
8973         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8974    (use (match_operand 2))
8975    (clobber (reg:CC FLAGS_REG))]
8976   "reload_completed"
8977   [(parallel [(set (match_dup 0) (match_dup 1))
8978               (clobber (reg:CC FLAGS_REG))])]
8980   rtx tmp;
8981   operands[0] = gen_rtx_REG (SImode,
8982                              true_regnum (operands[0])
8983                              + (TARGET_64BIT ? 1 : 2));
8984   if (GET_CODE (operands[1]) == ABS)
8985     {
8986       tmp = GEN_INT (0x7fff);
8987       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8988     }
8989   else
8990     {
8991       tmp = GEN_INT (0x8000);
8992       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8993     }
8994   operands[1] = tmp;
8997 ;; Conditionalize these after reload. If they match before reload, we
8998 ;; lose the clobber and ability to use integer instructions.
9000 (define_insn "*<code><mode>2_1"
9001   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9002         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9003   "TARGET_80387
9004    && (reload_completed
9005        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9006   "f<absneg_mnemonic>"
9007   [(set_attr "type" "fsgn")
9008    (set_attr "mode" "<MODE>")])
9010 (define_insn "*<code>extendsfdf2"
9011   [(set (match_operand:DF 0 "register_operand" "=f")
9012         (absneg:DF (float_extend:DF
9013                      (match_operand:SF 1 "register_operand" "0"))))]
9014   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9015   "f<absneg_mnemonic>"
9016   [(set_attr "type" "fsgn")
9017    (set_attr "mode" "DF")])
9019 (define_insn "*<code>extendsfxf2"
9020   [(set (match_operand:XF 0 "register_operand" "=f")
9021         (absneg:XF (float_extend:XF
9022                      (match_operand:SF 1 "register_operand" "0"))))]
9023   "TARGET_80387"
9024   "f<absneg_mnemonic>"
9025   [(set_attr "type" "fsgn")
9026    (set_attr "mode" "XF")])
9028 (define_insn "*<code>extenddfxf2"
9029   [(set (match_operand:XF 0 "register_operand" "=f")
9030         (absneg:XF (float_extend:XF
9031                      (match_operand:DF 1 "register_operand" "0"))))]
9032   "TARGET_80387"
9033   "f<absneg_mnemonic>"
9034   [(set_attr "type" "fsgn")
9035    (set_attr "mode" "XF")])
9037 ;; Copysign instructions
9039 (define_mode_iterator CSGNMODE [SF DF TF])
9040 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9042 (define_expand "copysign<mode>3"
9043   [(match_operand:CSGNMODE 0 "register_operand")
9044    (match_operand:CSGNMODE 1 "nonmemory_operand")
9045    (match_operand:CSGNMODE 2 "register_operand")]
9046   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9047    || (TARGET_SSE && (<MODE>mode == TFmode))"
9048   "ix86_expand_copysign (operands); DONE;")
9050 (define_insn_and_split "copysign<mode>3_const"
9051   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9052         (unspec:CSGNMODE
9053           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9054            (match_operand:CSGNMODE 2 "register_operand" "0")
9055            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9056           UNSPEC_COPYSIGN))]
9057   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9058    || (TARGET_SSE && (<MODE>mode == TFmode))"
9059   "#"
9060   "&& reload_completed"
9061   [(const_int 0)]
9062   "ix86_split_copysign_const (operands); DONE;")
9064 (define_insn "copysign<mode>3_var"
9065   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9066         (unspec:CSGNMODE
9067           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9068            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9069            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9070            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9071           UNSPEC_COPYSIGN))
9072    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9073   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9074    || (TARGET_SSE && (<MODE>mode == TFmode))"
9075   "#")
9077 (define_split
9078   [(set (match_operand:CSGNMODE 0 "register_operand")
9079         (unspec:CSGNMODE
9080           [(match_operand:CSGNMODE 2 "register_operand")
9081            (match_operand:CSGNMODE 3 "register_operand")
9082            (match_operand:<CSGNVMODE> 4)
9083            (match_operand:<CSGNVMODE> 5)]
9084           UNSPEC_COPYSIGN))
9085    (clobber (match_scratch:<CSGNVMODE> 1))]
9086   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9087     || (TARGET_SSE && (<MODE>mode == TFmode)))
9088    && reload_completed"
9089   [(const_int 0)]
9090   "ix86_split_copysign_var (operands); DONE;")
9092 ;; One complement instructions
9094 (define_expand "one_cmpl<mode>2"
9095   [(set (match_operand:SWIM 0 "nonimmediate_operand")
9096         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
9097   ""
9098   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9100 (define_insn "*one_cmpl<mode>2_1"
9101   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,k")
9102         (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,k")))]
9103   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9104   "@
9105    not{<imodesuffix>}\t%0
9106    knot<mskmodesuffix>\t{%1, %0|%0, %1}"
9107   [(set_attr "isa" "*,avx512bw")
9108    (set_attr "type" "negnot,msklog")
9109    (set_attr "prefix" "*,vex")
9110    (set_attr "mode" "<MODE>")])
9112 (define_insn "*one_cmplhi2_1"
9113   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k")
9114         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))]
9115   "ix86_unary_operator_ok (NOT, HImode, operands)"
9116   "@
9117    not{w}\t%0
9118    knotw\t{%1, %0|%0, %1}"
9119   [(set_attr "isa" "*,avx512f")
9120    (set_attr "type" "negnot,msklog")
9121    (set_attr "prefix" "*,vex")
9122    (set_attr "mode" "HI")])
9124 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9125 (define_insn "*one_cmplqi2_1"
9126   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
9127         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
9128   "ix86_unary_operator_ok (NOT, QImode, operands)"
9130   switch (which_alternative)
9131     {
9132     case 0:
9133       return "not{b}\t%0";
9134     case 1:
9135       return "not{l}\t%k0";
9136     case 2:
9137       if (TARGET_AVX512DQ)
9138         return "knotb\t{%1, %0|%0, %1}";
9139       return "knotw\t{%1, %0|%0, %1}";
9140     default:
9141       gcc_unreachable ();
9142     }
9144   [(set_attr "isa" "*,*,avx512f")
9145    (set_attr "type" "negnot,negnot,msklog")
9146    (set_attr "prefix" "*,*,vex")
9147    (set_attr "mode" "QI,SI,QI")])
9149 ;; ??? Currently never generated - xor is used instead.
9150 (define_insn "*one_cmplsi2_1_zext"
9151   [(set (match_operand:DI 0 "register_operand" "=r")
9152         (zero_extend:DI
9153           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9154   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9155   "not{l}\t%k0"
9156   [(set_attr "type" "negnot")
9157    (set_attr "mode" "SI")])
9159 (define_insn "*one_cmpl<mode>2_2"
9160   [(set (reg FLAGS_REG)
9161         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9162                  (const_int 0)))
9163    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9164         (not:SWI (match_dup 1)))]
9165   "ix86_match_ccmode (insn, CCNOmode)
9166    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9167   "#"
9168   [(set_attr "type" "alu1")
9169    (set_attr "mode" "<MODE>")])
9171 (define_split
9172   [(set (match_operand 0 "flags_reg_operand")
9173         (match_operator 2 "compare_operator"
9174           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9175            (const_int 0)]))
9176    (set (match_operand:SWI 1 "nonimmediate_operand")
9177         (not:SWI (match_dup 3)))]
9178   "ix86_match_ccmode (insn, CCNOmode)"
9179   [(parallel [(set (match_dup 0)
9180                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9181                                     (const_int 0)]))
9182               (set (match_dup 1)
9183                    (xor:SWI (match_dup 3) (const_int -1)))])])
9185 ;; ??? Currently never generated - xor is used instead.
9186 (define_insn "*one_cmplsi2_2_zext"
9187   [(set (reg FLAGS_REG)
9188         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9189                  (const_int 0)))
9190    (set (match_operand:DI 0 "register_operand" "=r")
9191         (zero_extend:DI (not:SI (match_dup 1))))]
9192   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9193    && ix86_unary_operator_ok (NOT, SImode, operands)"
9194   "#"
9195   [(set_attr "type" "alu1")
9196    (set_attr "mode" "SI")])
9198 (define_split
9199   [(set (match_operand 0 "flags_reg_operand")
9200         (match_operator 2 "compare_operator"
9201           [(not:SI (match_operand:SI 3 "register_operand"))
9202            (const_int 0)]))
9203    (set (match_operand:DI 1 "register_operand")
9204         (zero_extend:DI (not:SI (match_dup 3))))]
9205   "ix86_match_ccmode (insn, CCNOmode)"
9206   [(parallel [(set (match_dup 0)
9207                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9208                                     (const_int 0)]))
9209               (set (match_dup 1)
9210                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9212 ;; Shift instructions
9214 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9215 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9216 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9217 ;; from the assembler input.
9219 ;; This instruction shifts the target reg/mem as usual, but instead of
9220 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9221 ;; is a left shift double, bits are taken from the high order bits of
9222 ;; reg, else if the insn is a shift right double, bits are taken from the
9223 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9224 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9226 ;; Since sh[lr]d does not change the `reg' operand, that is done
9227 ;; separately, making all shifts emit pairs of shift double and normal
9228 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9229 ;; support a 63 bit shift, each shift where the count is in a reg expands
9230 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9232 ;; If the shift count is a constant, we need never emit more than one
9233 ;; shift pair, instead using moves and sign extension for counts greater
9234 ;; than 31.
9236 (define_expand "ashl<mode>3"
9237   [(set (match_operand:SDWIM 0 "<shift_operand>")
9238         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9239                       (match_operand:QI 2 "nonmemory_operand")))]
9240   ""
9241   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9243 (define_insn "*ashl<mode>3_doubleword"
9244   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9245         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9246                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9247    (clobber (reg:CC FLAGS_REG))]
9248   ""
9249   "#"
9250   [(set_attr "type" "multi")])
9252 (define_split
9253   [(set (match_operand:DWI 0 "register_operand")
9254         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9255                     (match_operand:QI 2 "nonmemory_operand")))
9256    (clobber (reg:CC FLAGS_REG))]
9257   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9258   [(const_int 0)]
9259   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9261 ;; By default we don't ask for a scratch register, because when DWImode
9262 ;; values are manipulated, registers are already at a premium.  But if
9263 ;; we have one handy, we won't turn it away.
9265 (define_peephole2
9266   [(match_scratch:DWIH 3 "r")
9267    (parallel [(set (match_operand:<DWI> 0 "register_operand")
9268                    (ashift:<DWI>
9269                      (match_operand:<DWI> 1 "nonmemory_operand")
9270                      (match_operand:QI 2 "nonmemory_operand")))
9271               (clobber (reg:CC FLAGS_REG))])
9272    (match_dup 3)]
9273   "TARGET_CMOVE"
9274   [(const_int 0)]
9275   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9277 (define_insn "x86_64_shld"
9278   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9279         (ior:DI (ashift:DI (match_dup 0)
9280                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9281                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9282                   (minus:QI (const_int 64) (match_dup 2)))))
9283    (clobber (reg:CC FLAGS_REG))]
9284   "TARGET_64BIT"
9285   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9286   [(set_attr "type" "ishift")
9287    (set_attr "prefix_0f" "1")
9288    (set_attr "mode" "DI")
9289    (set_attr "athlon_decode" "vector")
9290    (set_attr "amdfam10_decode" "vector")
9291    (set_attr "bdver1_decode" "vector")])
9293 (define_insn "x86_shld"
9294   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9295         (ior:SI (ashift:SI (match_dup 0)
9296                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9297                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9298                   (minus:QI (const_int 32) (match_dup 2)))))
9299    (clobber (reg:CC FLAGS_REG))]
9300   ""
9301   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9302   [(set_attr "type" "ishift")
9303    (set_attr "prefix_0f" "1")
9304    (set_attr "mode" "SI")
9305    (set_attr "pent_pair" "np")
9306    (set_attr "athlon_decode" "vector")
9307    (set_attr "amdfam10_decode" "vector")
9308    (set_attr "bdver1_decode" "vector")])
9310 (define_expand "x86_shift<mode>_adj_1"
9311   [(set (reg:CCZ FLAGS_REG)
9312         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9313                              (match_dup 4))
9314                      (const_int 0)))
9315    (set (match_operand:SWI48 0 "register_operand")
9316         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9317                             (match_operand:SWI48 1 "register_operand")
9318                             (match_dup 0)))
9319    (set (match_dup 1)
9320         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9321                             (match_operand:SWI48 3 "register_operand")
9322                             (match_dup 1)))]
9323   "TARGET_CMOVE"
9324   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9326 (define_expand "x86_shift<mode>_adj_2"
9327   [(use (match_operand:SWI48 0 "register_operand"))
9328    (use (match_operand:SWI48 1 "register_operand"))
9329    (use (match_operand:QI 2 "register_operand"))]
9330   ""
9332   rtx_code_label *label = gen_label_rtx ();
9333   rtx tmp;
9335   emit_insn (gen_testqi_ccz_1 (operands[2],
9336                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9338   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9339   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9340   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9341                               gen_rtx_LABEL_REF (VOIDmode, label),
9342                               pc_rtx);
9343   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9344   JUMP_LABEL (tmp) = label;
9346   emit_move_insn (operands[0], operands[1]);
9347   ix86_expand_clear (operands[1]);
9349   emit_label (label);
9350   LABEL_NUSES (label) = 1;
9352   DONE;
9355 ;; Avoid useless masking of count operand.
9356 (define_insn "*ashl<mode>3_mask"
9357   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9358         (ashift:SWI48
9359           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9360           (subreg:QI
9361             (and:SI
9362               (match_operand:SI 2 "register_operand" "c")
9363               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9364    (clobber (reg:CC FLAGS_REG))]
9365   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9366    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9367       == GET_MODE_BITSIZE (<MODE>mode)-1"
9369   return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9371   [(set_attr "type" "ishift")
9372    (set_attr "mode" "<MODE>")])
9374 (define_insn "*bmi2_ashl<mode>3_1"
9375   [(set (match_operand:SWI48 0 "register_operand" "=r")
9376         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9377                       (match_operand:SWI48 2 "register_operand" "r")))]
9378   "TARGET_BMI2"
9379   "shlx\t{%2, %1, %0|%0, %1, %2}"
9380   [(set_attr "type" "ishiftx")
9381    (set_attr "mode" "<MODE>")])
9383 (define_insn "*ashl<mode>3_1"
9384   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9385         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9386                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9387    (clobber (reg:CC FLAGS_REG))]
9388   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9390   switch (get_attr_type (insn))
9391     {
9392     case TYPE_LEA:
9393     case TYPE_ISHIFTX:
9394       return "#";
9396     case TYPE_ALU:
9397       gcc_assert (operands[2] == const1_rtx);
9398       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9399       return "add{<imodesuffix>}\t%0, %0";
9401     default:
9402       if (operands[2] == const1_rtx
9403           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9404         return "sal{<imodesuffix>}\t%0";
9405       else
9406         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9407     }
9409   [(set_attr "isa" "*,*,bmi2")
9410    (set (attr "type")
9411      (cond [(eq_attr "alternative" "1")
9412               (const_string "lea")
9413             (eq_attr "alternative" "2")
9414               (const_string "ishiftx")
9415             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9416                       (match_operand 0 "register_operand"))
9417                  (match_operand 2 "const1_operand"))
9418               (const_string "alu")
9419            ]
9420            (const_string "ishift")))
9421    (set (attr "length_immediate")
9422      (if_then_else
9423        (ior (eq_attr "type" "alu")
9424             (and (eq_attr "type" "ishift")
9425                  (and (match_operand 2 "const1_operand")
9426                       (ior (match_test "TARGET_SHIFT1")
9427                            (match_test "optimize_function_for_size_p (cfun)")))))
9428        (const_string "0")
9429        (const_string "*")))
9430    (set_attr "mode" "<MODE>")])
9432 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9433 (define_split
9434   [(set (match_operand:SWI48 0 "register_operand")
9435         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9436                       (match_operand:QI 2 "register_operand")))
9437    (clobber (reg:CC FLAGS_REG))]
9438   "TARGET_BMI2 && reload_completed"
9439   [(set (match_dup 0)
9440         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9441   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9443 (define_insn "*bmi2_ashlsi3_1_zext"
9444   [(set (match_operand:DI 0 "register_operand" "=r")
9445         (zero_extend:DI
9446           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9447                      (match_operand:SI 2 "register_operand" "r"))))]
9448   "TARGET_64BIT && TARGET_BMI2"
9449   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9450   [(set_attr "type" "ishiftx")
9451    (set_attr "mode" "SI")])
9453 (define_insn "*ashlsi3_1_zext"
9454   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9455         (zero_extend:DI
9456           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9457                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9458    (clobber (reg:CC FLAGS_REG))]
9459   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9461   switch (get_attr_type (insn))
9462     {
9463     case TYPE_LEA:
9464     case TYPE_ISHIFTX:
9465       return "#";
9467     case TYPE_ALU:
9468       gcc_assert (operands[2] == const1_rtx);
9469       return "add{l}\t%k0, %k0";
9471     default:
9472       if (operands[2] == const1_rtx
9473           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9474         return "sal{l}\t%k0";
9475       else
9476         return "sal{l}\t{%2, %k0|%k0, %2}";
9477     }
9479   [(set_attr "isa" "*,*,bmi2")
9480    (set (attr "type")
9481      (cond [(eq_attr "alternative" "1")
9482               (const_string "lea")
9483             (eq_attr "alternative" "2")
9484               (const_string "ishiftx")
9485             (and (match_test "TARGET_DOUBLE_WITH_ADD")
9486                  (match_operand 2 "const1_operand"))
9487               (const_string "alu")
9488            ]
9489            (const_string "ishift")))
9490    (set (attr "length_immediate")
9491      (if_then_else
9492        (ior (eq_attr "type" "alu")
9493             (and (eq_attr "type" "ishift")
9494                  (and (match_operand 2 "const1_operand")
9495                       (ior (match_test "TARGET_SHIFT1")
9496                            (match_test "optimize_function_for_size_p (cfun)")))))
9497        (const_string "0")
9498        (const_string "*")))
9499    (set_attr "mode" "SI")])
9501 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9502 (define_split
9503   [(set (match_operand:DI 0 "register_operand")
9504         (zero_extend:DI
9505           (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9506                      (match_operand:QI 2 "register_operand"))))
9507    (clobber (reg:CC FLAGS_REG))]
9508   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9509   [(set (match_dup 0)
9510         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9511   "operands[2] = gen_lowpart (SImode, operands[2]);")
9513 (define_insn "*ashlhi3_1"
9514   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9515         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9516                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9517    (clobber (reg:CC FLAGS_REG))]
9518   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9520   switch (get_attr_type (insn))
9521     {
9522     case TYPE_LEA:
9523       return "#";
9525     case TYPE_ALU:
9526       gcc_assert (operands[2] == const1_rtx);
9527       return "add{w}\t%0, %0";
9529     default:
9530       if (operands[2] == const1_rtx
9531           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9532         return "sal{w}\t%0";
9533       else
9534         return "sal{w}\t{%2, %0|%0, %2}";
9535     }
9537   [(set (attr "type")
9538      (cond [(eq_attr "alternative" "1")
9539               (const_string "lea")
9540             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9541                       (match_operand 0 "register_operand"))
9542                  (match_operand 2 "const1_operand"))
9543               (const_string "alu")
9544            ]
9545            (const_string "ishift")))
9546    (set (attr "length_immediate")
9547      (if_then_else
9548        (ior (eq_attr "type" "alu")
9549             (and (eq_attr "type" "ishift")
9550                  (and (match_operand 2 "const1_operand")
9551                       (ior (match_test "TARGET_SHIFT1")
9552                            (match_test "optimize_function_for_size_p (cfun)")))))
9553        (const_string "0")
9554        (const_string "*")))
9555    (set_attr "mode" "HI,SI")])
9557 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9558 (define_insn "*ashlqi3_1"
9559   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9560         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9561                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9562    (clobber (reg:CC FLAGS_REG))]
9563   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9565   switch (get_attr_type (insn))
9566     {
9567     case TYPE_LEA:
9568       return "#";
9570     case TYPE_ALU:
9571       gcc_assert (operands[2] == const1_rtx);
9572       if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
9573         return "add{l}\t%k0, %k0";
9574       else
9575         return "add{b}\t%0, %0";
9577     default:
9578       if (operands[2] == const1_rtx
9579           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9580         {
9581           if (get_attr_mode (insn) == MODE_SI)
9582             return "sal{l}\t%k0";
9583           else
9584             return "sal{b}\t%0";
9585         }
9586       else
9587         {
9588           if (get_attr_mode (insn) == MODE_SI)
9589             return "sal{l}\t{%2, %k0|%k0, %2}";
9590           else
9591             return "sal{b}\t{%2, %0|%0, %2}";
9592         }
9593     }
9595   [(set (attr "type")
9596      (cond [(eq_attr "alternative" "2")
9597               (const_string "lea")
9598             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9599                       (match_operand 0 "register_operand"))
9600                  (match_operand 2 "const1_operand"))
9601               (const_string "alu")
9602            ]
9603            (const_string "ishift")))
9604    (set (attr "length_immediate")
9605      (if_then_else
9606        (ior (eq_attr "type" "alu")
9607             (and (eq_attr "type" "ishift")
9608                  (and (match_operand 2 "const1_operand")
9609                       (ior (match_test "TARGET_SHIFT1")
9610                            (match_test "optimize_function_for_size_p (cfun)")))))
9611        (const_string "0")
9612        (const_string "*")))
9613    (set_attr "mode" "QI,SI,SI")])
9615 (define_insn "*ashlqi3_1_slp"
9616   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9617         (ashift:QI (match_dup 0)
9618                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9619    (clobber (reg:CC FLAGS_REG))]
9620   "(optimize_function_for_size_p (cfun)
9621     || !TARGET_PARTIAL_FLAG_REG_STALL
9622     || (operands[1] == const1_rtx
9623         && (TARGET_SHIFT1
9624             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9626   switch (get_attr_type (insn))
9627     {
9628     case TYPE_ALU:
9629       gcc_assert (operands[1] == const1_rtx);
9630       return "add{b}\t%0, %0";
9632     default:
9633       if (operands[1] == const1_rtx
9634           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9635         return "sal{b}\t%0";
9636       else
9637         return "sal{b}\t{%1, %0|%0, %1}";
9638     }
9640   [(set (attr "type")
9641      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9642                       (match_operand 0 "register_operand"))
9643                  (match_operand 1 "const1_operand"))
9644               (const_string "alu")
9645            ]
9646            (const_string "ishift1")))
9647    (set (attr "length_immediate")
9648      (if_then_else
9649        (ior (eq_attr "type" "alu")
9650             (and (eq_attr "type" "ishift1")
9651                  (and (match_operand 1 "const1_operand")
9652                       (ior (match_test "TARGET_SHIFT1")
9653                            (match_test "optimize_function_for_size_p (cfun)")))))
9654        (const_string "0")
9655        (const_string "*")))
9656    (set_attr "mode" "QI")])
9658 ;; Convert ashift to the lea pattern to avoid flags dependency.
9659 (define_split
9660   [(set (match_operand 0 "register_operand")
9661         (ashift (match_operand 1 "index_register_operand")
9662                 (match_operand:QI 2 "const_int_operand")))
9663    (clobber (reg:CC FLAGS_REG))]
9664   "GET_MODE (operands[0]) == GET_MODE (operands[1])
9665    && reload_completed
9666    && true_regnum (operands[0]) != true_regnum (operands[1])"
9667   [(const_int 0)]
9669   machine_mode mode = GET_MODE (operands[0]);
9670   rtx pat;
9672   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9673     { 
9674       mode = SImode; 
9675       operands[0] = gen_lowpart (mode, operands[0]);
9676       operands[1] = gen_lowpart (mode, operands[1]);
9677     }
9679   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9681   pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9683   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9684   DONE;
9687 ;; Convert ashift to the lea pattern to avoid flags dependency.
9688 (define_split
9689   [(set (match_operand:DI 0 "register_operand")
9690         (zero_extend:DI
9691           (ashift:SI (match_operand:SI 1 "index_register_operand")
9692                      (match_operand:QI 2 "const_int_operand"))))
9693    (clobber (reg:CC FLAGS_REG))]
9694   "TARGET_64BIT && reload_completed
9695    && true_regnum (operands[0]) != true_regnum (operands[1])"
9696   [(set (match_dup 0)
9697         (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9699   operands[1] = gen_lowpart (SImode, operands[1]);
9700   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9703 ;; This pattern can't accept a variable shift count, since shifts by
9704 ;; zero don't affect the flags.  We assume that shifts by constant
9705 ;; zero are optimized away.
9706 (define_insn "*ashl<mode>3_cmp"
9707   [(set (reg FLAGS_REG)
9708         (compare
9709           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9710                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9711           (const_int 0)))
9712    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9713         (ashift:SWI (match_dup 1) (match_dup 2)))]
9714   "(optimize_function_for_size_p (cfun)
9715     || !TARGET_PARTIAL_FLAG_REG_STALL
9716     || (operands[2] == const1_rtx
9717         && (TARGET_SHIFT1
9718             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9719    && ix86_match_ccmode (insn, CCGOCmode)
9720    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9722   switch (get_attr_type (insn))
9723     {
9724     case TYPE_ALU:
9725       gcc_assert (operands[2] == const1_rtx);
9726       return "add{<imodesuffix>}\t%0, %0";
9728     default:
9729       if (operands[2] == const1_rtx
9730           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9731         return "sal{<imodesuffix>}\t%0";
9732       else
9733         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9734     }
9736   [(set (attr "type")
9737      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9738                       (match_operand 0 "register_operand"))
9739                  (match_operand 2 "const1_operand"))
9740               (const_string "alu")
9741            ]
9742            (const_string "ishift")))
9743    (set (attr "length_immediate")
9744      (if_then_else
9745        (ior (eq_attr "type" "alu")
9746             (and (eq_attr "type" "ishift")
9747                  (and (match_operand 2 "const1_operand")
9748                       (ior (match_test "TARGET_SHIFT1")
9749                            (match_test "optimize_function_for_size_p (cfun)")))))
9750        (const_string "0")
9751        (const_string "*")))
9752    (set_attr "mode" "<MODE>")])
9754 (define_insn "*ashlsi3_cmp_zext"
9755   [(set (reg FLAGS_REG)
9756         (compare
9757           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9758                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9759           (const_int 0)))
9760    (set (match_operand:DI 0 "register_operand" "=r")
9761         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9762   "TARGET_64BIT
9763    && (optimize_function_for_size_p (cfun)
9764        || !TARGET_PARTIAL_FLAG_REG_STALL
9765        || (operands[2] == const1_rtx
9766            && (TARGET_SHIFT1
9767                || TARGET_DOUBLE_WITH_ADD)))
9768    && ix86_match_ccmode (insn, CCGOCmode)
9769    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9771   switch (get_attr_type (insn))
9772     {
9773     case TYPE_ALU:
9774       gcc_assert (operands[2] == const1_rtx);
9775       return "add{l}\t%k0, %k0";
9777     default:
9778       if (operands[2] == const1_rtx
9779           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9780         return "sal{l}\t%k0";
9781       else
9782         return "sal{l}\t{%2, %k0|%k0, %2}";
9783     }
9785   [(set (attr "type")
9786      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9787                  (match_operand 2 "const1_operand"))
9788               (const_string "alu")
9789            ]
9790            (const_string "ishift")))
9791    (set (attr "length_immediate")
9792      (if_then_else
9793        (ior (eq_attr "type" "alu")
9794             (and (eq_attr "type" "ishift")
9795                  (and (match_operand 2 "const1_operand")
9796                       (ior (match_test "TARGET_SHIFT1")
9797                            (match_test "optimize_function_for_size_p (cfun)")))))
9798        (const_string "0")
9799        (const_string "*")))
9800    (set_attr "mode" "SI")])
9802 (define_insn "*ashl<mode>3_cconly"
9803   [(set (reg FLAGS_REG)
9804         (compare
9805           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9806                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9807           (const_int 0)))
9808    (clobber (match_scratch:SWI 0 "=<r>"))]
9809   "(optimize_function_for_size_p (cfun)
9810     || !TARGET_PARTIAL_FLAG_REG_STALL
9811     || (operands[2] == const1_rtx
9812         && (TARGET_SHIFT1
9813             || TARGET_DOUBLE_WITH_ADD)))
9814    && ix86_match_ccmode (insn, CCGOCmode)"
9816   switch (get_attr_type (insn))
9817     {
9818     case TYPE_ALU:
9819       gcc_assert (operands[2] == const1_rtx);
9820       return "add{<imodesuffix>}\t%0, %0";
9822     default:
9823       if (operands[2] == const1_rtx
9824           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9825         return "sal{<imodesuffix>}\t%0";
9826       else
9827         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9828     }
9830   [(set (attr "type")
9831      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9832                       (match_operand 0 "register_operand"))
9833                  (match_operand 2 "const1_operand"))
9834               (const_string "alu")
9835            ]
9836            (const_string "ishift")))
9837    (set (attr "length_immediate")
9838      (if_then_else
9839        (ior (eq_attr "type" "alu")
9840             (and (eq_attr "type" "ishift")
9841                  (and (match_operand 2 "const1_operand")
9842                       (ior (match_test "TARGET_SHIFT1")
9843                            (match_test "optimize_function_for_size_p (cfun)")))))
9844        (const_string "0")
9845        (const_string "*")))
9846    (set_attr "mode" "<MODE>")])
9848 ;; See comment above `ashl<mode>3' about how this works.
9850 (define_expand "<shift_insn><mode>3"
9851   [(set (match_operand:SDWIM 0 "<shift_operand>")
9852         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9853                            (match_operand:QI 2 "nonmemory_operand")))]
9854   ""
9855   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9857 ;; Avoid useless masking of count operand.
9858 (define_insn "*<shift_insn><mode>3_mask"
9859   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9860         (any_shiftrt:SWI48
9861           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9862           (subreg:QI
9863             (and:SI
9864               (match_operand:SI 2 "register_operand" "c")
9865               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9866    (clobber (reg:CC FLAGS_REG))]
9867   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9868    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9869       == GET_MODE_BITSIZE (<MODE>mode)-1"
9871   return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9873   [(set_attr "type" "ishift")
9874    (set_attr "mode" "<MODE>")])
9876 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9877   [(set (match_operand:DWI 0 "register_operand" "=r")
9878         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9879                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9880    (clobber (reg:CC FLAGS_REG))]
9881   ""
9882   "#"
9883   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9884   [(const_int 0)]
9885   "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9886   [(set_attr "type" "multi")])
9888 ;; By default we don't ask for a scratch register, because when DWImode
9889 ;; values are manipulated, registers are already at a premium.  But if
9890 ;; we have one handy, we won't turn it away.
9892 (define_peephole2
9893   [(match_scratch:DWIH 3 "r")
9894    (parallel [(set (match_operand:<DWI> 0 "register_operand")
9895                    (any_shiftrt:<DWI>
9896                      (match_operand:<DWI> 1 "register_operand")
9897                      (match_operand:QI 2 "nonmemory_operand")))
9898               (clobber (reg:CC FLAGS_REG))])
9899    (match_dup 3)]
9900   "TARGET_CMOVE"
9901   [(const_int 0)]
9902   "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9904 (define_insn "x86_64_shrd"
9905   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9906         (ior:DI (lshiftrt:DI (match_dup 0)
9907                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9908                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9909                   (minus:QI (const_int 64) (match_dup 2)))))
9910    (clobber (reg:CC FLAGS_REG))]
9911   "TARGET_64BIT"
9912   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9913   [(set_attr "type" "ishift")
9914    (set_attr "prefix_0f" "1")
9915    (set_attr "mode" "DI")
9916    (set_attr "athlon_decode" "vector")
9917    (set_attr "amdfam10_decode" "vector")
9918    (set_attr "bdver1_decode" "vector")])
9920 (define_insn "x86_shrd"
9921   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9922         (ior:SI (lshiftrt:SI (match_dup 0)
9923                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9924                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9925                   (minus:QI (const_int 32) (match_dup 2)))))
9926    (clobber (reg:CC FLAGS_REG))]
9927   ""
9928   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9929   [(set_attr "type" "ishift")
9930    (set_attr "prefix_0f" "1")
9931    (set_attr "mode" "SI")
9932    (set_attr "pent_pair" "np")
9933    (set_attr "athlon_decode" "vector")
9934    (set_attr "amdfam10_decode" "vector")
9935    (set_attr "bdver1_decode" "vector")])
9937 (define_insn "ashrdi3_cvt"
9938   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9939         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9940                      (match_operand:QI 2 "const_int_operand")))
9941    (clobber (reg:CC FLAGS_REG))]
9942   "TARGET_64BIT && INTVAL (operands[2]) == 63
9943    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9944    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9945   "@
9946    {cqto|cqo}
9947    sar{q}\t{%2, %0|%0, %2}"
9948   [(set_attr "type" "imovx,ishift")
9949    (set_attr "prefix_0f" "0,*")
9950    (set_attr "length_immediate" "0,*")
9951    (set_attr "modrm" "0,1")
9952    (set_attr "mode" "DI")])
9954 (define_insn "ashrsi3_cvt"
9955   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9956         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9957                      (match_operand:QI 2 "const_int_operand")))
9958    (clobber (reg:CC FLAGS_REG))]
9959   "INTVAL (operands[2]) == 31
9960    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9961    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9962   "@
9963    {cltd|cdq}
9964    sar{l}\t{%2, %0|%0, %2}"
9965   [(set_attr "type" "imovx,ishift")
9966    (set_attr "prefix_0f" "0,*")
9967    (set_attr "length_immediate" "0,*")
9968    (set_attr "modrm" "0,1")
9969    (set_attr "mode" "SI")])
9971 (define_insn "*ashrsi3_cvt_zext"
9972   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9973         (zero_extend:DI
9974           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9975                        (match_operand:QI 2 "const_int_operand"))))
9976    (clobber (reg:CC FLAGS_REG))]
9977   "TARGET_64BIT && INTVAL (operands[2]) == 31
9978    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9979    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9980   "@
9981    {cltd|cdq}
9982    sar{l}\t{%2, %k0|%k0, %2}"
9983   [(set_attr "type" "imovx,ishift")
9984    (set_attr "prefix_0f" "0,*")
9985    (set_attr "length_immediate" "0,*")
9986    (set_attr "modrm" "0,1")
9987    (set_attr "mode" "SI")])
9989 (define_expand "x86_shift<mode>_adj_3"
9990   [(use (match_operand:SWI48 0 "register_operand"))
9991    (use (match_operand:SWI48 1 "register_operand"))
9992    (use (match_operand:QI 2 "register_operand"))]
9993   ""
9995   rtx_code_label *label = gen_label_rtx ();
9996   rtx tmp;
9998   emit_insn (gen_testqi_ccz_1 (operands[2],
9999                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10001   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10002   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10003   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10004                               gen_rtx_LABEL_REF (VOIDmode, label),
10005                               pc_rtx);
10006   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10007   JUMP_LABEL (tmp) = label;
10009   emit_move_insn (operands[0], operands[1]);
10010   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10011                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10012   emit_label (label);
10013   LABEL_NUSES (label) = 1;
10015   DONE;
10018 (define_insn "*bmi2_<shift_insn><mode>3_1"
10019   [(set (match_operand:SWI48 0 "register_operand" "=r")
10020         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10021                            (match_operand:SWI48 2 "register_operand" "r")))]
10022   "TARGET_BMI2"
10023   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
10024   [(set_attr "type" "ishiftx")
10025    (set_attr "mode" "<MODE>")])
10027 (define_insn "*<shift_insn><mode>3_1"
10028   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10029         (any_shiftrt:SWI48
10030           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10031           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
10032    (clobber (reg:CC FLAGS_REG))]
10033   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10035   switch (get_attr_type (insn))
10036     {
10037     case TYPE_ISHIFTX:
10038       return "#";
10040     default:
10041       if (operands[2] == const1_rtx
10042           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10043         return "<shift>{<imodesuffix>}\t%0";
10044       else
10045         return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10046     }
10048   [(set_attr "isa" "*,bmi2")
10049    (set_attr "type" "ishift,ishiftx")
10050    (set (attr "length_immediate")
10051      (if_then_else
10052        (and (match_operand 2 "const1_operand")
10053             (ior (match_test "TARGET_SHIFT1")
10054                  (match_test "optimize_function_for_size_p (cfun)")))
10055        (const_string "0")
10056        (const_string "*")))
10057    (set_attr "mode" "<MODE>")])
10059 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10060 (define_split
10061   [(set (match_operand:SWI48 0 "register_operand")
10062         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10063                            (match_operand:QI 2 "register_operand")))
10064    (clobber (reg:CC FLAGS_REG))]
10065   "TARGET_BMI2 && reload_completed"
10066   [(set (match_dup 0)
10067         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10068   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10070 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10071   [(set (match_operand:DI 0 "register_operand" "=r")
10072         (zero_extend:DI
10073           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10074                           (match_operand:SI 2 "register_operand" "r"))))]
10075   "TARGET_64BIT && TARGET_BMI2"
10076   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10077   [(set_attr "type" "ishiftx")
10078    (set_attr "mode" "SI")])
10080 (define_insn "*<shift_insn>si3_1_zext"
10081   [(set (match_operand:DI 0 "register_operand" "=r,r")
10082         (zero_extend:DI
10083           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10084                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10085    (clobber (reg:CC FLAGS_REG))]
10086   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10088   switch (get_attr_type (insn))
10089     {
10090     case TYPE_ISHIFTX:
10091       return "#";
10093     default:
10094       if (operands[2] == const1_rtx
10095           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10096         return "<shift>{l}\t%k0";
10097       else
10098         return "<shift>{l}\t{%2, %k0|%k0, %2}";
10099     }
10101   [(set_attr "isa" "*,bmi2")
10102    (set_attr "type" "ishift,ishiftx")
10103    (set (attr "length_immediate")
10104      (if_then_else
10105        (and (match_operand 2 "const1_operand")
10106             (ior (match_test "TARGET_SHIFT1")
10107                  (match_test "optimize_function_for_size_p (cfun)")))
10108        (const_string "0")
10109        (const_string "*")))
10110    (set_attr "mode" "SI")])
10112 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10113 (define_split
10114   [(set (match_operand:DI 0 "register_operand")
10115         (zero_extend:DI
10116           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10117                           (match_operand:QI 2 "register_operand"))))
10118    (clobber (reg:CC FLAGS_REG))]
10119   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10120   [(set (match_dup 0)
10121         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10122   "operands[2] = gen_lowpart (SImode, operands[2]);")
10124 (define_insn "*<shift_insn><mode>3_1"
10125   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10126         (any_shiftrt:SWI12
10127           (match_operand:SWI12 1 "nonimmediate_operand" "0")
10128           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10129    (clobber (reg:CC FLAGS_REG))]
10130   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10132   if (operands[2] == const1_rtx
10133       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10134     return "<shift>{<imodesuffix>}\t%0";
10135   else
10136     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10138   [(set_attr "type" "ishift")
10139    (set (attr "length_immediate")
10140      (if_then_else
10141        (and (match_operand 2 "const1_operand")
10142             (ior (match_test "TARGET_SHIFT1")
10143                  (match_test "optimize_function_for_size_p (cfun)")))
10144        (const_string "0")
10145        (const_string "*")))
10146    (set_attr "mode" "<MODE>")])
10148 (define_insn "*<shift_insn>qi3_1_slp"
10149   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10150         (any_shiftrt:QI (match_dup 0)
10151                         (match_operand:QI 1 "nonmemory_operand" "cI")))
10152    (clobber (reg:CC FLAGS_REG))]
10153   "(optimize_function_for_size_p (cfun)
10154     || !TARGET_PARTIAL_REG_STALL
10155     || (operands[1] == const1_rtx
10156         && TARGET_SHIFT1))"
10158   if (operands[1] == const1_rtx
10159       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10160     return "<shift>{b}\t%0";
10161   else
10162     return "<shift>{b}\t{%1, %0|%0, %1}";
10164   [(set_attr "type" "ishift1")
10165    (set (attr "length_immediate")
10166      (if_then_else
10167        (and (match_operand 1 "const1_operand")
10168             (ior (match_test "TARGET_SHIFT1")
10169                  (match_test "optimize_function_for_size_p (cfun)")))
10170        (const_string "0")
10171        (const_string "*")))
10172    (set_attr "mode" "QI")])
10174 ;; This pattern can't accept a variable shift count, since shifts by
10175 ;; zero don't affect the flags.  We assume that shifts by constant
10176 ;; zero are optimized away.
10177 (define_insn "*<shift_insn><mode>3_cmp"
10178   [(set (reg FLAGS_REG)
10179         (compare
10180           (any_shiftrt:SWI
10181             (match_operand:SWI 1 "nonimmediate_operand" "0")
10182             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10183           (const_int 0)))
10184    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10185         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10186   "(optimize_function_for_size_p (cfun)
10187     || !TARGET_PARTIAL_FLAG_REG_STALL
10188     || (operands[2] == const1_rtx
10189         && TARGET_SHIFT1))
10190    && ix86_match_ccmode (insn, CCGOCmode)
10191    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10193   if (operands[2] == const1_rtx
10194       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10195     return "<shift>{<imodesuffix>}\t%0";
10196   else
10197     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10199   [(set_attr "type" "ishift")
10200    (set (attr "length_immediate")
10201      (if_then_else
10202        (and (match_operand 2 "const1_operand")
10203             (ior (match_test "TARGET_SHIFT1")
10204                  (match_test "optimize_function_for_size_p (cfun)")))
10205        (const_string "0")
10206        (const_string "*")))
10207    (set_attr "mode" "<MODE>")])
10209 (define_insn "*<shift_insn>si3_cmp_zext"
10210   [(set (reg FLAGS_REG)
10211         (compare
10212           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10213                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
10214           (const_int 0)))
10215    (set (match_operand:DI 0 "register_operand" "=r")
10216         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10217   "TARGET_64BIT
10218    && (optimize_function_for_size_p (cfun)
10219        || !TARGET_PARTIAL_FLAG_REG_STALL
10220        || (operands[2] == const1_rtx
10221            && TARGET_SHIFT1))
10222    && ix86_match_ccmode (insn, CCGOCmode)
10223    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10225   if (operands[2] == const1_rtx
10226       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10227     return "<shift>{l}\t%k0";
10228   else
10229     return "<shift>{l}\t{%2, %k0|%k0, %2}";
10231   [(set_attr "type" "ishift")
10232    (set (attr "length_immediate")
10233      (if_then_else
10234        (and (match_operand 2 "const1_operand")
10235             (ior (match_test "TARGET_SHIFT1")
10236                  (match_test "optimize_function_for_size_p (cfun)")))
10237        (const_string "0")
10238        (const_string "*")))
10239    (set_attr "mode" "SI")])
10241 (define_insn "*<shift_insn><mode>3_cconly"
10242   [(set (reg FLAGS_REG)
10243         (compare
10244           (any_shiftrt:SWI
10245             (match_operand:SWI 1 "register_operand" "0")
10246             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10247           (const_int 0)))
10248    (clobber (match_scratch:SWI 0 "=<r>"))]
10249   "(optimize_function_for_size_p (cfun)
10250     || !TARGET_PARTIAL_FLAG_REG_STALL
10251     || (operands[2] == const1_rtx
10252         && TARGET_SHIFT1))
10253    && ix86_match_ccmode (insn, CCGOCmode)"
10255   if (operands[2] == const1_rtx
10256       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10257     return "<shift>{<imodesuffix>}\t%0";
10258   else
10259     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10261   [(set_attr "type" "ishift")
10262    (set (attr "length_immediate")
10263      (if_then_else
10264        (and (match_operand 2 "const1_operand")
10265             (ior (match_test "TARGET_SHIFT1")
10266                  (match_test "optimize_function_for_size_p (cfun)")))
10267        (const_string "0")
10268        (const_string "*")))
10269    (set_attr "mode" "<MODE>")])
10271 ;; Rotate instructions
10273 (define_expand "<rotate_insn>ti3"
10274   [(set (match_operand:TI 0 "register_operand")
10275         (any_rotate:TI (match_operand:TI 1 "register_operand")
10276                        (match_operand:QI 2 "nonmemory_operand")))]
10277   "TARGET_64BIT"
10279   if (const_1_to_63_operand (operands[2], VOIDmode))
10280     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10281                 (operands[0], operands[1], operands[2]));
10282   else
10283     FAIL;
10285   DONE;
10288 (define_expand "<rotate_insn>di3"
10289   [(set (match_operand:DI 0 "shiftdi_operand")
10290         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10291                        (match_operand:QI 2 "nonmemory_operand")))]
10292  ""
10294   if (TARGET_64BIT)
10295     ix86_expand_binary_operator (<CODE>, DImode, operands);
10296   else if (const_1_to_31_operand (operands[2], VOIDmode))
10297     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10298                 (operands[0], operands[1], operands[2]));
10299   else
10300     FAIL;
10302   DONE;
10305 (define_expand "<rotate_insn><mode>3"
10306   [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10307         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10308                             (match_operand:QI 2 "nonmemory_operand")))]
10309   ""
10310   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10312 ;; Avoid useless masking of count operand.
10313 (define_insn "*<rotate_insn><mode>3_mask"
10314   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10315         (any_rotate:SWI48
10316           (match_operand:SWI48 1 "nonimmediate_operand" "0")
10317           (subreg:QI
10318             (and:SI
10319               (match_operand:SI 2 "register_operand" "c")
10320               (match_operand:SI 3 "const_int_operand" "n")) 0)))
10321    (clobber (reg:CC FLAGS_REG))]
10322   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10323    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10324       == GET_MODE_BITSIZE (<MODE>mode)-1"
10326   return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10328   [(set_attr "type" "rotate")
10329    (set_attr "mode" "<MODE>")])
10331 ;; Implement rotation using two double-precision
10332 ;; shift instructions and a scratch register.
10334 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10335  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10336        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10337                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10338   (clobber (reg:CC FLAGS_REG))
10339   (clobber (match_scratch:DWIH 3 "=&r"))]
10340  ""
10341  "#"
10342  "reload_completed"
10343  [(set (match_dup 3) (match_dup 4))
10344   (parallel
10345    [(set (match_dup 4)
10346          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10347                    (lshiftrt:DWIH (match_dup 5)
10348                                   (minus:QI (match_dup 6) (match_dup 2)))))
10349     (clobber (reg:CC FLAGS_REG))])
10350   (parallel
10351    [(set (match_dup 5)
10352          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10353                    (lshiftrt:DWIH (match_dup 3)
10354                                   (minus:QI (match_dup 6) (match_dup 2)))))
10355     (clobber (reg:CC FLAGS_REG))])]
10357   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10359   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10362 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10363  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10364        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10365                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10366   (clobber (reg:CC FLAGS_REG))
10367   (clobber (match_scratch:DWIH 3 "=&r"))]
10368  ""
10369  "#"
10370  "reload_completed"
10371  [(set (match_dup 3) (match_dup 4))
10372   (parallel
10373    [(set (match_dup 4)
10374          (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10375                    (ashift:DWIH (match_dup 5)
10376                                 (minus:QI (match_dup 6) (match_dup 2)))))
10377     (clobber (reg:CC FLAGS_REG))])
10378   (parallel
10379    [(set (match_dup 5)
10380          (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10381                    (ashift:DWIH (match_dup 3)
10382                                 (minus:QI (match_dup 6) (match_dup 2)))))
10383     (clobber (reg:CC FLAGS_REG))])]
10385   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10387   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10390 (define_insn "*bmi2_rorx<mode>3_1"
10391   [(set (match_operand:SWI48 0 "register_operand" "=r")
10392         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10393                         (match_operand:QI 2 "immediate_operand" "<S>")))]
10394   "TARGET_BMI2"
10395   "rorx\t{%2, %1, %0|%0, %1, %2}"
10396   [(set_attr "type" "rotatex")
10397    (set_attr "mode" "<MODE>")])
10399 (define_insn "*<rotate_insn><mode>3_1"
10400   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10401         (any_rotate:SWI48
10402           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10403           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10404    (clobber (reg:CC FLAGS_REG))]
10405   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10407   switch (get_attr_type (insn))
10408     {
10409     case TYPE_ROTATEX:
10410       return "#";
10412     default:
10413       if (operands[2] == const1_rtx
10414           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10415         return "<rotate>{<imodesuffix>}\t%0";
10416       else
10417         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10418     }
10420   [(set_attr "isa" "*,bmi2")
10421    (set_attr "type" "rotate,rotatex")
10422    (set (attr "length_immediate")
10423      (if_then_else
10424        (and (eq_attr "type" "rotate")
10425             (and (match_operand 2 "const1_operand")
10426                  (ior (match_test "TARGET_SHIFT1")
10427                       (match_test "optimize_function_for_size_p (cfun)"))))
10428        (const_string "0")
10429        (const_string "*")))
10430    (set_attr "mode" "<MODE>")])
10432 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10433 (define_split
10434   [(set (match_operand:SWI48 0 "register_operand")
10435         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10436                       (match_operand:QI 2 "immediate_operand")))
10437    (clobber (reg:CC FLAGS_REG))]
10438   "TARGET_BMI2 && reload_completed"
10439   [(set (match_dup 0)
10440         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10442   operands[2]
10443     = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10446 (define_split
10447   [(set (match_operand:SWI48 0 "register_operand")
10448         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10449                         (match_operand:QI 2 "immediate_operand")))
10450    (clobber (reg:CC FLAGS_REG))]
10451   "TARGET_BMI2 && reload_completed"
10452   [(set (match_dup 0)
10453         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10455 (define_insn "*bmi2_rorxsi3_1_zext"
10456   [(set (match_operand:DI 0 "register_operand" "=r")
10457         (zero_extend:DI
10458           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10459                        (match_operand:QI 2 "immediate_operand" "I"))))]
10460   "TARGET_64BIT && TARGET_BMI2"
10461   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10462   [(set_attr "type" "rotatex")
10463    (set_attr "mode" "SI")])
10465 (define_insn "*<rotate_insn>si3_1_zext"
10466   [(set (match_operand:DI 0 "register_operand" "=r,r")
10467         (zero_extend:DI
10468           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10469                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10470    (clobber (reg:CC FLAGS_REG))]
10471   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10473   switch (get_attr_type (insn))
10474     {
10475     case TYPE_ROTATEX:
10476       return "#";
10478     default:
10479       if (operands[2] == const1_rtx
10480           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10481         return "<rotate>{l}\t%k0";
10482       else
10483         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10484     }
10486   [(set_attr "isa" "*,bmi2")
10487    (set_attr "type" "rotate,rotatex")
10488    (set (attr "length_immediate")
10489      (if_then_else
10490        (and (eq_attr "type" "rotate")
10491             (and (match_operand 2 "const1_operand")
10492                  (ior (match_test "TARGET_SHIFT1")
10493                       (match_test "optimize_function_for_size_p (cfun)"))))
10494        (const_string "0")
10495        (const_string "*")))
10496    (set_attr "mode" "SI")])
10498 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10499 (define_split
10500   [(set (match_operand:DI 0 "register_operand")
10501         (zero_extend:DI
10502           (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10503                      (match_operand:QI 2 "immediate_operand"))))
10504    (clobber (reg:CC FLAGS_REG))]
10505   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10506   [(set (match_dup 0)
10507         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10509   operands[2]
10510     = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10513 (define_split
10514   [(set (match_operand:DI 0 "register_operand")
10515         (zero_extend:DI
10516           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10517                        (match_operand:QI 2 "immediate_operand"))))
10518    (clobber (reg:CC FLAGS_REG))]
10519   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10520   [(set (match_dup 0)
10521         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10523 (define_insn "*<rotate_insn><mode>3_1"
10524   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10525         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10526                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10527    (clobber (reg:CC FLAGS_REG))]
10528   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10530   if (operands[2] == const1_rtx
10531       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10532     return "<rotate>{<imodesuffix>}\t%0";
10533   else
10534     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10536   [(set_attr "type" "rotate")
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" "<MODE>")])
10546 (define_insn "*<rotate_insn>qi3_1_slp"
10547   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10548         (any_rotate:QI (match_dup 0)
10549                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10550    (clobber (reg:CC FLAGS_REG))]
10551   "(optimize_function_for_size_p (cfun)
10552     || !TARGET_PARTIAL_REG_STALL
10553     || (operands[1] == const1_rtx
10554         && TARGET_SHIFT1))"
10556   if (operands[1] == const1_rtx
10557       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10558     return "<rotate>{b}\t%0";
10559   else
10560     return "<rotate>{b}\t{%1, %0|%0, %1}";
10562   [(set_attr "type" "rotate1")
10563    (set (attr "length_immediate")
10564      (if_then_else
10565        (and (match_operand 1 "const1_operand")
10566             (ior (match_test "TARGET_SHIFT1")
10567                  (match_test "optimize_function_for_size_p (cfun)")))
10568        (const_string "0")
10569        (const_string "*")))
10570    (set_attr "mode" "QI")])
10572 (define_split
10573  [(set (match_operand:HI 0 "register_operand")
10574        (any_rotate:HI (match_dup 0) (const_int 8)))
10575   (clobber (reg:CC FLAGS_REG))]
10576  "reload_completed
10577   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10578  [(parallel [(set (strict_low_part (match_dup 0))
10579                   (bswap:HI (match_dup 0)))
10580              (clobber (reg:CC FLAGS_REG))])])
10582 ;; Bit set / bit test instructions
10584 (define_expand "extv"
10585   [(set (match_operand:SI 0 "register_operand")
10586         (sign_extract:SI (match_operand:SI 1 "register_operand")
10587                          (match_operand:SI 2 "const8_operand")
10588                          (match_operand:SI 3 "const8_operand")))]
10589   ""
10591   /* Handle extractions from %ah et al.  */
10592   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10593     FAIL;
10595   /* From mips.md: extract_bit_field doesn't verify that our source
10596      matches the predicate, so check it again here.  */
10597   if (! ext_register_operand (operands[1], VOIDmode))
10598     FAIL;
10601 (define_expand "extzv"
10602   [(set (match_operand:SI 0 "register_operand")
10603         (zero_extract:SI (match_operand 1 "ext_register_operand")
10604                          (match_operand:SI 2 "const8_operand")
10605                          (match_operand:SI 3 "const8_operand")))]
10606   ""
10608   /* Handle extractions from %ah et al.  */
10609   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10610     FAIL;
10612   /* From mips.md: extract_bit_field doesn't verify that our source
10613      matches the predicate, so check it again here.  */
10614   if (! ext_register_operand (operands[1], VOIDmode))
10615     FAIL;
10618 (define_expand "insv"
10619   [(set (zero_extract (match_operand 0 "register_operand")
10620                       (match_operand 1 "const_int_operand")
10621                       (match_operand 2 "const_int_operand"))
10622         (match_operand 3 "register_operand"))]
10623   ""
10625   rtx (*gen_mov_insv_1) (rtx, rtx);
10627   if (ix86_expand_pinsr (operands))
10628     DONE;
10630   /* Handle insertions to %ah et al.  */
10631   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10632     FAIL;
10634   /* From mips.md: insert_bit_field doesn't verify that our source
10635      matches the predicate, so check it again here.  */
10636   if (! ext_register_operand (operands[0], VOIDmode))
10637     FAIL;
10639   gen_mov_insv_1 = (TARGET_64BIT
10640                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10642   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10643   DONE;
10646 ;; %%% bts, btr, btc, bt.
10647 ;; In general these instructions are *slow* when applied to memory,
10648 ;; since they enforce atomic operation.  When applied to registers,
10649 ;; it depends on the cpu implementation.  They're never faster than
10650 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10651 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10652 ;; within the instruction itself, so operating on bits in the high
10653 ;; 32-bits of a register becomes easier.
10655 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10656 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10657 ;; negdf respectively, so they can never be disabled entirely.
10659 (define_insn "*btsq"
10660   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10661                          (const_int 1)
10662                          (match_operand:DI 1 "const_0_to_63_operand"))
10663         (const_int 1))
10664    (clobber (reg:CC FLAGS_REG))]
10665   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10666   "bts{q}\t{%1, %0|%0, %1}"
10667   [(set_attr "type" "alu1")
10668    (set_attr "prefix_0f" "1")
10669    (set_attr "mode" "DI")])
10671 (define_insn "*btrq"
10672   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10673                          (const_int 1)
10674                          (match_operand:DI 1 "const_0_to_63_operand"))
10675         (const_int 0))
10676    (clobber (reg:CC FLAGS_REG))]
10677   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10678   "btr{q}\t{%1, %0|%0, %1}"
10679   [(set_attr "type" "alu1")
10680    (set_attr "prefix_0f" "1")
10681    (set_attr "mode" "DI")])
10683 (define_insn "*btcq"
10684   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10685                          (const_int 1)
10686                          (match_operand:DI 1 "const_0_to_63_operand"))
10687         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10688    (clobber (reg:CC FLAGS_REG))]
10689   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10690   "btc{q}\t{%1, %0|%0, %1}"
10691   [(set_attr "type" "alu1")
10692    (set_attr "prefix_0f" "1")
10693    (set_attr "mode" "DI")])
10695 ;; Allow Nocona to avoid these instructions if a register is available.
10697 (define_peephole2
10698   [(match_scratch:DI 2 "r")
10699    (parallel [(set (zero_extract:DI
10700                      (match_operand:DI 0 "register_operand")
10701                      (const_int 1)
10702                      (match_operand:DI 1 "const_0_to_63_operand"))
10703                    (const_int 1))
10704               (clobber (reg:CC FLAGS_REG))])]
10705   "TARGET_64BIT && !TARGET_USE_BT"
10706   [(const_int 0)]
10708   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10709   rtx op1;
10711   if (HOST_BITS_PER_WIDE_INT >= 64)
10712     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10713   else if (i < HOST_BITS_PER_WIDE_INT)
10714     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10715   else
10716     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10718   op1 = immed_double_const (lo, hi, DImode);
10719   if (i >= 31)
10720     {
10721       emit_move_insn (operands[2], op1);
10722       op1 = operands[2];
10723     }
10725   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10726   DONE;
10729 (define_peephole2
10730   [(match_scratch:DI 2 "r")
10731    (parallel [(set (zero_extract:DI
10732                      (match_operand:DI 0 "register_operand")
10733                      (const_int 1)
10734                      (match_operand:DI 1 "const_0_to_63_operand"))
10735                    (const_int 0))
10736               (clobber (reg:CC FLAGS_REG))])]
10737   "TARGET_64BIT && !TARGET_USE_BT"
10738   [(const_int 0)]
10740   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10741   rtx op1;
10743   if (HOST_BITS_PER_WIDE_INT >= 64)
10744     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10745   else if (i < HOST_BITS_PER_WIDE_INT)
10746     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10747   else
10748     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10750   op1 = immed_double_const (~lo, ~hi, DImode);
10751   if (i >= 32)
10752     {
10753       emit_move_insn (operands[2], op1);
10754       op1 = operands[2];
10755     }
10757   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10758   DONE;
10761 (define_peephole2
10762   [(match_scratch:DI 2 "r")
10763    (parallel [(set (zero_extract:DI
10764                      (match_operand:DI 0 "register_operand")
10765                      (const_int 1)
10766                      (match_operand:DI 1 "const_0_to_63_operand"))
10767               (not:DI (zero_extract:DI
10768                         (match_dup 0) (const_int 1) (match_dup 1))))
10769               (clobber (reg:CC FLAGS_REG))])]
10770   "TARGET_64BIT && !TARGET_USE_BT"
10771   [(const_int 0)]
10773   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10774   rtx op1;
10776   if (HOST_BITS_PER_WIDE_INT >= 64)
10777     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10778   else if (i < HOST_BITS_PER_WIDE_INT)
10779     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10780   else
10781     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10783   op1 = immed_double_const (lo, hi, DImode);
10784   if (i >= 31)
10785     {
10786       emit_move_insn (operands[2], op1);
10787       op1 = operands[2];
10788     }
10790   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10791   DONE;
10794 (define_insn "*bt<mode>"
10795   [(set (reg:CCC FLAGS_REG)
10796         (compare:CCC
10797           (zero_extract:SWI48
10798             (match_operand:SWI48 0 "register_operand" "r")
10799             (const_int 1)
10800             (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10801           (const_int 0)))]
10802   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10803   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10804   [(set_attr "type" "alu1")
10805    (set_attr "prefix_0f" "1")
10806    (set_attr "mode" "<MODE>")])
10808 ;; Store-flag instructions.
10810 ;; For all sCOND expanders, also expand the compare or test insn that
10811 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10813 (define_insn_and_split "*setcc_di_1"
10814   [(set (match_operand:DI 0 "register_operand" "=q")
10815         (match_operator:DI 1 "ix86_comparison_operator"
10816           [(reg FLAGS_REG) (const_int 0)]))]
10817   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10818   "#"
10819   "&& reload_completed"
10820   [(set (match_dup 2) (match_dup 1))
10821    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10823   PUT_MODE (operands[1], QImode);
10824   operands[2] = gen_lowpart (QImode, operands[0]);
10827 (define_insn_and_split "*setcc_si_1_and"
10828   [(set (match_operand:SI 0 "register_operand" "=q")
10829         (match_operator:SI 1 "ix86_comparison_operator"
10830           [(reg FLAGS_REG) (const_int 0)]))
10831    (clobber (reg:CC FLAGS_REG))]
10832   "!TARGET_PARTIAL_REG_STALL
10833    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10834   "#"
10835   "&& reload_completed"
10836   [(set (match_dup 2) (match_dup 1))
10837    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10838               (clobber (reg:CC FLAGS_REG))])]
10840   PUT_MODE (operands[1], QImode);
10841   operands[2] = gen_lowpart (QImode, operands[0]);
10844 (define_insn_and_split "*setcc_si_1_movzbl"
10845   [(set (match_operand:SI 0 "register_operand" "=q")
10846         (match_operator:SI 1 "ix86_comparison_operator"
10847           [(reg FLAGS_REG) (const_int 0)]))]
10848   "!TARGET_PARTIAL_REG_STALL
10849    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10850   "#"
10851   "&& reload_completed"
10852   [(set (match_dup 2) (match_dup 1))
10853    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10855   PUT_MODE (operands[1], QImode);
10856   operands[2] = gen_lowpart (QImode, operands[0]);
10859 (define_insn "*setcc_qi"
10860   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10861         (match_operator:QI 1 "ix86_comparison_operator"
10862           [(reg FLAGS_REG) (const_int 0)]))]
10863   ""
10864   "set%C1\t%0"
10865   [(set_attr "type" "setcc")
10866    (set_attr "mode" "QI")])
10868 (define_insn "*setcc_qi_slp"
10869   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10870         (match_operator:QI 1 "ix86_comparison_operator"
10871           [(reg FLAGS_REG) (const_int 0)]))]
10872   ""
10873   "set%C1\t%0"
10874   [(set_attr "type" "setcc")
10875    (set_attr "mode" "QI")])
10877 ;; In general it is not safe to assume too much about CCmode registers,
10878 ;; so simplify-rtx stops when it sees a second one.  Under certain
10879 ;; conditions this is safe on x86, so help combine not create
10881 ;;      seta    %al
10882 ;;      testb   %al, %al
10883 ;;      sete    %al
10885 (define_split
10886   [(set (match_operand:QI 0 "nonimmediate_operand")
10887         (ne:QI (match_operator 1 "ix86_comparison_operator"
10888                  [(reg FLAGS_REG) (const_int 0)])
10889             (const_int 0)))]
10890   ""
10891   [(set (match_dup 0) (match_dup 1))]
10892   "PUT_MODE (operands[1], QImode);")
10894 (define_split
10895   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10896         (ne:QI (match_operator 1 "ix86_comparison_operator"
10897                  [(reg FLAGS_REG) (const_int 0)])
10898             (const_int 0)))]
10899   ""
10900   [(set (match_dup 0) (match_dup 1))]
10901   "PUT_MODE (operands[1], QImode);")
10903 (define_split
10904   [(set (match_operand:QI 0 "nonimmediate_operand")
10905         (eq:QI (match_operator 1 "ix86_comparison_operator"
10906                  [(reg FLAGS_REG) (const_int 0)])
10907             (const_int 0)))]
10908   ""
10909   [(set (match_dup 0) (match_dup 1))]
10911   rtx new_op1 = copy_rtx (operands[1]);
10912   operands[1] = new_op1;
10913   PUT_MODE (new_op1, QImode);
10914   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10915                                              GET_MODE (XEXP (new_op1, 0))));
10917   /* Make sure that (a) the CCmode we have for the flags is strong
10918      enough for the reversed compare or (b) we have a valid FP compare.  */
10919   if (! ix86_comparison_operator (new_op1, VOIDmode))
10920     FAIL;
10923 (define_split
10924   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10925         (eq:QI (match_operator 1 "ix86_comparison_operator"
10926                  [(reg FLAGS_REG) (const_int 0)])
10927             (const_int 0)))]
10928   ""
10929   [(set (match_dup 0) (match_dup 1))]
10931   rtx new_op1 = copy_rtx (operands[1]);
10932   operands[1] = new_op1;
10933   PUT_MODE (new_op1, QImode);
10934   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10935                                              GET_MODE (XEXP (new_op1, 0))));
10937   /* Make sure that (a) the CCmode we have for the flags is strong
10938      enough for the reversed compare or (b) we have a valid FP compare.  */
10939   if (! ix86_comparison_operator (new_op1, VOIDmode))
10940     FAIL;
10943 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10944 ;; subsequent logical operations are used to imitate conditional moves.
10945 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10946 ;; it directly.
10948 (define_insn "setcc_<mode>_sse"
10949   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10950         (match_operator:MODEF 3 "sse_comparison_operator"
10951           [(match_operand:MODEF 1 "register_operand" "0,x")
10952            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10953   "SSE_FLOAT_MODE_P (<MODE>mode)"
10954   "@
10955    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10956    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10957   [(set_attr "isa" "noavx,avx")
10958    (set_attr "type" "ssecmp")
10959    (set_attr "length_immediate" "1")
10960    (set_attr "prefix" "orig,vex")
10961    (set_attr "mode" "<MODE>")])
10963 ;; Basic conditional jump instructions.
10964 ;; We ignore the overflow flag for signed branch instructions.
10966 (define_insn "*jcc_1_bnd"
10967   [(set (pc)
10968         (if_then_else (match_operator 1 "ix86_comparison_operator"
10969                                       [(reg FLAGS_REG) (const_int 0)])
10970                       (label_ref (match_operand 0))
10971                       (pc)))]
10972   "TARGET_MPX && ix86_bnd_prefixed_insn_p (insn)"
10973   "bnd %+j%C1\t%l0"
10974   [(set_attr "type" "ibr")
10975    (set_attr "modrm" "0")
10976    (set (attr "length")
10977            (if_then_else (and (ge (minus (match_dup 0) (pc))
10978                                   (const_int -126))
10979                               (lt (minus (match_dup 0) (pc))
10980                                   (const_int 128)))
10981              (const_int 3)
10982              (const_int 7)))])
10984 (define_insn "*jcc_1"
10985   [(set (pc)
10986         (if_then_else (match_operator 1 "ix86_comparison_operator"
10987                                       [(reg FLAGS_REG) (const_int 0)])
10988                       (label_ref (match_operand 0))
10989                       (pc)))]
10990   ""
10991   "%+j%C1\t%l0"
10992   [(set_attr "type" "ibr")
10993    (set_attr "modrm" "0")
10994    (set (attr "length")
10995            (if_then_else (and (ge (minus (match_dup 0) (pc))
10996                                   (const_int -126))
10997                               (lt (minus (match_dup 0) (pc))
10998                                   (const_int 128)))
10999              (const_int 2)
11000              (const_int 6)))])
11002 (define_insn "*jcc_2_bnd"
11003   [(set (pc)
11004         (if_then_else (match_operator 1 "ix86_comparison_operator"
11005                                       [(reg FLAGS_REG) (const_int 0)])
11006                       (pc)
11007                       (label_ref (match_operand 0))))]
11008   "TARGET_MPX && ix86_bnd_prefixed_insn_p (insn)"
11009   "bnd %+j%c1\t%l0"
11010   [(set_attr "type" "ibr")
11011    (set_attr "modrm" "0")
11012    (set (attr "length")
11013            (if_then_else (and (ge (minus (match_dup 0) (pc))
11014                                   (const_int -126))
11015                               (lt (minus (match_dup 0) (pc))
11016                                   (const_int 128)))
11017              (const_int 3)
11018              (const_int 7)))])
11020 (define_insn "*jcc_2"
11021   [(set (pc)
11022         (if_then_else (match_operator 1 "ix86_comparison_operator"
11023                                       [(reg FLAGS_REG) (const_int 0)])
11024                       (pc)
11025                       (label_ref (match_operand 0))))]
11026   ""
11027   "%+j%c1\t%l0"
11028   [(set_attr "type" "ibr")
11029    (set_attr "modrm" "0")
11030    (set (attr "length")
11031            (if_then_else (and (ge (minus (match_dup 0) (pc))
11032                                   (const_int -126))
11033                               (lt (minus (match_dup 0) (pc))
11034                                   (const_int 128)))
11035              (const_int 2)
11036              (const_int 6)))])
11038 ;; In general it is not safe to assume too much about CCmode registers,
11039 ;; so simplify-rtx stops when it sees a second one.  Under certain
11040 ;; conditions this is safe on x86, so help combine not create
11042 ;;      seta    %al
11043 ;;      testb   %al, %al
11044 ;;      je      Lfoo
11046 (define_split
11047   [(set (pc)
11048         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11049                                       [(reg FLAGS_REG) (const_int 0)])
11050                           (const_int 0))
11051                       (label_ref (match_operand 1))
11052                       (pc)))]
11053   ""
11054   [(set (pc)
11055         (if_then_else (match_dup 0)
11056                       (label_ref (match_dup 1))
11057                       (pc)))]
11058   "PUT_MODE (operands[0], VOIDmode);")
11060 (define_split
11061   [(set (pc)
11062         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11063                                       [(reg FLAGS_REG) (const_int 0)])
11064                           (const_int 0))
11065                       (label_ref (match_operand 1))
11066                       (pc)))]
11067   ""
11068   [(set (pc)
11069         (if_then_else (match_dup 0)
11070                       (label_ref (match_dup 1))
11071                       (pc)))]
11073   rtx new_op0 = copy_rtx (operands[0]);
11074   operands[0] = new_op0;
11075   PUT_MODE (new_op0, VOIDmode);
11076   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
11077                                              GET_MODE (XEXP (new_op0, 0))));
11079   /* Make sure that (a) the CCmode we have for the flags is strong
11080      enough for the reversed compare or (b) we have a valid FP compare.  */
11081   if (! ix86_comparison_operator (new_op0, VOIDmode))
11082     FAIL;
11085 ;; zero_extend in SImode is correct also for DImode, since this is what combine
11086 ;; pass generates from shift insn with QImode operand.  Actually, the mode
11087 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
11088 ;; appropriate modulo of the bit offset value.
11090 (define_insn_and_split "*jcc_bt<mode>"
11091   [(set (pc)
11092         (if_then_else (match_operator 0 "bt_comparison_operator"
11093                         [(zero_extract:SWI48
11094                            (match_operand:SWI48 1 "register_operand" "r")
11095                            (const_int 1)
11096                            (zero_extend:SI
11097                              (match_operand:QI 2 "register_operand" "r")))
11098                          (const_int 0)])
11099                       (label_ref (match_operand 3))
11100                       (pc)))
11101    (clobber (reg:CC FLAGS_REG))]
11102   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11103   "#"
11104   "&& 1"
11105   [(set (reg:CCC FLAGS_REG)
11106         (compare:CCC
11107           (zero_extract:SWI48
11108             (match_dup 1)
11109             (const_int 1)
11110             (match_dup 2))
11111           (const_int 0)))
11112    (set (pc)
11113         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11114                       (label_ref (match_dup 3))
11115                       (pc)))]
11117   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
11119   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11122 ;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode
11123 ;; zero extended to SImode.
11124 (define_insn_and_split "*jcc_bt<mode>_1"
11125   [(set (pc)
11126         (if_then_else (match_operator 0 "bt_comparison_operator"
11127                         [(zero_extract:SWI48
11128                            (match_operand:SWI48 1 "register_operand" "r")
11129                            (const_int 1)
11130                            (match_operand:SI 2 "register_operand" "r"))
11131                          (const_int 0)])
11132                       (label_ref (match_operand 3))
11133                       (pc)))
11134    (clobber (reg:CC FLAGS_REG))]
11135   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11136   "#"
11137   "&& 1"
11138   [(set (reg:CCC FLAGS_REG)
11139         (compare:CCC
11140           (zero_extract:SWI48
11141             (match_dup 1)
11142             (const_int 1)
11143             (match_dup 2))
11144           (const_int 0)))
11145    (set (pc)
11146         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11147                       (label_ref (match_dup 3))
11148                       (pc)))]
11150   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11152   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11155 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
11156 ;; also for DImode, this is what combine produces.
11157 (define_insn_and_split "*jcc_bt<mode>_mask"
11158   [(set (pc)
11159         (if_then_else (match_operator 0 "bt_comparison_operator"
11160                         [(zero_extract:SWI48
11161                            (match_operand:SWI48 1 "register_operand" "r")
11162                            (const_int 1)
11163                            (and:SI
11164                              (match_operand:SI 2 "register_operand" "r")
11165                              (match_operand:SI 3 "const_int_operand" "n")))])
11166                       (label_ref (match_operand 4))
11167                       (pc)))
11168    (clobber (reg:CC FLAGS_REG))]
11169   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11170    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11171       == GET_MODE_BITSIZE (<MODE>mode)-1"
11172   "#"
11173   "&& 1"
11174   [(set (reg:CCC FLAGS_REG)
11175         (compare:CCC
11176           (zero_extract:SWI48
11177             (match_dup 1)
11178             (const_int 1)
11179             (match_dup 2))
11180           (const_int 0)))
11181    (set (pc)
11182         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11183                       (label_ref (match_dup 4))
11184                       (pc)))]
11186   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11188   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11191 (define_insn_and_split "*jcc_btsi_1"
11192   [(set (pc)
11193         (if_then_else (match_operator 0 "bt_comparison_operator"
11194                         [(and:SI
11195                            (lshiftrt:SI
11196                              (match_operand:SI 1 "register_operand" "r")
11197                              (match_operand:QI 2 "register_operand" "r"))
11198                            (const_int 1))
11199                          (const_int 0)])
11200                       (label_ref (match_operand 3))
11201                       (pc)))
11202    (clobber (reg:CC FLAGS_REG))]
11203   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11204   "#"
11205   "&& 1"
11206   [(set (reg:CCC FLAGS_REG)
11207         (compare:CCC
11208           (zero_extract:SI
11209             (match_dup 1)
11210             (const_int 1)
11211             (match_dup 2))
11212           (const_int 0)))
11213    (set (pc)
11214         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11215                       (label_ref (match_dup 3))
11216                       (pc)))]
11218   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11220   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11223 ;; avoid useless masking of bit offset operand
11224 (define_insn_and_split "*jcc_btsi_mask_1"
11225   [(set (pc)
11226         (if_then_else
11227           (match_operator 0 "bt_comparison_operator"
11228             [(and:SI
11229                (lshiftrt:SI
11230                  (match_operand:SI 1 "register_operand" "r")
11231                  (subreg:QI
11232                    (and:SI
11233                      (match_operand:SI 2 "register_operand" "r")
11234                      (match_operand:SI 3 "const_int_operand" "n")) 0))
11235                (const_int 1))
11236              (const_int 0)])
11237           (label_ref (match_operand 4))
11238           (pc)))
11239    (clobber (reg:CC FLAGS_REG))]
11240   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11241    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11242   "#"
11243   "&& 1"
11244   [(set (reg:CCC FLAGS_REG)
11245         (compare:CCC
11246           (zero_extract:SI
11247             (match_dup 1)
11248             (const_int 1)
11249             (match_dup 2))
11250           (const_int 0)))
11251    (set (pc)
11252         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11253                       (label_ref (match_dup 4))
11254                       (pc)))]
11255   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11257 ;; Define combination compare-and-branch fp compare instructions to help
11258 ;; combine.
11260 (define_insn "*jcc<mode>_0_i387"
11261   [(set (pc)
11262         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11263                         [(match_operand:X87MODEF 1 "register_operand" "f")
11264                          (match_operand:X87MODEF 2 "const0_operand")])
11265           (label_ref (match_operand 3))
11266           (pc)))
11267    (clobber (reg:CCFP FPSR_REG))
11268    (clobber (reg:CCFP FLAGS_REG))
11269    (clobber (match_scratch:HI 4 "=a"))]
11270   "TARGET_80387 && !TARGET_CMOVE"
11271   "#")
11273 (define_insn "*jcc<mode>_0_r_i387"
11274   [(set (pc)
11275         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11276                         [(match_operand:X87MODEF 1 "register_operand" "f")
11277                          (match_operand:X87MODEF 2 "const0_operand")])
11278           (pc)
11279           (label_ref (match_operand 3))))
11280    (clobber (reg:CCFP FPSR_REG))
11281    (clobber (reg:CCFP FLAGS_REG))
11282    (clobber (match_scratch:HI 4 "=a"))]
11283   "TARGET_80387 && !TARGET_CMOVE"
11284   "#")
11286 (define_insn "*jccxf_i387"
11287   [(set (pc)
11288         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11289                         [(match_operand:XF 1 "register_operand" "f")
11290                          (match_operand:XF 2 "register_operand" "f")])
11291           (label_ref (match_operand 3))
11292           (pc)))
11293    (clobber (reg:CCFP FPSR_REG))
11294    (clobber (reg:CCFP FLAGS_REG))
11295    (clobber (match_scratch:HI 4 "=a"))]
11296   "TARGET_80387 && !TARGET_CMOVE"
11297   "#")
11299 (define_insn "*jccxf_r_i387"
11300   [(set (pc)
11301         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11302                         [(match_operand:XF 1 "register_operand" "f")
11303                          (match_operand:XF 2 "register_operand" "f")])
11304           (pc)
11305           (label_ref (match_operand 3))))
11306    (clobber (reg:CCFP FPSR_REG))
11307    (clobber (reg:CCFP FLAGS_REG))
11308    (clobber (match_scratch:HI 4 "=a"))]
11309   "TARGET_80387 && !TARGET_CMOVE"
11310   "#")
11312 (define_insn "*jcc<mode>_i387"
11313   [(set (pc)
11314         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11315                         [(match_operand:MODEF 1 "register_operand" "f")
11316                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11317           (label_ref (match_operand 3))
11318           (pc)))
11319    (clobber (reg:CCFP FPSR_REG))
11320    (clobber (reg:CCFP FLAGS_REG))
11321    (clobber (match_scratch:HI 4 "=a"))]
11322   "TARGET_80387 && !TARGET_CMOVE"
11323   "#")
11325 (define_insn "*jcc<mode>_r_i387"
11326   [(set (pc)
11327         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11328                         [(match_operand:MODEF 1 "register_operand" "f")
11329                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11330           (pc)
11331           (label_ref (match_operand 3))))
11332    (clobber (reg:CCFP FPSR_REG))
11333    (clobber (reg:CCFP FLAGS_REG))
11334    (clobber (match_scratch:HI 4 "=a"))]
11335   "TARGET_80387 && !TARGET_CMOVE"
11336   "#")
11338 (define_insn "*jccu<mode>_i387"
11339   [(set (pc)
11340         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11341                         [(match_operand:X87MODEF 1 "register_operand" "f")
11342                          (match_operand:X87MODEF 2 "register_operand" "f")])
11343           (label_ref (match_operand 3))
11344           (pc)))
11345    (clobber (reg:CCFP FPSR_REG))
11346    (clobber (reg:CCFP FLAGS_REG))
11347    (clobber (match_scratch:HI 4 "=a"))]
11348   "TARGET_80387 && !TARGET_CMOVE"
11349   "#")
11351 (define_insn "*jccu<mode>_r_i387"
11352   [(set (pc)
11353         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11354                         [(match_operand:X87MODEF 1 "register_operand" "f")
11355                          (match_operand:X87MODEF 2 "register_operand" "f")])
11356           (pc)
11357           (label_ref (match_operand 3))))
11358    (clobber (reg:CCFP FPSR_REG))
11359    (clobber (reg:CCFP FLAGS_REG))
11360    (clobber (match_scratch:HI 4 "=a"))]
11361   "TARGET_80387 && !TARGET_CMOVE"
11362   "#")
11364 (define_split
11365   [(set (pc)
11366         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11367                         [(match_operand:X87MODEF 1 "register_operand")
11368                          (match_operand:X87MODEF 2 "nonimmediate_operand")])
11369           (match_operand 3)
11370           (match_operand 4)))
11371    (clobber (reg:CCFP FPSR_REG))
11372    (clobber (reg:CCFP FLAGS_REG))]
11373   "TARGET_80387 && !TARGET_CMOVE
11374    && reload_completed"
11375   [(const_int 0)]
11377   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11378                         operands[3], operands[4], NULL_RTX);
11379   DONE;
11382 (define_split
11383   [(set (pc)
11384         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11385                         [(match_operand:X87MODEF 1 "register_operand")
11386                          (match_operand:X87MODEF 2 "general_operand")])
11387           (match_operand 3)
11388           (match_operand 4)))
11389    (clobber (reg:CCFP FPSR_REG))
11390    (clobber (reg:CCFP FLAGS_REG))
11391    (clobber (match_scratch:HI 5))]
11392   "TARGET_80387 && !TARGET_CMOVE
11393    && reload_completed"
11394   [(const_int 0)]
11396   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11397                         operands[3], operands[4], operands[5]);
11398   DONE;
11401 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11402 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11403 ;; with a precedence over other operators and is always put in the first
11404 ;; place. Swap condition and operands to match ficom instruction.
11406 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11407   [(set (pc)
11408         (if_then_else
11409           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11410             [(match_operator:X87MODEF 1 "float_operator"
11411               [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11412              (match_operand:X87MODEF 3 "register_operand" "f")])
11413           (label_ref (match_operand 4))
11414           (pc)))
11415    (clobber (reg:CCFP FPSR_REG))
11416    (clobber (reg:CCFP FLAGS_REG))
11417    (clobber (match_scratch:HI 5 "=a"))]
11418   "TARGET_80387 && !TARGET_CMOVE
11419    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11420        || optimize_function_for_size_p (cfun))"
11421   "#")
11423 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11424   [(set (pc)
11425         (if_then_else
11426           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11427             [(match_operator:X87MODEF 1 "float_operator"
11428               [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11429              (match_operand:X87MODEF 3 "register_operand" "f")])
11430           (pc)
11431           (label_ref (match_operand 4))))
11432    (clobber (reg:CCFP FPSR_REG))
11433    (clobber (reg:CCFP FLAGS_REG))
11434    (clobber (match_scratch:HI 5 "=a"))]
11435   "TARGET_80387 && !TARGET_CMOVE
11436    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11437        || optimize_function_for_size_p (cfun))"
11438   "#")
11440 (define_split
11441   [(set (pc)
11442         (if_then_else
11443           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11444             [(match_operator:X87MODEF 1 "float_operator"
11445               [(match_operand:SWI24 2 "memory_operand")])
11446              (match_operand:X87MODEF 3 "register_operand")])
11447           (match_operand 4)
11448           (match_operand 5)))
11449    (clobber (reg:CCFP FPSR_REG))
11450    (clobber (reg:CCFP FLAGS_REG))
11451    (clobber (match_scratch:HI 6))]
11452   "TARGET_80387 && !TARGET_CMOVE
11453    && reload_completed"
11454   [(const_int 0)]
11456   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11457                         gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11458                         operands[4], operands[5], operands[6]);
11459   DONE;
11462 ;; Unconditional and other jump instructions
11464 (define_insn "jump_bnd"
11465   [(set (pc)
11466         (label_ref (match_operand 0)))]
11467   "TARGET_MPX && ix86_bnd_prefixed_insn_p (insn)"
11468   "bnd jmp\t%l0"
11469   [(set_attr "type" "ibr")
11470    (set (attr "length")
11471            (if_then_else (and (ge (minus (match_dup 0) (pc))
11472                                   (const_int -126))
11473                               (lt (minus (match_dup 0) (pc))
11474                                   (const_int 128)))
11475              (const_int 3)
11476              (const_int 6)))
11477    (set_attr "modrm" "0")])
11479 (define_insn "jump"
11480   [(set (pc)
11481         (label_ref (match_operand 0)))]
11482   ""
11483   "jmp\t%l0"
11484   [(set_attr "type" "ibr")
11485    (set (attr "length")
11486            (if_then_else (and (ge (minus (match_dup 0) (pc))
11487                                   (const_int -126))
11488                               (lt (minus (match_dup 0) (pc))
11489                                   (const_int 128)))
11490              (const_int 2)
11491              (const_int 5)))
11492    (set_attr "modrm" "0")])
11494 (define_expand "indirect_jump"
11495   [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11496   ""
11498   if (TARGET_X32)
11499     operands[0] = convert_memory_address (word_mode, operands[0]);
11502 (define_insn "*indirect_jump"
11503   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11504   ""
11505   "%!jmp\t%A0"
11506   [(set_attr "type" "ibr")
11507    (set_attr "length_immediate" "0")])
11509 (define_expand "tablejump"
11510   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11511               (use (label_ref (match_operand 1)))])]
11512   ""
11514   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11515      relative.  Convert the relative address to an absolute address.  */
11516   if (flag_pic)
11517     {
11518       rtx op0, op1;
11519       enum rtx_code code;
11521       /* We can't use @GOTOFF for text labels on VxWorks;
11522          see gotoff_operand.  */
11523       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11524         {
11525           code = PLUS;
11526           op0 = operands[0];
11527           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11528         }
11529       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11530         {
11531           code = PLUS;
11532           op0 = operands[0];
11533           op1 = pic_offset_table_rtx;
11534         }
11535       else
11536         {
11537           code = MINUS;
11538           op0 = pic_offset_table_rtx;
11539           op1 = operands[0];
11540         }
11542       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11543                                          OPTAB_DIRECT);
11544     }
11546   if (TARGET_X32)
11547     operands[0] = convert_memory_address (word_mode, operands[0]);
11550 (define_insn "*tablejump_1"
11551   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11552    (use (label_ref (match_operand 1)))]
11553   ""
11554   "%!jmp\t%A0"
11555   [(set_attr "type" "ibr")
11556    (set_attr "length_immediate" "0")])
11558 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11560 (define_peephole2
11561   [(set (reg FLAGS_REG) (match_operand 0))
11562    (set (match_operand:QI 1 "register_operand")
11563         (match_operator:QI 2 "ix86_comparison_operator"
11564           [(reg FLAGS_REG) (const_int 0)]))
11565    (set (match_operand 3 "any_QIreg_operand")
11566         (zero_extend (match_dup 1)))]
11567   "(peep2_reg_dead_p (3, operands[1])
11568     || operands_match_p (operands[1], operands[3]))
11569    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11570   [(set (match_dup 4) (match_dup 0))
11571    (set (strict_low_part (match_dup 5))
11572         (match_dup 2))]
11574   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11575   operands[5] = gen_lowpart (QImode, operands[3]);
11576   ix86_expand_clear (operands[3]);
11579 (define_peephole2
11580   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11581               (match_operand 4)])
11582    (set (match_operand:QI 1 "register_operand")
11583         (match_operator:QI 2 "ix86_comparison_operator"
11584           [(reg FLAGS_REG) (const_int 0)]))
11585    (set (match_operand 3 "any_QIreg_operand")
11586         (zero_extend (match_dup 1)))]
11587   "(peep2_reg_dead_p (3, operands[1])
11588     || operands_match_p (operands[1], operands[3]))
11589    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11590   [(parallel [(set (match_dup 5) (match_dup 0))
11591               (match_dup 4)])
11592    (set (strict_low_part (match_dup 6))
11593         (match_dup 2))]
11595   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11596   operands[6] = gen_lowpart (QImode, operands[3]);
11597   ix86_expand_clear (operands[3]);
11600 ;; Similar, but match zero extend with andsi3.
11602 (define_peephole2
11603   [(set (reg FLAGS_REG) (match_operand 0))
11604    (set (match_operand:QI 1 "register_operand")
11605         (match_operator:QI 2 "ix86_comparison_operator"
11606           [(reg FLAGS_REG) (const_int 0)]))
11607    (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
11608                    (and:SI (match_dup 3) (const_int 255)))
11609               (clobber (reg:CC FLAGS_REG))])]
11610   "REGNO (operands[1]) == REGNO (operands[3])
11611    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11612   [(set (match_dup 4) (match_dup 0))
11613    (set (strict_low_part (match_dup 5))
11614         (match_dup 2))]
11616   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11617   operands[5] = gen_lowpart (QImode, operands[3]);
11618   ix86_expand_clear (operands[3]);
11621 (define_peephole2
11622   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11623               (match_operand 4)])
11624    (set (match_operand:QI 1 "register_operand")
11625         (match_operator:QI 2 "ix86_comparison_operator"
11626           [(reg FLAGS_REG) (const_int 0)]))
11627    (parallel [(set (match_operand 3 "any_QIreg_operand")
11628                    (zero_extend (match_dup 1)))
11629               (clobber (reg:CC FLAGS_REG))])]
11630   "(peep2_reg_dead_p (3, operands[1])
11631     || operands_match_p (operands[1], operands[3]))
11632    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11633   [(parallel [(set (match_dup 5) (match_dup 0))
11634               (match_dup 4)])
11635    (set (strict_low_part (match_dup 6))
11636         (match_dup 2))]
11638   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11639   operands[6] = gen_lowpart (QImode, operands[3]);
11640   ix86_expand_clear (operands[3]);
11643 ;; Call instructions.
11645 ;; The predicates normally associated with named expanders are not properly
11646 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11647 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11649 ;; P6 processors will jump to the address after the decrement when %esp
11650 ;; is used as a call operand, so they will execute return address as a code.
11651 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11653 ;; Register constraint for call instruction.
11654 (define_mode_attr c [(SI "l") (DI "r")])
11656 ;; Call subroutine returning no value.
11658 (define_expand "call"
11659   [(call (match_operand:QI 0)
11660          (match_operand 1))
11661    (use (match_operand 2))]
11662   ""
11664   ix86_expand_call (NULL, operands[0], operands[1],
11665                     operands[2], NULL, false);
11666   DONE;
11669 (define_expand "sibcall"
11670   [(call (match_operand:QI 0)
11671          (match_operand 1))
11672    (use (match_operand 2))]
11673   ""
11675   ix86_expand_call (NULL, operands[0], operands[1],
11676                     operands[2], NULL, true);
11677   DONE;
11680 (define_insn "*call"
11681   [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
11682          (match_operand 1))]
11683   "!SIBLING_CALL_P (insn)"
11684   "* return ix86_output_call_insn (insn, operands[0]);"
11685   [(set_attr "type" "call")])
11687 (define_insn "*sibcall"
11688   [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
11689          (match_operand 1))]
11690   "SIBLING_CALL_P (insn)"
11691   "* return ix86_output_call_insn (insn, operands[0]);"
11692   [(set_attr "type" "call")])
11694 (define_insn "*sibcall_memory"
11695   [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
11696          (match_operand 1))
11697    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11698   "!TARGET_X32"
11699   "* return ix86_output_call_insn (insn, operands[0]);"
11700   [(set_attr "type" "call")])
11702 (define_peephole2
11703   [(set (match_operand:W 0 "register_operand")
11704         (match_operand:W 1 "memory_operand"))
11705    (call (mem:QI (match_dup 0))
11706          (match_operand 3))]
11707   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11708    && peep2_reg_dead_p (2, operands[0])"
11709   [(parallel [(call (mem:QI (match_dup 1))
11710                     (match_dup 3))
11711               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11713 (define_peephole2
11714   [(set (match_operand:W 0 "register_operand")
11715         (match_operand:W 1 "memory_operand"))
11716    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11717    (call (mem:QI (match_dup 0))
11718          (match_operand 3))]
11719   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11720    && peep2_reg_dead_p (3, operands[0])"
11721   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11722    (parallel [(call (mem:QI (match_dup 1))
11723                     (match_dup 3))
11724               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11726 (define_expand "call_pop"
11727   [(parallel [(call (match_operand:QI 0)
11728                     (match_operand:SI 1))
11729               (set (reg:SI SP_REG)
11730                    (plus:SI (reg:SI SP_REG)
11731                             (match_operand:SI 3)))])]
11732   "!TARGET_64BIT"
11734   ix86_expand_call (NULL, operands[0], operands[1],
11735                     operands[2], operands[3], false);
11736   DONE;
11739 (define_insn "*call_pop"
11740   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
11741          (match_operand 1))
11742    (set (reg:SI SP_REG)
11743         (plus:SI (reg:SI SP_REG)
11744                  (match_operand:SI 2 "immediate_operand" "i")))]
11745   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11746   "* return ix86_output_call_insn (insn, operands[0]);"
11747   [(set_attr "type" "call")])
11749 (define_insn "*sibcall_pop"
11750   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
11751          (match_operand 1))
11752    (set (reg:SI SP_REG)
11753         (plus:SI (reg:SI SP_REG)
11754                  (match_operand:SI 2 "immediate_operand" "i")))]
11755   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11756   "* return ix86_output_call_insn (insn, operands[0]);"
11757   [(set_attr "type" "call")])
11759 (define_insn "*sibcall_pop_memory"
11760   [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
11761          (match_operand 1))
11762    (set (reg:SI SP_REG)
11763         (plus:SI (reg:SI SP_REG)
11764                  (match_operand:SI 2 "immediate_operand" "i")))
11765    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11766   "!TARGET_64BIT"
11767   "* return ix86_output_call_insn (insn, operands[0]);"
11768   [(set_attr "type" "call")])
11770 (define_peephole2
11771   [(set (match_operand:SI 0 "register_operand")
11772         (match_operand:SI 1 "memory_operand"))
11773    (parallel [(call (mem:QI (match_dup 0))
11774                     (match_operand 3))
11775               (set (reg:SI SP_REG)
11776                    (plus:SI (reg:SI SP_REG)
11777                             (match_operand:SI 4 "immediate_operand")))])]
11778   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11779    && peep2_reg_dead_p (2, operands[0])"
11780   [(parallel [(call (mem:QI (match_dup 1))
11781                     (match_dup 3))
11782               (set (reg:SI SP_REG)
11783                    (plus:SI (reg:SI SP_REG)
11784                             (match_dup 4)))
11785               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11787 (define_peephole2
11788   [(set (match_operand:SI 0 "register_operand")
11789         (match_operand:SI 1 "memory_operand"))
11790    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11791    (parallel [(call (mem:QI (match_dup 0))
11792                     (match_operand 3))
11793               (set (reg:SI SP_REG)
11794                    (plus:SI (reg:SI SP_REG)
11795                             (match_operand:SI 4 "immediate_operand")))])]
11796   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11797    && peep2_reg_dead_p (3, operands[0])"
11798   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11799    (parallel [(call (mem:QI (match_dup 1))
11800                     (match_dup 3))
11801               (set (reg:SI SP_REG)
11802                    (plus:SI (reg:SI SP_REG)
11803                             (match_dup 4)))
11804               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11806 ;; Combining simple memory jump instruction
11808 (define_peephole2
11809   [(set (match_operand:W 0 "register_operand")
11810         (match_operand:W 1 "memory_operand"))
11811    (set (pc) (match_dup 0))]
11812   "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
11813   [(set (pc) (match_dup 1))])
11815 ;; Call subroutine, returning value in operand 0
11817 (define_expand "call_value"
11818   [(set (match_operand 0)
11819         (call (match_operand:QI 1)
11820               (match_operand 2)))
11821    (use (match_operand 3))]
11822   ""
11824   ix86_expand_call (operands[0], operands[1], operands[2],
11825                     operands[3], NULL, false);
11826   DONE;
11829 (define_expand "sibcall_value"
11830   [(set (match_operand 0)
11831         (call (match_operand:QI 1)
11832               (match_operand 2)))
11833    (use (match_operand 3))]
11834   ""
11836   ix86_expand_call (operands[0], operands[1], operands[2],
11837                     operands[3], NULL, true);
11838   DONE;
11841 (define_insn "*call_value"
11842   [(set (match_operand 0)
11843         (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
11844               (match_operand 2)))]
11845   "!SIBLING_CALL_P (insn)"
11846   "* return ix86_output_call_insn (insn, operands[1]);"
11847   [(set_attr "type" "callv")])
11849 (define_insn "*sibcall_value"
11850   [(set (match_operand 0)
11851         (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
11852               (match_operand 2)))]
11853   "SIBLING_CALL_P (insn)"
11854   "* return ix86_output_call_insn (insn, operands[1]);"
11855   [(set_attr "type" "callv")])
11857 (define_insn "*sibcall_value_memory"
11858   [(set (match_operand 0)
11859         (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
11860               (match_operand 2)))
11861    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11862   "!TARGET_X32"
11863   "* return ix86_output_call_insn (insn, operands[1]);"
11864   [(set_attr "type" "callv")])
11866 (define_peephole2
11867   [(set (match_operand:W 0 "register_operand")
11868         (match_operand:W 1 "memory_operand"))
11869    (set (match_operand 2)
11870    (call (mem:QI (match_dup 0))
11871                  (match_operand 3)))]
11872   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11873    && peep2_reg_dead_p (2, operands[0])"
11874   [(parallel [(set (match_dup 2)
11875                    (call (mem:QI (match_dup 1))
11876                          (match_dup 3)))
11877               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11879 (define_peephole2
11880   [(set (match_operand:W 0 "register_operand")
11881         (match_operand:W 1 "memory_operand"))
11882    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11883    (set (match_operand 2)
11884         (call (mem:QI (match_dup 0))
11885               (match_operand 3)))]
11886   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11887    && peep2_reg_dead_p (3, operands[0])"
11888   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11889    (parallel [(set (match_dup 2)
11890                    (call (mem:QI (match_dup 1))
11891                          (match_dup 3)))
11892               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11894 (define_expand "call_value_pop"
11895   [(parallel [(set (match_operand 0)
11896                    (call (match_operand:QI 1)
11897                          (match_operand:SI 2)))
11898               (set (reg:SI SP_REG)
11899                    (plus:SI (reg:SI SP_REG)
11900                             (match_operand:SI 4)))])]
11901   "!TARGET_64BIT"
11903   ix86_expand_call (operands[0], operands[1], operands[2],
11904                     operands[3], operands[4], false);
11905   DONE;
11908 (define_insn "*call_value_pop"
11909   [(set (match_operand 0)
11910         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
11911               (match_operand 2)))
11912    (set (reg:SI SP_REG)
11913         (plus:SI (reg:SI SP_REG)
11914                  (match_operand:SI 3 "immediate_operand" "i")))]
11915   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11916   "* return ix86_output_call_insn (insn, operands[1]);"
11917   [(set_attr "type" "callv")])
11919 (define_insn "*sibcall_value_pop"
11920   [(set (match_operand 0)
11921         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
11922               (match_operand 2)))
11923    (set (reg:SI SP_REG)
11924         (plus:SI (reg:SI SP_REG)
11925                  (match_operand:SI 3 "immediate_operand" "i")))]
11926   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11927   "* return ix86_output_call_insn (insn, operands[1]);"
11928   [(set_attr "type" "callv")])
11930 (define_insn "*sibcall_value_pop_memory"
11931   [(set (match_operand 0)
11932         (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
11933               (match_operand 2)))
11934    (set (reg:SI SP_REG)
11935         (plus:SI (reg:SI SP_REG)
11936                  (match_operand:SI 3 "immediate_operand" "i")))
11937    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11938   "!TARGET_64BIT"
11939   "* return ix86_output_call_insn (insn, operands[1]);"
11940   [(set_attr "type" "callv")])
11942 (define_peephole2
11943   [(set (match_operand:SI 0 "register_operand")
11944         (match_operand:SI 1 "memory_operand"))
11945    (parallel [(set (match_operand 2)
11946                    (call (mem:QI (match_dup 0))
11947                          (match_operand 3)))
11948               (set (reg:SI SP_REG)
11949                    (plus:SI (reg:SI SP_REG)
11950                             (match_operand:SI 4 "immediate_operand")))])]
11951   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11952    && peep2_reg_dead_p (2, operands[0])"
11953   [(parallel [(set (match_dup 2)
11954                    (call (mem:QI (match_dup 1))
11955                          (match_dup 3)))
11956               (set (reg:SI SP_REG)
11957                    (plus:SI (reg:SI SP_REG)
11958                             (match_dup 4)))
11959               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11961 (define_peephole2
11962   [(set (match_operand:SI 0 "register_operand")
11963         (match_operand:SI 1 "memory_operand"))
11964    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11965    (parallel [(set (match_operand 2)
11966                    (call (mem:QI (match_dup 0))
11967                          (match_operand 3)))
11968               (set (reg:SI SP_REG)
11969                    (plus:SI (reg:SI SP_REG)
11970                             (match_operand:SI 4 "immediate_operand")))])]
11971   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11972    && peep2_reg_dead_p (3, operands[0])"
11973   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11974    (parallel [(set (match_dup 2)
11975                    (call (mem:QI (match_dup 1))
11976                          (match_dup 3)))
11977               (set (reg:SI SP_REG)
11978                    (plus:SI (reg:SI SP_REG)
11979                             (match_dup 4)))
11980               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11982 ;; Call subroutine returning any type.
11984 (define_expand "untyped_call"
11985   [(parallel [(call (match_operand 0)
11986                     (const_int 0))
11987               (match_operand 1)
11988               (match_operand 2)])]
11989   ""
11991   int i;
11993   /* In order to give reg-stack an easier job in validating two
11994      coprocessor registers as containing a possible return value,
11995      simply pretend the untyped call returns a complex long double
11996      value. 
11998      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11999      and should have the default ABI.  */
12001   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
12002                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
12003                     operands[0], const0_rtx,
12004                     GEN_INT ((TARGET_64BIT
12005                               ? (ix86_abi == SYSV_ABI
12006                                  ? X86_64_SSE_REGPARM_MAX
12007                                  : X86_64_MS_SSE_REGPARM_MAX)
12008                               : X86_32_SSE_REGPARM_MAX)
12009                              - 1),
12010                     NULL, false);
12012   for (i = 0; i < XVECLEN (operands[2], 0); i++)
12013     {
12014       rtx set = XVECEXP (operands[2], 0, i);
12015       emit_move_insn (SET_DEST (set), SET_SRC (set));
12016     }
12018   /* The optimizer does not know that the call sets the function value
12019      registers we stored in the result block.  We avoid problems by
12020      claiming that all hard registers are used and clobbered at this
12021      point.  */
12022   emit_insn (gen_blockage ());
12024   DONE;
12027 ;; Prologue and epilogue instructions
12029 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
12030 ;; all of memory.  This blocks insns from being moved across this point.
12032 (define_insn "blockage"
12033   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
12034   ""
12035   ""
12036   [(set_attr "length" "0")])
12038 ;; Do not schedule instructions accessing memory across this point.
12040 (define_expand "memory_blockage"
12041   [(set (match_dup 0)
12042         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12043   ""
12045   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12046   MEM_VOLATILE_P (operands[0]) = 1;
12049 (define_insn "*memory_blockage"
12050   [(set (match_operand:BLK 0)
12051         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12052   ""
12053   ""
12054   [(set_attr "length" "0")])
12056 ;; As USE insns aren't meaningful after reload, this is used instead
12057 ;; to prevent deleting instructions setting registers for PIC code
12058 (define_insn "prologue_use"
12059   [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
12060   ""
12061   ""
12062   [(set_attr "length" "0")])
12064 ;; Insn emitted into the body of a function to return from a function.
12065 ;; This is only done if the function's epilogue is known to be simple.
12066 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12068 (define_expand "return"
12069   [(simple_return)]
12070   "ix86_can_use_return_insn_p ()"
12072   if (crtl->args.pops_args)
12073     {
12074       rtx popc = GEN_INT (crtl->args.pops_args);
12075       emit_jump_insn (gen_simple_return_pop_internal (popc));
12076       DONE;
12077     }
12080 ;; We need to disable this for TARGET_SEH, as otherwise
12081 ;; shrink-wrapped prologue gets enabled too.  This might exceed
12082 ;; the maximum size of prologue in unwind information.
12084 (define_expand "simple_return"
12085   [(simple_return)]
12086   "!TARGET_SEH"
12088   if (crtl->args.pops_args)
12089     {
12090       rtx popc = GEN_INT (crtl->args.pops_args);
12091       emit_jump_insn (gen_simple_return_pop_internal (popc));
12092       DONE;
12093     }
12096 (define_insn "simple_return_internal"
12097   [(simple_return)]
12098   "reload_completed"
12099   "%!ret"
12100   [(set_attr "length_nobnd" "1")
12101    (set_attr "atom_unit" "jeu")
12102    (set_attr "length_immediate" "0")
12103    (set_attr "modrm" "0")])
12105 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12106 ;; instruction Athlon and K8 have.
12108 (define_insn "simple_return_internal_long"
12109   [(simple_return)
12110    (unspec [(const_int 0)] UNSPEC_REP)]
12111   "reload_completed"
12113   if (ix86_bnd_prefixed_insn_p (insn))
12114     return "%!ret";
12116   return "rep%; ret";
12118   [(set_attr "length" "2")
12119    (set_attr "atom_unit" "jeu")
12120    (set_attr "length_immediate" "0")
12121    (set_attr "prefix_rep" "1")
12122    (set_attr "modrm" "0")])
12124 (define_insn "simple_return_pop_internal"
12125   [(simple_return)
12126    (use (match_operand:SI 0 "const_int_operand"))]
12127   "reload_completed"
12128   "%!ret\t%0"
12129   [(set_attr "length_nobnd" "3")
12130    (set_attr "atom_unit" "jeu")
12131    (set_attr "length_immediate" "2")
12132    (set_attr "modrm" "0")])
12134 (define_insn "simple_return_indirect_internal"
12135   [(simple_return)
12136    (use (match_operand:SI 0 "register_operand" "r"))]
12137   "reload_completed"
12138   "%!jmp\t%A0"
12139   [(set_attr "type" "ibr")
12140    (set_attr "length_immediate" "0")])
12142 (define_insn "nop"
12143   [(const_int 0)]
12144   ""
12145   "nop"
12146   [(set_attr "length" "1")
12147    (set_attr "length_immediate" "0")
12148    (set_attr "modrm" "0")])
12150 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
12151 (define_insn "nops"
12152   [(unspec_volatile [(match_operand 0 "const_int_operand")]
12153                     UNSPECV_NOPS)]
12154   "reload_completed"
12156   int num = INTVAL (operands[0]);
12158   gcc_assert (IN_RANGE (num, 1, 8));
12160   while (num--)
12161     fputs ("\tnop\n", asm_out_file);
12163   return "";
12165   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12166    (set_attr "length_immediate" "0")
12167    (set_attr "modrm" "0")])
12169 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
12170 ;; branch prediction penalty for the third jump in a 16-byte
12171 ;; block on K8.
12173 (define_insn "pad"
12174   [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12175   ""
12177 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12178   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12179 #else
12180   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12181      The align insn is used to avoid 3 jump instructions in the row to improve
12182      branch prediction and the benefits hardly outweigh the cost of extra 8
12183      nops on the average inserted by full alignment pseudo operation.  */
12184 #endif
12185   return "";
12187   [(set_attr "length" "16")])
12189 (define_expand "prologue"
12190   [(const_int 0)]
12191   ""
12192   "ix86_expand_prologue (); DONE;")
12194 (define_insn "set_got"
12195   [(set (match_operand:SI 0 "register_operand" "=r")
12196         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12197    (clobber (reg:CC FLAGS_REG))]
12198   "!TARGET_64BIT"
12199   "* return output_set_got (operands[0], NULL_RTX);"
12200   [(set_attr "type" "multi")
12201    (set_attr "length" "12")])
12203 (define_insn "set_got_labelled"
12204   [(set (match_operand:SI 0 "register_operand" "=r")
12205         (unspec:SI [(label_ref (match_operand 1))]
12206          UNSPEC_SET_GOT))
12207    (clobber (reg:CC FLAGS_REG))]
12208   "!TARGET_64BIT"
12209   "* return output_set_got (operands[0], operands[1]);"
12210   [(set_attr "type" "multi")
12211    (set_attr "length" "12")])
12213 (define_insn "set_got_rex64"
12214   [(set (match_operand:DI 0 "register_operand" "=r")
12215         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12216   "TARGET_64BIT"
12217   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12218   [(set_attr "type" "lea")
12219    (set_attr "length_address" "4")
12220    (set_attr "mode" "DI")])
12222 (define_insn "set_rip_rex64"
12223   [(set (match_operand:DI 0 "register_operand" "=r")
12224         (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12225   "TARGET_64BIT"
12226   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12227   [(set_attr "type" "lea")
12228    (set_attr "length_address" "4")
12229    (set_attr "mode" "DI")])
12231 (define_insn "set_got_offset_rex64"
12232   [(set (match_operand:DI 0 "register_operand" "=r")
12233         (unspec:DI
12234           [(label_ref (match_operand 1))]
12235           UNSPEC_SET_GOT_OFFSET))]
12236   "TARGET_LP64"
12237   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12238   [(set_attr "type" "imov")
12239    (set_attr "length_immediate" "0")
12240    (set_attr "length_address" "8")
12241    (set_attr "mode" "DI")])
12243 (define_expand "epilogue"
12244   [(const_int 0)]
12245   ""
12246   "ix86_expand_epilogue (1); DONE;")
12248 (define_expand "sibcall_epilogue"
12249   [(const_int 0)]
12250   ""
12251   "ix86_expand_epilogue (0); DONE;")
12253 (define_expand "eh_return"
12254   [(use (match_operand 0 "register_operand"))]
12255   ""
12257   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12259   /* Tricky bit: we write the address of the handler to which we will
12260      be returning into someone else's stack frame, one word below the
12261      stack address we wish to restore.  */
12262   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12263   tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12264   tmp = gen_rtx_MEM (Pmode, tmp);
12265   emit_move_insn (tmp, ra);
12267   emit_jump_insn (gen_eh_return_internal ());
12268   emit_barrier ();
12269   DONE;
12272 (define_insn_and_split "eh_return_internal"
12273   [(eh_return)]
12274   ""
12275   "#"
12276   "epilogue_completed"
12277   [(const_int 0)]
12278   "ix86_expand_epilogue (2); DONE;")
12280 (define_insn "leave"
12281   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12282    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12283    (clobber (mem:BLK (scratch)))]
12284   "!TARGET_64BIT"
12285   "leave"
12286   [(set_attr "type" "leave")])
12288 (define_insn "leave_rex64"
12289   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12290    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12291    (clobber (mem:BLK (scratch)))]
12292   "TARGET_64BIT"
12293   "leave"
12294   [(set_attr "type" "leave")])
12296 ;; Handle -fsplit-stack.
12298 (define_expand "split_stack_prologue"
12299   [(const_int 0)]
12300   ""
12302   ix86_expand_split_stack_prologue ();
12303   DONE;
12306 ;; In order to support the call/return predictor, we use a return
12307 ;; instruction which the middle-end doesn't see.
12308 (define_insn "split_stack_return"
12309   [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12310                      UNSPECV_SPLIT_STACK_RETURN)]
12311   ""
12313   if (operands[0] == const0_rtx)
12314     return "ret";
12315   else
12316     return "ret\t%0";
12318   [(set_attr "atom_unit" "jeu")
12319    (set_attr "modrm" "0")
12320    (set (attr "length")
12321         (if_then_else (match_operand:SI 0 "const0_operand")
12322                       (const_int 1)
12323                       (const_int 3)))
12324    (set (attr "length_immediate")
12325         (if_then_else (match_operand:SI 0 "const0_operand")
12326                       (const_int 0)
12327                       (const_int 2)))])
12329 ;; If there are operand 0 bytes available on the stack, jump to
12330 ;; operand 1.
12332 (define_expand "split_stack_space_check"
12333   [(set (pc) (if_then_else
12334               (ltu (minus (reg SP_REG)
12335                           (match_operand 0 "register_operand"))
12336                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12337               (label_ref (match_operand 1))
12338               (pc)))]
12339   ""
12341   rtx reg, size, limit;
12343   reg = gen_reg_rtx (Pmode);
12344   size = force_reg (Pmode, operands[0]);
12345   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12346   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12347                           UNSPEC_STACK_CHECK);
12348   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12349   ix86_expand_branch (GEU, reg, limit, operands[1]);
12351   DONE;
12354 ;; Bit manipulation instructions.
12356 (define_expand "ffs<mode>2"
12357   [(set (match_dup 2) (const_int -1))
12358    (parallel [(set (match_dup 3) (match_dup 4))
12359               (set (match_operand:SWI48 0 "register_operand")
12360                    (ctz:SWI48
12361                      (match_operand:SWI48 1 "nonimmediate_operand")))])
12362    (set (match_dup 0) (if_then_else:SWI48
12363                         (eq (match_dup 3) (const_int 0))
12364                         (match_dup 2)
12365                         (match_dup 0)))
12366    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12367               (clobber (reg:CC FLAGS_REG))])]
12368   ""
12370   machine_mode flags_mode;
12372   if (<MODE>mode == SImode && !TARGET_CMOVE)
12373     {
12374       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12375       DONE;
12376     }
12378   flags_mode
12379     = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12381   operands[2] = gen_reg_rtx (<MODE>mode);
12382   operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12383   operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12386 (define_insn_and_split "ffssi2_no_cmove"
12387   [(set (match_operand:SI 0 "register_operand" "=r")
12388         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12389    (clobber (match_scratch:SI 2 "=&q"))
12390    (clobber (reg:CC FLAGS_REG))]
12391   "!TARGET_CMOVE"
12392   "#"
12393   "&& reload_completed"
12394   [(parallel [(set (match_dup 4) (match_dup 5))
12395               (set (match_dup 0) (ctz:SI (match_dup 1)))])
12396    (set (strict_low_part (match_dup 3))
12397         (eq:QI (match_dup 4) (const_int 0)))
12398    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12399               (clobber (reg:CC FLAGS_REG))])
12400    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12401               (clobber (reg:CC FLAGS_REG))])
12402    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12403               (clobber (reg:CC FLAGS_REG))])]
12405   machine_mode flags_mode
12406     = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12408   operands[3] = gen_lowpart (QImode, operands[2]);
12409   operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12410   operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12412   ix86_expand_clear (operands[2]);
12415 (define_insn "*tzcnt<mode>_1"
12416   [(set (reg:CCC FLAGS_REG)
12417         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12418                      (const_int 0)))
12419    (set (match_operand:SWI48 0 "register_operand" "=r")
12420         (ctz:SWI48 (match_dup 1)))]
12421   "TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI"
12422   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12423   [(set_attr "type" "alu1")
12424    (set_attr "prefix_0f" "1")
12425    (set_attr "prefix_rep" "1")
12426    (set_attr "btver2_decode" "double")
12427    (set_attr "mode" "<MODE>")])
12429 (define_insn "*bsf<mode>_1"
12430   [(set (reg:CCZ FLAGS_REG)
12431         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12432                      (const_int 0)))
12433    (set (match_operand:SWI48 0 "register_operand" "=r")
12434         (ctz:SWI48 (match_dup 1)))]
12435   ""
12436   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12437   [(set_attr "type" "alu1")
12438    (set_attr "prefix_0f" "1")
12439    (set_attr "btver2_decode" "double")
12440    (set_attr "mode" "<MODE>")])
12442 (define_expand "ctz<mode>2"
12443   [(parallel
12444     [(set (match_operand:SWI248 0 "register_operand")
12445           (ctz:SWI248
12446             (match_operand:SWI248 1 "nonimmediate_operand")))
12447      (clobber (reg:CC FLAGS_REG))])])
12449 ; False dependency happens when destination is only updated by tzcnt,
12450 ; lzcnt or popcnt.  There is no false dependency when destination is
12451 ; also used in source.
12452 (define_insn_and_split "*ctz<mode>2_falsedep_1"
12453   [(set (match_operand:SWI48 0 "register_operand" "=r")
12454         (ctz:SWI48
12455           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12456    (clobber (reg:CC FLAGS_REG))]
12457   "(TARGET_BMI || TARGET_GENERIC)
12458    && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12459   "#"
12460   "&& reload_completed"
12461   [(parallel
12462     [(set (match_dup 0)
12463           (ctz:SWI48 (match_dup 1)))
12464      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12465      (clobber (reg:CC FLAGS_REG))])]
12467   if (!reg_mentioned_p (operands[0], operands[1]))
12468     ix86_expand_clear (operands[0]);
12471 (define_insn "*ctz<mode>2_falsedep"
12472   [(set (match_operand:SWI48 0 "register_operand" "=r")
12473         (ctz:SWI48
12474           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12475    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12476            UNSPEC_INSN_FALSE_DEP)
12477    (clobber (reg:CC FLAGS_REG))]
12478   ""
12480   if (TARGET_BMI)
12481     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12482   else if (TARGET_GENERIC)
12483     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
12484     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12485   else
12486     gcc_unreachable ();
12488   [(set_attr "type" "alu1")
12489    (set_attr "prefix_0f" "1")
12490    (set_attr "prefix_rep" "1")
12491    (set_attr "mode" "<MODE>")])
12493 (define_insn "*ctz<mode>2"
12494   [(set (match_operand:SWI248 0 "register_operand" "=r")
12495         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12496    (clobber (reg:CC FLAGS_REG))]
12497   ""
12499   if (TARGET_BMI)
12500     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12501   else if (optimize_function_for_size_p (cfun))
12502     ;
12503   else if (TARGET_GENERIC)
12504     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
12505     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12507   return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12509   [(set_attr "type" "alu1")
12510    (set_attr "prefix_0f" "1")
12511    (set (attr "prefix_rep")
12512      (if_then_else
12513        (ior (match_test "TARGET_BMI")
12514             (and (not (match_test "optimize_function_for_size_p (cfun)"))
12515                  (match_test "TARGET_GENERIC")))
12516        (const_string "1")
12517        (const_string "0")))
12518    (set_attr "mode" "<MODE>")])
12520 (define_expand "clz<mode>2"
12521   [(parallel
12522      [(set (match_operand:SWI248 0 "register_operand")
12523            (minus:SWI248
12524              (match_dup 2)
12525              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12526       (clobber (reg:CC FLAGS_REG))])
12527    (parallel
12528      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12529       (clobber (reg:CC FLAGS_REG))])]
12530   ""
12532   if (TARGET_LZCNT)
12533     {
12534       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12535       DONE;
12536     }
12537   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12540 (define_expand "clz<mode>2_lzcnt"
12541   [(parallel
12542     [(set (match_operand:SWI248 0 "register_operand")
12543           (clz:SWI248
12544             (match_operand:SWI248 1 "nonimmediate_operand")))
12545      (clobber (reg:CC FLAGS_REG))])]
12546   "TARGET_LZCNT")
12548 (define_insn_and_split "*clz<mode>2_lzcnt_falsedep_1"
12549   [(set (match_operand:SWI48 0 "register_operand" "=r")
12550         (clz:SWI48
12551           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12552    (clobber (reg:CC FLAGS_REG))]
12553   "TARGET_LZCNT
12554    && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12555   "#"
12556   "&& reload_completed"
12557   [(parallel
12558     [(set (match_dup 0)
12559           (clz:SWI48 (match_dup 1)))
12560      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12561      (clobber (reg:CC FLAGS_REG))])]
12563   if (!reg_mentioned_p (operands[0], operands[1]))
12564     ix86_expand_clear (operands[0]);
12567 (define_insn "*clz<mode>2_lzcnt_falsedep"
12568   [(set (match_operand:SWI48 0 "register_operand" "=r")
12569         (clz:SWI48
12570           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12571    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12572            UNSPEC_INSN_FALSE_DEP)
12573    (clobber (reg:CC FLAGS_REG))]
12574   "TARGET_LZCNT"
12575   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12576   [(set_attr "prefix_rep" "1")
12577    (set_attr "type" "bitmanip")
12578    (set_attr "mode" "<MODE>")])
12580 (define_insn "*clz<mode>2_lzcnt"
12581   [(set (match_operand:SWI248 0 "register_operand" "=r")
12582         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12583    (clobber (reg:CC FLAGS_REG))]
12584   "TARGET_LZCNT"
12585   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12586   [(set_attr "prefix_rep" "1")
12587    (set_attr "type" "bitmanip")
12588    (set_attr "mode" "<MODE>")])
12590 ;; BMI instructions.
12591 (define_insn "*bmi_andn_<mode>"
12592   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12593         (and:SWI48
12594           (not:SWI48
12595             (match_operand:SWI48 1 "register_operand" "r,r"))
12596             (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12597    (clobber (reg:CC FLAGS_REG))]
12598   "TARGET_BMI"
12599   "andn\t{%2, %1, %0|%0, %1, %2}"
12600   [(set_attr "type" "bitmanip")
12601    (set_attr "btver2_decode" "direct, double")
12602    (set_attr "mode" "<MODE>")])
12604 (define_insn "bmi_bextr_<mode>"
12605   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12606         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12607                        (match_operand:SWI48 2 "register_operand" "r,r")]
12608                        UNSPEC_BEXTR))
12609    (clobber (reg:CC FLAGS_REG))]
12610   "TARGET_BMI"
12611   "bextr\t{%2, %1, %0|%0, %1, %2}"
12612   [(set_attr "type" "bitmanip")
12613    (set_attr "btver2_decode" "direct, double")
12614    (set_attr "mode" "<MODE>")])
12616 (define_insn "*bmi_blsi_<mode>"
12617   [(set (match_operand:SWI48 0 "register_operand" "=r")
12618         (and:SWI48
12619           (neg:SWI48
12620             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12621           (match_dup 1)))
12622    (clobber (reg:CC FLAGS_REG))]
12623   "TARGET_BMI"
12624   "blsi\t{%1, %0|%0, %1}"
12625   [(set_attr "type" "bitmanip")
12626    (set_attr "btver2_decode" "double")
12627    (set_attr "mode" "<MODE>")])
12629 (define_insn "*bmi_blsmsk_<mode>"
12630   [(set (match_operand:SWI48 0 "register_operand" "=r")
12631         (xor:SWI48
12632           (plus:SWI48
12633             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12634             (const_int -1))
12635           (match_dup 1)))
12636    (clobber (reg:CC FLAGS_REG))]
12637   "TARGET_BMI"
12638   "blsmsk\t{%1, %0|%0, %1}"
12639   [(set_attr "type" "bitmanip")
12640    (set_attr "btver2_decode" "double")
12641    (set_attr "mode" "<MODE>")])
12643 (define_insn "*bmi_blsr_<mode>"
12644   [(set (match_operand:SWI48 0 "register_operand" "=r")
12645         (and:SWI48
12646           (plus:SWI48
12647             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12648             (const_int -1))
12649           (match_dup 1)))
12650    (clobber (reg:CC FLAGS_REG))]
12651    "TARGET_BMI"
12652    "blsr\t{%1, %0|%0, %1}"
12653   [(set_attr "type" "bitmanip")
12654    (set_attr "btver2_decode" "double")
12655    (set_attr "mode" "<MODE>")])
12657 ;; BMI2 instructions.
12658 (define_expand "bmi2_bzhi_<mode>3"
12659   [(parallel
12660     [(set (match_operand:SWI48 0 "register_operand")
12661           (zero_extract:SWI48
12662             (match_operand:SWI48 1 "nonimmediate_operand")
12663             (umin:SWI48
12664               (and:SWI48 (match_operand:SWI48 2 "register_operand")
12665                          (const_int 255))
12666               (match_dup 3))
12667             (const_int 0)))
12668      (clobber (reg:CC FLAGS_REG))])]
12669   "TARGET_BMI2"
12670   "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
12672 (define_insn "*bmi2_bzhi_<mode>3"
12673   [(set (match_operand:SWI48 0 "register_operand" "=r")
12674         (zero_extract:SWI48
12675           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12676           (umin:SWI48
12677             (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
12678                        (const_int 255))
12679             (match_operand:SWI48 3 "const_int_operand" "n"))
12680           (const_int 0)))
12681    (clobber (reg:CC FLAGS_REG))]
12682   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12683   "bzhi\t{%2, %1, %0|%0, %1, %2}"
12684   [(set_attr "type" "bitmanip")
12685    (set_attr "prefix" "vex")
12686    (set_attr "mode" "<MODE>")])
12688 (define_mode_attr k [(SI "k") (DI "q")])
12689 (define_insn "*bmi2_bzhi_<mode>3_1"
12690   [(set (match_operand:SWI48 0 "register_operand" "=r")
12691         (zero_extract:SWI48
12692           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12693           (umin:SWI48
12694             (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
12695             (match_operand:SWI48 3 "const_int_operand" "n"))
12696           (const_int 0)))
12697    (clobber (reg:CC FLAGS_REG))]
12698   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12699   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
12700   [(set_attr "type" "bitmanip")
12701    (set_attr "prefix" "vex")
12702    (set_attr "mode" "<MODE>")])
12704 (define_insn "bmi2_pdep_<mode>3"
12705   [(set (match_operand:SWI48 0 "register_operand" "=r")
12706         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12707                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12708                        UNSPEC_PDEP))]
12709   "TARGET_BMI2"
12710   "pdep\t{%2, %1, %0|%0, %1, %2}"
12711   [(set_attr "type" "bitmanip")
12712    (set_attr "prefix" "vex")
12713    (set_attr "mode" "<MODE>")])
12715 (define_insn "bmi2_pext_<mode>3"
12716   [(set (match_operand:SWI48 0 "register_operand" "=r")
12717         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12718                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12719                        UNSPEC_PEXT))]
12720   "TARGET_BMI2"
12721   "pext\t{%2, %1, %0|%0, %1, %2}"
12722   [(set_attr "type" "bitmanip")
12723    (set_attr "prefix" "vex")
12724    (set_attr "mode" "<MODE>")])
12726 ;; TBM instructions.
12727 (define_insn "tbm_bextri_<mode>"
12728   [(set (match_operand:SWI48 0 "register_operand" "=r")
12729         (zero_extract:SWI48
12730           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12731           (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12732           (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12733    (clobber (reg:CC FLAGS_REG))]
12734    "TARGET_TBM"
12736   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12737   return "bextr\t{%2, %1, %0|%0, %1, %2}";
12739   [(set_attr "type" "bitmanip")
12740    (set_attr "mode" "<MODE>")])
12742 (define_insn "*tbm_blcfill_<mode>"
12743   [(set (match_operand:SWI48 0 "register_operand" "=r")
12744         (and:SWI48
12745           (plus:SWI48
12746             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12747             (const_int 1))
12748           (match_dup 1)))
12749    (clobber (reg:CC FLAGS_REG))]
12750    "TARGET_TBM"
12751    "blcfill\t{%1, %0|%0, %1}"
12752   [(set_attr "type" "bitmanip")
12753    (set_attr "mode" "<MODE>")])
12755 (define_insn "*tbm_blci_<mode>"
12756   [(set (match_operand:SWI48 0 "register_operand" "=r")
12757         (ior:SWI48
12758           (not:SWI48
12759             (plus:SWI48
12760               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12761               (const_int 1)))
12762           (match_dup 1)))
12763    (clobber (reg:CC FLAGS_REG))]
12764    "TARGET_TBM"
12765    "blci\t{%1, %0|%0, %1}"
12766   [(set_attr "type" "bitmanip")
12767    (set_attr "mode" "<MODE>")])
12769 (define_insn "*tbm_blcic_<mode>"
12770   [(set (match_operand:SWI48 0 "register_operand" "=r")
12771         (and:SWI48
12772           (plus:SWI48
12773             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12774             (const_int 1))
12775           (not:SWI48
12776             (match_dup 1))))
12777    (clobber (reg:CC FLAGS_REG))]
12778    "TARGET_TBM"
12779    "blcic\t{%1, %0|%0, %1}"
12780   [(set_attr "type" "bitmanip")
12781    (set_attr "mode" "<MODE>")])
12783 (define_insn "*tbm_blcmsk_<mode>"
12784   [(set (match_operand:SWI48 0 "register_operand" "=r")
12785         (xor:SWI48
12786           (plus:SWI48
12787             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12788             (const_int 1))
12789           (match_dup 1)))
12790    (clobber (reg:CC FLAGS_REG))]
12791    "TARGET_TBM"
12792    "blcmsk\t{%1, %0|%0, %1}"
12793   [(set_attr "type" "bitmanip")
12794    (set_attr "mode" "<MODE>")])
12796 (define_insn "*tbm_blcs_<mode>"
12797   [(set (match_operand:SWI48 0 "register_operand" "=r")
12798         (ior:SWI48
12799           (plus:SWI48
12800             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12801             (const_int 1))
12802           (match_dup 1)))
12803    (clobber (reg:CC FLAGS_REG))]
12804    "TARGET_TBM"
12805    "blcs\t{%1, %0|%0, %1}"
12806   [(set_attr "type" "bitmanip")
12807    (set_attr "mode" "<MODE>")])
12809 (define_insn "*tbm_blsfill_<mode>"
12810   [(set (match_operand:SWI48 0 "register_operand" "=r")
12811         (ior:SWI48
12812           (plus:SWI48
12813             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12814             (const_int -1))
12815           (match_dup 1)))
12816    (clobber (reg:CC FLAGS_REG))]
12817    "TARGET_TBM"
12818    "blsfill\t{%1, %0|%0, %1}"
12819   [(set_attr "type" "bitmanip")
12820    (set_attr "mode" "<MODE>")])
12822 (define_insn "*tbm_blsic_<mode>"
12823   [(set (match_operand:SWI48 0 "register_operand" "=r")
12824         (ior:SWI48
12825           (plus:SWI48
12826             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12827             (const_int -1))
12828           (not:SWI48
12829             (match_dup 1))))
12830    (clobber (reg:CC FLAGS_REG))]
12831    "TARGET_TBM"
12832    "blsic\t{%1, %0|%0, %1}"
12833   [(set_attr "type" "bitmanip")
12834    (set_attr "mode" "<MODE>")])
12836 (define_insn "*tbm_t1mskc_<mode>"
12837   [(set (match_operand:SWI48 0 "register_operand" "=r")
12838         (ior:SWI48
12839           (plus:SWI48
12840             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12841             (const_int 1))
12842           (not:SWI48
12843             (match_dup 1))))
12844    (clobber (reg:CC FLAGS_REG))]
12845    "TARGET_TBM"
12846    "t1mskc\t{%1, %0|%0, %1}"
12847   [(set_attr "type" "bitmanip")
12848    (set_attr "mode" "<MODE>")])
12850 (define_insn "*tbm_tzmsk_<mode>"
12851   [(set (match_operand:SWI48 0 "register_operand" "=r")
12852         (and:SWI48
12853           (plus:SWI48
12854             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12855             (const_int -1))
12856           (not:SWI48
12857             (match_dup 1))))
12858    (clobber (reg:CC FLAGS_REG))]
12859    "TARGET_TBM"
12860    "tzmsk\t{%1, %0|%0, %1}"
12861   [(set_attr "type" "bitmanip")
12862    (set_attr "mode" "<MODE>")])
12864 (define_insn "bsr_rex64"
12865   [(set (match_operand:DI 0 "register_operand" "=r")
12866         (minus:DI (const_int 63)
12867                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12868    (clobber (reg:CC FLAGS_REG))]
12869   "TARGET_64BIT"
12870   "bsr{q}\t{%1, %0|%0, %1}"
12871   [(set_attr "type" "alu1")
12872    (set_attr "prefix_0f" "1")
12873    (set_attr "mode" "DI")])
12875 (define_insn "bsr"
12876   [(set (match_operand:SI 0 "register_operand" "=r")
12877         (minus:SI (const_int 31)
12878                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12879    (clobber (reg:CC FLAGS_REG))]
12880   ""
12881   "bsr{l}\t{%1, %0|%0, %1}"
12882   [(set_attr "type" "alu1")
12883    (set_attr "prefix_0f" "1")
12884    (set_attr "mode" "SI")])
12886 (define_insn "*bsrhi"
12887   [(set (match_operand:HI 0 "register_operand" "=r")
12888         (minus:HI (const_int 15)
12889                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12890    (clobber (reg:CC FLAGS_REG))]
12891   ""
12892   "bsr{w}\t{%1, %0|%0, %1}"
12893   [(set_attr "type" "alu1")
12894    (set_attr "prefix_0f" "1")
12895    (set_attr "mode" "HI")])
12897 (define_expand "popcount<mode>2"
12898   [(parallel
12899     [(set (match_operand:SWI248 0 "register_operand")
12900           (popcount:SWI248
12901             (match_operand:SWI248 1 "nonimmediate_operand")))
12902      (clobber (reg:CC FLAGS_REG))])]
12903   "TARGET_POPCNT")
12905 (define_insn_and_split "*popcount<mode>2_falsedep_1"
12906   [(set (match_operand:SWI48 0 "register_operand" "=r")
12907         (popcount:SWI48
12908           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12909    (clobber (reg:CC FLAGS_REG))]
12910   "TARGET_POPCNT
12911    && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12912   "#"
12913   "&& reload_completed"
12914   [(parallel
12915     [(set (match_dup 0)
12916           (popcount:SWI48 (match_dup 1)))
12917      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12918      (clobber (reg:CC FLAGS_REG))])]
12920   if (!reg_mentioned_p (operands[0], operands[1]))
12921     ix86_expand_clear (operands[0]);
12924 (define_insn "*popcount<mode>2_falsedep"
12925   [(set (match_operand:SWI48 0 "register_operand" "=r")
12926         (popcount:SWI48
12927           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12928    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12929            UNSPEC_INSN_FALSE_DEP)
12930    (clobber (reg:CC FLAGS_REG))]
12931   "TARGET_POPCNT"
12933 #if TARGET_MACHO
12934   return "popcnt\t{%1, %0|%0, %1}";
12935 #else
12936   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12937 #endif
12939   [(set_attr "prefix_rep" "1")
12940    (set_attr "type" "bitmanip")
12941    (set_attr "mode" "<MODE>")])
12943 (define_insn "*popcount<mode>2"
12944   [(set (match_operand:SWI248 0 "register_operand" "=r")
12945         (popcount:SWI248
12946           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12947    (clobber (reg:CC FLAGS_REG))]
12948   "TARGET_POPCNT"
12950 #if TARGET_MACHO
12951   return "popcnt\t{%1, %0|%0, %1}";
12952 #else
12953   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12954 #endif
12956   [(set_attr "prefix_rep" "1")
12957    (set_attr "type" "bitmanip")
12958    (set_attr "mode" "<MODE>")])
12960 (define_expand "bswapdi2"
12961   [(set (match_operand:DI 0 "register_operand")
12962         (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12963   "TARGET_64BIT"
12965   if (!TARGET_MOVBE)
12966     operands[1] = force_reg (DImode, operands[1]);
12969 (define_expand "bswapsi2"
12970   [(set (match_operand:SI 0 "register_operand")
12971         (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12972   ""
12974   if (TARGET_MOVBE)
12975     ;
12976   else if (TARGET_BSWAP)
12977     operands[1] = force_reg (SImode, operands[1]);
12978   else
12979     {
12980       rtx x = operands[0];
12982       emit_move_insn (x, operands[1]);
12983       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12984       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12985       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12986       DONE;
12987     }
12990 (define_insn "*bswap<mode>2_movbe"
12991   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12992         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12993   "TARGET_MOVBE
12994    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12995   "@
12996     bswap\t%0
12997     movbe\t{%1, %0|%0, %1}
12998     movbe\t{%1, %0|%0, %1}"
12999   [(set_attr "type" "bitmanip,imov,imov")
13000    (set_attr "modrm" "0,1,1")
13001    (set_attr "prefix_0f" "*,1,1")
13002    (set_attr "prefix_extra" "*,1,1")
13003    (set_attr "mode" "<MODE>")])
13005 (define_insn "*bswap<mode>2"
13006   [(set (match_operand:SWI48 0 "register_operand" "=r")
13007         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
13008   "TARGET_BSWAP"
13009   "bswap\t%0"
13010   [(set_attr "type" "bitmanip")
13011    (set_attr "modrm" "0")
13012    (set_attr "mode" "<MODE>")])
13014 (define_insn "*bswaphi_lowpart_1"
13015   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
13016         (bswap:HI (match_dup 0)))
13017    (clobber (reg:CC FLAGS_REG))]
13018   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
13019   "@
13020     xchg{b}\t{%h0, %b0|%b0, %h0}
13021     rol{w}\t{$8, %0|%0, 8}"
13022   [(set_attr "length" "2,4")
13023    (set_attr "mode" "QI,HI")])
13025 (define_insn "bswaphi_lowpart"
13026   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
13027         (bswap:HI (match_dup 0)))
13028    (clobber (reg:CC FLAGS_REG))]
13029   ""
13030   "rol{w}\t{$8, %0|%0, 8}"
13031   [(set_attr "length" "4")
13032    (set_attr "mode" "HI")])
13034 (define_expand "paritydi2"
13035   [(set (match_operand:DI 0 "register_operand")
13036         (parity:DI (match_operand:DI 1 "register_operand")))]
13037   "! TARGET_POPCNT"
13039   rtx scratch = gen_reg_rtx (QImode);
13040   rtx cond;
13042   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
13043                                 NULL_RTX, operands[1]));
13045   cond = gen_rtx_fmt_ee (ORDERED, QImode,
13046                          gen_rtx_REG (CCmode, FLAGS_REG),
13047                          const0_rtx);
13048   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
13050   if (TARGET_64BIT)
13051     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
13052   else
13053     {
13054       rtx tmp = gen_reg_rtx (SImode);
13056       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
13057       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
13058     }
13059   DONE;
13062 (define_expand "paritysi2"
13063   [(set (match_operand:SI 0 "register_operand")
13064         (parity:SI (match_operand:SI 1 "register_operand")))]
13065   "! TARGET_POPCNT"
13067   rtx scratch = gen_reg_rtx (QImode);
13068   rtx cond;
13070   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
13072   cond = gen_rtx_fmt_ee (ORDERED, QImode,
13073                          gen_rtx_REG (CCmode, FLAGS_REG),
13074                          const0_rtx);
13075   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
13077   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
13078   DONE;
13081 (define_insn_and_split "paritydi2_cmp"
13082   [(set (reg:CC FLAGS_REG)
13083         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
13084                    UNSPEC_PARITY))
13085    (clobber (match_scratch:DI 0 "=r"))
13086    (clobber (match_scratch:SI 1 "=&r"))
13087    (clobber (match_scratch:HI 2 "=Q"))]
13088   "! TARGET_POPCNT"
13089   "#"
13090   "&& reload_completed"
13091   [(parallel
13092      [(set (match_dup 1)
13093            (xor:SI (match_dup 1) (match_dup 4)))
13094       (clobber (reg:CC FLAGS_REG))])
13095    (parallel
13096      [(set (reg:CC FLAGS_REG)
13097            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13098       (clobber (match_dup 1))
13099       (clobber (match_dup 2))])]
13101   operands[4] = gen_lowpart (SImode, operands[3]);
13103   if (TARGET_64BIT)
13104     {
13105       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
13106       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
13107     }
13108   else
13109     operands[1] = gen_highpart (SImode, operands[3]);
13112 (define_insn_and_split "paritysi2_cmp"
13113   [(set (reg:CC FLAGS_REG)
13114         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
13115                    UNSPEC_PARITY))
13116    (clobber (match_scratch:SI 0 "=r"))
13117    (clobber (match_scratch:HI 1 "=&Q"))]
13118   "! TARGET_POPCNT"
13119   "#"
13120   "&& reload_completed"
13121   [(parallel
13122      [(set (match_dup 1)
13123            (xor:HI (match_dup 1) (match_dup 3)))
13124       (clobber (reg:CC FLAGS_REG))])
13125    (parallel
13126      [(set (reg:CC FLAGS_REG)
13127            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13128       (clobber (match_dup 1))])]
13130   operands[3] = gen_lowpart (HImode, operands[2]);
13132   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
13133   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
13136 (define_insn "*parityhi2_cmp"
13137   [(set (reg:CC FLAGS_REG)
13138         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
13139                    UNSPEC_PARITY))
13140    (clobber (match_scratch:HI 0 "=Q"))]
13141   "! TARGET_POPCNT"
13142   "xor{b}\t{%h0, %b0|%b0, %h0}"
13143   [(set_attr "length" "2")
13144    (set_attr "mode" "HI")])
13147 ;; Thread-local storage patterns for ELF.
13149 ;; Note that these code sequences must appear exactly as shown
13150 ;; in order to allow linker relaxation.
13152 (define_insn "*tls_global_dynamic_32_gnu"
13153   [(set (match_operand:SI 0 "register_operand" "=a")
13154         (unspec:SI
13155          [(match_operand:SI 1 "register_operand" "b")
13156           (match_operand 2 "tls_symbolic_operand")
13157           (match_operand 3 "constant_call_address_operand" "Bz")
13158           (reg:SI SP_REG)]
13159          UNSPEC_TLS_GD))
13160    (clobber (match_scratch:SI 4 "=d"))
13161    (clobber (match_scratch:SI 5 "=c"))
13162    (clobber (reg:CC FLAGS_REG))]
13163   "!TARGET_64BIT && TARGET_GNU_TLS"
13165   output_asm_insn
13166     ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
13167   if (TARGET_SUN_TLS)
13168 #ifdef HAVE_AS_IX86_TLSGDPLT
13169     return "call\t%a2@tlsgdplt";
13170 #else
13171     return "call\t%p3@plt";
13172 #endif
13173   return "call\t%P3";
13175   [(set_attr "type" "multi")
13176    (set_attr "length" "12")])
13178 (define_expand "tls_global_dynamic_32"
13179   [(parallel
13180     [(set (match_operand:SI 0 "register_operand")
13181           (unspec:SI [(match_operand:SI 2 "register_operand")
13182                       (match_operand 1 "tls_symbolic_operand")
13183                       (match_operand 3 "constant_call_address_operand")
13184                       (reg:SI SP_REG)]
13185                      UNSPEC_TLS_GD))
13186      (clobber (match_scratch:SI 4))
13187      (clobber (match_scratch:SI 5))
13188      (clobber (reg:CC FLAGS_REG))])]
13189   ""
13190   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13192 (define_insn "*tls_global_dynamic_64_<mode>"
13193   [(set (match_operand:P 0 "register_operand" "=a")
13194         (call:P
13195          (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
13196          (match_operand 3)))
13197    (unspec:P [(match_operand 1 "tls_symbolic_operand")]
13198              UNSPEC_TLS_GD)]
13199   "TARGET_64BIT"
13201   if (!TARGET_X32)
13202     fputs (ASM_BYTE "0x66\n", asm_out_file);
13203   output_asm_insn
13204     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13205   fputs (ASM_SHORT "0x6666\n", asm_out_file);
13206   fputs ("\trex64\n", asm_out_file);
13207   if (TARGET_SUN_TLS)
13208     return "call\t%p2@plt";
13209   return "call\t%P2";
13211   [(set_attr "type" "multi")
13212    (set (attr "length")
13213         (symbol_ref "TARGET_X32 ? 15 : 16"))])
13215 (define_insn "*tls_global_dynamic_64_largepic"
13216   [(set (match_operand:DI 0 "register_operand" "=a")
13217         (call:DI
13218          (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
13219                           (match_operand:DI 3 "immediate_operand" "i")))
13220          (match_operand 4)))
13221    (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13222              UNSPEC_TLS_GD)]
13223   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13224    && GET_CODE (operands[3]) == CONST
13225    && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
13226    && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
13228   output_asm_insn
13229     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13230   output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
13231   output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
13232   return "call\t{*%%rax|rax}";
13234   [(set_attr "type" "multi")
13235    (set_attr "length" "22")])
13237 (define_expand "tls_global_dynamic_64_<mode>"
13238   [(parallel
13239     [(set (match_operand:P 0 "register_operand")
13240           (call:P
13241            (mem:QI (match_operand 2))
13242            (const_int 0)))
13243      (unspec:P [(match_operand 1 "tls_symbolic_operand")]
13244                UNSPEC_TLS_GD)])]
13245   "TARGET_64BIT"
13246   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13248 (define_insn "*tls_local_dynamic_base_32_gnu"
13249   [(set (match_operand:SI 0 "register_operand" "=a")
13250         (unspec:SI
13251          [(match_operand:SI 1 "register_operand" "b")
13252           (match_operand 2 "constant_call_address_operand" "Bz")
13253           (reg:SI SP_REG)]
13254          UNSPEC_TLS_LD_BASE))
13255    (clobber (match_scratch:SI 3 "=d"))
13256    (clobber (match_scratch:SI 4 "=c"))
13257    (clobber (reg:CC FLAGS_REG))]
13258   "!TARGET_64BIT && TARGET_GNU_TLS"
13260   output_asm_insn
13261     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
13262   if (TARGET_SUN_TLS)
13263     {
13264       if (HAVE_AS_IX86_TLSLDMPLT)
13265         return "call\t%&@tlsldmplt";
13266       else
13267         return "call\t%p2@plt";
13268     }
13269   return "call\t%P2";
13271   [(set_attr "type" "multi")
13272    (set_attr "length" "11")])
13274 (define_expand "tls_local_dynamic_base_32"
13275   [(parallel
13276      [(set (match_operand:SI 0 "register_operand")
13277            (unspec:SI
13278             [(match_operand:SI 1 "register_operand")
13279              (match_operand 2 "constant_call_address_operand")
13280              (reg:SI SP_REG)]
13281             UNSPEC_TLS_LD_BASE))
13282       (clobber (match_scratch:SI 3))
13283       (clobber (match_scratch:SI 4))
13284       (clobber (reg:CC FLAGS_REG))])]
13285   ""
13286   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13288 (define_insn "*tls_local_dynamic_base_64_<mode>"
13289   [(set (match_operand:P 0 "register_operand" "=a")
13290         (call:P
13291          (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
13292          (match_operand 2)))
13293    (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13294   "TARGET_64BIT"
13296   output_asm_insn
13297     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13298   if (TARGET_SUN_TLS)
13299     return "call\t%p1@plt";
13300   return "call\t%P1";
13302   [(set_attr "type" "multi")
13303    (set_attr "length" "12")])
13305 (define_insn "*tls_local_dynamic_base_64_largepic"
13306   [(set (match_operand:DI 0 "register_operand" "=a")
13307         (call:DI
13308          (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13309                           (match_operand:DI 2 "immediate_operand" "i")))
13310          (match_operand 3)))
13311    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13312   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13313    && GET_CODE (operands[2]) == CONST
13314    && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13315    && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13317   output_asm_insn
13318     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13319   output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13320   output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13321   return "call\t{*%%rax|rax}";
13323   [(set_attr "type" "multi")
13324    (set_attr "length" "22")])
13326 (define_expand "tls_local_dynamic_base_64_<mode>"
13327   [(parallel
13328      [(set (match_operand:P 0 "register_operand")
13329            (call:P
13330             (mem:QI (match_operand 1))
13331             (const_int 0)))
13332       (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13333   "TARGET_64BIT"
13334   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13336 ;; Local dynamic of a single variable is a lose.  Show combine how
13337 ;; to convert that back to global dynamic.
13339 (define_insn_and_split "*tls_local_dynamic_32_once"
13340   [(set (match_operand:SI 0 "register_operand" "=a")
13341         (plus:SI
13342          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13343                      (match_operand 2 "constant_call_address_operand" "Bz")
13344                      (reg:SI SP_REG)]
13345                     UNSPEC_TLS_LD_BASE)
13346          (const:SI (unspec:SI
13347                     [(match_operand 3 "tls_symbolic_operand")]
13348                     UNSPEC_DTPOFF))))
13349    (clobber (match_scratch:SI 4 "=d"))
13350    (clobber (match_scratch:SI 5 "=c"))
13351    (clobber (reg:CC FLAGS_REG))]
13352   ""
13353   "#"
13354   ""
13355   [(parallel
13356      [(set (match_dup 0)
13357            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13358                        (reg:SI SP_REG)]
13359                       UNSPEC_TLS_GD))
13360       (clobber (match_dup 4))
13361       (clobber (match_dup 5))
13362       (clobber (reg:CC FLAGS_REG))])])
13364 ;; Segment register for the thread base ptr load
13365 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13367 ;; Load and add the thread base pointer from %<tp_seg>:0.
13368 (define_insn "*load_tp_x32"
13369   [(set (match_operand:SI 0 "register_operand" "=r")
13370         (unspec:SI [(const_int 0)] UNSPEC_TP))]
13371   "TARGET_X32"
13372   "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13373   [(set_attr "type" "imov")
13374    (set_attr "modrm" "0")
13375    (set_attr "length" "7")
13376    (set_attr "memory" "load")
13377    (set_attr "imm_disp" "false")])
13379 (define_insn "*load_tp_x32_zext"
13380   [(set (match_operand:DI 0 "register_operand" "=r")
13381         (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13382   "TARGET_X32"
13383   "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13384   [(set_attr "type" "imov")
13385    (set_attr "modrm" "0")
13386    (set_attr "length" "7")
13387    (set_attr "memory" "load")
13388    (set_attr "imm_disp" "false")])
13390 (define_insn "*load_tp_<mode>"
13391   [(set (match_operand:P 0 "register_operand" "=r")
13392         (unspec:P [(const_int 0)] UNSPEC_TP))]
13393   "!TARGET_X32"
13394   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13395   [(set_attr "type" "imov")
13396    (set_attr "modrm" "0")
13397    (set_attr "length" "7")
13398    (set_attr "memory" "load")
13399    (set_attr "imm_disp" "false")])
13401 (define_insn "*add_tp_x32"
13402   [(set (match_operand:SI 0 "register_operand" "=r")
13403         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13404                  (match_operand:SI 1 "register_operand" "0")))
13405    (clobber (reg:CC FLAGS_REG))]
13406   "TARGET_X32"
13407   "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13408   [(set_attr "type" "alu")
13409    (set_attr "modrm" "0")
13410    (set_attr "length" "7")
13411    (set_attr "memory" "load")
13412    (set_attr "imm_disp" "false")])
13414 (define_insn "*add_tp_x32_zext"
13415   [(set (match_operand:DI 0 "register_operand" "=r")
13416         (zero_extend:DI
13417           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13418                    (match_operand:SI 1 "register_operand" "0"))))
13419    (clobber (reg:CC FLAGS_REG))]
13420   "TARGET_X32"
13421   "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13422   [(set_attr "type" "alu")
13423    (set_attr "modrm" "0")
13424    (set_attr "length" "7")
13425    (set_attr "memory" "load")
13426    (set_attr "imm_disp" "false")])
13428 (define_insn "*add_tp_<mode>"
13429   [(set (match_operand:P 0 "register_operand" "=r")
13430         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13431                 (match_operand:P 1 "register_operand" "0")))
13432    (clobber (reg:CC FLAGS_REG))]
13433   "!TARGET_X32"
13434   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13435   [(set_attr "type" "alu")
13436    (set_attr "modrm" "0")
13437    (set_attr "length" "7")
13438    (set_attr "memory" "load")
13439    (set_attr "imm_disp" "false")])
13441 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13442 ;; %rax as destination of the initial executable code sequence.
13443 (define_insn "tls_initial_exec_64_sun"
13444   [(set (match_operand:DI 0 "register_operand" "=a")
13445         (unspec:DI
13446          [(match_operand 1 "tls_symbolic_operand")]
13447          UNSPEC_TLS_IE_SUN))
13448    (clobber (reg:CC FLAGS_REG))]
13449   "TARGET_64BIT && TARGET_SUN_TLS"
13451   output_asm_insn
13452     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13453   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13455   [(set_attr "type" "multi")])
13457 ;; GNU2 TLS patterns can be split.
13459 (define_expand "tls_dynamic_gnu2_32"
13460   [(set (match_dup 3)
13461         (plus:SI (match_operand:SI 2 "register_operand")
13462                  (const:SI
13463                   (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13464                              UNSPEC_TLSDESC))))
13465    (parallel
13466     [(set (match_operand:SI 0 "register_operand")
13467           (unspec:SI [(match_dup 1) (match_dup 3)
13468                       (match_dup 2) (reg:SI SP_REG)]
13469                       UNSPEC_TLSDESC))
13470      (clobber (reg:CC FLAGS_REG))])]
13471   "!TARGET_64BIT && TARGET_GNU2_TLS"
13473   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13474   ix86_tls_descriptor_calls_expanded_in_cfun = true;
13477 (define_insn "*tls_dynamic_gnu2_lea_32"
13478   [(set (match_operand:SI 0 "register_operand" "=r")
13479         (plus:SI (match_operand:SI 1 "register_operand" "b")
13480                  (const:SI
13481                   (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13482                               UNSPEC_TLSDESC))))]
13483   "!TARGET_64BIT && TARGET_GNU2_TLS"
13484   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13485   [(set_attr "type" "lea")
13486    (set_attr "mode" "SI")
13487    (set_attr "length" "6")
13488    (set_attr "length_address" "4")])
13490 (define_insn "*tls_dynamic_gnu2_call_32"
13491   [(set (match_operand:SI 0 "register_operand" "=a")
13492         (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13493                     (match_operand:SI 2 "register_operand" "0")
13494                     ;; we have to make sure %ebx still points to the GOT
13495                     (match_operand:SI 3 "register_operand" "b")
13496                     (reg:SI SP_REG)]
13497                    UNSPEC_TLSDESC))
13498    (clobber (reg:CC FLAGS_REG))]
13499   "!TARGET_64BIT && TARGET_GNU2_TLS"
13500   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13501   [(set_attr "type" "call")
13502    (set_attr "length" "2")
13503    (set_attr "length_address" "0")])
13505 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13506   [(set (match_operand:SI 0 "register_operand" "=&a")
13507         (plus:SI
13508          (unspec:SI [(match_operand 3 "tls_modbase_operand")
13509                      (match_operand:SI 4)
13510                      (match_operand:SI 2 "register_operand" "b")
13511                      (reg:SI SP_REG)]
13512                     UNSPEC_TLSDESC)
13513          (const:SI (unspec:SI
13514                     [(match_operand 1 "tls_symbolic_operand")]
13515                     UNSPEC_DTPOFF))))
13516    (clobber (reg:CC FLAGS_REG))]
13517   "!TARGET_64BIT && TARGET_GNU2_TLS"
13518   "#"
13519   ""
13520   [(set (match_dup 0) (match_dup 5))]
13522   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13523   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13526 (define_expand "tls_dynamic_gnu2_64"
13527   [(set (match_dup 2)
13528         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13529                    UNSPEC_TLSDESC))
13530    (parallel
13531     [(set (match_operand:DI 0 "register_operand")
13532           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13533                      UNSPEC_TLSDESC))
13534      (clobber (reg:CC FLAGS_REG))])]
13535   "TARGET_64BIT && TARGET_GNU2_TLS"
13537   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13538   ix86_tls_descriptor_calls_expanded_in_cfun = true;
13541 (define_insn "*tls_dynamic_gnu2_lea_64"
13542   [(set (match_operand:DI 0 "register_operand" "=r")
13543         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13544                    UNSPEC_TLSDESC))]
13545   "TARGET_64BIT && TARGET_GNU2_TLS"
13546   "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13547   [(set_attr "type" "lea")
13548    (set_attr "mode" "DI")
13549    (set_attr "length" "7")
13550    (set_attr "length_address" "4")])
13552 (define_insn "*tls_dynamic_gnu2_call_64"
13553   [(set (match_operand:DI 0 "register_operand" "=a")
13554         (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13555                     (match_operand:DI 2 "register_operand" "0")
13556                     (reg:DI SP_REG)]
13557                    UNSPEC_TLSDESC))
13558    (clobber (reg:CC FLAGS_REG))]
13559   "TARGET_64BIT && TARGET_GNU2_TLS"
13560   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13561   [(set_attr "type" "call")
13562    (set_attr "length" "2")
13563    (set_attr "length_address" "0")])
13565 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13566   [(set (match_operand:DI 0 "register_operand" "=&a")
13567         (plus:DI
13568          (unspec:DI [(match_operand 2 "tls_modbase_operand")
13569                      (match_operand:DI 3)
13570                      (reg:DI SP_REG)]
13571                     UNSPEC_TLSDESC)
13572          (const:DI (unspec:DI
13573                     [(match_operand 1 "tls_symbolic_operand")]
13574                     UNSPEC_DTPOFF))))
13575    (clobber (reg:CC FLAGS_REG))]
13576   "TARGET_64BIT && TARGET_GNU2_TLS"
13577   "#"
13578   ""
13579   [(set (match_dup 0) (match_dup 4))]
13581   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13582   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13585 ;; These patterns match the binary 387 instructions for addM3, subM3,
13586 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
13587 ;; SFmode.  The first is the normal insn, the second the same insn but
13588 ;; with one operand a conversion, and the third the same insn but with
13589 ;; the other operand a conversion.  The conversion may be SFmode or
13590 ;; SImode if the target mode DFmode, but only SImode if the target mode
13591 ;; is SFmode.
13593 ;; Gcc is slightly more smart about handling normal two address instructions
13594 ;; so use special patterns for add and mull.
13596 (define_insn "*fop_<mode>_comm_mixed"
13597   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13598         (match_operator:MODEF 3 "binary_fp_operator"
13599           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13600            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13601   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13602    && COMMUTATIVE_ARITH_P (operands[3])
13603    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13604   "* return output_387_binary_op (insn, operands);"
13605   [(set (attr "type")
13606         (if_then_else (eq_attr "alternative" "1,2")
13607            (if_then_else (match_operand:MODEF 3 "mult_operator")
13608               (const_string "ssemul")
13609               (const_string "sseadd"))
13610            (if_then_else (match_operand:MODEF 3 "mult_operator")
13611               (const_string "fmul")
13612               (const_string "fop"))))
13613    (set_attr "isa" "*,noavx,avx")
13614    (set_attr "prefix" "orig,orig,vex")
13615    (set_attr "mode" "<MODE>")])
13617 (define_insn "*fop_<mode>_comm_sse"
13618   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
13619         (match_operator:MODEF 3 "binary_fp_operator"
13620           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
13621            (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]))]
13622   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13623    && COMMUTATIVE_ARITH_P (operands[3])
13624    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13625   "* return output_387_binary_op (insn, operands);"
13626   [(set (attr "type")
13627         (if_then_else (match_operand:MODEF 3 "mult_operator")
13628            (const_string "ssemul")
13629            (const_string "sseadd")))
13630    (set_attr "isa" "noavx,avx")
13631    (set_attr "prefix" "orig,vex")
13632    (set_attr "mode" "<MODE>")])
13634 (define_insn "*fop_<mode>_comm_i387"
13635   [(set (match_operand:MODEF 0 "register_operand" "=f")
13636         (match_operator:MODEF 3 "binary_fp_operator"
13637           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13638            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13639   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13640    && COMMUTATIVE_ARITH_P (operands[3])
13641    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13642   "* return output_387_binary_op (insn, operands);"
13643   [(set (attr "type")
13644         (if_then_else (match_operand:MODEF 3 "mult_operator")
13645            (const_string "fmul")
13646            (const_string "fop")))
13647    (set_attr "mode" "<MODE>")])
13649 (define_insn "*fop_<mode>_1_mixed"
13650   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13651         (match_operator:MODEF 3 "binary_fp_operator"
13652           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13653            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13654   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13655    && !COMMUTATIVE_ARITH_P (operands[3])
13656    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13657   "* return output_387_binary_op (insn, operands);"
13658   [(set (attr "type")
13659         (cond [(and (eq_attr "alternative" "2,3")
13660                     (match_operand:MODEF 3 "mult_operator"))
13661                  (const_string "ssemul")
13662                (and (eq_attr "alternative" "2,3")
13663                     (match_operand:MODEF 3 "div_operator"))
13664                  (const_string "ssediv")
13665                (eq_attr "alternative" "2,3")
13666                  (const_string "sseadd")
13667                (match_operand:MODEF 3 "mult_operator")
13668                  (const_string "fmul")
13669                (match_operand:MODEF 3 "div_operator")
13670                  (const_string "fdiv")
13671               ]
13672               (const_string "fop")))
13673    (set_attr "isa" "*,*,noavx,avx")
13674    (set_attr "prefix" "orig,orig,orig,vex")
13675    (set_attr "mode" "<MODE>")])
13677 (define_insn "*rcpsf2_sse"
13678   [(set (match_operand:SF 0 "register_operand" "=x")
13679         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13680                    UNSPEC_RCP))]
13681   "TARGET_SSE_MATH"
13682   "%vrcpss\t{%1, %d0|%d0, %1}"
13683   [(set_attr "type" "sse")
13684    (set_attr "atom_sse_attr" "rcp")
13685    (set_attr "btver2_sse_attr" "rcp")
13686    (set_attr "prefix" "maybe_vex")
13687    (set_attr "mode" "SF")])
13689 (define_insn "*fop_<mode>_1_sse"
13690   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13691         (match_operator:MODEF 3 "binary_fp_operator"
13692           [(match_operand:MODEF 1 "register_operand" "0,x")
13693            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13694   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13695    && !COMMUTATIVE_ARITH_P (operands[3])"
13696   "* return output_387_binary_op (insn, operands);"
13697   [(set (attr "type")
13698         (cond [(match_operand:MODEF 3 "mult_operator")
13699                  (const_string "ssemul")
13700                (match_operand:MODEF 3 "div_operator")
13701                  (const_string "ssediv")
13702               ]
13703               (const_string "sseadd")))
13704    (set_attr "isa" "noavx,avx")
13705    (set_attr "prefix" "orig,vex")
13706    (set_attr "mode" "<MODE>")])
13708 ;; This pattern is not fully shadowed by the pattern above.
13709 (define_insn "*fop_<mode>_1_i387"
13710   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13711         (match_operator:MODEF 3 "binary_fp_operator"
13712           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13713            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13714   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13715    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13716    && !COMMUTATIVE_ARITH_P (operands[3])
13717    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13718   "* return output_387_binary_op (insn, operands);"
13719   [(set (attr "type")
13720         (cond [(match_operand:MODEF 3 "mult_operator")
13721                  (const_string "fmul")
13722                (match_operand:MODEF 3 "div_operator")
13723                  (const_string "fdiv")
13724               ]
13725               (const_string "fop")))
13726    (set_attr "mode" "<MODE>")])
13728 ;; ??? Add SSE splitters for these!
13729 (define_insn "*fop_<MODEF:mode>_2_i387"
13730   [(set (match_operand:MODEF 0 "register_operand" "=f")
13731         (match_operator:MODEF 3 "binary_fp_operator"
13732           [(float:MODEF
13733              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13734            (match_operand:MODEF 2 "register_operand" "0")]))]
13735   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13736    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13737    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13738        || optimize_function_for_size_p (cfun))"
13739   { return output_387_binary_op (insn, operands); }
13740   [(set (attr "type")
13741         (cond [(match_operand:MODEF 3 "mult_operator")
13742                  (const_string "fmul")
13743                (match_operand:MODEF 3 "div_operator")
13744                  (const_string "fdiv")
13745               ]
13746               (const_string "fop")))
13747    (set_attr "fp_int_src" "true")
13748    (set_attr "mode" "<SWI24:MODE>")])
13750 (define_insn "*fop_<MODEF:mode>_3_i387"
13751   [(set (match_operand:MODEF 0 "register_operand" "=f")
13752         (match_operator:MODEF 3 "binary_fp_operator"
13753           [(match_operand:MODEF 1 "register_operand" "0")
13754            (float:MODEF
13755              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13756   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13757    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13758    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13759        || optimize_function_for_size_p (cfun))"
13760   { return output_387_binary_op (insn, operands); }
13761   [(set (attr "type")
13762         (cond [(match_operand:MODEF 3 "mult_operator")
13763                  (const_string "fmul")
13764                (match_operand:MODEF 3 "div_operator")
13765                  (const_string "fdiv")
13766               ]
13767               (const_string "fop")))
13768    (set_attr "fp_int_src" "true")
13769    (set_attr "mode" "<MODE>")])
13771 (define_insn "*fop_df_4_i387"
13772   [(set (match_operand:DF 0 "register_operand" "=f,f")
13773         (match_operator:DF 3 "binary_fp_operator"
13774            [(float_extend:DF
13775              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13776             (match_operand:DF 2 "register_operand" "0,f")]))]
13777   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13778    && !(TARGET_SSE2 && TARGET_SSE_MATH)
13779    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13780   "* return output_387_binary_op (insn, operands);"
13781   [(set (attr "type")
13782         (cond [(match_operand:DF 3 "mult_operator")
13783                  (const_string "fmul")
13784                (match_operand:DF 3 "div_operator")
13785                  (const_string "fdiv")
13786               ]
13787               (const_string "fop")))
13788    (set_attr "mode" "SF")])
13790 (define_insn "*fop_df_5_i387"
13791   [(set (match_operand:DF 0 "register_operand" "=f,f")
13792         (match_operator:DF 3 "binary_fp_operator"
13793           [(match_operand:DF 1 "register_operand" "0,f")
13794            (float_extend:DF
13795             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13796   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13797    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13798   "* return output_387_binary_op (insn, operands);"
13799   [(set (attr "type")
13800         (cond [(match_operand:DF 3 "mult_operator")
13801                  (const_string "fmul")
13802                (match_operand:DF 3 "div_operator")
13803                  (const_string "fdiv")
13804               ]
13805               (const_string "fop")))
13806    (set_attr "mode" "SF")])
13808 (define_insn "*fop_df_6_i387"
13809   [(set (match_operand:DF 0 "register_operand" "=f,f")
13810         (match_operator:DF 3 "binary_fp_operator"
13811           [(float_extend:DF
13812             (match_operand:SF 1 "register_operand" "0,f"))
13813            (float_extend:DF
13814             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13815   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13816    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13817   "* return output_387_binary_op (insn, operands);"
13818   [(set (attr "type")
13819         (cond [(match_operand:DF 3 "mult_operator")
13820                  (const_string "fmul")
13821                (match_operand:DF 3 "div_operator")
13822                  (const_string "fdiv")
13823               ]
13824               (const_string "fop")))
13825    (set_attr "mode" "SF")])
13827 (define_insn "*fop_xf_comm_i387"
13828   [(set (match_operand:XF 0 "register_operand" "=f")
13829         (match_operator:XF 3 "binary_fp_operator"
13830                         [(match_operand:XF 1 "register_operand" "%0")
13831                          (match_operand:XF 2 "register_operand" "f")]))]
13832   "TARGET_80387
13833    && COMMUTATIVE_ARITH_P (operands[3])"
13834   "* return output_387_binary_op (insn, operands);"
13835   [(set (attr "type")
13836         (if_then_else (match_operand:XF 3 "mult_operator")
13837            (const_string "fmul")
13838            (const_string "fop")))
13839    (set_attr "mode" "XF")])
13841 (define_insn "*fop_xf_1_i387"
13842   [(set (match_operand:XF 0 "register_operand" "=f,f")
13843         (match_operator:XF 3 "binary_fp_operator"
13844                         [(match_operand:XF 1 "register_operand" "0,f")
13845                          (match_operand:XF 2 "register_operand" "f,0")]))]
13846   "TARGET_80387
13847    && !COMMUTATIVE_ARITH_P (operands[3])"
13848   "* return output_387_binary_op (insn, operands);"
13849   [(set (attr "type")
13850         (cond [(match_operand:XF 3 "mult_operator")
13851                  (const_string "fmul")
13852                (match_operand:XF 3 "div_operator")
13853                  (const_string "fdiv")
13854               ]
13855               (const_string "fop")))
13856    (set_attr "mode" "XF")])
13858 (define_insn "*fop_xf_2_i387"
13859   [(set (match_operand:XF 0 "register_operand" "=f")
13860         (match_operator:XF 3 "binary_fp_operator"
13861           [(float:XF
13862              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13863            (match_operand:XF 2 "register_operand" "0")]))]
13864   "TARGET_80387
13865    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13866   { return output_387_binary_op (insn, operands); }
13867   [(set (attr "type")
13868         (cond [(match_operand:XF 3 "mult_operator")
13869                  (const_string "fmul")
13870                (match_operand:XF 3 "div_operator")
13871                  (const_string "fdiv")
13872               ]
13873               (const_string "fop")))
13874    (set_attr "fp_int_src" "true")
13875    (set_attr "mode" "<MODE>")])
13877 (define_insn "*fop_xf_3_i387"
13878   [(set (match_operand:XF 0 "register_operand" "=f")
13879         (match_operator:XF 3 "binary_fp_operator"
13880           [(match_operand:XF 1 "register_operand" "0")
13881            (float:XF
13882              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13883   "TARGET_80387
13884    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13885   { return output_387_binary_op (insn, operands); }
13886   [(set (attr "type")
13887         (cond [(match_operand:XF 3 "mult_operator")
13888                  (const_string "fmul")
13889                (match_operand:XF 3 "div_operator")
13890                  (const_string "fdiv")
13891               ]
13892               (const_string "fop")))
13893    (set_attr "fp_int_src" "true")
13894    (set_attr "mode" "<MODE>")])
13896 (define_insn "*fop_xf_4_i387"
13897   [(set (match_operand:XF 0 "register_operand" "=f,f")
13898         (match_operator:XF 3 "binary_fp_operator"
13899            [(float_extend:XF
13900               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13901             (match_operand:XF 2 "register_operand" "0,f")]))]
13902   "TARGET_80387"
13903   "* return output_387_binary_op (insn, operands);"
13904   [(set (attr "type")
13905         (cond [(match_operand:XF 3 "mult_operator")
13906                  (const_string "fmul")
13907                (match_operand:XF 3 "div_operator")
13908                  (const_string "fdiv")
13909               ]
13910               (const_string "fop")))
13911    (set_attr "mode" "<MODE>")])
13913 (define_insn "*fop_xf_5_i387"
13914   [(set (match_operand:XF 0 "register_operand" "=f,f")
13915         (match_operator:XF 3 "binary_fp_operator"
13916           [(match_operand:XF 1 "register_operand" "0,f")
13917            (float_extend:XF
13918              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13919   "TARGET_80387"
13920   "* return output_387_binary_op (insn, operands);"
13921   [(set (attr "type")
13922         (cond [(match_operand:XF 3 "mult_operator")
13923                  (const_string "fmul")
13924                (match_operand:XF 3 "div_operator")
13925                  (const_string "fdiv")
13926               ]
13927               (const_string "fop")))
13928    (set_attr "mode" "<MODE>")])
13930 (define_insn "*fop_xf_6_i387"
13931   [(set (match_operand:XF 0 "register_operand" "=f,f")
13932         (match_operator:XF 3 "binary_fp_operator"
13933           [(float_extend:XF
13934              (match_operand:MODEF 1 "register_operand" "0,f"))
13935            (float_extend:XF
13936              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13937   "TARGET_80387"
13938   "* return output_387_binary_op (insn, operands);"
13939   [(set (attr "type")
13940         (cond [(match_operand:XF 3 "mult_operator")
13941                  (const_string "fmul")
13942                (match_operand:XF 3 "div_operator")
13943                  (const_string "fdiv")
13944               ]
13945               (const_string "fop")))
13946    (set_attr "mode" "<MODE>")])
13948 ;; FPU special functions.
13950 ;; This pattern implements a no-op XFmode truncation for
13951 ;; all fancy i386 XFmode math functions.
13953 (define_insn "truncxf<mode>2_i387_noop_unspec"
13954   [(set (match_operand:MODEF 0 "register_operand" "=f")
13955         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13956         UNSPEC_TRUNC_NOOP))]
13957   "TARGET_USE_FANCY_MATH_387"
13958   "* return output_387_reg_move (insn, operands);"
13959   [(set_attr "type" "fmov")
13960    (set_attr "mode" "<MODE>")])
13962 (define_insn "sqrtxf2"
13963   [(set (match_operand:XF 0 "register_operand" "=f")
13964         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13965   "TARGET_USE_FANCY_MATH_387"
13966   "fsqrt"
13967   [(set_attr "type" "fpspc")
13968    (set_attr "mode" "XF")
13969    (set_attr "athlon_decode" "direct")
13970    (set_attr "amdfam10_decode" "direct")
13971    (set_attr "bdver1_decode" "direct")])
13973 (define_insn "sqrt_extend<mode>xf2_i387"
13974   [(set (match_operand:XF 0 "register_operand" "=f")
13975         (sqrt:XF
13976           (float_extend:XF
13977             (match_operand:MODEF 1 "register_operand" "0"))))]
13978   "TARGET_USE_FANCY_MATH_387"
13979   "fsqrt"
13980   [(set_attr "type" "fpspc")
13981    (set_attr "mode" "XF")
13982    (set_attr "athlon_decode" "direct")
13983    (set_attr "amdfam10_decode" "direct")
13984    (set_attr "bdver1_decode" "direct")])
13986 (define_insn "*rsqrtsf2_sse"
13987   [(set (match_operand:SF 0 "register_operand" "=x")
13988         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13989                    UNSPEC_RSQRT))]
13990   "TARGET_SSE_MATH"
13991   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13992   [(set_attr "type" "sse")
13993    (set_attr "atom_sse_attr" "rcp")
13994    (set_attr "btver2_sse_attr" "rcp")
13995    (set_attr "prefix" "maybe_vex")
13996    (set_attr "mode" "SF")])
13998 (define_expand "rsqrtsf2"
13999   [(set (match_operand:SF 0 "register_operand")
14000         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
14001                    UNSPEC_RSQRT))]
14002   "TARGET_SSE_MATH"
14004   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
14005   DONE;
14008 (define_insn "*sqrt<mode>2_sse"
14009   [(set (match_operand:MODEF 0 "register_operand" "=x")
14010         (sqrt:MODEF
14011           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
14012   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
14013   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
14014   [(set_attr "type" "sse")
14015    (set_attr "atom_sse_attr" "sqrt")
14016    (set_attr "btver2_sse_attr" "sqrt")
14017    (set_attr "prefix" "maybe_vex")
14018    (set_attr "mode" "<MODE>")
14019    (set_attr "athlon_decode" "*")
14020    (set_attr "amdfam10_decode" "*")
14021    (set_attr "bdver1_decode" "*")])
14023 (define_expand "sqrt<mode>2"
14024   [(set (match_operand:MODEF 0 "register_operand")
14025         (sqrt:MODEF
14026           (match_operand:MODEF 1 "nonimmediate_operand")))]
14027   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
14028    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14030   if (<MODE>mode == SFmode
14031       && TARGET_SSE_MATH
14032       && TARGET_RECIP_SQRT
14033       && !optimize_function_for_size_p (cfun)
14034       && flag_finite_math_only && !flag_trapping_math
14035       && flag_unsafe_math_optimizations)
14036     {
14037       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
14038       DONE;
14039     }
14041   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
14042     {
14043       rtx op0 = gen_reg_rtx (XFmode);
14044       rtx op1 = force_reg (<MODE>mode, operands[1]);
14046       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
14047       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
14048       DONE;
14049    }
14052 (define_insn "fpremxf4_i387"
14053   [(set (match_operand:XF 0 "register_operand" "=f")
14054         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14055                     (match_operand:XF 3 "register_operand" "1")]
14056                    UNSPEC_FPREM_F))
14057    (set (match_operand:XF 1 "register_operand" "=u")
14058         (unspec:XF [(match_dup 2) (match_dup 3)]
14059                    UNSPEC_FPREM_U))
14060    (set (reg:CCFP FPSR_REG)
14061         (unspec:CCFP [(match_dup 2) (match_dup 3)]
14062                      UNSPEC_C2_FLAG))]
14063   "TARGET_USE_FANCY_MATH_387
14064    && flag_finite_math_only"
14065   "fprem"
14066   [(set_attr "type" "fpspc")
14067    (set_attr "mode" "XF")])
14069 (define_expand "fmodxf3"
14070   [(use (match_operand:XF 0 "register_operand"))
14071    (use (match_operand:XF 1 "general_operand"))
14072    (use (match_operand:XF 2 "general_operand"))]
14073   "TARGET_USE_FANCY_MATH_387
14074    && flag_finite_math_only"
14076   rtx_code_label *label = gen_label_rtx ();
14078   rtx op1 = gen_reg_rtx (XFmode);
14079   rtx op2 = gen_reg_rtx (XFmode);
14081   emit_move_insn (op2, operands[2]);
14082   emit_move_insn (op1, operands[1]);
14084   emit_label (label);
14085   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14086   ix86_emit_fp_unordered_jump (label);
14087   LABEL_NUSES (label) = 1;
14089   emit_move_insn (operands[0], op1);
14090   DONE;
14093 (define_expand "fmod<mode>3"
14094   [(use (match_operand:MODEF 0 "register_operand"))
14095    (use (match_operand:MODEF 1 "general_operand"))
14096    (use (match_operand:MODEF 2 "general_operand"))]
14097   "TARGET_USE_FANCY_MATH_387
14098    && flag_finite_math_only"
14100   rtx (*gen_truncxf) (rtx, rtx);
14102   rtx_code_label *label = gen_label_rtx ();
14104   rtx op1 = gen_reg_rtx (XFmode);
14105   rtx op2 = gen_reg_rtx (XFmode);
14107   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14108   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14110   emit_label (label);
14111   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14112   ix86_emit_fp_unordered_jump (label);
14113   LABEL_NUSES (label) = 1;
14115   /* Truncate the result properly for strict SSE math.  */
14116   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14117       && !TARGET_MIX_SSE_I387)
14118     gen_truncxf = gen_truncxf<mode>2;
14119   else
14120     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14122   emit_insn (gen_truncxf (operands[0], op1));
14123   DONE;
14126 (define_insn "fprem1xf4_i387"
14127   [(set (match_operand:XF 0 "register_operand" "=f")
14128         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14129                     (match_operand:XF 3 "register_operand" "1")]
14130                    UNSPEC_FPREM1_F))
14131    (set (match_operand:XF 1 "register_operand" "=u")
14132         (unspec:XF [(match_dup 2) (match_dup 3)]
14133                    UNSPEC_FPREM1_U))
14134    (set (reg:CCFP FPSR_REG)
14135         (unspec:CCFP [(match_dup 2) (match_dup 3)]
14136                      UNSPEC_C2_FLAG))]
14137   "TARGET_USE_FANCY_MATH_387
14138    && flag_finite_math_only"
14139   "fprem1"
14140   [(set_attr "type" "fpspc")
14141    (set_attr "mode" "XF")])
14143 (define_expand "remainderxf3"
14144   [(use (match_operand:XF 0 "register_operand"))
14145    (use (match_operand:XF 1 "general_operand"))
14146    (use (match_operand:XF 2 "general_operand"))]
14147   "TARGET_USE_FANCY_MATH_387
14148    && flag_finite_math_only"
14150   rtx_code_label *label = gen_label_rtx ();
14152   rtx op1 = gen_reg_rtx (XFmode);
14153   rtx op2 = gen_reg_rtx (XFmode);
14155   emit_move_insn (op2, operands[2]);
14156   emit_move_insn (op1, operands[1]);
14158   emit_label (label);
14159   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14160   ix86_emit_fp_unordered_jump (label);
14161   LABEL_NUSES (label) = 1;
14163   emit_move_insn (operands[0], op1);
14164   DONE;
14167 (define_expand "remainder<mode>3"
14168   [(use (match_operand:MODEF 0 "register_operand"))
14169    (use (match_operand:MODEF 1 "general_operand"))
14170    (use (match_operand:MODEF 2 "general_operand"))]
14171   "TARGET_USE_FANCY_MATH_387
14172    && flag_finite_math_only"
14174   rtx (*gen_truncxf) (rtx, rtx);
14176   rtx_code_label *label = gen_label_rtx ();
14178   rtx op1 = gen_reg_rtx (XFmode);
14179   rtx op2 = gen_reg_rtx (XFmode);
14181   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14182   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14184   emit_label (label);
14186   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14187   ix86_emit_fp_unordered_jump (label);
14188   LABEL_NUSES (label) = 1;
14190   /* Truncate the result properly for strict SSE math.  */
14191   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14192       && !TARGET_MIX_SSE_I387)
14193     gen_truncxf = gen_truncxf<mode>2;
14194   else
14195     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14197   emit_insn (gen_truncxf (operands[0], op1));
14198   DONE;
14201 (define_int_iterator SINCOS
14202         [UNSPEC_SIN
14203          UNSPEC_COS])
14205 (define_int_attr sincos
14206         [(UNSPEC_SIN "sin")
14207          (UNSPEC_COS "cos")])
14209 (define_insn "*<sincos>xf2_i387"
14210   [(set (match_operand:XF 0 "register_operand" "=f")
14211         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14212                    SINCOS))]
14213   "TARGET_USE_FANCY_MATH_387
14214    && flag_unsafe_math_optimizations"
14215   "f<sincos>"
14216   [(set_attr "type" "fpspc")
14217    (set_attr "mode" "XF")])
14219 (define_insn "*<sincos>_extend<mode>xf2_i387"
14220   [(set (match_operand:XF 0 "register_operand" "=f")
14221         (unspec:XF [(float_extend:XF
14222                       (match_operand:MODEF 1 "register_operand" "0"))]
14223                    SINCOS))]
14224   "TARGET_USE_FANCY_MATH_387
14225    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14226        || TARGET_MIX_SSE_I387)
14227    && flag_unsafe_math_optimizations"
14228   "f<sincos>"
14229   [(set_attr "type" "fpspc")
14230    (set_attr "mode" "XF")])
14232 ;; When sincos pattern is defined, sin and cos builtin functions will be
14233 ;; expanded to sincos pattern with one of its outputs left unused.
14234 ;; CSE pass will figure out if two sincos patterns can be combined,
14235 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14236 ;; depending on the unused output.
14238 (define_insn "sincosxf3"
14239   [(set (match_operand:XF 0 "register_operand" "=f")
14240         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14241                    UNSPEC_SINCOS_COS))
14242    (set (match_operand:XF 1 "register_operand" "=u")
14243         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14244   "TARGET_USE_FANCY_MATH_387
14245    && flag_unsafe_math_optimizations"
14246   "fsincos"
14247   [(set_attr "type" "fpspc")
14248    (set_attr "mode" "XF")])
14250 (define_split
14251   [(set (match_operand:XF 0 "register_operand")
14252         (unspec:XF [(match_operand:XF 2 "register_operand")]
14253                    UNSPEC_SINCOS_COS))
14254    (set (match_operand:XF 1 "register_operand")
14255         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14256   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14257    && can_create_pseudo_p ()"
14258   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
14260 (define_split
14261   [(set (match_operand:XF 0 "register_operand")
14262         (unspec:XF [(match_operand:XF 2 "register_operand")]
14263                    UNSPEC_SINCOS_COS))
14264    (set (match_operand:XF 1 "register_operand")
14265         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14266   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14267    && can_create_pseudo_p ()"
14268   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
14270 (define_insn "sincos_extend<mode>xf3_i387"
14271   [(set (match_operand:XF 0 "register_operand" "=f")
14272         (unspec:XF [(float_extend:XF
14273                       (match_operand:MODEF 2 "register_operand" "0"))]
14274                    UNSPEC_SINCOS_COS))
14275    (set (match_operand:XF 1 "register_operand" "=u")
14276         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14277   "TARGET_USE_FANCY_MATH_387
14278    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14279        || TARGET_MIX_SSE_I387)
14280    && flag_unsafe_math_optimizations"
14281   "fsincos"
14282   [(set_attr "type" "fpspc")
14283    (set_attr "mode" "XF")])
14285 (define_split
14286   [(set (match_operand:XF 0 "register_operand")
14287         (unspec:XF [(float_extend:XF
14288                       (match_operand:MODEF 2 "register_operand"))]
14289                    UNSPEC_SINCOS_COS))
14290    (set (match_operand:XF 1 "register_operand")
14291         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14292   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14293    && can_create_pseudo_p ()"
14294   [(set (match_dup 1)
14295         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14297 (define_split
14298   [(set (match_operand:XF 0 "register_operand")
14299         (unspec:XF [(float_extend:XF
14300                       (match_operand:MODEF 2 "register_operand"))]
14301                    UNSPEC_SINCOS_COS))
14302    (set (match_operand:XF 1 "register_operand")
14303         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14304   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14305    && can_create_pseudo_p ()"
14306   [(set (match_dup 0)
14307         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14309 (define_expand "sincos<mode>3"
14310   [(use (match_operand:MODEF 0 "register_operand"))
14311    (use (match_operand:MODEF 1 "register_operand"))
14312    (use (match_operand:MODEF 2 "register_operand"))]
14313   "TARGET_USE_FANCY_MATH_387
14314    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14315        || TARGET_MIX_SSE_I387)
14316    && flag_unsafe_math_optimizations"
14318   rtx op0 = gen_reg_rtx (XFmode);
14319   rtx op1 = gen_reg_rtx (XFmode);
14321   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14322   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14323   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14324   DONE;
14327 (define_insn "fptanxf4_i387"
14328   [(set (match_operand:XF 0 "register_operand" "=f")
14329         (match_operand:XF 3 "const_double_operand" "F"))
14330    (set (match_operand:XF 1 "register_operand" "=u")
14331         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14332                    UNSPEC_TAN))]
14333   "TARGET_USE_FANCY_MATH_387
14334    && flag_unsafe_math_optimizations
14335    && standard_80387_constant_p (operands[3]) == 2"
14336   "fptan"
14337   [(set_attr "type" "fpspc")
14338    (set_attr "mode" "XF")])
14340 (define_insn "fptan_extend<mode>xf4_i387"
14341   [(set (match_operand:MODEF 0 "register_operand" "=f")
14342         (match_operand:MODEF 3 "const_double_operand" "F"))
14343    (set (match_operand:XF 1 "register_operand" "=u")
14344         (unspec:XF [(float_extend:XF
14345                       (match_operand:MODEF 2 "register_operand" "0"))]
14346                    UNSPEC_TAN))]
14347   "TARGET_USE_FANCY_MATH_387
14348    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14349        || TARGET_MIX_SSE_I387)
14350    && flag_unsafe_math_optimizations
14351    && standard_80387_constant_p (operands[3]) == 2"
14352   "fptan"
14353   [(set_attr "type" "fpspc")
14354    (set_attr "mode" "XF")])
14356 (define_expand "tanxf2"
14357   [(use (match_operand:XF 0 "register_operand"))
14358    (use (match_operand:XF 1 "register_operand"))]
14359   "TARGET_USE_FANCY_MATH_387
14360    && flag_unsafe_math_optimizations"
14362   rtx one = gen_reg_rtx (XFmode);
14363   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14365   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14366   DONE;
14369 (define_expand "tan<mode>2"
14370   [(use (match_operand:MODEF 0 "register_operand"))
14371    (use (match_operand:MODEF 1 "register_operand"))]
14372   "TARGET_USE_FANCY_MATH_387
14373    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14374        || TARGET_MIX_SSE_I387)
14375    && flag_unsafe_math_optimizations"
14377   rtx op0 = gen_reg_rtx (XFmode);
14379   rtx one = gen_reg_rtx (<MODE>mode);
14380   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14382   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14383                                              operands[1], op2));
14384   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14385   DONE;
14388 (define_insn "*fpatanxf3_i387"
14389   [(set (match_operand:XF 0 "register_operand" "=f")
14390         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14391                     (match_operand:XF 2 "register_operand" "u")]
14392                    UNSPEC_FPATAN))
14393    (clobber (match_scratch:XF 3 "=2"))]
14394   "TARGET_USE_FANCY_MATH_387
14395    && flag_unsafe_math_optimizations"
14396   "fpatan"
14397   [(set_attr "type" "fpspc")
14398    (set_attr "mode" "XF")])
14400 (define_insn "fpatan_extend<mode>xf3_i387"
14401   [(set (match_operand:XF 0 "register_operand" "=f")
14402         (unspec:XF [(float_extend:XF
14403                       (match_operand:MODEF 1 "register_operand" "0"))
14404                     (float_extend:XF
14405                       (match_operand:MODEF 2 "register_operand" "u"))]
14406                    UNSPEC_FPATAN))
14407    (clobber (match_scratch:XF 3 "=2"))]
14408   "TARGET_USE_FANCY_MATH_387
14409    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14410        || TARGET_MIX_SSE_I387)
14411    && flag_unsafe_math_optimizations"
14412   "fpatan"
14413   [(set_attr "type" "fpspc")
14414    (set_attr "mode" "XF")])
14416 (define_expand "atan2xf3"
14417   [(parallel [(set (match_operand:XF 0 "register_operand")
14418                    (unspec:XF [(match_operand:XF 2 "register_operand")
14419                                (match_operand:XF 1 "register_operand")]
14420                               UNSPEC_FPATAN))
14421               (clobber (match_scratch:XF 3))])]
14422   "TARGET_USE_FANCY_MATH_387
14423    && flag_unsafe_math_optimizations")
14425 (define_expand "atan2<mode>3"
14426   [(use (match_operand:MODEF 0 "register_operand"))
14427    (use (match_operand:MODEF 1 "register_operand"))
14428    (use (match_operand:MODEF 2 "register_operand"))]
14429   "TARGET_USE_FANCY_MATH_387
14430    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14431        || TARGET_MIX_SSE_I387)
14432    && flag_unsafe_math_optimizations"
14434   rtx op0 = gen_reg_rtx (XFmode);
14436   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14437   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14438   DONE;
14441 (define_expand "atanxf2"
14442   [(parallel [(set (match_operand:XF 0 "register_operand")
14443                    (unspec:XF [(match_dup 2)
14444                                (match_operand:XF 1 "register_operand")]
14445                               UNSPEC_FPATAN))
14446               (clobber (match_scratch:XF 3))])]
14447   "TARGET_USE_FANCY_MATH_387
14448    && flag_unsafe_math_optimizations"
14450   operands[2] = gen_reg_rtx (XFmode);
14451   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
14454 (define_expand "atan<mode>2"
14455   [(use (match_operand:MODEF 0 "register_operand"))
14456    (use (match_operand:MODEF 1 "register_operand"))]
14457   "TARGET_USE_FANCY_MATH_387
14458    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14459        || TARGET_MIX_SSE_I387)
14460    && flag_unsafe_math_optimizations"
14462   rtx op0 = gen_reg_rtx (XFmode);
14464   rtx op2 = gen_reg_rtx (<MODE>mode);
14465   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
14467   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14468   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14469   DONE;
14472 (define_expand "asinxf2"
14473   [(set (match_dup 2)
14474         (mult:XF (match_operand:XF 1 "register_operand")
14475                  (match_dup 1)))
14476    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14477    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14478    (parallel [(set (match_operand:XF 0 "register_operand")
14479                    (unspec:XF [(match_dup 5) (match_dup 1)]
14480                               UNSPEC_FPATAN))
14481               (clobber (match_scratch:XF 6))])]
14482   "TARGET_USE_FANCY_MATH_387
14483    && flag_unsafe_math_optimizations"
14485   int i;
14487   if (optimize_insn_for_size_p ())
14488     FAIL;
14490   for (i = 2; i < 6; i++)
14491     operands[i] = gen_reg_rtx (XFmode);
14493   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14496 (define_expand "asin<mode>2"
14497   [(use (match_operand:MODEF 0 "register_operand"))
14498    (use (match_operand:MODEF 1 "general_operand"))]
14499  "TARGET_USE_FANCY_MATH_387
14500    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14501        || TARGET_MIX_SSE_I387)
14502    && flag_unsafe_math_optimizations"
14504   rtx op0 = gen_reg_rtx (XFmode);
14505   rtx op1 = gen_reg_rtx (XFmode);
14507   if (optimize_insn_for_size_p ())
14508     FAIL;
14510   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14511   emit_insn (gen_asinxf2 (op0, op1));
14512   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14513   DONE;
14516 (define_expand "acosxf2"
14517   [(set (match_dup 2)
14518         (mult:XF (match_operand:XF 1 "register_operand")
14519                  (match_dup 1)))
14520    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14521    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14522    (parallel [(set (match_operand:XF 0 "register_operand")
14523                    (unspec:XF [(match_dup 1) (match_dup 5)]
14524                               UNSPEC_FPATAN))
14525               (clobber (match_scratch:XF 6))])]
14526   "TARGET_USE_FANCY_MATH_387
14527    && flag_unsafe_math_optimizations"
14529   int i;
14531   if (optimize_insn_for_size_p ())
14532     FAIL;
14534   for (i = 2; i < 6; i++)
14535     operands[i] = gen_reg_rtx (XFmode);
14537   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14540 (define_expand "acos<mode>2"
14541   [(use (match_operand:MODEF 0 "register_operand"))
14542    (use (match_operand:MODEF 1 "general_operand"))]
14543  "TARGET_USE_FANCY_MATH_387
14544    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14545        || TARGET_MIX_SSE_I387)
14546    && flag_unsafe_math_optimizations"
14548   rtx op0 = gen_reg_rtx (XFmode);
14549   rtx op1 = gen_reg_rtx (XFmode);
14551   if (optimize_insn_for_size_p ())
14552     FAIL;
14554   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14555   emit_insn (gen_acosxf2 (op0, op1));
14556   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14557   DONE;
14560 (define_insn "fyl2xxf3_i387"
14561   [(set (match_operand:XF 0 "register_operand" "=f")
14562         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14563                     (match_operand:XF 2 "register_operand" "u")]
14564                    UNSPEC_FYL2X))
14565    (clobber (match_scratch:XF 3 "=2"))]
14566   "TARGET_USE_FANCY_MATH_387
14567    && flag_unsafe_math_optimizations"
14568   "fyl2x"
14569   [(set_attr "type" "fpspc")
14570    (set_attr "mode" "XF")])
14572 (define_insn "fyl2x_extend<mode>xf3_i387"
14573   [(set (match_operand:XF 0 "register_operand" "=f")
14574         (unspec:XF [(float_extend:XF
14575                       (match_operand:MODEF 1 "register_operand" "0"))
14576                     (match_operand:XF 2 "register_operand" "u")]
14577                    UNSPEC_FYL2X))
14578    (clobber (match_scratch:XF 3 "=2"))]
14579   "TARGET_USE_FANCY_MATH_387
14580    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14581        || TARGET_MIX_SSE_I387)
14582    && flag_unsafe_math_optimizations"
14583   "fyl2x"
14584   [(set_attr "type" "fpspc")
14585    (set_attr "mode" "XF")])
14587 (define_expand "logxf2"
14588   [(parallel [(set (match_operand:XF 0 "register_operand")
14589                    (unspec:XF [(match_operand:XF 1 "register_operand")
14590                                (match_dup 2)] UNSPEC_FYL2X))
14591               (clobber (match_scratch:XF 3))])]
14592   "TARGET_USE_FANCY_MATH_387
14593    && flag_unsafe_math_optimizations"
14595   operands[2] = gen_reg_rtx (XFmode);
14596   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14599 (define_expand "log<mode>2"
14600   [(use (match_operand:MODEF 0 "register_operand"))
14601    (use (match_operand:MODEF 1 "register_operand"))]
14602   "TARGET_USE_FANCY_MATH_387
14603    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14604        || TARGET_MIX_SSE_I387)
14605    && flag_unsafe_math_optimizations"
14607   rtx op0 = gen_reg_rtx (XFmode);
14609   rtx op2 = gen_reg_rtx (XFmode);
14610   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14612   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14613   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14614   DONE;
14617 (define_expand "log10xf2"
14618   [(parallel [(set (match_operand:XF 0 "register_operand")
14619                    (unspec:XF [(match_operand:XF 1 "register_operand")
14620                                (match_dup 2)] UNSPEC_FYL2X))
14621               (clobber (match_scratch:XF 3))])]
14622   "TARGET_USE_FANCY_MATH_387
14623    && flag_unsafe_math_optimizations"
14625   operands[2] = gen_reg_rtx (XFmode);
14626   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14629 (define_expand "log10<mode>2"
14630   [(use (match_operand:MODEF 0 "register_operand"))
14631    (use (match_operand:MODEF 1 "register_operand"))]
14632   "TARGET_USE_FANCY_MATH_387
14633    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14634        || TARGET_MIX_SSE_I387)
14635    && flag_unsafe_math_optimizations"
14637   rtx op0 = gen_reg_rtx (XFmode);
14639   rtx op2 = gen_reg_rtx (XFmode);
14640   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14642   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14643   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14644   DONE;
14647 (define_expand "log2xf2"
14648   [(parallel [(set (match_operand:XF 0 "register_operand")
14649                    (unspec:XF [(match_operand:XF 1 "register_operand")
14650                                (match_dup 2)] UNSPEC_FYL2X))
14651               (clobber (match_scratch:XF 3))])]
14652   "TARGET_USE_FANCY_MATH_387
14653    && flag_unsafe_math_optimizations"
14655   operands[2] = gen_reg_rtx (XFmode);
14656   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14659 (define_expand "log2<mode>2"
14660   [(use (match_operand:MODEF 0 "register_operand"))
14661    (use (match_operand:MODEF 1 "register_operand"))]
14662   "TARGET_USE_FANCY_MATH_387
14663    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14664        || TARGET_MIX_SSE_I387)
14665    && flag_unsafe_math_optimizations"
14667   rtx op0 = gen_reg_rtx (XFmode);
14669   rtx op2 = gen_reg_rtx (XFmode);
14670   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14672   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14673   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14674   DONE;
14677 (define_insn "fyl2xp1xf3_i387"
14678   [(set (match_operand:XF 0 "register_operand" "=f")
14679         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14680                     (match_operand:XF 2 "register_operand" "u")]
14681                    UNSPEC_FYL2XP1))
14682    (clobber (match_scratch:XF 3 "=2"))]
14683   "TARGET_USE_FANCY_MATH_387
14684    && flag_unsafe_math_optimizations"
14685   "fyl2xp1"
14686   [(set_attr "type" "fpspc")
14687    (set_attr "mode" "XF")])
14689 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14690   [(set (match_operand:XF 0 "register_operand" "=f")
14691         (unspec:XF [(float_extend:XF
14692                       (match_operand:MODEF 1 "register_operand" "0"))
14693                     (match_operand:XF 2 "register_operand" "u")]
14694                    UNSPEC_FYL2XP1))
14695    (clobber (match_scratch:XF 3 "=2"))]
14696   "TARGET_USE_FANCY_MATH_387
14697    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14698        || TARGET_MIX_SSE_I387)
14699    && flag_unsafe_math_optimizations"
14700   "fyl2xp1"
14701   [(set_attr "type" "fpspc")
14702    (set_attr "mode" "XF")])
14704 (define_expand "log1pxf2"
14705   [(use (match_operand:XF 0 "register_operand"))
14706    (use (match_operand:XF 1 "register_operand"))]
14707   "TARGET_USE_FANCY_MATH_387
14708    && flag_unsafe_math_optimizations"
14710   if (optimize_insn_for_size_p ())
14711     FAIL;
14713   ix86_emit_i387_log1p (operands[0], operands[1]);
14714   DONE;
14717 (define_expand "log1p<mode>2"
14718   [(use (match_operand:MODEF 0 "register_operand"))
14719    (use (match_operand:MODEF 1 "register_operand"))]
14720   "TARGET_USE_FANCY_MATH_387
14721    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14722        || TARGET_MIX_SSE_I387)
14723    && flag_unsafe_math_optimizations"
14725   rtx op0;
14727   if (optimize_insn_for_size_p ())
14728     FAIL;
14730   op0 = gen_reg_rtx (XFmode);
14732   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14734   ix86_emit_i387_log1p (op0, operands[1]);
14735   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14736   DONE;
14739 (define_insn "fxtractxf3_i387"
14740   [(set (match_operand:XF 0 "register_operand" "=f")
14741         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14742                    UNSPEC_XTRACT_FRACT))
14743    (set (match_operand:XF 1 "register_operand" "=u")
14744         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14745   "TARGET_USE_FANCY_MATH_387
14746    && flag_unsafe_math_optimizations"
14747   "fxtract"
14748   [(set_attr "type" "fpspc")
14749    (set_attr "mode" "XF")])
14751 (define_insn "fxtract_extend<mode>xf3_i387"
14752   [(set (match_operand:XF 0 "register_operand" "=f")
14753         (unspec:XF [(float_extend:XF
14754                       (match_operand:MODEF 2 "register_operand" "0"))]
14755                    UNSPEC_XTRACT_FRACT))
14756    (set (match_operand:XF 1 "register_operand" "=u")
14757         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14758   "TARGET_USE_FANCY_MATH_387
14759    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14760        || TARGET_MIX_SSE_I387)
14761    && flag_unsafe_math_optimizations"
14762   "fxtract"
14763   [(set_attr "type" "fpspc")
14764    (set_attr "mode" "XF")])
14766 (define_expand "logbxf2"
14767   [(parallel [(set (match_dup 2)
14768                    (unspec:XF [(match_operand:XF 1 "register_operand")]
14769                               UNSPEC_XTRACT_FRACT))
14770               (set (match_operand:XF 0 "register_operand")
14771                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14772   "TARGET_USE_FANCY_MATH_387
14773    && flag_unsafe_math_optimizations"
14774   "operands[2] = gen_reg_rtx (XFmode);")
14776 (define_expand "logb<mode>2"
14777   [(use (match_operand:MODEF 0 "register_operand"))
14778    (use (match_operand:MODEF 1 "register_operand"))]
14779   "TARGET_USE_FANCY_MATH_387
14780    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14781        || TARGET_MIX_SSE_I387)
14782    && flag_unsafe_math_optimizations"
14784   rtx op0 = gen_reg_rtx (XFmode);
14785   rtx op1 = gen_reg_rtx (XFmode);
14787   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14788   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14789   DONE;
14792 (define_expand "ilogbxf2"
14793   [(use (match_operand:SI 0 "register_operand"))
14794    (use (match_operand:XF 1 "register_operand"))]
14795   "TARGET_USE_FANCY_MATH_387
14796    && flag_unsafe_math_optimizations"
14798   rtx op0, op1;
14800   if (optimize_insn_for_size_p ())
14801     FAIL;
14803   op0 = gen_reg_rtx (XFmode);
14804   op1 = gen_reg_rtx (XFmode);
14806   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14807   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14808   DONE;
14811 (define_expand "ilogb<mode>2"
14812   [(use (match_operand:SI 0 "register_operand"))
14813    (use (match_operand:MODEF 1 "register_operand"))]
14814   "TARGET_USE_FANCY_MATH_387
14815    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14816        || TARGET_MIX_SSE_I387)
14817    && flag_unsafe_math_optimizations"
14819   rtx op0, op1;
14821   if (optimize_insn_for_size_p ())
14822     FAIL;
14824   op0 = gen_reg_rtx (XFmode);
14825   op1 = gen_reg_rtx (XFmode);
14827   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14828   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14829   DONE;
14832 (define_insn "*f2xm1xf2_i387"
14833   [(set (match_operand:XF 0 "register_operand" "=f")
14834         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14835                    UNSPEC_F2XM1))]
14836   "TARGET_USE_FANCY_MATH_387
14837    && flag_unsafe_math_optimizations"
14838   "f2xm1"
14839   [(set_attr "type" "fpspc")
14840    (set_attr "mode" "XF")])
14842 (define_insn "fscalexf4_i387"
14843   [(set (match_operand:XF 0 "register_operand" "=f")
14844         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14845                     (match_operand:XF 3 "register_operand" "1")]
14846                    UNSPEC_FSCALE_FRACT))
14847    (set (match_operand:XF 1 "register_operand" "=u")
14848         (unspec:XF [(match_dup 2) (match_dup 3)]
14849                    UNSPEC_FSCALE_EXP))]
14850   "TARGET_USE_FANCY_MATH_387
14851    && flag_unsafe_math_optimizations"
14852   "fscale"
14853   [(set_attr "type" "fpspc")
14854    (set_attr "mode" "XF")])
14856 (define_expand "expNcorexf3"
14857   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14858                                (match_operand:XF 2 "register_operand")))
14859    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14860    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14861    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14862    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14863    (parallel [(set (match_operand:XF 0 "register_operand")
14864                    (unspec:XF [(match_dup 8) (match_dup 4)]
14865                               UNSPEC_FSCALE_FRACT))
14866               (set (match_dup 9)
14867                    (unspec:XF [(match_dup 8) (match_dup 4)]
14868                               UNSPEC_FSCALE_EXP))])]
14869   "TARGET_USE_FANCY_MATH_387
14870    && flag_unsafe_math_optimizations"
14872   int i;
14874   if (optimize_insn_for_size_p ())
14875     FAIL;
14877   for (i = 3; i < 10; i++)
14878     operands[i] = gen_reg_rtx (XFmode);
14880   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14883 (define_expand "expxf2"
14884   [(use (match_operand:XF 0 "register_operand"))
14885    (use (match_operand:XF 1 "register_operand"))]
14886   "TARGET_USE_FANCY_MATH_387
14887    && flag_unsafe_math_optimizations"
14889   rtx op2;
14891   if (optimize_insn_for_size_p ())
14892     FAIL;
14894   op2 = gen_reg_rtx (XFmode);
14895   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14897   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14898   DONE;
14901 (define_expand "exp<mode>2"
14902   [(use (match_operand:MODEF 0 "register_operand"))
14903    (use (match_operand:MODEF 1 "general_operand"))]
14904  "TARGET_USE_FANCY_MATH_387
14905    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14906        || TARGET_MIX_SSE_I387)
14907    && flag_unsafe_math_optimizations"
14909   rtx op0, op1;
14911   if (optimize_insn_for_size_p ())
14912     FAIL;
14914   op0 = gen_reg_rtx (XFmode);
14915   op1 = gen_reg_rtx (XFmode);
14917   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14918   emit_insn (gen_expxf2 (op0, op1));
14919   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14920   DONE;
14923 (define_expand "exp10xf2"
14924   [(use (match_operand:XF 0 "register_operand"))
14925    (use (match_operand:XF 1 "register_operand"))]
14926   "TARGET_USE_FANCY_MATH_387
14927    && flag_unsafe_math_optimizations"
14929   rtx op2;
14931   if (optimize_insn_for_size_p ())
14932     FAIL;
14934   op2 = gen_reg_rtx (XFmode);
14935   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14937   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14938   DONE;
14941 (define_expand "exp10<mode>2"
14942   [(use (match_operand:MODEF 0 "register_operand"))
14943    (use (match_operand:MODEF 1 "general_operand"))]
14944  "TARGET_USE_FANCY_MATH_387
14945    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14946        || TARGET_MIX_SSE_I387)
14947    && flag_unsafe_math_optimizations"
14949   rtx op0, op1;
14951   if (optimize_insn_for_size_p ())
14952     FAIL;
14954   op0 = gen_reg_rtx (XFmode);
14955   op1 = gen_reg_rtx (XFmode);
14957   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14958   emit_insn (gen_exp10xf2 (op0, op1));
14959   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14960   DONE;
14963 (define_expand "exp2xf2"
14964   [(use (match_operand:XF 0 "register_operand"))
14965    (use (match_operand:XF 1 "register_operand"))]
14966   "TARGET_USE_FANCY_MATH_387
14967    && flag_unsafe_math_optimizations"
14969   rtx op2;
14971   if (optimize_insn_for_size_p ())
14972     FAIL;
14974   op2 = gen_reg_rtx (XFmode);
14975   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14977   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14978   DONE;
14981 (define_expand "exp2<mode>2"
14982   [(use (match_operand:MODEF 0 "register_operand"))
14983    (use (match_operand:MODEF 1 "general_operand"))]
14984  "TARGET_USE_FANCY_MATH_387
14985    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14986        || TARGET_MIX_SSE_I387)
14987    && flag_unsafe_math_optimizations"
14989   rtx op0, op1;
14991   if (optimize_insn_for_size_p ())
14992     FAIL;
14994   op0 = gen_reg_rtx (XFmode);
14995   op1 = gen_reg_rtx (XFmode);
14997   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14998   emit_insn (gen_exp2xf2 (op0, op1));
14999   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15000   DONE;
15003 (define_expand "expm1xf2"
15004   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15005                                (match_dup 2)))
15006    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15007    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15008    (set (match_dup 9) (float_extend:XF (match_dup 13)))
15009    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15010    (parallel [(set (match_dup 7)
15011                    (unspec:XF [(match_dup 6) (match_dup 4)]
15012                               UNSPEC_FSCALE_FRACT))
15013               (set (match_dup 8)
15014                    (unspec:XF [(match_dup 6) (match_dup 4)]
15015                               UNSPEC_FSCALE_EXP))])
15016    (parallel [(set (match_dup 10)
15017                    (unspec:XF [(match_dup 9) (match_dup 8)]
15018                               UNSPEC_FSCALE_FRACT))
15019               (set (match_dup 11)
15020                    (unspec:XF [(match_dup 9) (match_dup 8)]
15021                               UNSPEC_FSCALE_EXP))])
15022    (set (match_dup 12) (minus:XF (match_dup 10)
15023                                  (float_extend:XF (match_dup 13))))
15024    (set (match_operand:XF 0 "register_operand")
15025         (plus:XF (match_dup 12) (match_dup 7)))]
15026   "TARGET_USE_FANCY_MATH_387
15027    && flag_unsafe_math_optimizations"
15029   int i;
15031   if (optimize_insn_for_size_p ())
15032     FAIL;
15034   for (i = 2; i < 13; i++)
15035     operands[i] = gen_reg_rtx (XFmode);
15037   operands[13]
15038     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
15040   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
15043 (define_expand "expm1<mode>2"
15044   [(use (match_operand:MODEF 0 "register_operand"))
15045    (use (match_operand:MODEF 1 "general_operand"))]
15046  "TARGET_USE_FANCY_MATH_387
15047    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15048        || TARGET_MIX_SSE_I387)
15049    && flag_unsafe_math_optimizations"
15051   rtx op0, op1;
15053   if (optimize_insn_for_size_p ())
15054     FAIL;
15056   op0 = gen_reg_rtx (XFmode);
15057   op1 = gen_reg_rtx (XFmode);
15059   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15060   emit_insn (gen_expm1xf2 (op0, op1));
15061   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15062   DONE;
15065 (define_expand "ldexpxf3"
15066   [(match_operand:XF 0 "register_operand")
15067    (match_operand:XF 1 "register_operand")
15068    (match_operand:SI 2 "register_operand")]
15069   "TARGET_USE_FANCY_MATH_387
15070    && flag_unsafe_math_optimizations"
15072   rtx tmp1, tmp2;
15073   if (optimize_insn_for_size_p ())
15074     FAIL;
15076   tmp1 = gen_reg_rtx (XFmode);
15077   tmp2 = gen_reg_rtx (XFmode);
15079   emit_insn (gen_floatsixf2 (tmp1, operands[2]));
15080   emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
15081                                  operands[1], tmp1));
15082   DONE;
15085 (define_expand "ldexp<mode>3"
15086   [(use (match_operand:MODEF 0 "register_operand"))
15087    (use (match_operand:MODEF 1 "general_operand"))
15088    (use (match_operand:SI 2 "register_operand"))]
15089  "TARGET_USE_FANCY_MATH_387
15090    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15091        || TARGET_MIX_SSE_I387)
15092    && flag_unsafe_math_optimizations"
15094   rtx op0, op1;
15096   if (optimize_insn_for_size_p ())
15097     FAIL;
15099   op0 = gen_reg_rtx (XFmode);
15100   op1 = gen_reg_rtx (XFmode);
15102   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15103   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
15104   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15105   DONE;
15108 (define_expand "scalbxf3"
15109   [(parallel [(set (match_operand:XF 0 " register_operand")
15110                    (unspec:XF [(match_operand:XF 1 "register_operand")
15111                                (match_operand:XF 2 "register_operand")]
15112                               UNSPEC_FSCALE_FRACT))
15113               (set (match_dup 3)
15114                    (unspec:XF [(match_dup 1) (match_dup 2)]
15115                               UNSPEC_FSCALE_EXP))])]
15116   "TARGET_USE_FANCY_MATH_387
15117    && flag_unsafe_math_optimizations"
15119   if (optimize_insn_for_size_p ())
15120     FAIL;
15122   operands[3] = gen_reg_rtx (XFmode);
15125 (define_expand "scalb<mode>3"
15126   [(use (match_operand:MODEF 0 "register_operand"))
15127    (use (match_operand:MODEF 1 "general_operand"))
15128    (use (match_operand:MODEF 2 "general_operand"))]
15129  "TARGET_USE_FANCY_MATH_387
15130    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15131        || TARGET_MIX_SSE_I387)
15132    && flag_unsafe_math_optimizations"
15134   rtx op0, op1, op2;
15136   if (optimize_insn_for_size_p ())
15137     FAIL;
15139   op0 = gen_reg_rtx (XFmode);
15140   op1 = gen_reg_rtx (XFmode);
15141   op2 = gen_reg_rtx (XFmode);
15143   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15144   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15145   emit_insn (gen_scalbxf3 (op0, op1, op2));
15146   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15147   DONE;
15150 (define_expand "significandxf2"
15151   [(parallel [(set (match_operand:XF 0 "register_operand")
15152                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15153                               UNSPEC_XTRACT_FRACT))
15154               (set (match_dup 2)
15155                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15156   "TARGET_USE_FANCY_MATH_387
15157    && flag_unsafe_math_optimizations"
15158   "operands[2] = gen_reg_rtx (XFmode);")
15160 (define_expand "significand<mode>2"
15161   [(use (match_operand:MODEF 0 "register_operand"))
15162    (use (match_operand:MODEF 1 "register_operand"))]
15163   "TARGET_USE_FANCY_MATH_387
15164    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15165        || TARGET_MIX_SSE_I387)
15166    && flag_unsafe_math_optimizations"
15168   rtx op0 = gen_reg_rtx (XFmode);
15169   rtx op1 = gen_reg_rtx (XFmode);
15171   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15172   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15173   DONE;
15177 (define_insn "sse4_1_round<mode>2"
15178   [(set (match_operand:MODEF 0 "register_operand" "=x")
15179         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
15180                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
15181                       UNSPEC_ROUND))]
15182   "TARGET_ROUND"
15183   "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
15184   [(set_attr "type" "ssecvt")
15185    (set_attr "prefix_extra" "1")
15186    (set_attr "prefix" "maybe_vex")
15187    (set_attr "mode" "<MODE>")])
15189 (define_insn "rintxf2"
15190   [(set (match_operand:XF 0 "register_operand" "=f")
15191         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15192                    UNSPEC_FRNDINT))]
15193   "TARGET_USE_FANCY_MATH_387
15194    && flag_unsafe_math_optimizations"
15195   "frndint"
15196   [(set_attr "type" "fpspc")
15197    (set_attr "mode" "XF")])
15199 (define_expand "rint<mode>2"
15200   [(use (match_operand:MODEF 0 "register_operand"))
15201    (use (match_operand:MODEF 1 "register_operand"))]
15202   "(TARGET_USE_FANCY_MATH_387
15203     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15204         || TARGET_MIX_SSE_I387)
15205     && flag_unsafe_math_optimizations)
15206    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15207        && !flag_trapping_math)"
15209   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15210       && !flag_trapping_math)
15211     {
15212       if (TARGET_ROUND)
15213         emit_insn (gen_sse4_1_round<mode>2
15214                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
15215       else if (optimize_insn_for_size_p ())
15216         FAIL;
15217       else
15218         ix86_expand_rint (operands[0], operands[1]);
15219     }
15220   else
15221     {
15222       rtx op0 = gen_reg_rtx (XFmode);
15223       rtx op1 = gen_reg_rtx (XFmode);
15225       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15226       emit_insn (gen_rintxf2 (op0, op1));
15228       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15229     }
15230   DONE;
15233 (define_expand "round<mode>2"
15234   [(match_operand:X87MODEF 0 "register_operand")
15235    (match_operand:X87MODEF 1 "nonimmediate_operand")]
15236   "(TARGET_USE_FANCY_MATH_387
15237     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15238         || TARGET_MIX_SSE_I387)
15239     && flag_unsafe_math_optimizations)
15240    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15241        && !flag_trapping_math && !flag_rounding_math)"
15243   if (optimize_insn_for_size_p ())
15244     FAIL;
15246   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15247       && !flag_trapping_math && !flag_rounding_math)
15248     {
15249       if (TARGET_ROUND)
15250         {
15251           operands[1] = force_reg (<MODE>mode, operands[1]);
15252           ix86_expand_round_sse4 (operands[0], operands[1]);
15253         }
15254       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15255         ix86_expand_round (operands[0], operands[1]);
15256       else
15257         ix86_expand_rounddf_32 (operands[0], operands[1]);
15258     }
15259   else
15260     {
15261       operands[1] = force_reg (<MODE>mode, operands[1]);
15262       ix86_emit_i387_round (operands[0], operands[1]);
15263     }
15264   DONE;
15267 (define_insn_and_split "*fistdi2_1"
15268   [(set (match_operand:DI 0 "nonimmediate_operand")
15269         (unspec:DI [(match_operand:XF 1 "register_operand")]
15270                    UNSPEC_FIST))]
15271   "TARGET_USE_FANCY_MATH_387
15272    && can_create_pseudo_p ()"
15273   "#"
15274   "&& 1"
15275   [(const_int 0)]
15277   if (memory_operand (operands[0], VOIDmode))
15278     emit_insn (gen_fistdi2 (operands[0], operands[1]));
15279   else
15280     {
15281       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15282       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15283                                          operands[2]));
15284     }
15285   DONE;
15287   [(set_attr "type" "fpspc")
15288    (set_attr "mode" "DI")])
15290 (define_insn "fistdi2"
15291   [(set (match_operand:DI 0 "memory_operand" "=m")
15292         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15293                    UNSPEC_FIST))
15294    (clobber (match_scratch:XF 2 "=&1f"))]
15295   "TARGET_USE_FANCY_MATH_387"
15296   "* return output_fix_trunc (insn, operands, false);"
15297   [(set_attr "type" "fpspc")
15298    (set_attr "mode" "DI")])
15300 (define_insn "fistdi2_with_temp"
15301   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15302         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15303                    UNSPEC_FIST))
15304    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15305    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15306   "TARGET_USE_FANCY_MATH_387"
15307   "#"
15308   [(set_attr "type" "fpspc")
15309    (set_attr "mode" "DI")])
15311 (define_split
15312   [(set (match_operand:DI 0 "register_operand")
15313         (unspec:DI [(match_operand:XF 1 "register_operand")]
15314                    UNSPEC_FIST))
15315    (clobber (match_operand:DI 2 "memory_operand"))
15316    (clobber (match_scratch 3))]
15317   "reload_completed"
15318   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15319               (clobber (match_dup 3))])
15320    (set (match_dup 0) (match_dup 2))])
15322 (define_split
15323   [(set (match_operand:DI 0 "memory_operand")
15324         (unspec:DI [(match_operand:XF 1 "register_operand")]
15325                    UNSPEC_FIST))
15326    (clobber (match_operand:DI 2 "memory_operand"))
15327    (clobber (match_scratch 3))]
15328   "reload_completed"
15329   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15330               (clobber (match_dup 3))])])
15332 (define_insn_and_split "*fist<mode>2_1"
15333   [(set (match_operand:SWI24 0 "register_operand")
15334         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15335                       UNSPEC_FIST))]
15336   "TARGET_USE_FANCY_MATH_387
15337    && can_create_pseudo_p ()"
15338   "#"
15339   "&& 1"
15340   [(const_int 0)]
15342   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15343   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15344                                         operands[2]));
15345   DONE;
15347   [(set_attr "type" "fpspc")
15348    (set_attr "mode" "<MODE>")])
15350 (define_insn "fist<mode>2"
15351   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15352         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15353                       UNSPEC_FIST))]
15354   "TARGET_USE_FANCY_MATH_387"
15355   "* return output_fix_trunc (insn, operands, false);"
15356   [(set_attr "type" "fpspc")
15357    (set_attr "mode" "<MODE>")])
15359 (define_insn "fist<mode>2_with_temp"
15360   [(set (match_operand:SWI24 0 "register_operand" "=r")
15361         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15362                       UNSPEC_FIST))
15363    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15364   "TARGET_USE_FANCY_MATH_387"
15365   "#"
15366   [(set_attr "type" "fpspc")
15367    (set_attr "mode" "<MODE>")])
15369 (define_split
15370   [(set (match_operand:SWI24 0 "register_operand")
15371         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15372                       UNSPEC_FIST))
15373    (clobber (match_operand:SWI24 2 "memory_operand"))]
15374   "reload_completed"
15375   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15376    (set (match_dup 0) (match_dup 2))])
15378 (define_split
15379   [(set (match_operand:SWI24 0 "memory_operand")
15380         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15381                       UNSPEC_FIST))
15382    (clobber (match_operand:SWI24 2 "memory_operand"))]
15383   "reload_completed"
15384   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15386 (define_expand "lrintxf<mode>2"
15387   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15388      (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15389                      UNSPEC_FIST))]
15390   "TARGET_USE_FANCY_MATH_387")
15392 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15393   [(set (match_operand:SWI48 0 "nonimmediate_operand")
15394      (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15395                    UNSPEC_FIX_NOTRUNC))]
15396   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15398 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15399   [(match_operand:SWI248x 0 "nonimmediate_operand")
15400    (match_operand:X87MODEF 1 "register_operand")]
15401   "(TARGET_USE_FANCY_MATH_387
15402     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15403         || TARGET_MIX_SSE_I387)
15404     && flag_unsafe_math_optimizations)
15405    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15406        && <SWI248x:MODE>mode != HImode 
15407        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15408        && !flag_trapping_math && !flag_rounding_math)"
15410   if (optimize_insn_for_size_p ())
15411     FAIL;
15413   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15414       && <SWI248x:MODE>mode != HImode
15415       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15416       && !flag_trapping_math && !flag_rounding_math)
15417     ix86_expand_lround (operands[0], operands[1]);
15418   else
15419     ix86_emit_i387_round (operands[0], operands[1]);
15420   DONE;
15423 (define_int_iterator FRNDINT_ROUNDING
15424         [UNSPEC_FRNDINT_FLOOR
15425          UNSPEC_FRNDINT_CEIL
15426          UNSPEC_FRNDINT_TRUNC])
15428 (define_int_iterator FIST_ROUNDING
15429         [UNSPEC_FIST_FLOOR
15430          UNSPEC_FIST_CEIL])
15432 ;; Base name for define_insn
15433 (define_int_attr rounding_insn
15434         [(UNSPEC_FRNDINT_FLOOR "floor")
15435          (UNSPEC_FRNDINT_CEIL "ceil")
15436          (UNSPEC_FRNDINT_TRUNC "btrunc")
15437          (UNSPEC_FIST_FLOOR "floor")
15438          (UNSPEC_FIST_CEIL "ceil")])
15440 (define_int_attr rounding
15441         [(UNSPEC_FRNDINT_FLOOR "floor")
15442          (UNSPEC_FRNDINT_CEIL "ceil")
15443          (UNSPEC_FRNDINT_TRUNC "trunc")
15444          (UNSPEC_FIST_FLOOR "floor")
15445          (UNSPEC_FIST_CEIL "ceil")])
15447 (define_int_attr ROUNDING
15448         [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15449          (UNSPEC_FRNDINT_CEIL "CEIL")
15450          (UNSPEC_FRNDINT_TRUNC "TRUNC")
15451          (UNSPEC_FIST_FLOOR "FLOOR")
15452          (UNSPEC_FIST_CEIL "CEIL")])
15454 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15455 (define_insn_and_split "frndintxf2_<rounding>"
15456   [(set (match_operand:XF 0 "register_operand")
15457         (unspec:XF [(match_operand:XF 1 "register_operand")]
15458                    FRNDINT_ROUNDING))
15459    (clobber (reg:CC FLAGS_REG))]
15460   "TARGET_USE_FANCY_MATH_387
15461    && flag_unsafe_math_optimizations
15462    && can_create_pseudo_p ()"
15463   "#"
15464   "&& 1"
15465   [(const_int 0)]
15467   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15469   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15470   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15472   emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15473                                              operands[2], operands[3]));
15474   DONE;
15476   [(set_attr "type" "frndint")
15477    (set_attr "i387_cw" "<rounding>")
15478    (set_attr "mode" "XF")])
15480 (define_insn "frndintxf2_<rounding>_i387"
15481   [(set (match_operand:XF 0 "register_operand" "=f")
15482         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15483                    FRNDINT_ROUNDING))
15484    (use (match_operand:HI 2 "memory_operand" "m"))
15485    (use (match_operand:HI 3 "memory_operand" "m"))]
15486   "TARGET_USE_FANCY_MATH_387
15487    && flag_unsafe_math_optimizations"
15488   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15489   [(set_attr "type" "frndint")
15490    (set_attr "i387_cw" "<rounding>")
15491    (set_attr "mode" "XF")])
15493 (define_expand "<rounding_insn>xf2"
15494   [(parallel [(set (match_operand:XF 0 "register_operand")
15495                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15496                               FRNDINT_ROUNDING))
15497               (clobber (reg:CC FLAGS_REG))])]
15498   "TARGET_USE_FANCY_MATH_387
15499    && flag_unsafe_math_optimizations
15500    && !optimize_insn_for_size_p ()")
15502 (define_expand "<rounding_insn><mode>2"
15503   [(parallel [(set (match_operand:MODEF 0 "register_operand")
15504                    (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15505                                  FRNDINT_ROUNDING))
15506               (clobber (reg:CC FLAGS_REG))])]
15507   "(TARGET_USE_FANCY_MATH_387
15508     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15509         || TARGET_MIX_SSE_I387)
15510     && flag_unsafe_math_optimizations)
15511    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15512        && !flag_trapping_math)"
15514   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15515       && !flag_trapping_math)
15516     {
15517       if (TARGET_ROUND)
15518         emit_insn (gen_sse4_1_round<mode>2
15519                    (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15520       else if (optimize_insn_for_size_p ())
15521         FAIL;
15522       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15523         {
15524           if (ROUND_<ROUNDING> == ROUND_FLOOR)
15525             ix86_expand_floorceil (operands[0], operands[1], true);
15526           else if (ROUND_<ROUNDING> == ROUND_CEIL)
15527             ix86_expand_floorceil (operands[0], operands[1], false);
15528           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15529             ix86_expand_trunc (operands[0], operands[1]);
15530           else
15531             gcc_unreachable ();
15532         }
15533       else
15534         {
15535           if (ROUND_<ROUNDING> == ROUND_FLOOR)
15536             ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15537           else if (ROUND_<ROUNDING> == ROUND_CEIL)
15538             ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15539           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15540             ix86_expand_truncdf_32 (operands[0], operands[1]);
15541           else
15542             gcc_unreachable ();
15543         }
15544     }
15545   else
15546     {
15547       rtx op0, op1;
15549       if (optimize_insn_for_size_p ())
15550         FAIL;
15552       op0 = gen_reg_rtx (XFmode);
15553       op1 = gen_reg_rtx (XFmode);
15554       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15555       emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15557       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15558     }
15559   DONE;
15562 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15563 (define_insn_and_split "frndintxf2_mask_pm"
15564   [(set (match_operand:XF 0 "register_operand")
15565         (unspec:XF [(match_operand:XF 1 "register_operand")]
15566                    UNSPEC_FRNDINT_MASK_PM))
15567    (clobber (reg:CC FLAGS_REG))]
15568   "TARGET_USE_FANCY_MATH_387
15569    && flag_unsafe_math_optimizations
15570    && can_create_pseudo_p ()"
15571   "#"
15572   "&& 1"
15573   [(const_int 0)]
15575   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15577   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15578   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15580   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15581                                           operands[2], operands[3]));
15582   DONE;
15584   [(set_attr "type" "frndint")
15585    (set_attr "i387_cw" "mask_pm")
15586    (set_attr "mode" "XF")])
15588 (define_insn "frndintxf2_mask_pm_i387"
15589   [(set (match_operand:XF 0 "register_operand" "=f")
15590         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15591                    UNSPEC_FRNDINT_MASK_PM))
15592    (use (match_operand:HI 2 "memory_operand" "m"))
15593    (use (match_operand:HI 3 "memory_operand" "m"))]
15594   "TARGET_USE_FANCY_MATH_387
15595    && flag_unsafe_math_optimizations"
15596   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15597   [(set_attr "type" "frndint")
15598    (set_attr "i387_cw" "mask_pm")
15599    (set_attr "mode" "XF")])
15601 (define_expand "nearbyintxf2"
15602   [(parallel [(set (match_operand:XF 0 "register_operand")
15603                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15604                               UNSPEC_FRNDINT_MASK_PM))
15605               (clobber (reg:CC FLAGS_REG))])]
15606   "TARGET_USE_FANCY_MATH_387
15607    && flag_unsafe_math_optimizations")
15609 (define_expand "nearbyint<mode>2"
15610   [(use (match_operand:MODEF 0 "register_operand"))
15611    (use (match_operand:MODEF 1 "register_operand"))]
15612   "TARGET_USE_FANCY_MATH_387
15613    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15614        || TARGET_MIX_SSE_I387)
15615    && flag_unsafe_math_optimizations"
15617   rtx op0 = gen_reg_rtx (XFmode);
15618   rtx op1 = gen_reg_rtx (XFmode);
15620   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15621   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15623   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15624   DONE;
15627 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15628 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15629   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15630         (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15631                         FIST_ROUNDING))
15632    (clobber (reg:CC FLAGS_REG))]
15633   "TARGET_USE_FANCY_MATH_387
15634    && flag_unsafe_math_optimizations
15635    && can_create_pseudo_p ()"
15636   "#"
15637   "&& 1"
15638   [(const_int 0)]
15640   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15642   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15643   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15644   if (memory_operand (operands[0], VOIDmode))
15645     emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15646                                            operands[2], operands[3]));
15647   else
15648     {
15649       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15650       emit_insn (gen_fist<mode>2_<rounding>_with_temp
15651                   (operands[0], operands[1], operands[2],
15652                    operands[3], operands[4]));
15653     }
15654   DONE;
15656   [(set_attr "type" "fistp")
15657    (set_attr "i387_cw" "<rounding>")
15658    (set_attr "mode" "<MODE>")])
15660 (define_insn "fistdi2_<rounding>"
15661   [(set (match_operand:DI 0 "memory_operand" "=m")
15662         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15663                    FIST_ROUNDING))
15664    (use (match_operand:HI 2 "memory_operand" "m"))
15665    (use (match_operand:HI 3 "memory_operand" "m"))
15666    (clobber (match_scratch:XF 4 "=&1f"))]
15667   "TARGET_USE_FANCY_MATH_387
15668    && flag_unsafe_math_optimizations"
15669   "* return output_fix_trunc (insn, operands, false);"
15670   [(set_attr "type" "fistp")
15671    (set_attr "i387_cw" "<rounding>")
15672    (set_attr "mode" "DI")])
15674 (define_insn "fistdi2_<rounding>_with_temp"
15675   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15676         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15677                    FIST_ROUNDING))
15678    (use (match_operand:HI 2 "memory_operand" "m,m"))
15679    (use (match_operand:HI 3 "memory_operand" "m,m"))
15680    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15681    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15682   "TARGET_USE_FANCY_MATH_387
15683    && flag_unsafe_math_optimizations"
15684   "#"
15685   [(set_attr "type" "fistp")
15686    (set_attr "i387_cw" "<rounding>")
15687    (set_attr "mode" "DI")])
15689 (define_split
15690   [(set (match_operand:DI 0 "register_operand")
15691         (unspec:DI [(match_operand:XF 1 "register_operand")]
15692                    FIST_ROUNDING))
15693    (use (match_operand:HI 2 "memory_operand"))
15694    (use (match_operand:HI 3 "memory_operand"))
15695    (clobber (match_operand:DI 4 "memory_operand"))
15696    (clobber (match_scratch 5))]
15697   "reload_completed"
15698   [(parallel [(set (match_dup 4)
15699                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15700               (use (match_dup 2))
15701               (use (match_dup 3))
15702               (clobber (match_dup 5))])
15703    (set (match_dup 0) (match_dup 4))])
15705 (define_split
15706   [(set (match_operand:DI 0 "memory_operand")
15707         (unspec:DI [(match_operand:XF 1 "register_operand")]
15708                    FIST_ROUNDING))
15709    (use (match_operand:HI 2 "memory_operand"))
15710    (use (match_operand:HI 3 "memory_operand"))
15711    (clobber (match_operand:DI 4 "memory_operand"))
15712    (clobber (match_scratch 5))]
15713   "reload_completed"
15714   [(parallel [(set (match_dup 0)
15715                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15716               (use (match_dup 2))
15717               (use (match_dup 3))
15718               (clobber (match_dup 5))])])
15720 (define_insn "fist<mode>2_<rounding>"
15721   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15722         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15723                       FIST_ROUNDING))
15724    (use (match_operand:HI 2 "memory_operand" "m"))
15725    (use (match_operand:HI 3 "memory_operand" "m"))]
15726   "TARGET_USE_FANCY_MATH_387
15727    && flag_unsafe_math_optimizations"
15728   "* return output_fix_trunc (insn, operands, false);"
15729   [(set_attr "type" "fistp")
15730    (set_attr "i387_cw" "<rounding>")
15731    (set_attr "mode" "<MODE>")])
15733 (define_insn "fist<mode>2_<rounding>_with_temp"
15734   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15735         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15736                       FIST_ROUNDING))
15737    (use (match_operand:HI 2 "memory_operand" "m,m"))
15738    (use (match_operand:HI 3 "memory_operand" "m,m"))
15739    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15740   "TARGET_USE_FANCY_MATH_387
15741    && flag_unsafe_math_optimizations"
15742   "#"
15743   [(set_attr "type" "fistp")
15744    (set_attr "i387_cw" "<rounding>")
15745    (set_attr "mode" "<MODE>")])
15747 (define_split
15748   [(set (match_operand:SWI24 0 "register_operand")
15749         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15750                       FIST_ROUNDING))
15751    (use (match_operand:HI 2 "memory_operand"))
15752    (use (match_operand:HI 3 "memory_operand"))
15753    (clobber (match_operand:SWI24 4 "memory_operand"))]
15754   "reload_completed"
15755   [(parallel [(set (match_dup 4)
15756                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15757               (use (match_dup 2))
15758               (use (match_dup 3))])
15759    (set (match_dup 0) (match_dup 4))])
15761 (define_split
15762   [(set (match_operand:SWI24 0 "memory_operand")
15763         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15764                       FIST_ROUNDING))
15765    (use (match_operand:HI 2 "memory_operand"))
15766    (use (match_operand:HI 3 "memory_operand"))
15767    (clobber (match_operand:SWI24 4 "memory_operand"))]
15768   "reload_completed"
15769   [(parallel [(set (match_dup 0)
15770                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15771               (use (match_dup 2))
15772               (use (match_dup 3))])])
15774 (define_expand "l<rounding_insn>xf<mode>2"
15775   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15776                    (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15777                                    FIST_ROUNDING))
15778               (clobber (reg:CC FLAGS_REG))])]
15779   "TARGET_USE_FANCY_MATH_387
15780    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15781    && flag_unsafe_math_optimizations")
15783 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15784   [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15785                    (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15786                                  FIST_ROUNDING))
15787               (clobber (reg:CC FLAGS_REG))])]
15788   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15789    && !flag_trapping_math"
15791   if (TARGET_64BIT && optimize_insn_for_size_p ())
15792     FAIL;
15794   if (ROUND_<ROUNDING> == ROUND_FLOOR)
15795     ix86_expand_lfloorceil (operands[0], operands[1], true);
15796   else if (ROUND_<ROUNDING> == ROUND_CEIL)
15797     ix86_expand_lfloorceil (operands[0], operands[1], false);
15798   else
15799     gcc_unreachable ();
15801   DONE;
15804 (define_insn "fxam<mode>2_i387"
15805   [(set (match_operand:HI 0 "register_operand" "=a")
15806         (unspec:HI
15807           [(match_operand:X87MODEF 1 "register_operand" "f")]
15808           UNSPEC_FXAM))]
15809   "TARGET_USE_FANCY_MATH_387"
15810   "fxam\n\tfnstsw\t%0"
15811   [(set_attr "type" "multi")
15812    (set_attr "length" "4")
15813    (set_attr "unit" "i387")
15814    (set_attr "mode" "<MODE>")])
15816 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15817   [(set (match_operand:HI 0 "register_operand")
15818         (unspec:HI
15819           [(match_operand:MODEF 1 "memory_operand")]
15820           UNSPEC_FXAM_MEM))]
15821   "TARGET_USE_FANCY_MATH_387
15822    && can_create_pseudo_p ()"
15823   "#"
15824   "&& 1"
15825   [(set (match_dup 2)(match_dup 1))
15826    (set (match_dup 0)
15827         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15829   operands[2] = gen_reg_rtx (<MODE>mode);
15831   MEM_VOLATILE_P (operands[1]) = 1;
15833   [(set_attr "type" "multi")
15834    (set_attr "unit" "i387")
15835    (set_attr "mode" "<MODE>")])
15837 (define_expand "isinfxf2"
15838   [(use (match_operand:SI 0 "register_operand"))
15839    (use (match_operand:XF 1 "register_operand"))]
15840   "TARGET_USE_FANCY_MATH_387
15841    && ix86_libc_has_function (function_c99_misc)"
15843   rtx mask = GEN_INT (0x45);
15844   rtx val = GEN_INT (0x05);
15846   rtx cond;
15848   rtx scratch = gen_reg_rtx (HImode);
15849   rtx res = gen_reg_rtx (QImode);
15851   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15853   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15854   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15855   cond = gen_rtx_fmt_ee (EQ, QImode,
15856                          gen_rtx_REG (CCmode, FLAGS_REG),
15857                          const0_rtx);
15858   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15859   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15860   DONE;
15863 (define_expand "isinf<mode>2"
15864   [(use (match_operand:SI 0 "register_operand"))
15865    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15866   "TARGET_USE_FANCY_MATH_387
15867    && ix86_libc_has_function (function_c99_misc)
15868    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15870   rtx mask = GEN_INT (0x45);
15871   rtx val = GEN_INT (0x05);
15873   rtx cond;
15875   rtx scratch = gen_reg_rtx (HImode);
15876   rtx res = gen_reg_rtx (QImode);
15878   /* Remove excess precision by forcing value through memory. */
15879   if (memory_operand (operands[1], VOIDmode))
15880     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15881   else
15882     {
15883       rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15885       emit_move_insn (temp, operands[1]);
15886       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15887     }
15889   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15890   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15891   cond = gen_rtx_fmt_ee (EQ, QImode,
15892                          gen_rtx_REG (CCmode, FLAGS_REG),
15893                          const0_rtx);
15894   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15895   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15896   DONE;
15899 (define_expand "signbitxf2"
15900   [(use (match_operand:SI 0 "register_operand"))
15901    (use (match_operand:XF 1 "register_operand"))]
15902   "TARGET_USE_FANCY_MATH_387"
15904   rtx scratch = gen_reg_rtx (HImode);
15906   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15907   emit_insn (gen_andsi3 (operands[0],
15908              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15909   DONE;
15912 (define_insn "movmsk_df"
15913   [(set (match_operand:SI 0 "register_operand" "=r")
15914         (unspec:SI
15915           [(match_operand:DF 1 "register_operand" "x")]
15916           UNSPEC_MOVMSK))]
15917   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15918   "%vmovmskpd\t{%1, %0|%0, %1}"
15919   [(set_attr "type" "ssemov")
15920    (set_attr "prefix" "maybe_vex")
15921    (set_attr "mode" "DF")])
15923 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15924 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15925 (define_expand "signbitdf2"
15926   [(use (match_operand:SI 0 "register_operand"))
15927    (use (match_operand:DF 1 "register_operand"))]
15928   "TARGET_USE_FANCY_MATH_387
15929    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15931   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15932     {
15933       emit_insn (gen_movmsk_df (operands[0], operands[1]));
15934       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15935     }
15936   else
15937     {
15938       rtx scratch = gen_reg_rtx (HImode);
15940       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15941       emit_insn (gen_andsi3 (operands[0],
15942                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15943     }
15944   DONE;
15947 (define_expand "signbitsf2"
15948   [(use (match_operand:SI 0 "register_operand"))
15949    (use (match_operand:SF 1 "register_operand"))]
15950   "TARGET_USE_FANCY_MATH_387
15951    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15953   rtx scratch = gen_reg_rtx (HImode);
15955   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15956   emit_insn (gen_andsi3 (operands[0],
15957              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15958   DONE;
15961 ;; Block operation instructions
15963 (define_insn "cld"
15964   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15965   ""
15966   "cld"
15967   [(set_attr "length" "1")
15968    (set_attr "length_immediate" "0")
15969    (set_attr "modrm" "0")])
15971 (define_expand "movmem<mode>"
15972   [(use (match_operand:BLK 0 "memory_operand"))
15973    (use (match_operand:BLK 1 "memory_operand"))
15974    (use (match_operand:SWI48 2 "nonmemory_operand"))
15975    (use (match_operand:SWI48 3 "const_int_operand"))
15976    (use (match_operand:SI 4 "const_int_operand"))
15977    (use (match_operand:SI 5 "const_int_operand"))
15978    (use (match_operand:SI 6 ""))
15979    (use (match_operand:SI 7 ""))
15980    (use (match_operand:SI 8 ""))]
15981   ""
15983  if (ix86_expand_set_or_movmem (operands[0], operands[1],
15984                                 operands[2], NULL, operands[3],
15985                                 operands[4], operands[5],
15986                                 operands[6], operands[7],
15987                                 operands[8], false))
15988    DONE;
15989  else
15990    FAIL;
15993 ;; Most CPUs don't like single string operations
15994 ;; Handle this case here to simplify previous expander.
15996 (define_expand "strmov"
15997   [(set (match_dup 4) (match_operand 3 "memory_operand"))
15998    (set (match_operand 1 "memory_operand") (match_dup 4))
15999    (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
16000               (clobber (reg:CC FLAGS_REG))])
16001    (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
16002               (clobber (reg:CC FLAGS_REG))])]
16003   ""
16005   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16007   /* If .md ever supports :P for Pmode, these can be directly
16008      in the pattern above.  */
16009   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16010   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16012   /* Can't use this if the user has appropriated esi or edi.  */
16013   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16014       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
16015     {
16016       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16017                                       operands[2], operands[3],
16018                                       operands[5], operands[6]));
16019       DONE;
16020     }
16022   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16025 (define_expand "strmov_singleop"
16026   [(parallel [(set (match_operand 1 "memory_operand")
16027                    (match_operand 3 "memory_operand"))
16028               (set (match_operand 0 "register_operand")
16029                    (match_operand 4))
16030               (set (match_operand 2 "register_operand")
16031                    (match_operand 5))])]
16032   ""
16033   "ix86_current_function_needs_cld = 1;")
16035 (define_insn "*strmovdi_rex_1"
16036   [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
16037         (mem:DI (match_operand:P 3 "register_operand" "1")))
16038    (set (match_operand:P 0 "register_operand" "=D")
16039         (plus:P (match_dup 2)
16040                 (const_int 8)))
16041    (set (match_operand:P 1 "register_operand" "=S")
16042         (plus:P (match_dup 3)
16043                 (const_int 8)))]
16044   "TARGET_64BIT
16045    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16046   "%^movsq"
16047   [(set_attr "type" "str")
16048    (set_attr "memory" "both")
16049    (set_attr "mode" "DI")])
16051 (define_insn "*strmovsi_1"
16052   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
16053         (mem:SI (match_operand:P 3 "register_operand" "1")))
16054    (set (match_operand:P 0 "register_operand" "=D")
16055         (plus:P (match_dup 2)
16056                 (const_int 4)))
16057    (set (match_operand:P 1 "register_operand" "=S")
16058         (plus:P (match_dup 3)
16059                 (const_int 4)))]
16060   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16061   "%^movs{l|d}"
16062   [(set_attr "type" "str")
16063    (set_attr "memory" "both")
16064    (set_attr "mode" "SI")])
16066 (define_insn "*strmovhi_1"
16067   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
16068         (mem:HI (match_operand:P 3 "register_operand" "1")))
16069    (set (match_operand:P 0 "register_operand" "=D")
16070         (plus:P (match_dup 2)
16071                 (const_int 2)))
16072    (set (match_operand:P 1 "register_operand" "=S")
16073         (plus:P (match_dup 3)
16074                 (const_int 2)))]
16075   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16076   "%^movsw"
16077   [(set_attr "type" "str")
16078    (set_attr "memory" "both")
16079    (set_attr "mode" "HI")])
16081 (define_insn "*strmovqi_1"
16082   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
16083         (mem:QI (match_operand:P 3 "register_operand" "1")))
16084    (set (match_operand:P 0 "register_operand" "=D")
16085         (plus:P (match_dup 2)
16086                 (const_int 1)))
16087    (set (match_operand:P 1 "register_operand" "=S")
16088         (plus:P (match_dup 3)
16089                 (const_int 1)))]
16090   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16091   "%^movsb"
16092   [(set_attr "type" "str")
16093    (set_attr "memory" "both")
16094    (set (attr "prefix_rex")
16095         (if_then_else
16096           (match_test "<P:MODE>mode == DImode")
16097           (const_string "0")
16098           (const_string "*")))
16099    (set_attr "mode" "QI")])
16101 (define_expand "rep_mov"
16102   [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
16103               (set (match_operand 0 "register_operand")
16104                    (match_operand 5))
16105               (set (match_operand 2 "register_operand")
16106                    (match_operand 6))
16107               (set (match_operand 1 "memory_operand")
16108                    (match_operand 3 "memory_operand"))
16109               (use (match_dup 4))])]
16110   ""
16111   "ix86_current_function_needs_cld = 1;")
16113 (define_insn "*rep_movdi_rex64"
16114   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16115    (set (match_operand:P 0 "register_operand" "=D")
16116         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16117                           (const_int 3))
16118                 (match_operand:P 3 "register_operand" "0")))
16119    (set (match_operand:P 1 "register_operand" "=S")
16120         (plus:P (ashift:P (match_dup 5) (const_int 3))
16121                 (match_operand:P 4 "register_operand" "1")))
16122    (set (mem:BLK (match_dup 3))
16123         (mem:BLK (match_dup 4)))
16124    (use (match_dup 5))]
16125   "TARGET_64BIT
16126    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16127   "%^rep{%;} movsq"
16128   [(set_attr "type" "str")
16129    (set_attr "prefix_rep" "1")
16130    (set_attr "memory" "both")
16131    (set_attr "mode" "DI")])
16133 (define_insn "*rep_movsi"
16134   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16135    (set (match_operand:P 0 "register_operand" "=D")
16136         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16137                           (const_int 2))
16138                  (match_operand:P 3 "register_operand" "0")))
16139    (set (match_operand:P 1 "register_operand" "=S")
16140         (plus:P (ashift:P (match_dup 5) (const_int 2))
16141                 (match_operand:P 4 "register_operand" "1")))
16142    (set (mem:BLK (match_dup 3))
16143         (mem:BLK (match_dup 4)))
16144    (use (match_dup 5))]
16145   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16146   "%^rep{%;} movs{l|d}"
16147   [(set_attr "type" "str")
16148    (set_attr "prefix_rep" "1")
16149    (set_attr "memory" "both")
16150    (set_attr "mode" "SI")])
16152 (define_insn "*rep_movqi"
16153   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16154    (set (match_operand:P 0 "register_operand" "=D")
16155         (plus:P (match_operand:P 3 "register_operand" "0")
16156                 (match_operand:P 5 "register_operand" "2")))
16157    (set (match_operand:P 1 "register_operand" "=S")
16158         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
16159    (set (mem:BLK (match_dup 3))
16160         (mem:BLK (match_dup 4)))
16161    (use (match_dup 5))]
16162   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16163   "%^rep{%;} movsb"
16164   [(set_attr "type" "str")
16165    (set_attr "prefix_rep" "1")
16166    (set_attr "memory" "both")
16167    (set_attr "mode" "QI")])
16169 (define_expand "setmem<mode>"
16170    [(use (match_operand:BLK 0 "memory_operand"))
16171     (use (match_operand:SWI48 1 "nonmemory_operand"))
16172     (use (match_operand:QI 2 "nonmemory_operand"))
16173     (use (match_operand 3 "const_int_operand"))
16174     (use (match_operand:SI 4 "const_int_operand"))
16175     (use (match_operand:SI 5 "const_int_operand"))
16176     (use (match_operand:SI 6 ""))
16177     (use (match_operand:SI 7 ""))
16178     (use (match_operand:SI 8 ""))]
16179   ""
16181  if (ix86_expand_set_or_movmem (operands[0], NULL,
16182                                 operands[1], operands[2],
16183                                 operands[3], operands[4],
16184                                 operands[5], operands[6],
16185                                 operands[7], operands[8], true))
16186    DONE;
16187  else
16188    FAIL;
16191 ;; Most CPUs don't like single string operations
16192 ;; Handle this case here to simplify previous expander.
16194 (define_expand "strset"
16195   [(set (match_operand 1 "memory_operand")
16196         (match_operand 2 "register_operand"))
16197    (parallel [(set (match_operand 0 "register_operand")
16198                    (match_dup 3))
16199               (clobber (reg:CC FLAGS_REG))])]
16200   ""
16202   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16203     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16205   /* If .md ever supports :P for Pmode, this can be directly
16206      in the pattern above.  */
16207   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16208                               GEN_INT (GET_MODE_SIZE (GET_MODE
16209                                                       (operands[2]))));
16210   /* Can't use this if the user has appropriated eax or edi.  */
16211   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16212       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
16213     {
16214       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16215                                       operands[3]));
16216       DONE;
16217     }
16220 (define_expand "strset_singleop"
16221   [(parallel [(set (match_operand 1 "memory_operand")
16222                    (match_operand 2 "register_operand"))
16223               (set (match_operand 0 "register_operand")
16224                    (match_operand 3))
16225               (unspec [(const_int 0)] UNSPEC_STOS)])]
16226   ""
16227   "ix86_current_function_needs_cld = 1;")
16229 (define_insn "*strsetdi_rex_1"
16230   [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16231         (match_operand:DI 2 "register_operand" "a"))
16232    (set (match_operand:P 0 "register_operand" "=D")
16233         (plus:P (match_dup 1)
16234                 (const_int 8)))
16235    (unspec [(const_int 0)] UNSPEC_STOS)]
16236   "TARGET_64BIT
16237    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16238   "%^stosq"
16239   [(set_attr "type" "str")
16240    (set_attr "memory" "store")
16241    (set_attr "mode" "DI")])
16243 (define_insn "*strsetsi_1"
16244   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16245         (match_operand:SI 2 "register_operand" "a"))
16246    (set (match_operand:P 0 "register_operand" "=D")
16247         (plus:P (match_dup 1)
16248                 (const_int 4)))
16249    (unspec [(const_int 0)] UNSPEC_STOS)]
16250   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16251   "%^stos{l|d}"
16252   [(set_attr "type" "str")
16253    (set_attr "memory" "store")
16254    (set_attr "mode" "SI")])
16256 (define_insn "*strsethi_1"
16257   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16258         (match_operand:HI 2 "register_operand" "a"))
16259    (set (match_operand:P 0 "register_operand" "=D")
16260         (plus:P (match_dup 1)
16261                 (const_int 2)))
16262    (unspec [(const_int 0)] UNSPEC_STOS)]
16263   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16264   "%^stosw"
16265   [(set_attr "type" "str")
16266    (set_attr "memory" "store")
16267    (set_attr "mode" "HI")])
16269 (define_insn "*strsetqi_1"
16270   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16271         (match_operand:QI 2 "register_operand" "a"))
16272    (set (match_operand:P 0 "register_operand" "=D")
16273         (plus:P (match_dup 1)
16274                 (const_int 1)))
16275    (unspec [(const_int 0)] UNSPEC_STOS)]
16276   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16277   "%^stosb"
16278   [(set_attr "type" "str")
16279    (set_attr "memory" "store")
16280    (set (attr "prefix_rex")
16281         (if_then_else
16282           (match_test "<P:MODE>mode == DImode")
16283           (const_string "0")
16284           (const_string "*")))
16285    (set_attr "mode" "QI")])
16287 (define_expand "rep_stos"
16288   [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16289               (set (match_operand 0 "register_operand")
16290                    (match_operand 4))
16291               (set (match_operand 2 "memory_operand") (const_int 0))
16292               (use (match_operand 3 "register_operand"))
16293               (use (match_dup 1))])]
16294   ""
16295   "ix86_current_function_needs_cld = 1;")
16297 (define_insn "*rep_stosdi_rex64"
16298   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16299    (set (match_operand:P 0 "register_operand" "=D")
16300         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16301                           (const_int 3))
16302                  (match_operand:P 3 "register_operand" "0")))
16303    (set (mem:BLK (match_dup 3))
16304         (const_int 0))
16305    (use (match_operand:DI 2 "register_operand" "a"))
16306    (use (match_dup 4))]
16307   "TARGET_64BIT
16308    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16309   "%^rep{%;} stosq"
16310   [(set_attr "type" "str")
16311    (set_attr "prefix_rep" "1")
16312    (set_attr "memory" "store")
16313    (set_attr "mode" "DI")])
16315 (define_insn "*rep_stossi"
16316   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16317    (set (match_operand:P 0 "register_operand" "=D")
16318         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16319                           (const_int 2))
16320                  (match_operand:P 3 "register_operand" "0")))
16321    (set (mem:BLK (match_dup 3))
16322         (const_int 0))
16323    (use (match_operand:SI 2 "register_operand" "a"))
16324    (use (match_dup 4))]
16325   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16326   "%^rep{%;} stos{l|d}"
16327   [(set_attr "type" "str")
16328    (set_attr "prefix_rep" "1")
16329    (set_attr "memory" "store")
16330    (set_attr "mode" "SI")])
16332 (define_insn "*rep_stosqi"
16333   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16334    (set (match_operand:P 0 "register_operand" "=D")
16335         (plus:P (match_operand:P 3 "register_operand" "0")
16336                 (match_operand:P 4 "register_operand" "1")))
16337    (set (mem:BLK (match_dup 3))
16338         (const_int 0))
16339    (use (match_operand:QI 2 "register_operand" "a"))
16340    (use (match_dup 4))]
16341   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16342   "%^rep{%;} stosb"
16343   [(set_attr "type" "str")
16344    (set_attr "prefix_rep" "1")
16345    (set_attr "memory" "store")
16346    (set (attr "prefix_rex")
16347         (if_then_else
16348           (match_test "<P:MODE>mode == DImode")
16349           (const_string "0")
16350           (const_string "*")))
16351    (set_attr "mode" "QI")])
16353 (define_expand "cmpstrnsi"
16354   [(set (match_operand:SI 0 "register_operand")
16355         (compare:SI (match_operand:BLK 1 "general_operand")
16356                     (match_operand:BLK 2 "general_operand")))
16357    (use (match_operand 3 "general_operand"))
16358    (use (match_operand 4 "immediate_operand"))]
16359   ""
16361   rtx addr1, addr2, out, outlow, count, countreg, align;
16363   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16364     FAIL;
16366   /* Can't use this if the user has appropriated ecx, esi or edi.  */
16367   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16368     FAIL;
16370   out = operands[0];
16371   if (!REG_P (out))
16372     out = gen_reg_rtx (SImode);
16374   addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16375   addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16376   if (addr1 != XEXP (operands[1], 0))
16377     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16378   if (addr2 != XEXP (operands[2], 0))
16379     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16381   count = operands[3];
16382   countreg = ix86_zero_extend_to_Pmode (count);
16384   /* %%% Iff we are testing strict equality, we can use known alignment
16385      to good advantage.  This may be possible with combine, particularly
16386      once cc0 is dead.  */
16387   align = operands[4];
16389   if (CONST_INT_P (count))
16390     {
16391       if (INTVAL (count) == 0)
16392         {
16393           emit_move_insn (operands[0], const0_rtx);
16394           DONE;
16395         }
16396       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16397                                      operands[1], operands[2]));
16398     }
16399   else
16400     {
16401       rtx (*gen_cmp) (rtx, rtx);
16403       gen_cmp = (TARGET_64BIT
16404                  ? gen_cmpdi_1 : gen_cmpsi_1);
16406       emit_insn (gen_cmp (countreg, countreg));
16407       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16408                                   operands[1], operands[2]));
16409     }
16411   outlow = gen_lowpart (QImode, out);
16412   emit_insn (gen_cmpintqi (outlow));
16413   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16415   if (operands[0] != out)
16416     emit_move_insn (operands[0], out);
16418   DONE;
16421 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16423 (define_expand "cmpintqi"
16424   [(set (match_dup 1)
16425         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16426    (set (match_dup 2)
16427         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16428    (parallel [(set (match_operand:QI 0 "register_operand")
16429                    (minus:QI (match_dup 1)
16430                              (match_dup 2)))
16431               (clobber (reg:CC FLAGS_REG))])]
16432   ""
16434   operands[1] = gen_reg_rtx (QImode);
16435   operands[2] = gen_reg_rtx (QImode);
16438 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16439 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16441 (define_expand "cmpstrnqi_nz_1"
16442   [(parallel [(set (reg:CC FLAGS_REG)
16443                    (compare:CC (match_operand 4 "memory_operand")
16444                                (match_operand 5 "memory_operand")))
16445               (use (match_operand 2 "register_operand"))
16446               (use (match_operand:SI 3 "immediate_operand"))
16447               (clobber (match_operand 0 "register_operand"))
16448               (clobber (match_operand 1 "register_operand"))
16449               (clobber (match_dup 2))])]
16450   ""
16451   "ix86_current_function_needs_cld = 1;")
16453 (define_insn "*cmpstrnqi_nz_1"
16454   [(set (reg:CC FLAGS_REG)
16455         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16456                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16457    (use (match_operand:P 6 "register_operand" "2"))
16458    (use (match_operand:SI 3 "immediate_operand" "i"))
16459    (clobber (match_operand:P 0 "register_operand" "=S"))
16460    (clobber (match_operand:P 1 "register_operand" "=D"))
16461    (clobber (match_operand:P 2 "register_operand" "=c"))]
16462   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16463   "%^repz{%;} cmpsb"
16464   [(set_attr "type" "str")
16465    (set_attr "mode" "QI")
16466    (set (attr "prefix_rex")
16467         (if_then_else
16468           (match_test "<P:MODE>mode == DImode")
16469           (const_string "0")
16470           (const_string "*")))
16471    (set_attr "prefix_rep" "1")])
16473 ;; The same, but the count is not known to not be zero.
16475 (define_expand "cmpstrnqi_1"
16476   [(parallel [(set (reg:CC FLAGS_REG)
16477                 (if_then_else:CC (ne (match_operand 2 "register_operand")
16478                                      (const_int 0))
16479                   (compare:CC (match_operand 4 "memory_operand")
16480                               (match_operand 5 "memory_operand"))
16481                   (const_int 0)))
16482               (use (match_operand:SI 3 "immediate_operand"))
16483               (use (reg:CC FLAGS_REG))
16484               (clobber (match_operand 0 "register_operand"))
16485               (clobber (match_operand 1 "register_operand"))
16486               (clobber (match_dup 2))])]
16487   ""
16488   "ix86_current_function_needs_cld = 1;")
16490 (define_insn "*cmpstrnqi_1"
16491   [(set (reg:CC FLAGS_REG)
16492         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16493                              (const_int 0))
16494           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16495                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
16496           (const_int 0)))
16497    (use (match_operand:SI 3 "immediate_operand" "i"))
16498    (use (reg:CC FLAGS_REG))
16499    (clobber (match_operand:P 0 "register_operand" "=S"))
16500    (clobber (match_operand:P 1 "register_operand" "=D"))
16501    (clobber (match_operand:P 2 "register_operand" "=c"))]
16502   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16503   "%^repz{%;} cmpsb"
16504   [(set_attr "type" "str")
16505    (set_attr "mode" "QI")
16506    (set (attr "prefix_rex")
16507         (if_then_else
16508           (match_test "<P:MODE>mode == DImode")
16509           (const_string "0")
16510           (const_string "*")))
16511    (set_attr "prefix_rep" "1")])
16513 (define_expand "strlen<mode>"
16514   [(set (match_operand:P 0 "register_operand")
16515         (unspec:P [(match_operand:BLK 1 "general_operand")
16516                    (match_operand:QI 2 "immediate_operand")
16517                    (match_operand 3 "immediate_operand")]
16518                   UNSPEC_SCAS))]
16519   ""
16521  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16522    DONE;
16523  else
16524    FAIL;
16527 (define_expand "strlenqi_1"
16528   [(parallel [(set (match_operand 0 "register_operand")
16529                    (match_operand 2))
16530               (clobber (match_operand 1 "register_operand"))
16531               (clobber (reg:CC FLAGS_REG))])]
16532   ""
16533   "ix86_current_function_needs_cld = 1;")
16535 (define_insn "*strlenqi_1"
16536   [(set (match_operand:P 0 "register_operand" "=&c")
16537         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16538                    (match_operand:QI 2 "register_operand" "a")
16539                    (match_operand:P 3 "immediate_operand" "i")
16540                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16541    (clobber (match_operand:P 1 "register_operand" "=D"))
16542    (clobber (reg:CC FLAGS_REG))]
16543   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16544   "%^repnz{%;} scasb"
16545   [(set_attr "type" "str")
16546    (set_attr "mode" "QI")
16547    (set (attr "prefix_rex")
16548         (if_then_else
16549           (match_test "<P:MODE>mode == DImode")
16550           (const_string "0")
16551           (const_string "*")))
16552    (set_attr "prefix_rep" "1")])
16554 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
16555 ;; handled in combine, but it is not currently up to the task.
16556 ;; When used for their truth value, the cmpstrn* expanders generate
16557 ;; code like this:
16559 ;;   repz cmpsb
16560 ;;   seta       %al
16561 ;;   setb       %dl
16562 ;;   cmpb       %al, %dl
16563 ;;   jcc        label
16565 ;; The intermediate three instructions are unnecessary.
16567 ;; This one handles cmpstrn*_nz_1...
16568 (define_peephole2
16569   [(parallel[
16570      (set (reg:CC FLAGS_REG)
16571           (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16572                       (mem:BLK (match_operand 5 "register_operand"))))
16573      (use (match_operand 6 "register_operand"))
16574      (use (match_operand:SI 3 "immediate_operand"))
16575      (clobber (match_operand 0 "register_operand"))
16576      (clobber (match_operand 1 "register_operand"))
16577      (clobber (match_operand 2 "register_operand"))])
16578    (set (match_operand:QI 7 "register_operand")
16579         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16580    (set (match_operand:QI 8 "register_operand")
16581         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16582    (set (reg FLAGS_REG)
16583         (compare (match_dup 7) (match_dup 8)))
16584   ]
16585   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16586   [(parallel[
16587      (set (reg:CC FLAGS_REG)
16588           (compare:CC (mem:BLK (match_dup 4))
16589                       (mem:BLK (match_dup 5))))
16590      (use (match_dup 6))
16591      (use (match_dup 3))
16592      (clobber (match_dup 0))
16593      (clobber (match_dup 1))
16594      (clobber (match_dup 2))])])
16596 ;; ...and this one handles cmpstrn*_1.
16597 (define_peephole2
16598   [(parallel[
16599      (set (reg:CC FLAGS_REG)
16600           (if_then_else:CC (ne (match_operand 6 "register_operand")
16601                                (const_int 0))
16602             (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16603                         (mem:BLK (match_operand 5 "register_operand")))
16604             (const_int 0)))
16605      (use (match_operand:SI 3 "immediate_operand"))
16606      (use (reg:CC FLAGS_REG))
16607      (clobber (match_operand 0 "register_operand"))
16608      (clobber (match_operand 1 "register_operand"))
16609      (clobber (match_operand 2 "register_operand"))])
16610    (set (match_operand:QI 7 "register_operand")
16611         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16612    (set (match_operand:QI 8 "register_operand")
16613         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16614    (set (reg FLAGS_REG)
16615         (compare (match_dup 7) (match_dup 8)))
16616   ]
16617   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16618   [(parallel[
16619      (set (reg:CC FLAGS_REG)
16620           (if_then_else:CC (ne (match_dup 6)
16621                                (const_int 0))
16622             (compare:CC (mem:BLK (match_dup 4))
16623                         (mem:BLK (match_dup 5)))
16624             (const_int 0)))
16625      (use (match_dup 3))
16626      (use (reg:CC FLAGS_REG))
16627      (clobber (match_dup 0))
16628      (clobber (match_dup 1))
16629      (clobber (match_dup 2))])])
16631 ;; Conditional move instructions.
16633 (define_expand "mov<mode>cc"
16634   [(set (match_operand:SWIM 0 "register_operand")
16635         (if_then_else:SWIM (match_operand 1 "comparison_operator")
16636                            (match_operand:SWIM 2 "<general_operand>")
16637                            (match_operand:SWIM 3 "<general_operand>")))]
16638   ""
16639   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16641 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16642 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16643 ;; So just document what we're doing explicitly.
16645 (define_expand "x86_mov<mode>cc_0_m1"
16646   [(parallel
16647     [(set (match_operand:SWI48 0 "register_operand")
16648           (if_then_else:SWI48
16649             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16650              [(match_operand 1 "flags_reg_operand")
16651               (const_int 0)])
16652             (const_int -1)
16653             (const_int 0)))
16654      (clobber (reg:CC FLAGS_REG))])])
16656 (define_insn "*x86_mov<mode>cc_0_m1"
16657   [(set (match_operand:SWI48 0 "register_operand" "=r")
16658         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16659                              [(reg FLAGS_REG) (const_int 0)])
16660           (const_int -1)
16661           (const_int 0)))
16662    (clobber (reg:CC FLAGS_REG))]
16663   ""
16664   "sbb{<imodesuffix>}\t%0, %0"
16665   ; Since we don't have the proper number of operands for an alu insn,
16666   ; fill in all the blanks.
16667   [(set_attr "type" "alu")
16668    (set_attr "use_carry" "1")
16669    (set_attr "pent_pair" "pu")
16670    (set_attr "memory" "none")
16671    (set_attr "imm_disp" "false")
16672    (set_attr "mode" "<MODE>")
16673    (set_attr "length_immediate" "0")])
16675 (define_insn "*x86_mov<mode>cc_0_m1_se"
16676   [(set (match_operand:SWI48 0 "register_operand" "=r")
16677         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16678                              [(reg FLAGS_REG) (const_int 0)])
16679                             (const_int 1)
16680                             (const_int 0)))
16681    (clobber (reg:CC FLAGS_REG))]
16682   ""
16683   "sbb{<imodesuffix>}\t%0, %0"
16684   [(set_attr "type" "alu")
16685    (set_attr "use_carry" "1")
16686    (set_attr "pent_pair" "pu")
16687    (set_attr "memory" "none")
16688    (set_attr "imm_disp" "false")
16689    (set_attr "mode" "<MODE>")
16690    (set_attr "length_immediate" "0")])
16692 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16693   [(set (match_operand:SWI48 0 "register_operand" "=r")
16694         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16695                     [(reg FLAGS_REG) (const_int 0)])))
16696    (clobber (reg:CC FLAGS_REG))]
16697   ""
16698   "sbb{<imodesuffix>}\t%0, %0"
16699   [(set_attr "type" "alu")
16700    (set_attr "use_carry" "1")
16701    (set_attr "pent_pair" "pu")
16702    (set_attr "memory" "none")
16703    (set_attr "imm_disp" "false")
16704    (set_attr "mode" "<MODE>")
16705    (set_attr "length_immediate" "0")])
16707 (define_insn "*mov<mode>cc_noc"
16708   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16709         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16710                                [(reg FLAGS_REG) (const_int 0)])
16711           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16712           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16713   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16714   "@
16715    cmov%O2%C1\t{%2, %0|%0, %2}
16716    cmov%O2%c1\t{%3, %0|%0, %3}"
16717   [(set_attr "type" "icmov")
16718    (set_attr "mode" "<MODE>")])
16720 ;; Don't do conditional moves with memory inputs.  This splitter helps
16721 ;; register starved x86_32 by forcing inputs into registers before reload.
16722 (define_split
16723   [(set (match_operand:SWI248 0 "register_operand")
16724         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16725                                [(reg FLAGS_REG) (const_int 0)])
16726           (match_operand:SWI248 2 "nonimmediate_operand")
16727           (match_operand:SWI248 3 "nonimmediate_operand")))]
16728   "!TARGET_64BIT && TARGET_CMOVE
16729    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16730    && (MEM_P (operands[2]) || MEM_P (operands[3]))
16731    && can_create_pseudo_p ()
16732    && optimize_insn_for_speed_p ()"
16733   [(set (match_dup 0)
16734         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16736   if (MEM_P (operands[2]))
16737     operands[2] = force_reg (<MODE>mode, operands[2]);
16738   if (MEM_P (operands[3]))
16739     operands[3] = force_reg (<MODE>mode, operands[3]);
16742 (define_insn "*movqicc_noc"
16743   [(set (match_operand:QI 0 "register_operand" "=r,r")
16744         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16745                            [(reg FLAGS_REG) (const_int 0)])
16746                       (match_operand:QI 2 "register_operand" "r,0")
16747                       (match_operand:QI 3 "register_operand" "0,r")))]
16748   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16749   "#"
16750   [(set_attr "type" "icmov")
16751    (set_attr "mode" "QI")])
16753 (define_split
16754   [(set (match_operand:SWI12 0 "register_operand")
16755         (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16756                               [(reg FLAGS_REG) (const_int 0)])
16757                       (match_operand:SWI12 2 "register_operand")
16758                       (match_operand:SWI12 3 "register_operand")))]
16759   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16760    && reload_completed"
16761   [(set (match_dup 0)
16762         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16764   operands[0] = gen_lowpart (SImode, operands[0]);
16765   operands[2] = gen_lowpart (SImode, operands[2]);
16766   operands[3] = gen_lowpart (SImode, operands[3]);
16769 ;; Don't do conditional moves with memory inputs
16770 (define_peephole2
16771   [(match_scratch:SWI248 2 "r")
16772    (set (match_operand:SWI248 0 "register_operand")
16773         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16774                                [(reg FLAGS_REG) (const_int 0)])
16775           (match_dup 0)
16776           (match_operand:SWI248 3 "memory_operand")))]
16777   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16778    && optimize_insn_for_speed_p ()"
16779   [(set (match_dup 2) (match_dup 3))
16780    (set (match_dup 0)
16781         (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
16783 (define_peephole2
16784   [(match_scratch:SWI248 2 "r")
16785    (set (match_operand:SWI248 0 "register_operand")
16786         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16787                                [(reg FLAGS_REG) (const_int 0)])
16788           (match_operand:SWI248 3 "memory_operand")
16789           (match_dup 0)))]
16790   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16791    && optimize_insn_for_speed_p ()"
16792   [(set (match_dup 2) (match_dup 3))
16793    (set (match_dup 0)
16794         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
16796 (define_expand "mov<mode>cc"
16797   [(set (match_operand:X87MODEF 0 "register_operand")
16798         (if_then_else:X87MODEF
16799           (match_operand 1 "comparison_operator")
16800           (match_operand:X87MODEF 2 "register_operand")
16801           (match_operand:X87MODEF 3 "register_operand")))]
16802   "(TARGET_80387 && TARGET_CMOVE)
16803    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16804   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16806 (define_insn "*movxfcc_1"
16807   [(set (match_operand:XF 0 "register_operand" "=f,f")
16808         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16809                                 [(reg FLAGS_REG) (const_int 0)])
16810                       (match_operand:XF 2 "register_operand" "f,0")
16811                       (match_operand:XF 3 "register_operand" "0,f")))]
16812   "TARGET_80387 && TARGET_CMOVE"
16813   "@
16814    fcmov%F1\t{%2, %0|%0, %2}
16815    fcmov%f1\t{%3, %0|%0, %3}"
16816   [(set_attr "type" "fcmov")
16817    (set_attr "mode" "XF")])
16819 (define_insn "*movdfcc_1"
16820   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16821         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16822                                 [(reg FLAGS_REG) (const_int 0)])
16823                       (match_operand:DF 2 "nonimmediate_operand"
16824                                                "f ,0,rm,0 ,rm,0")
16825                       (match_operand:DF 3 "nonimmediate_operand"
16826                                                "0 ,f,0 ,rm,0, rm")))]
16827   "TARGET_80387 && TARGET_CMOVE
16828    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16829   "@
16830    fcmov%F1\t{%2, %0|%0, %2}
16831    fcmov%f1\t{%3, %0|%0, %3}
16832    #
16833    #
16834    cmov%O2%C1\t{%2, %0|%0, %2}
16835    cmov%O2%c1\t{%3, %0|%0, %3}"
16836   [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16837    (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16838    (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16840 (define_split
16841   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16842         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16843                                 [(reg FLAGS_REG) (const_int 0)])
16844                       (match_operand:DF 2 "nonimmediate_operand")
16845                       (match_operand:DF 3 "nonimmediate_operand")))]
16846   "!TARGET_64BIT && reload_completed"
16847   [(set (match_dup 2)
16848         (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16849    (set (match_dup 3)
16850         (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16852   split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16853   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16856 (define_insn "*movsfcc_1_387"
16857   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16858         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16859                                 [(reg FLAGS_REG) (const_int 0)])
16860                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16861                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16862   "TARGET_80387 && TARGET_CMOVE
16863    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16864   "@
16865    fcmov%F1\t{%2, %0|%0, %2}
16866    fcmov%f1\t{%3, %0|%0, %3}
16867    cmov%O2%C1\t{%2, %0|%0, %2}
16868    cmov%O2%c1\t{%3, %0|%0, %3}"
16869   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16870    (set_attr "mode" "SF,SF,SI,SI")])
16872 ;; Don't do conditional moves with memory inputs.  This splitter helps
16873 ;; register starved x86_32 by forcing inputs into registers before reload.
16874 (define_split
16875   [(set (match_operand:MODEF 0 "register_operand")
16876         (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16877                               [(reg FLAGS_REG) (const_int 0)])
16878           (match_operand:MODEF 2 "nonimmediate_operand")
16879           (match_operand:MODEF 3 "nonimmediate_operand")))]
16880   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16881    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16882    && (MEM_P (operands[2]) || MEM_P (operands[3]))
16883    && can_create_pseudo_p ()
16884    && optimize_insn_for_speed_p ()"
16885   [(set (match_dup 0)
16886         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16888   if (MEM_P (operands[2]))
16889     operands[2] = force_reg (<MODE>mode, operands[2]);
16890   if (MEM_P (operands[3]))
16891     operands[3] = force_reg (<MODE>mode, operands[3]);
16894 ;; Don't do conditional moves with memory inputs
16895 (define_peephole2
16896   [(match_scratch:MODEF 2 "r")
16897    (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16898         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16899                               [(reg FLAGS_REG) (const_int 0)])
16900           (match_dup 0)
16901           (match_operand:MODEF 3 "memory_operand")))]
16902   "(<MODE>mode != DFmode || TARGET_64BIT)
16903    && TARGET_80387 && TARGET_CMOVE
16904    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16905    && optimize_insn_for_speed_p ()"
16906   [(set (match_dup 2) (match_dup 3))
16907    (set (match_dup 0)
16908         (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16910 (define_peephole2
16911   [(match_scratch:MODEF 2 "r")
16912    (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16913         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16914                               [(reg FLAGS_REG) (const_int 0)])
16915           (match_operand:MODEF 3 "memory_operand")
16916           (match_dup 0)))]
16917   "(<MODE>mode != DFmode || TARGET_64BIT)
16918    && TARGET_80387 && TARGET_CMOVE
16919    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16920    && optimize_insn_for_speed_p ()"
16921   [(set (match_dup 2) (match_dup 3))
16922    (set (match_dup 0)
16923         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16925 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16926 ;; the scalar versions to have only XMM registers as operands.
16928 ;; XOP conditional move
16929 (define_insn "*xop_pcmov_<mode>"
16930   [(set (match_operand:MODEF 0 "register_operand" "=x")
16931         (if_then_else:MODEF
16932           (match_operand:MODEF 1 "register_operand" "x")
16933           (match_operand:MODEF 2 "register_operand" "x")
16934           (match_operand:MODEF 3 "register_operand" "x")))]
16935   "TARGET_XOP"
16936   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16937   [(set_attr "type" "sse4arg")])
16939 ;; These versions of the min/max patterns are intentionally ignorant of
16940 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16941 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16942 ;; are undefined in this condition, we're certain this is correct.
16944 (define_insn "<code><mode>3"
16945   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16946         (smaxmin:MODEF
16947           (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
16948           (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
16949   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16950   "@
16951    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16952    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16953   [(set_attr "isa" "noavx,avx")
16954    (set_attr "prefix" "orig,vex")
16955    (set_attr "type" "sseadd")
16956    (set_attr "mode" "<MODE>")])
16958 ;; These versions of the min/max patterns implement exactly the operations
16959 ;;   min = (op1 < op2 ? op1 : op2)
16960 ;;   max = (!(op1 < op2) ? op1 : op2)
16961 ;; Their operands are not commutative, and thus they may be used in the
16962 ;; presence of -0.0 and NaN.
16964 (define_int_iterator IEEE_MAXMIN
16965         [UNSPEC_IEEE_MAX
16966          UNSPEC_IEEE_MIN])
16968 (define_int_attr ieee_maxmin
16969         [(UNSPEC_IEEE_MAX "max")
16970          (UNSPEC_IEEE_MIN "min")])
16972 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16973   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16974         (unspec:MODEF
16975           [(match_operand:MODEF 1 "register_operand" "0,x")
16976            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16977           IEEE_MAXMIN))]
16978   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16979   "@
16980    <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16981    v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16982   [(set_attr "isa" "noavx,avx")
16983    (set_attr "prefix" "orig,vex")
16984    (set_attr "type" "sseadd")
16985    (set_attr "mode" "<MODE>")])
16987 ;; Make two stack loads independent:
16988 ;;   fld aa              fld aa
16989 ;;   fld %st(0)     ->   fld bb
16990 ;;   fmul bb             fmul %st(1), %st
16992 ;; Actually we only match the last two instructions for simplicity.
16993 (define_peephole2
16994   [(set (match_operand 0 "fp_register_operand")
16995         (match_operand 1 "fp_register_operand"))
16996    (set (match_dup 0)
16997         (match_operator 2 "binary_fp_operator"
16998            [(match_dup 0)
16999             (match_operand 3 "memory_operand")]))]
17000   "REGNO (operands[0]) != REGNO (operands[1])"
17001   [(set (match_dup 0) (match_dup 3))
17002    (set (match_dup 0) (match_dup 4))]
17004   ;; The % modifier is not operational anymore in peephole2's, so we have to
17005   ;; swap the operands manually in the case of addition and multiplication.
17007   rtx op0, op1;
17009   if (COMMUTATIVE_ARITH_P (operands[2]))
17010     op0 = operands[0], op1 = operands[1];
17011   else
17012     op0 = operands[1], op1 = operands[0];
17014   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
17015                                 GET_MODE (operands[2]),
17016                                 op0, op1);
17019 ;; Conditional addition patterns
17020 (define_expand "add<mode>cc"
17021   [(match_operand:SWI 0 "register_operand")
17022    (match_operand 1 "ordered_comparison_operator")
17023    (match_operand:SWI 2 "register_operand")
17024    (match_operand:SWI 3 "const_int_operand")]
17025   ""
17026   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
17028 ;; Misc patterns (?)
17030 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17031 ;; Otherwise there will be nothing to keep
17033 ;; [(set (reg ebp) (reg esp))]
17034 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17035 ;;  (clobber (eflags)]
17036 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17038 ;; in proper program order.
17040 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
17041   [(set (match_operand:P 0 "register_operand" "=r,r")
17042         (plus:P (match_operand:P 1 "register_operand" "0,r")
17043                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
17044    (clobber (reg:CC FLAGS_REG))
17045    (clobber (mem:BLK (scratch)))]
17046   ""
17048   switch (get_attr_type (insn))
17049     {
17050     case TYPE_IMOV:
17051       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
17053     case TYPE_ALU:
17054       gcc_assert (rtx_equal_p (operands[0], operands[1]));
17055       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
17056         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
17058       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
17060     default:
17061       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17062       return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
17063     }
17065   [(set (attr "type")
17066         (cond [(and (eq_attr "alternative" "0")
17067                     (not (match_test "TARGET_OPT_AGU")))
17068                  (const_string "alu")
17069                (match_operand:<MODE> 2 "const0_operand")
17070                  (const_string "imov")
17071               ]
17072               (const_string "lea")))
17073    (set (attr "length_immediate")
17074         (cond [(eq_attr "type" "imov")
17075                  (const_string "0")
17076                (and (eq_attr "type" "alu")
17077                     (match_operand 2 "const128_operand"))
17078                  (const_string "1")
17079               ]
17080               (const_string "*")))
17081    (set_attr "mode" "<MODE>")])
17083 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
17084   [(set (match_operand:P 0 "register_operand" "=r")
17085         (minus:P (match_operand:P 1 "register_operand" "0")
17086                  (match_operand:P 2 "register_operand" "r")))
17087    (clobber (reg:CC FLAGS_REG))
17088    (clobber (mem:BLK (scratch)))]
17089   ""
17090   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
17091   [(set_attr "type" "alu")
17092    (set_attr "mode" "<MODE>")])
17094 (define_insn "allocate_stack_worker_probe_<mode>"
17095   [(set (match_operand:P 0 "register_operand" "=a")
17096         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17097                             UNSPECV_STACK_PROBE))
17098    (clobber (reg:CC FLAGS_REG))]
17099   "ix86_target_stack_probe ()"
17100   "call\t___chkstk_ms"
17101   [(set_attr "type" "multi")
17102    (set_attr "length" "5")])
17104 (define_expand "allocate_stack"
17105   [(match_operand 0 "register_operand")
17106    (match_operand 1 "general_operand")]
17107   "ix86_target_stack_probe ()"
17109   rtx x;
17111 #ifndef CHECK_STACK_LIMIT
17112 #define CHECK_STACK_LIMIT 0
17113 #endif
17115   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17116       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17117     x = operands[1];
17118   else
17119     {
17120       rtx (*insn) (rtx, rtx);
17122       x = copy_to_mode_reg (Pmode, operands[1]);
17124       insn = (TARGET_64BIT
17125               ? gen_allocate_stack_worker_probe_di
17126               : gen_allocate_stack_worker_probe_si);
17128       emit_insn (insn (x, x));
17129     }
17131   x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
17132                            stack_pointer_rtx, 0, OPTAB_DIRECT);
17134   if (x != stack_pointer_rtx)
17135     emit_move_insn (stack_pointer_rtx, x);
17137   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17138   DONE;
17141 ;; Use IOR for stack probes, this is shorter.
17142 (define_expand "probe_stack"
17143   [(match_operand 0 "memory_operand")]
17144   ""
17146   rtx (*gen_ior3) (rtx, rtx, rtx);
17148   gen_ior3 = (GET_MODE (operands[0]) == DImode
17149               ? gen_iordi3 : gen_iorsi3);
17151   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
17152   DONE;
17155 (define_insn "adjust_stack_and_probe<mode>"
17156   [(set (match_operand:P 0 "register_operand" "=r")
17157         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17158                             UNSPECV_PROBE_STACK_RANGE))
17159    (set (reg:P SP_REG)
17160         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
17161    (clobber (reg:CC FLAGS_REG))
17162    (clobber (mem:BLK (scratch)))]
17163   ""
17164   "* return output_adjust_stack_and_probe (operands[0]);"
17165   [(set_attr "type" "multi")])
17167 (define_insn "probe_stack_range<mode>"
17168   [(set (match_operand:P 0 "register_operand" "=r")
17169         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
17170                             (match_operand:P 2 "const_int_operand" "n")]
17171                             UNSPECV_PROBE_STACK_RANGE))
17172    (clobber (reg:CC FLAGS_REG))]
17173   ""
17174   "* return output_probe_stack_range (operands[0], operands[2]);"
17175   [(set_attr "type" "multi")])
17177 (define_expand "builtin_setjmp_receiver"
17178   [(label_ref (match_operand 0))]
17179   "!TARGET_64BIT && flag_pic"
17181 #if TARGET_MACHO
17182   if (TARGET_MACHO)
17183     {
17184       rtx xops[3];
17185       rtx_code_label *label_rtx = gen_label_rtx ();
17186       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17187       xops[0] = xops[1] = pic_offset_table_rtx;
17188       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17189       ix86_expand_binary_operator (MINUS, SImode, xops);
17190     }
17191   else
17192 #endif
17193     emit_insn (gen_set_got (pic_offset_table_rtx));
17194   DONE;
17197 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17198 ;; Do not split instructions with mask registers.
17199 (define_split
17200   [(set (match_operand 0 "general_reg_operand")
17201         (match_operator 3 "promotable_binary_operator"
17202            [(match_operand 1 "general_reg_operand")
17203             (match_operand 2 "aligned_operand")]))
17204    (clobber (reg:CC FLAGS_REG))]
17205   "! TARGET_PARTIAL_REG_STALL && reload_completed
17206    && ((GET_MODE (operands[0]) == HImode
17207         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17208             /* ??? next two lines just !satisfies_constraint_K (...) */
17209             || !CONST_INT_P (operands[2])
17210             || satisfies_constraint_K (operands[2])))
17211        || (GET_MODE (operands[0]) == QImode
17212            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17213   [(parallel [(set (match_dup 0)
17214                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17215               (clobber (reg:CC FLAGS_REG))])]
17217   operands[0] = gen_lowpart (SImode, operands[0]);
17218   operands[1] = gen_lowpart (SImode, operands[1]);
17219   if (GET_CODE (operands[3]) != ASHIFT)
17220     operands[2] = gen_lowpart (SImode, operands[2]);
17221   PUT_MODE (operands[3], SImode);
17224 ; Promote the QImode tests, as i386 has encoding of the AND
17225 ; instruction with 32-bit sign-extended immediate and thus the
17226 ; instruction size is unchanged, except in the %eax case for
17227 ; which it is increased by one byte, hence the ! optimize_size.
17228 (define_split
17229   [(set (match_operand 0 "flags_reg_operand")
17230         (match_operator 2 "compare_operator"
17231           [(and (match_operand 3 "aligned_operand")
17232                 (match_operand 4 "const_int_operand"))
17233            (const_int 0)]))
17234    (set (match_operand 1 "register_operand")
17235         (and (match_dup 3) (match_dup 4)))]
17236   "! TARGET_PARTIAL_REG_STALL && reload_completed
17237    && optimize_insn_for_speed_p ()
17238    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17239        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17240    /* Ensure that the operand will remain sign-extended immediate.  */
17241    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17242   [(parallel [(set (match_dup 0)
17243                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17244                                     (const_int 0)]))
17245               (set (match_dup 1)
17246                    (and:SI (match_dup 3) (match_dup 4)))])]
17248   operands[4]
17249     = gen_int_mode (INTVAL (operands[4])
17250                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17251   operands[1] = gen_lowpart (SImode, operands[1]);
17252   operands[3] = gen_lowpart (SImode, operands[3]);
17255 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17256 ; the TEST instruction with 32-bit sign-extended immediate and thus
17257 ; the instruction size would at least double, which is not what we
17258 ; want even with ! optimize_size.
17259 (define_split
17260   [(set (match_operand 0 "flags_reg_operand")
17261         (match_operator 1 "compare_operator"
17262           [(and (match_operand:HI 2 "aligned_operand")
17263                 (match_operand:HI 3 "const_int_operand"))
17264            (const_int 0)]))]
17265   "! TARGET_PARTIAL_REG_STALL && reload_completed
17266    && ! TARGET_FAST_PREFIX
17267    && optimize_insn_for_speed_p ()
17268    /* Ensure that the operand will remain sign-extended immediate.  */
17269    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17270   [(set (match_dup 0)
17271         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17272                          (const_int 0)]))]
17274   operands[3]
17275     = gen_int_mode (INTVAL (operands[3])
17276                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17277   operands[2] = gen_lowpart (SImode, operands[2]);
17280 (define_split
17281   [(set (match_operand 0 "register_operand")
17282         (neg (match_operand 1 "register_operand")))
17283    (clobber (reg:CC FLAGS_REG))]
17284   "! TARGET_PARTIAL_REG_STALL && reload_completed
17285    && (GET_MODE (operands[0]) == HImode
17286        || (GET_MODE (operands[0]) == QImode
17287            && (TARGET_PROMOTE_QImode
17288                || optimize_insn_for_size_p ())))"
17289   [(parallel [(set (match_dup 0)
17290                    (neg:SI (match_dup 1)))
17291               (clobber (reg:CC FLAGS_REG))])]
17293   operands[0] = gen_lowpart (SImode, operands[0]);
17294   operands[1] = gen_lowpart (SImode, operands[1]);
17297 ;; Do not split instructions with mask regs.
17298 (define_split
17299   [(set (match_operand 0 "general_reg_operand")
17300         (not (match_operand 1 "general_reg_operand")))]
17301   "! TARGET_PARTIAL_REG_STALL && reload_completed
17302    && (GET_MODE (operands[0]) == HImode
17303        || (GET_MODE (operands[0]) == QImode
17304            && (TARGET_PROMOTE_QImode
17305                || optimize_insn_for_size_p ())))"
17306   [(set (match_dup 0)
17307         (not:SI (match_dup 1)))]
17309   operands[0] = gen_lowpart (SImode, operands[0]);
17310   operands[1] = gen_lowpart (SImode, operands[1]);
17313 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
17314 ;; transform a complex memory operation into two memory to register operations.
17316 ;; Don't push memory operands
17317 (define_peephole2
17318   [(set (match_operand:SWI 0 "push_operand")
17319         (match_operand:SWI 1 "memory_operand"))
17320    (match_scratch:SWI 2 "<r>")]
17321   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17322    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17323   [(set (match_dup 2) (match_dup 1))
17324    (set (match_dup 0) (match_dup 2))])
17326 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17327 ;; SImode pushes.
17328 (define_peephole2
17329   [(set (match_operand:SF 0 "push_operand")
17330         (match_operand:SF 1 "memory_operand"))
17331    (match_scratch:SF 2 "r")]
17332   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17333    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17334   [(set (match_dup 2) (match_dup 1))
17335    (set (match_dup 0) (match_dup 2))])
17337 ;; Don't move an immediate directly to memory when the instruction
17338 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17339 (define_peephole2
17340   [(match_scratch:SWI124 1 "<r>")
17341    (set (match_operand:SWI124 0 "memory_operand")
17342         (const_int 0))]
17343   "optimize_insn_for_speed_p ()
17344    && ((<MODE>mode == HImode
17345        && TARGET_LCP_STALL)
17346        || (!TARGET_USE_MOV0
17347           && TARGET_SPLIT_LONG_MOVES
17348           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17349    && peep2_regno_dead_p (0, FLAGS_REG)"
17350   [(parallel [(set (match_dup 2) (const_int 0))
17351               (clobber (reg:CC FLAGS_REG))])
17352    (set (match_dup 0) (match_dup 1))]
17353   "operands[2] = gen_lowpart (SImode, operands[1]);")
17355 (define_peephole2
17356   [(match_scratch:SWI124 2 "<r>")
17357    (set (match_operand:SWI124 0 "memory_operand")
17358         (match_operand:SWI124 1 "immediate_operand"))]
17359   "optimize_insn_for_speed_p ()
17360    && ((<MODE>mode == HImode
17361        && TARGET_LCP_STALL)
17362        || (TARGET_SPLIT_LONG_MOVES
17363           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17364   [(set (match_dup 2) (match_dup 1))
17365    (set (match_dup 0) (match_dup 2))])
17367 ;; Don't compare memory with zero, load and use a test instead.
17368 (define_peephole2
17369   [(set (match_operand 0 "flags_reg_operand")
17370         (match_operator 1 "compare_operator"
17371           [(match_operand:SI 2 "memory_operand")
17372            (const_int 0)]))
17373    (match_scratch:SI 3 "r")]
17374   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17375   [(set (match_dup 3) (match_dup 2))
17376    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17378 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17379 ;; Don't split NOTs with a displacement operand, because resulting XOR
17380 ;; will not be pairable anyway.
17382 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17383 ;; represented using a modRM byte.  The XOR replacement is long decoded,
17384 ;; so this split helps here as well.
17386 ;; Note: Can't do this as a regular split because we can't get proper
17387 ;; lifetime information then.
17389 (define_peephole2
17390   [(set (match_operand:SWI124 0 "nonimmediate_operand")
17391         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
17392   "optimize_insn_for_speed_p ()
17393    && ((TARGET_NOT_UNPAIRABLE
17394         && (!MEM_P (operands[0])
17395             || !memory_displacement_operand (operands[0], <MODE>mode)))
17396        || (TARGET_NOT_VECTORMODE
17397            && long_memory_operand (operands[0], <MODE>mode)))
17398    && peep2_regno_dead_p (0, FLAGS_REG)"
17399   [(parallel [(set (match_dup 0)
17400                    (xor:SWI124 (match_dup 1) (const_int -1)))
17401               (clobber (reg:CC FLAGS_REG))])])
17403 ;; Non pairable "test imm, reg" instructions can be translated to
17404 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17405 ;; byte opcode instead of two, have a short form for byte operands),
17406 ;; so do it for other CPUs as well.  Given that the value was dead,
17407 ;; this should not create any new dependencies.  Pass on the sub-word
17408 ;; versions if we're concerned about partial register stalls.
17410 (define_peephole2
17411   [(set (match_operand 0 "flags_reg_operand")
17412         (match_operator 1 "compare_operator"
17413           [(and:SI (match_operand:SI 2 "register_operand")
17414                    (match_operand:SI 3 "immediate_operand"))
17415            (const_int 0)]))]
17416   "ix86_match_ccmode (insn, CCNOmode)
17417    && (true_regnum (operands[2]) != AX_REG
17418        || satisfies_constraint_K (operands[3]))
17419    && peep2_reg_dead_p (1, operands[2])"
17420   [(parallel
17421      [(set (match_dup 0)
17422            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17423                             (const_int 0)]))
17424       (set (match_dup 2)
17425            (and:SI (match_dup 2) (match_dup 3)))])])
17427 ;; We don't need to handle HImode case, because it will be promoted to SImode
17428 ;; on ! TARGET_PARTIAL_REG_STALL
17430 (define_peephole2
17431   [(set (match_operand 0 "flags_reg_operand")
17432         (match_operator 1 "compare_operator"
17433           [(and:QI (match_operand:QI 2 "register_operand")
17434                    (match_operand:QI 3 "immediate_operand"))
17435            (const_int 0)]))]
17436   "! TARGET_PARTIAL_REG_STALL
17437    && ix86_match_ccmode (insn, CCNOmode)
17438    && true_regnum (operands[2]) != AX_REG
17439    && peep2_reg_dead_p (1, operands[2])"
17440   [(parallel
17441      [(set (match_dup 0)
17442            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17443                             (const_int 0)]))
17444       (set (match_dup 2)
17445            (and:QI (match_dup 2) (match_dup 3)))])])
17447 (define_peephole2
17448   [(set (match_operand 0 "flags_reg_operand")
17449         (match_operator 1 "compare_operator"
17450           [(and:SI
17451              (zero_extract:SI
17452                (match_operand 2 "QIreg_operand")
17453                (const_int 8)
17454                (const_int 8))
17455              (match_operand 3 "const_int_operand"))
17456            (const_int 0)]))]
17457   "! TARGET_PARTIAL_REG_STALL
17458    && ix86_match_ccmode (insn, CCNOmode)
17459    && true_regnum (operands[2]) != AX_REG
17460    && peep2_reg_dead_p (1, operands[2])"
17461   [(parallel [(set (match_dup 0)
17462                    (match_op_dup 1
17463                      [(and:SI
17464                         (zero_extract:SI
17465                           (match_dup 2)
17466                           (const_int 8)
17467                           (const_int 8))
17468                         (match_dup 3))
17469                       (const_int 0)]))
17470               (set (zero_extract:SI (match_dup 2)
17471                                     (const_int 8)
17472                                     (const_int 8))
17473                    (and:SI
17474                      (zero_extract:SI
17475                        (match_dup 2)
17476                        (const_int 8)
17477                        (const_int 8))
17478                      (match_dup 3)))])])
17480 ;; Don't do logical operations with memory inputs.
17481 (define_peephole2
17482   [(match_scratch:SI 2 "r")
17483    (parallel [(set (match_operand:SI 0 "register_operand")
17484                    (match_operator:SI 3 "arith_or_logical_operator"
17485                      [(match_dup 0)
17486                       (match_operand:SI 1 "memory_operand")]))
17487               (clobber (reg:CC FLAGS_REG))])]
17488   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17489   [(set (match_dup 2) (match_dup 1))
17490    (parallel [(set (match_dup 0)
17491                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17492               (clobber (reg:CC FLAGS_REG))])])
17494 (define_peephole2
17495   [(match_scratch:SI 2 "r")
17496    (parallel [(set (match_operand:SI 0 "register_operand")
17497                    (match_operator:SI 3 "arith_or_logical_operator"
17498                      [(match_operand:SI 1 "memory_operand")
17499                       (match_dup 0)]))
17500               (clobber (reg:CC FLAGS_REG))])]
17501   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17502   [(set (match_dup 2) (match_dup 1))
17503    (parallel [(set (match_dup 0)
17504                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17505               (clobber (reg:CC FLAGS_REG))])])
17507 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17508 ;; refers to the destination of the load!
17510 (define_peephole2
17511   [(set (match_operand:SI 0 "register_operand")
17512         (match_operand:SI 1 "register_operand"))
17513    (parallel [(set (match_dup 0)
17514                    (match_operator:SI 3 "commutative_operator"
17515                      [(match_dup 0)
17516                       (match_operand:SI 2 "memory_operand")]))
17517               (clobber (reg:CC FLAGS_REG))])]
17518   "REGNO (operands[0]) != REGNO (operands[1])
17519    && GENERAL_REGNO_P (REGNO (operands[0]))
17520    && GENERAL_REGNO_P (REGNO (operands[1]))"
17521   [(set (match_dup 0) (match_dup 4))
17522    (parallel [(set (match_dup 0)
17523                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17524               (clobber (reg:CC FLAGS_REG))])]
17525   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17527 (define_peephole2
17528   [(set (match_operand 0 "register_operand")
17529         (match_operand 1 "register_operand"))
17530    (set (match_dup 0)
17531                    (match_operator 3 "commutative_operator"
17532                      [(match_dup 0)
17533                       (match_operand 2 "memory_operand")]))]
17534   "REGNO (operands[0]) != REGNO (operands[1])
17535    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
17536        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17537   [(set (match_dup 0) (match_dup 2))
17538    (set (match_dup 0)
17539         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17541 ; Don't do logical operations with memory outputs
17543 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17544 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17545 ; the same decoder scheduling characteristics as the original.
17547 (define_peephole2
17548   [(match_scratch:SI 2 "r")
17549    (parallel [(set (match_operand:SI 0 "memory_operand")
17550                    (match_operator:SI 3 "arith_or_logical_operator"
17551                      [(match_dup 0)
17552                       (match_operand:SI 1 "nonmemory_operand")]))
17553               (clobber (reg:CC FLAGS_REG))])]
17554   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17555    /* Do not split stack checking probes.  */
17556    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17557   [(set (match_dup 2) (match_dup 0))
17558    (parallel [(set (match_dup 2)
17559                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17560               (clobber (reg:CC FLAGS_REG))])
17561    (set (match_dup 0) (match_dup 2))])
17563 (define_peephole2
17564   [(match_scratch:SI 2 "r")
17565    (parallel [(set (match_operand:SI 0 "memory_operand")
17566                    (match_operator:SI 3 "arith_or_logical_operator"
17567                      [(match_operand:SI 1 "nonmemory_operand")
17568                       (match_dup 0)]))
17569               (clobber (reg:CC FLAGS_REG))])]
17570   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17571    /* Do not split stack checking probes.  */
17572    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17573   [(set (match_dup 2) (match_dup 0))
17574    (parallel [(set (match_dup 2)
17575                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17576               (clobber (reg:CC FLAGS_REG))])
17577    (set (match_dup 0) (match_dup 2))])
17579 ;; Attempt to use arith or logical operations with memory outputs with
17580 ;; setting of flags.
17581 (define_peephole2
17582   [(set (match_operand:SWI 0 "register_operand")
17583         (match_operand:SWI 1 "memory_operand"))
17584    (parallel [(set (match_dup 0)
17585                    (match_operator:SWI 3 "plusminuslogic_operator"
17586                      [(match_dup 0)
17587                       (match_operand:SWI 2 "<nonmemory_operand>")]))
17588               (clobber (reg:CC FLAGS_REG))])
17589    (set (match_dup 1) (match_dup 0))
17590    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17591   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17592    && peep2_reg_dead_p (4, operands[0])
17593    && !reg_overlap_mentioned_p (operands[0], operands[1])
17594    && !reg_overlap_mentioned_p (operands[0], operands[2])
17595    && (<MODE>mode != QImode
17596        || immediate_operand (operands[2], QImode)
17597        || any_QIreg_operand (operands[2], QImode))
17598    && ix86_match_ccmode (peep2_next_insn (3),
17599                          (GET_CODE (operands[3]) == PLUS
17600                           || GET_CODE (operands[3]) == MINUS)
17601                          ? CCGOCmode : CCNOmode)"
17602   [(parallel [(set (match_dup 4) (match_dup 5))
17603               (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17604                                                   (match_dup 2)]))])]
17606   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17607   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17608                                 copy_rtx (operands[1]),
17609                                 copy_rtx (operands[2]));
17610   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17611                                  operands[5], const0_rtx);
17614 (define_peephole2
17615   [(parallel [(set (match_operand:SWI 0 "register_operand")
17616                    (match_operator:SWI 2 "plusminuslogic_operator"
17617                      [(match_dup 0)
17618                       (match_operand:SWI 1 "memory_operand")]))
17619               (clobber (reg:CC FLAGS_REG))])
17620    (set (match_dup 1) (match_dup 0))
17621    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17622   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17623    && GET_CODE (operands[2]) != MINUS
17624    && peep2_reg_dead_p (3, operands[0])
17625    && !reg_overlap_mentioned_p (operands[0], operands[1])
17626    && ix86_match_ccmode (peep2_next_insn (2),
17627                          GET_CODE (operands[2]) == PLUS
17628                          ? CCGOCmode : CCNOmode)"
17629   [(parallel [(set (match_dup 3) (match_dup 4))
17630               (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17631                                                   (match_dup 0)]))])]
17633   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17634   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17635                                 copy_rtx (operands[1]),
17636                                 copy_rtx (operands[0]));
17637   operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17638                                  operands[4], const0_rtx);
17641 (define_peephole2
17642   [(set (match_operand:SWI12 0 "register_operand")
17643         (match_operand:SWI12 1 "memory_operand"))
17644    (parallel [(set (match_operand:SI 4 "register_operand")
17645                    (match_operator:SI 3 "plusminuslogic_operator"
17646                      [(match_dup 4)
17647                       (match_operand:SI 2 "nonmemory_operand")]))
17648               (clobber (reg:CC FLAGS_REG))])
17649    (set (match_dup 1) (match_dup 0))
17650    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17651   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17652    && REG_P (operands[0]) && REG_P (operands[4])
17653    && REGNO (operands[0]) == REGNO (operands[4])
17654    && peep2_reg_dead_p (4, operands[0])
17655    && (<MODE>mode != QImode
17656        || immediate_operand (operands[2], SImode)
17657        || any_QIreg_operand (operands[2], SImode))
17658    && !reg_overlap_mentioned_p (operands[0], operands[1])
17659    && !reg_overlap_mentioned_p (operands[0], operands[2])
17660    && ix86_match_ccmode (peep2_next_insn (3),
17661                          (GET_CODE (operands[3]) == PLUS
17662                           || GET_CODE (operands[3]) == MINUS)
17663                          ? CCGOCmode : CCNOmode)"
17664   [(parallel [(set (match_dup 4) (match_dup 5))
17665               (set (match_dup 1) (match_dup 6))])]
17667   operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17668   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17669   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17670                                 copy_rtx (operands[1]), operands[2]);
17671   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17672                                  operands[5], const0_rtx);
17673   operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17674                                 copy_rtx (operands[1]),
17675                                 copy_rtx (operands[2]));
17678 ;; Attempt to always use XOR for zeroing registers.
17679 (define_peephole2
17680   [(set (match_operand 0 "register_operand")
17681         (match_operand 1 "const0_operand"))]
17682   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17683    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17684    && GENERAL_REG_P (operands[0])
17685    && peep2_regno_dead_p (0, FLAGS_REG)"
17686   [(parallel [(set (match_dup 0) (const_int 0))
17687               (clobber (reg:CC FLAGS_REG))])]
17688   "operands[0] = gen_lowpart (word_mode, operands[0]);")
17690 (define_peephole2
17691   [(set (strict_low_part (match_operand 0 "register_operand"))
17692         (const_int 0))]
17693   "(GET_MODE (operands[0]) == QImode
17694     || GET_MODE (operands[0]) == HImode)
17695    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17696    && peep2_regno_dead_p (0, FLAGS_REG)"
17697   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17698               (clobber (reg:CC FLAGS_REG))])])
17700 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17701 (define_peephole2
17702   [(set (match_operand:SWI248 0 "register_operand")
17703         (const_int -1))]
17704   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17705    && peep2_regno_dead_p (0, FLAGS_REG)"
17706   [(parallel [(set (match_dup 0) (const_int -1))
17707               (clobber (reg:CC FLAGS_REG))])]
17709   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
17710     operands[0] = gen_lowpart (SImode, operands[0]);
17713 ;; Attempt to convert simple lea to add/shift.
17714 ;; These can be created by move expanders.
17715 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17716 ;; relevant lea instructions were already split.
17718 (define_peephole2
17719   [(set (match_operand:SWI48 0 "register_operand")
17720         (plus:SWI48 (match_dup 0)
17721                     (match_operand:SWI48 1 "<nonmemory_operand>")))]
17722   "!TARGET_OPT_AGU
17723    && peep2_regno_dead_p (0, FLAGS_REG)"
17724   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17725               (clobber (reg:CC FLAGS_REG))])])
17727 (define_peephole2
17728   [(set (match_operand:SWI48 0 "register_operand")
17729         (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17730                     (match_dup 0)))]
17731   "!TARGET_OPT_AGU
17732    && peep2_regno_dead_p (0, FLAGS_REG)"
17733   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17734               (clobber (reg:CC FLAGS_REG))])])
17736 (define_peephole2
17737   [(set (match_operand:DI 0 "register_operand")
17738         (zero_extend:DI
17739           (plus:SI (match_operand:SI 1 "register_operand")
17740                    (match_operand:SI 2 "nonmemory_operand"))))]
17741   "TARGET_64BIT && !TARGET_OPT_AGU
17742    && REGNO (operands[0]) == REGNO (operands[1])
17743    && peep2_regno_dead_p (0, FLAGS_REG)"
17744   [(parallel [(set (match_dup 0)
17745                    (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17746               (clobber (reg:CC FLAGS_REG))])])
17748 (define_peephole2
17749   [(set (match_operand:DI 0 "register_operand")
17750         (zero_extend:DI
17751           (plus:SI (match_operand:SI 1 "nonmemory_operand")
17752                    (match_operand:SI 2 "register_operand"))))]
17753   "TARGET_64BIT && !TARGET_OPT_AGU
17754    && REGNO (operands[0]) == REGNO (operands[2])
17755    && peep2_regno_dead_p (0, FLAGS_REG)"
17756   [(parallel [(set (match_dup 0)
17757                    (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17758               (clobber (reg:CC FLAGS_REG))])])
17760 (define_peephole2
17761   [(set (match_operand:SWI48 0 "register_operand")
17762         (mult:SWI48 (match_dup 0)
17763                     (match_operand:SWI48 1 "const_int_operand")))]
17764   "exact_log2 (INTVAL (operands[1])) >= 0
17765    && peep2_regno_dead_p (0, FLAGS_REG)"
17766   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17767               (clobber (reg:CC FLAGS_REG))])]
17768   "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17770 (define_peephole2
17771   [(set (match_operand:DI 0 "register_operand")
17772         (zero_extend:DI
17773           (mult:SI (match_operand:SI 1 "register_operand")
17774                    (match_operand:SI 2 "const_int_operand"))))]
17775   "TARGET_64BIT
17776    && exact_log2 (INTVAL (operands[2])) >= 0
17777    && REGNO (operands[0]) == REGNO (operands[1])
17778    && peep2_regno_dead_p (0, FLAGS_REG)"
17779   [(parallel [(set (match_dup 0)
17780                    (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
17781               (clobber (reg:CC FLAGS_REG))])]
17782   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17784 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17785 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17786 ;; On many CPUs it is also faster, since special hardware to avoid esp
17787 ;; dependencies is present.
17789 ;; While some of these conversions may be done using splitters, we use
17790 ;; peepholes in order to allow combine_stack_adjustments pass to see
17791 ;; nonobfuscated RTL.
17793 ;; Convert prologue esp subtractions to push.
17794 ;; We need register to push.  In order to keep verify_flow_info happy we have
17795 ;; two choices
17796 ;; - use scratch and clobber it in order to avoid dependencies
17797 ;; - use already live register
17798 ;; We can't use the second way right now, since there is no reliable way how to
17799 ;; verify that given register is live.  First choice will also most likely in
17800 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17801 ;; call clobbered registers are dead.  We may want to use base pointer as an
17802 ;; alternative when no register is available later.
17804 (define_peephole2
17805   [(match_scratch:W 1 "r")
17806    (parallel [(set (reg:P SP_REG)
17807                    (plus:P (reg:P SP_REG)
17808                            (match_operand:P 0 "const_int_operand")))
17809               (clobber (reg:CC FLAGS_REG))
17810               (clobber (mem:BLK (scratch)))])]
17811   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17812    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17813   [(clobber (match_dup 1))
17814    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17815               (clobber (mem:BLK (scratch)))])])
17817 (define_peephole2
17818   [(match_scratch:W 1 "r")
17819    (parallel [(set (reg:P SP_REG)
17820                    (plus:P (reg:P SP_REG)
17821                            (match_operand:P 0 "const_int_operand")))
17822               (clobber (reg:CC FLAGS_REG))
17823               (clobber (mem:BLK (scratch)))])]
17824   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17825    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17826   [(clobber (match_dup 1))
17827    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17828    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17829               (clobber (mem:BLK (scratch)))])])
17831 ;; Convert esp subtractions to push.
17832 (define_peephole2
17833   [(match_scratch:W 1 "r")
17834    (parallel [(set (reg:P SP_REG)
17835                    (plus:P (reg:P SP_REG)
17836                            (match_operand:P 0 "const_int_operand")))
17837               (clobber (reg:CC FLAGS_REG))])]
17838   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17839    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17840   [(clobber (match_dup 1))
17841    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17843 (define_peephole2
17844   [(match_scratch:W 1 "r")
17845    (parallel [(set (reg:P SP_REG)
17846                    (plus:P (reg:P SP_REG)
17847                            (match_operand:P 0 "const_int_operand")))
17848               (clobber (reg:CC FLAGS_REG))])]
17849   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17850    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17851   [(clobber (match_dup 1))
17852    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17853    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17855 ;; Convert epilogue deallocator to pop.
17856 (define_peephole2
17857   [(match_scratch:W 1 "r")
17858    (parallel [(set (reg:P SP_REG)
17859                    (plus:P (reg:P SP_REG)
17860                            (match_operand:P 0 "const_int_operand")))
17861               (clobber (reg:CC FLAGS_REG))
17862               (clobber (mem:BLK (scratch)))])]
17863   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17864    && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17865   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17866               (clobber (mem:BLK (scratch)))])])
17868 ;; Two pops case is tricky, since pop causes dependency
17869 ;; on destination register.  We use two registers if available.
17870 (define_peephole2
17871   [(match_scratch:W 1 "r")
17872    (match_scratch:W 2 "r")
17873    (parallel [(set (reg:P SP_REG)
17874                    (plus:P (reg:P SP_REG)
17875                            (match_operand:P 0 "const_int_operand")))
17876               (clobber (reg:CC FLAGS_REG))
17877               (clobber (mem:BLK (scratch)))])]
17878   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17879    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17880   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17881               (clobber (mem:BLK (scratch)))])
17882    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17884 (define_peephole2
17885   [(match_scratch:W 1 "r")
17886    (parallel [(set (reg:P SP_REG)
17887                    (plus:P (reg:P SP_REG)
17888                            (match_operand:P 0 "const_int_operand")))
17889               (clobber (reg:CC FLAGS_REG))
17890               (clobber (mem:BLK (scratch)))])]
17891   "optimize_insn_for_size_p ()
17892    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17893   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17894               (clobber (mem:BLK (scratch)))])
17895    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17897 ;; Convert esp additions to pop.
17898 (define_peephole2
17899   [(match_scratch:W 1 "r")
17900    (parallel [(set (reg:P SP_REG)
17901                    (plus:P (reg:P SP_REG)
17902                            (match_operand:P 0 "const_int_operand")))
17903               (clobber (reg:CC FLAGS_REG))])]
17904   "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17905   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17907 ;; Two pops case is tricky, since pop causes dependency
17908 ;; on destination register.  We use two registers if available.
17909 (define_peephole2
17910   [(match_scratch:W 1 "r")
17911    (match_scratch:W 2 "r")
17912    (parallel [(set (reg:P SP_REG)
17913                    (plus:P (reg:P SP_REG)
17914                            (match_operand:P 0 "const_int_operand")))
17915               (clobber (reg:CC FLAGS_REG))])]
17916   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17917   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17918    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17920 (define_peephole2
17921   [(match_scratch:W 1 "r")
17922    (parallel [(set (reg:P SP_REG)
17923                    (plus:P (reg:P SP_REG)
17924                            (match_operand:P 0 "const_int_operand")))
17925               (clobber (reg:CC FLAGS_REG))])]
17926   "optimize_insn_for_size_p ()
17927    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17928   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17929    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17931 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17932 ;; required and register dies.  Similarly for 128 to -128.
17933 (define_peephole2
17934   [(set (match_operand 0 "flags_reg_operand")
17935         (match_operator 1 "compare_operator"
17936           [(match_operand 2 "register_operand")
17937            (match_operand 3 "const_int_operand")]))]
17938   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17939      && incdec_operand (operands[3], GET_MODE (operands[3])))
17940     || (!TARGET_FUSE_CMP_AND_BRANCH
17941         && INTVAL (operands[3]) == 128))
17942    && ix86_match_ccmode (insn, CCGCmode)
17943    && peep2_reg_dead_p (1, operands[2])"
17944   [(parallel [(set (match_dup 0)
17945                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17946               (clobber (match_dup 2))])])
17948 ;; Convert imul by three, five and nine into lea
17949 (define_peephole2
17950   [(parallel
17951     [(set (match_operand:SWI48 0 "register_operand")
17952           (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17953                       (match_operand:SWI48 2 "const359_operand")))
17954      (clobber (reg:CC FLAGS_REG))])]
17955   "!TARGET_PARTIAL_REG_STALL
17956    || <MODE>mode == SImode
17957    || optimize_function_for_size_p (cfun)"
17958   [(set (match_dup 0)
17959         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17960                     (match_dup 1)))]
17961   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17963 (define_peephole2
17964   [(parallel
17965     [(set (match_operand:SWI48 0 "register_operand")
17966           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17967                       (match_operand:SWI48 2 "const359_operand")))
17968      (clobber (reg:CC FLAGS_REG))])]
17969   "optimize_insn_for_speed_p ()
17970    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17971   [(set (match_dup 0) (match_dup 1))
17972    (set (match_dup 0)
17973         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17974                     (match_dup 0)))]
17975   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17977 ;; imul $32bit_imm, mem, reg is vector decoded, while
17978 ;; imul $32bit_imm, reg, reg is direct decoded.
17979 (define_peephole2
17980   [(match_scratch:SWI48 3 "r")
17981    (parallel [(set (match_operand:SWI48 0 "register_operand")
17982                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17983                                (match_operand:SWI48 2 "immediate_operand")))
17984               (clobber (reg:CC FLAGS_REG))])]
17985   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17986    && !satisfies_constraint_K (operands[2])"
17987   [(set (match_dup 3) (match_dup 1))
17988    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17989               (clobber (reg:CC FLAGS_REG))])])
17991 (define_peephole2
17992   [(match_scratch:SI 3 "r")
17993    (parallel [(set (match_operand:DI 0 "register_operand")
17994                    (zero_extend:DI
17995                      (mult:SI (match_operand:SI 1 "memory_operand")
17996                               (match_operand:SI 2 "immediate_operand"))))
17997               (clobber (reg:CC FLAGS_REG))])]
17998   "TARGET_64BIT
17999    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18000    && !satisfies_constraint_K (operands[2])"
18001   [(set (match_dup 3) (match_dup 1))
18002    (parallel [(set (match_dup 0)
18003                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18004               (clobber (reg:CC FLAGS_REG))])])
18006 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18007 ;; Convert it into imul reg, reg
18008 ;; It would be better to force assembler to encode instruction using long
18009 ;; immediate, but there is apparently no way to do so.
18010 (define_peephole2
18011   [(parallel [(set (match_operand:SWI248 0 "register_operand")
18012                    (mult:SWI248
18013                     (match_operand:SWI248 1 "nonimmediate_operand")
18014                     (match_operand:SWI248 2 "const_int_operand")))
18015               (clobber (reg:CC FLAGS_REG))])
18016    (match_scratch:SWI248 3 "r")]
18017   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18018    && satisfies_constraint_K (operands[2])"
18019   [(set (match_dup 3) (match_dup 2))
18020    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
18021               (clobber (reg:CC FLAGS_REG))])]
18023   if (!rtx_equal_p (operands[0], operands[1]))
18024     emit_move_insn (operands[0], operands[1]);
18027 ;; After splitting up read-modify operations, array accesses with memory
18028 ;; operands might end up in form:
18029 ;;  sall    $2, %eax
18030 ;;  movl    4(%esp), %edx
18031 ;;  addl    %edx, %eax
18032 ;; instead of pre-splitting:
18033 ;;  sall    $2, %eax
18034 ;;  addl    4(%esp), %eax
18035 ;; Turn it into:
18036 ;;  movl    4(%esp), %edx
18037 ;;  leal    (%edx,%eax,4), %eax
18039 (define_peephole2
18040   [(match_scratch:W 5 "r")
18041    (parallel [(set (match_operand 0 "register_operand")
18042                    (ashift (match_operand 1 "register_operand")
18043                            (match_operand 2 "const_int_operand")))
18044                (clobber (reg:CC FLAGS_REG))])
18045    (parallel [(set (match_operand 3 "register_operand")
18046                    (plus (match_dup 0)
18047                          (match_operand 4 "x86_64_general_operand")))
18048                    (clobber (reg:CC FLAGS_REG))])]
18049   "IN_RANGE (INTVAL (operands[2]), 1, 3)
18050    /* Validate MODE for lea.  */
18051    && ((!TARGET_PARTIAL_REG_STALL
18052         && (GET_MODE (operands[0]) == QImode
18053             || GET_MODE (operands[0]) == HImode))
18054        || GET_MODE (operands[0]) == SImode
18055        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18056    && (rtx_equal_p (operands[0], operands[3])
18057        || peep2_reg_dead_p (2, operands[0]))
18058    /* We reorder load and the shift.  */
18059    && !reg_overlap_mentioned_p (operands[0], operands[4])"
18060   [(set (match_dup 5) (match_dup 4))
18061    (set (match_dup 0) (match_dup 1))]
18063   machine_mode op1mode = GET_MODE (operands[1]);
18064   machine_mode mode = op1mode == DImode ? DImode : SImode;
18065   int scale = 1 << INTVAL (operands[2]);
18066   rtx index = gen_lowpart (word_mode, operands[1]);
18067   rtx base = gen_lowpart (word_mode, operands[5]);
18068   rtx dest = gen_lowpart (mode, operands[3]);
18070   operands[1] = gen_rtx_PLUS (word_mode, base,
18071                               gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
18072   operands[5] = base;
18073   if (mode != word_mode)
18074     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18075   if (op1mode != word_mode)
18076     operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
18077   operands[0] = dest;
18080 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18081 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18082 ;; caught for use by garbage collectors and the like.  Using an insn that
18083 ;; maps to SIGILL makes it more likely the program will rightfully die.
18084 ;; Keeping with tradition, "6" is in honor of #UD.
18085 (define_insn "trap"
18086   [(trap_if (const_int 1) (const_int 6))]
18087   ""
18089 #ifdef HAVE_AS_IX86_UD2
18090   return "ud2";
18091 #else
18092   return ASM_SHORT "0x0b0f";
18093 #endif
18095   [(set_attr "length" "2")])
18097 (define_expand "prefetch"
18098   [(prefetch (match_operand 0 "address_operand")
18099              (match_operand:SI 1 "const_int_operand")
18100              (match_operand:SI 2 "const_int_operand"))]
18101   "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18103   bool write = INTVAL (operands[1]) != 0;
18104   int locality = INTVAL (operands[2]);
18106   gcc_assert (IN_RANGE (locality, 0, 3));
18108   /* Use 3dNOW prefetch in case we are asking for write prefetch not
18109      supported by SSE counterpart or the SSE prefetch is not available
18110      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
18111      of locality.  */
18112   if (TARGET_PREFETCHWT1 && write && locality <= 2)
18113     operands[2] = const2_rtx;
18114   else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
18115     operands[2] = GEN_INT (3);
18116   else
18117     operands[1] = const0_rtx;
18120 (define_insn "*prefetch_sse"
18121   [(prefetch (match_operand 0 "address_operand" "p")
18122              (const_int 0)
18123              (match_operand:SI 1 "const_int_operand"))]
18124   "TARGET_PREFETCH_SSE"
18126   static const char * const patterns[4] = {
18127    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18128   };
18130   int locality = INTVAL (operands[1]);
18131   gcc_assert (IN_RANGE (locality, 0, 3));
18133   return patterns[locality];
18135   [(set_attr "type" "sse")
18136    (set_attr "atom_sse_attr" "prefetch")
18137    (set (attr "length_address")
18138         (symbol_ref "memory_address_length (operands[0], false)"))
18139    (set_attr "memory" "none")])
18141 (define_insn "*prefetch_3dnow"
18142   [(prefetch (match_operand 0 "address_operand" "p")
18143              (match_operand:SI 1 "const_int_operand" "n")
18144              (const_int 3))]
18145   "TARGET_PRFCHW"
18147   if (INTVAL (operands[1]) == 0)
18148     return "prefetch\t%a0";
18149   else
18150     return "prefetchw\t%a0";
18152   [(set_attr "type" "mmx")
18153    (set (attr "length_address")
18154         (symbol_ref "memory_address_length (operands[0], false)"))
18155    (set_attr "memory" "none")])
18157 (define_insn "*prefetch_prefetchwt1"
18158   [(prefetch (match_operand 0 "address_operand" "p")
18159              (const_int 1)
18160              (const_int 2))]
18161   "TARGET_PREFETCHWT1"
18162   "prefetchwt1\t%a0";
18163   [(set_attr "type" "sse")
18164    (set (attr "length_address")
18165         (symbol_ref "memory_address_length (operands[0], false)"))
18166    (set_attr "memory" "none")])
18168 (define_expand "stack_protect_set"
18169   [(match_operand 0 "memory_operand")
18170    (match_operand 1 "memory_operand")]
18171   "TARGET_SSP_TLS_GUARD"
18173   rtx (*insn)(rtx, rtx);
18175 #ifdef TARGET_THREAD_SSP_OFFSET
18176   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18177   insn = (TARGET_LP64
18178           ? gen_stack_tls_protect_set_di
18179           : gen_stack_tls_protect_set_si);
18180 #else
18181   insn = (TARGET_LP64
18182           ? gen_stack_protect_set_di
18183           : gen_stack_protect_set_si);
18184 #endif
18186   emit_insn (insn (operands[0], operands[1]));
18187   DONE;
18190 (define_insn "stack_protect_set_<mode>"
18191   [(set (match_operand:PTR 0 "memory_operand" "=m")
18192         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
18193                     UNSPEC_SP_SET))
18194    (set (match_scratch:PTR 2 "=&r") (const_int 0))
18195    (clobber (reg:CC FLAGS_REG))]
18196   "TARGET_SSP_TLS_GUARD"
18197   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18198   [(set_attr "type" "multi")])
18200 (define_insn "stack_tls_protect_set_<mode>"
18201   [(set (match_operand:PTR 0 "memory_operand" "=m")
18202         (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
18203                     UNSPEC_SP_TLS_SET))
18204    (set (match_scratch:PTR 2 "=&r") (const_int 0))
18205    (clobber (reg:CC FLAGS_REG))]
18206   ""
18207   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18208   [(set_attr "type" "multi")])
18210 (define_expand "stack_protect_test"
18211   [(match_operand 0 "memory_operand")
18212    (match_operand 1 "memory_operand")
18213    (match_operand 2)]
18214   "TARGET_SSP_TLS_GUARD"
18216   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18218   rtx (*insn)(rtx, rtx, rtx);
18220 #ifdef TARGET_THREAD_SSP_OFFSET
18221   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18222   insn = (TARGET_LP64
18223           ? gen_stack_tls_protect_test_di
18224           : gen_stack_tls_protect_test_si);
18225 #else
18226   insn = (TARGET_LP64
18227           ? gen_stack_protect_test_di
18228           : gen_stack_protect_test_si);
18229 #endif
18231   emit_insn (insn (flags, operands[0], operands[1]));
18233   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18234                                   flags, const0_rtx, operands[2]));
18235   DONE;
18238 (define_insn "stack_protect_test_<mode>"
18239   [(set (match_operand:CCZ 0 "flags_reg_operand")
18240         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18241                      (match_operand:PTR 2 "memory_operand" "m")]
18242                     UNSPEC_SP_TEST))
18243    (clobber (match_scratch:PTR 3 "=&r"))]
18244   "TARGET_SSP_TLS_GUARD"
18245   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18246   [(set_attr "type" "multi")])
18248 (define_insn "stack_tls_protect_test_<mode>"
18249   [(set (match_operand:CCZ 0 "flags_reg_operand")
18250         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18251                      (match_operand:PTR 2 "const_int_operand" "i")]
18252                     UNSPEC_SP_TLS_TEST))
18253    (clobber (match_scratch:PTR 3 "=r"))]
18254   ""
18255   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
18256   [(set_attr "type" "multi")])
18258 (define_insn "sse4_2_crc32<mode>"
18259   [(set (match_operand:SI 0 "register_operand" "=r")
18260         (unspec:SI
18261           [(match_operand:SI 1 "register_operand" "0")
18262            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18263           UNSPEC_CRC32))]
18264   "TARGET_SSE4_2 || TARGET_CRC32"
18265   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18266   [(set_attr "type" "sselog1")
18267    (set_attr "prefix_rep" "1")
18268    (set_attr "prefix_extra" "1")
18269    (set (attr "prefix_data16")
18270      (if_then_else (match_operand:HI 2)
18271        (const_string "1")
18272        (const_string "*")))
18273    (set (attr "prefix_rex")
18274      (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18275        (const_string "1")
18276        (const_string "*")))
18277    (set_attr "mode" "SI")])
18279 (define_insn "sse4_2_crc32di"
18280   [(set (match_operand:DI 0 "register_operand" "=r")
18281         (unspec:DI
18282           [(match_operand:DI 1 "register_operand" "0")
18283            (match_operand:DI 2 "nonimmediate_operand" "rm")]
18284           UNSPEC_CRC32))]
18285   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18286   "crc32{q}\t{%2, %0|%0, %2}"
18287   [(set_attr "type" "sselog1")
18288    (set_attr "prefix_rep" "1")
18289    (set_attr "prefix_extra" "1")
18290    (set_attr "mode" "DI")])
18292 (define_insn "rdpmc"
18293   [(set (match_operand:DI 0 "register_operand" "=A")
18294         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18295                             UNSPECV_RDPMC))]
18296   "!TARGET_64BIT"
18297   "rdpmc"
18298   [(set_attr "type" "other")
18299    (set_attr "length" "2")])
18301 (define_insn "rdpmc_rex64"
18302   [(set (match_operand:DI 0 "register_operand" "=a")
18303         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18304                             UNSPECV_RDPMC))
18305    (set (match_operand:DI 1 "register_operand" "=d")
18306         (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18307   "TARGET_64BIT"
18308   "rdpmc"
18309   [(set_attr "type" "other")
18310    (set_attr "length" "2")])
18312 (define_insn "rdtsc"
18313   [(set (match_operand:DI 0 "register_operand" "=A")
18314         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18315   "!TARGET_64BIT"
18316   "rdtsc"
18317   [(set_attr "type" "other")
18318    (set_attr "length" "2")])
18320 (define_insn "rdtsc_rex64"
18321   [(set (match_operand:DI 0 "register_operand" "=a")
18322         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18323    (set (match_operand:DI 1 "register_operand" "=d")
18324         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18325   "TARGET_64BIT"
18326   "rdtsc"
18327   [(set_attr "type" "other")
18328    (set_attr "length" "2")])
18330 (define_insn "rdtscp"
18331   [(set (match_operand:DI 0 "register_operand" "=A")
18332         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18333    (set (match_operand:SI 1 "register_operand" "=c")
18334         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18335   "!TARGET_64BIT"
18336   "rdtscp"
18337   [(set_attr "type" "other")
18338    (set_attr "length" "3")])
18340 (define_insn "rdtscp_rex64"
18341   [(set (match_operand:DI 0 "register_operand" "=a")
18342         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18343    (set (match_operand:DI 1 "register_operand" "=d")
18344         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18345    (set (match_operand:SI 2 "register_operand" "=c")
18346         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18347   "TARGET_64BIT"
18348   "rdtscp"
18349   [(set_attr "type" "other")
18350    (set_attr "length" "3")])
18352 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18354 ;; FXSR, XSAVE and XSAVEOPT instructions
18356 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18358 (define_insn "fxsave"
18359   [(set (match_operand:BLK 0 "memory_operand" "=m")
18360         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18361   "TARGET_FXSR"
18362   "fxsave\t%0"
18363   [(set_attr "type" "other")
18364    (set_attr "memory" "store")
18365    (set (attr "length")
18366         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18368 (define_insn "fxsave64"
18369   [(set (match_operand:BLK 0 "memory_operand" "=m")
18370         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18371   "TARGET_64BIT && TARGET_FXSR"
18372   "fxsave64\t%0"
18373   [(set_attr "type" "other")
18374    (set_attr "memory" "store")
18375    (set (attr "length")
18376         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18378 (define_insn "fxrstor"
18379   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18380                     UNSPECV_FXRSTOR)]
18381   "TARGET_FXSR"
18382   "fxrstor\t%0"
18383   [(set_attr "type" "other")
18384    (set_attr "memory" "load")
18385    (set (attr "length")
18386         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18388 (define_insn "fxrstor64"
18389   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18390                     UNSPECV_FXRSTOR64)]
18391   "TARGET_64BIT && TARGET_FXSR"
18392   "fxrstor64\t%0"
18393   [(set_attr "type" "other")
18394    (set_attr "memory" "load")
18395    (set (attr "length")
18396         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18398 (define_int_iterator ANY_XSAVE
18399         [UNSPECV_XSAVE
18400          (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
18401          (UNSPECV_XSAVEC "TARGET_XSAVEC")
18402          (UNSPECV_XSAVES "TARGET_XSAVES")])
18404 (define_int_iterator ANY_XSAVE64
18405         [UNSPECV_XSAVE64
18406          (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
18407          (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
18408          (UNSPECV_XSAVES64 "TARGET_XSAVES")])
18410 (define_int_attr xsave
18411         [(UNSPECV_XSAVE "xsave")
18412          (UNSPECV_XSAVE64 "xsave64")
18413          (UNSPECV_XSAVEOPT "xsaveopt")
18414          (UNSPECV_XSAVEOPT64 "xsaveopt64")
18415          (UNSPECV_XSAVEC "xsavec")
18416          (UNSPECV_XSAVEC64 "xsavec64")
18417          (UNSPECV_XSAVES "xsaves")
18418          (UNSPECV_XSAVES64 "xsaves64")])
18420 (define_int_iterator ANY_XRSTOR
18421         [UNSPECV_XRSTOR
18422          (UNSPECV_XRSTORS "TARGET_XSAVES")])
18424 (define_int_iterator ANY_XRSTOR64
18425         [UNSPECV_XRSTOR64
18426          (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
18428 (define_int_attr xrstor
18429         [(UNSPECV_XRSTOR "xrstor")
18430          (UNSPECV_XRSTOR64 "xrstor")
18431          (UNSPECV_XRSTORS "xrstors")
18432          (UNSPECV_XRSTORS64 "xrstors")])
18434 (define_insn "<xsave>"
18435   [(set (match_operand:BLK 0 "memory_operand" "=m")
18436         (unspec_volatile:BLK
18437          [(match_operand:DI 1 "register_operand" "A")]
18438          ANY_XSAVE))]
18439   "!TARGET_64BIT && TARGET_XSAVE"
18440   "<xsave>\t%0"
18441   [(set_attr "type" "other")
18442    (set_attr "memory" "store")
18443    (set (attr "length")
18444         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18446 (define_insn "<xsave>_rex64"
18447   [(set (match_operand:BLK 0 "memory_operand" "=m")
18448         (unspec_volatile:BLK
18449          [(match_operand:SI 1 "register_operand" "a")
18450           (match_operand:SI 2 "register_operand" "d")]
18451          ANY_XSAVE))]
18452   "TARGET_64BIT && TARGET_XSAVE"
18453   "<xsave>\t%0"
18454   [(set_attr "type" "other")
18455    (set_attr "memory" "store")
18456    (set (attr "length")
18457         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18459 (define_insn "<xsave>"
18460   [(set (match_operand:BLK 0 "memory_operand" "=m")
18461         (unspec_volatile:BLK
18462          [(match_operand:SI 1 "register_operand" "a")
18463           (match_operand:SI 2 "register_operand" "d")]
18464          ANY_XSAVE64))]
18465   "TARGET_64BIT && TARGET_XSAVE"
18466   "<xsave>\t%0"
18467   [(set_attr "type" "other")
18468    (set_attr "memory" "store")
18469    (set (attr "length")
18470         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18472 (define_insn "<xrstor>"
18473    [(unspec_volatile:BLK
18474      [(match_operand:BLK 0 "memory_operand" "m")
18475       (match_operand:DI 1 "register_operand" "A")]
18476      ANY_XRSTOR)]
18477   "!TARGET_64BIT && TARGET_XSAVE"
18478   "<xrstor>\t%0"
18479   [(set_attr "type" "other")
18480    (set_attr "memory" "load")
18481    (set (attr "length")
18482         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18484 (define_insn "<xrstor>_rex64"
18485    [(unspec_volatile:BLK
18486      [(match_operand:BLK 0 "memory_operand" "m")
18487       (match_operand:SI 1 "register_operand" "a")
18488       (match_operand:SI 2 "register_operand" "d")]
18489      ANY_XRSTOR)]
18490   "TARGET_64BIT && TARGET_XSAVE"
18491   "<xrstor>\t%0"
18492   [(set_attr "type" "other")
18493    (set_attr "memory" "load")
18494    (set (attr "length")
18495         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18497 (define_insn "<xrstor>64"
18498    [(unspec_volatile:BLK
18499      [(match_operand:BLK 0 "memory_operand" "m")
18500       (match_operand:SI 1 "register_operand" "a")
18501       (match_operand:SI 2 "register_operand" "d")]
18502      ANY_XRSTOR64)]
18503   "TARGET_64BIT && TARGET_XSAVE"
18504   "<xrstor>64\t%0"
18505   [(set_attr "type" "other")
18506    (set_attr "memory" "load")
18507    (set (attr "length")
18508         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18510 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18512 ;; Floating-point instructions for atomic compound assignments
18514 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18516 ; Clobber all floating-point registers on environment save and restore
18517 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18518 (define_insn "fnstenv"
18519   [(set (match_operand:BLK 0 "memory_operand" "=m")
18520         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18521    (clobber (reg:HI FPCR_REG))
18522    (clobber (reg:XF ST0_REG))
18523    (clobber (reg:XF ST1_REG))
18524    (clobber (reg:XF ST2_REG))
18525    (clobber (reg:XF ST3_REG))
18526    (clobber (reg:XF ST4_REG))
18527    (clobber (reg:XF ST5_REG))
18528    (clobber (reg:XF ST6_REG))
18529    (clobber (reg:XF ST7_REG))]
18530   "TARGET_80387"
18531   "fnstenv\t%0"
18532   [(set_attr "type" "other")
18533    (set_attr "memory" "store")
18534    (set (attr "length")
18535         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18537 (define_insn "fldenv"
18538   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18539                     UNSPECV_FLDENV)
18540    (clobber (reg:CCFP FPSR_REG))
18541    (clobber (reg:HI FPCR_REG))
18542    (clobber (reg:XF ST0_REG))
18543    (clobber (reg:XF ST1_REG))
18544    (clobber (reg:XF ST2_REG))
18545    (clobber (reg:XF ST3_REG))
18546    (clobber (reg:XF ST4_REG))
18547    (clobber (reg:XF ST5_REG))
18548    (clobber (reg:XF ST6_REG))
18549    (clobber (reg:XF ST7_REG))]
18550   "TARGET_80387"
18551   "fldenv\t%0"
18552   [(set_attr "type" "other")
18553    (set_attr "memory" "load")
18554    (set (attr "length")
18555         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18557 (define_insn "fnstsw"
18558   [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
18559         (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18560   "TARGET_80387"
18561   "fnstsw\t%0"
18562   [(set_attr "type" "other,other")
18563    (set_attr "memory" "none,store")
18564    (set (attr "length")
18565         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18567 (define_insn "fnclex"
18568   [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
18569   "TARGET_80387"
18570   "fnclex"
18571   [(set_attr "type" "other")
18572    (set_attr "memory" "none")
18573    (set_attr "length" "2")])
18575 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18577 ;; LWP instructions
18579 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18581 (define_expand "lwp_llwpcb"
18582   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18583                     UNSPECV_LLWP_INTRINSIC)]
18584   "TARGET_LWP")
18586 (define_insn "*lwp_llwpcb<mode>1"
18587   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18588                     UNSPECV_LLWP_INTRINSIC)]
18589   "TARGET_LWP"
18590   "llwpcb\t%0"
18591   [(set_attr "type" "lwp")
18592    (set_attr "mode" "<MODE>")
18593    (set_attr "length" "5")])
18595 (define_expand "lwp_slwpcb"
18596   [(set (match_operand 0 "register_operand" "=r")
18597         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18598   "TARGET_LWP"
18600   rtx (*insn)(rtx);
18602   insn = (Pmode == DImode
18603           ? gen_lwp_slwpcbdi
18604           : gen_lwp_slwpcbsi);
18606   emit_insn (insn (operands[0]));
18607   DONE;
18610 (define_insn "lwp_slwpcb<mode>"
18611   [(set (match_operand:P 0 "register_operand" "=r")
18612         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18613   "TARGET_LWP"
18614   "slwpcb\t%0"
18615   [(set_attr "type" "lwp")
18616    (set_attr "mode" "<MODE>")
18617    (set_attr "length" "5")])
18619 (define_expand "lwp_lwpval<mode>3"
18620   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18621                      (match_operand:SI 2 "nonimmediate_operand" "rm")
18622                      (match_operand:SI 3 "const_int_operand" "i")]
18623                     UNSPECV_LWPVAL_INTRINSIC)]
18624   "TARGET_LWP"
18625   ;; Avoid unused variable warning.
18626   "(void) operands[0];")
18628 (define_insn "*lwp_lwpval<mode>3_1"
18629   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18630                      (match_operand:SI 1 "nonimmediate_operand" "rm")
18631                      (match_operand:SI 2 "const_int_operand" "i")]
18632                     UNSPECV_LWPVAL_INTRINSIC)]
18633   "TARGET_LWP"
18634   "lwpval\t{%2, %1, %0|%0, %1, %2}"
18635   [(set_attr "type" "lwp")
18636    (set_attr "mode" "<MODE>")
18637    (set (attr "length")
18638         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18640 (define_expand "lwp_lwpins<mode>3"
18641   [(set (reg:CCC FLAGS_REG)
18642         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18643                               (match_operand:SI 2 "nonimmediate_operand" "rm")
18644                               (match_operand:SI 3 "const_int_operand" "i")]
18645                              UNSPECV_LWPINS_INTRINSIC))
18646    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18647         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18648   "TARGET_LWP")
18650 (define_insn "*lwp_lwpins<mode>3_1"
18651   [(set (reg:CCC FLAGS_REG)
18652         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18653                               (match_operand:SI 1 "nonimmediate_operand" "rm")
18654                               (match_operand:SI 2 "const_int_operand" "i")]
18655                              UNSPECV_LWPINS_INTRINSIC))]
18656   "TARGET_LWP"
18657   "lwpins\t{%2, %1, %0|%0, %1, %2}"
18658   [(set_attr "type" "lwp")
18659    (set_attr "mode" "<MODE>")
18660    (set (attr "length")
18661         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18663 (define_int_iterator RDFSGSBASE
18664         [UNSPECV_RDFSBASE
18665          UNSPECV_RDGSBASE])
18667 (define_int_iterator WRFSGSBASE
18668         [UNSPECV_WRFSBASE
18669          UNSPECV_WRGSBASE])
18671 (define_int_attr fsgs
18672         [(UNSPECV_RDFSBASE "fs")
18673          (UNSPECV_RDGSBASE "gs")
18674          (UNSPECV_WRFSBASE "fs")
18675          (UNSPECV_WRGSBASE "gs")])
18677 (define_insn "rd<fsgs>base<mode>"
18678   [(set (match_operand:SWI48 0 "register_operand" "=r")
18679         (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18680   "TARGET_64BIT && TARGET_FSGSBASE"
18681   "rd<fsgs>base\t%0"
18682   [(set_attr "type" "other")
18683    (set_attr "prefix_extra" "2")])
18685 (define_insn "wr<fsgs>base<mode>"
18686   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18687                     WRFSGSBASE)]
18688   "TARGET_64BIT && TARGET_FSGSBASE"
18689   "wr<fsgs>base\t%0"
18690   [(set_attr "type" "other")
18691    (set_attr "prefix_extra" "2")])
18693 (define_insn "rdrand<mode>_1"
18694   [(set (match_operand:SWI248 0 "register_operand" "=r")
18695         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18696    (set (reg:CCC FLAGS_REG)
18697         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18698   "TARGET_RDRND"
18699   "rdrand\t%0"
18700   [(set_attr "type" "other")
18701    (set_attr "prefix_extra" "1")])
18703 (define_insn "rdseed<mode>_1"
18704   [(set (match_operand:SWI248 0 "register_operand" "=r")
18705         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18706    (set (reg:CCC FLAGS_REG)
18707         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18708   "TARGET_RDSEED"
18709   "rdseed\t%0"
18710   [(set_attr "type" "other")
18711    (set_attr "prefix_extra" "1")])
18713 (define_expand "pause"
18714   [(set (match_dup 0)
18715         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18716   ""
18718   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18719   MEM_VOLATILE_P (operands[0]) = 1;
18722 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18723 ;; They have the same encoding.
18724 (define_insn "*pause"
18725   [(set (match_operand:BLK 0)
18726         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18727   ""
18728   "rep%; nop"
18729   [(set_attr "length" "2")
18730    (set_attr "memory" "unknown")])
18732 (define_expand "xbegin"
18733   [(set (match_operand:SI 0 "register_operand")
18734         (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18735   "TARGET_RTM"
18737   rtx_code_label *label = gen_label_rtx ();
18739   /* xbegin is emitted as jump_insn, so reload won't be able
18740      to reload its operand.  Force the value into AX hard register.  */
18741   rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18742   emit_move_insn (ax_reg, constm1_rtx);
18744   emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18746   emit_label (label);
18747   LABEL_NUSES (label) = 1;
18749   emit_move_insn (operands[0], ax_reg);
18751   DONE;
18754 (define_insn "xbegin_1"
18755   [(set (pc)
18756         (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18757                           (const_int 0))
18758                       (label_ref (match_operand 1))
18759                       (pc)))
18760    (set (match_operand:SI 0 "register_operand" "+a")
18761         (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18762   "TARGET_RTM"
18763   "xbegin\t%l1"
18764   [(set_attr "type" "other")
18765    (set_attr "length" "6")])
18767 (define_insn "xend"
18768   [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18769   "TARGET_RTM"
18770   "xend"
18771   [(set_attr "type" "other")
18772    (set_attr "length" "3")])
18774 (define_insn "xabort"
18775   [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18776                     UNSPECV_XABORT)]
18777   "TARGET_RTM"
18778   "xabort\t%0"
18779   [(set_attr "type" "other")
18780    (set_attr "length" "3")])
18782 (define_expand "xtest"
18783   [(set (match_operand:QI 0 "register_operand")
18784         (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18785   "TARGET_RTM"
18787   emit_insn (gen_xtest_1 ());
18789   ix86_expand_setcc (operands[0], NE,
18790                      gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18791   DONE;
18794 (define_insn "xtest_1"
18795   [(set (reg:CCZ FLAGS_REG)
18796         (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18797   "TARGET_RTM"
18798   "xtest"
18799   [(set_attr "type" "other")
18800    (set_attr "length" "3")])
18802 (define_insn "pcommit"
18803   [(unspec_volatile [(const_int 0)] UNSPECV_PCOMMIT)]
18804   "TARGET_PCOMMIT"
18805   "pcommit"
18806   [(set_attr "type" "other")
18807    (set_attr "length" "4")])
18809 (define_insn "clwb"
18810   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18811                    UNSPECV_CLWB)]
18812   "TARGET_CLWB"
18813   "clwb\t%a0"
18814   [(set_attr "type" "sse")
18815    (set_attr "atom_sse_attr" "fence")
18816    (set_attr "memory" "unknown")])
18818 (define_insn "clflushopt"
18819   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18820                    UNSPECV_CLFLUSHOPT)]
18821   "TARGET_CLFLUSHOPT"
18822   "clflushopt\t%a0"
18823   [(set_attr "type" "sse")
18824    (set_attr "atom_sse_attr" "fence")
18825    (set_attr "memory" "unknown")])
18827 ;; MPX instructions
18829 (define_expand "<mode>_mk"
18830   [(set (match_operand:BND 0 "register_operand")
18831     (unspec:BND
18832       [(mem:<bnd_ptr>
18833        (match_par_dup 3
18834         [(match_operand:<bnd_ptr> 1 "register_operand")
18835          (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
18836       UNSPEC_BNDMK))]
18837   "TARGET_MPX"
18839   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18840                                                   operands[2]),
18841                                 UNSPEC_BNDMK_ADDR);
18844 (define_insn "*<mode>_mk"
18845   [(set (match_operand:BND 0 "register_operand" "=w")
18846     (unspec:BND
18847       [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18848         [(unspec:<bnd_ptr>
18849            [(match_operand:<bnd_ptr> 1 "register_operand" "r")
18850             (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
18851            UNSPEC_BNDMK_ADDR)])]
18852       UNSPEC_BNDMK))]
18853   "TARGET_MPX"
18854   "bndmk\t{%3, %0|%0, %3}"
18855   [(set_attr "type" "mpxmk")])
18857 (define_expand "mov<mode>"
18858   [(set (match_operand:BND 0 "general_operand")
18859         (match_operand:BND 1 "general_operand"))]
18860   "TARGET_MPX"
18862   ix86_expand_move (<MODE>mode, operands);DONE;
18865 (define_insn "*mov<mode>_internal_mpx"
18866   [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
18867         (match_operand:BND 1 "general_operand" "wm,w"))]
18868   "TARGET_MPX"
18869   "bndmov\t{%1, %0|%0, %1}"
18870   [(set_attr "type" "mpxmov")])
18872 (define_expand "<mode>_<bndcheck>"
18873   [(parallel [(unspec [(match_operand:BND 0 "register_operand")
18874                        (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
18875               (set (match_dup 2)
18876                    (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18877   "TARGET_MPX"
18879   operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
18880   MEM_VOLATILE_P (operands[2]) = 1;
18883 (define_insn "*<mode>_<bndcheck>"
18884   [(parallel [(unspec [(match_operand:BND 0 "register_operand" "w")
18885                        (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
18886               (set (match_operand:BLK 2 "bnd_mem_operator")
18887                    (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18888   "TARGET_MPX"
18889   "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
18890   [(set_attr "type" "mpxchk")])
18892 (define_expand "<mode>_ldx"
18893   [(parallel [(set:BND (match_operand:BND 0 "register_operand")
18894                        (unspec:BND
18895                          [(mem:<bnd_ptr>
18896                            (match_par_dup 3
18897                              [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
18898                               (match_operand:<bnd_ptr> 2 "register_operand")]))]
18899                          UNSPEC_BNDLDX))
18900               (use (mem:BLK (match_dup 1)))])]
18901   "TARGET_MPX"
18903   /* Avoid registers which connot be used as index.  */
18904   if (!index_register_operand (operands[2], Pmode))
18905     {
18906       rtx temp = gen_reg_rtx (Pmode);
18907       emit_move_insn (temp, operands[2]);
18908       operands[2] = temp;
18909     }
18911   /* If it was a register originally then it may have
18912      mode other than Pmode.  We need to extend in such
18913      case because bndldx may work only with Pmode regs.  */
18914   if (GET_MODE (operands[2]) != Pmode)
18915     operands[2] = ix86_zero_extend_to_Pmode (operands[2]);
18917   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18918                                                   operands[2]),
18919                                 UNSPEC_BNDLDX_ADDR);
18922 (define_insn "*<mode>_ldx"
18923   [(parallel [(set:BND (match_operand:BND 0 "register_operand" "=w")
18924                        (unspec:BND
18925                          [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18926                            [(unspec:<bnd_ptr>
18927                              [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
18928                               (match_operand:<bnd_ptr> 2 "register_operand" "l")]
18929                             UNSPEC_BNDLDX_ADDR)])]
18930                          UNSPEC_BNDLDX))
18931               (use (mem:BLK (match_dup 1)))])]
18932   "TARGET_MPX"
18933   "bndldx\t{%3, %0|%0, %3}"
18934   [(set_attr "type" "mpxld")])
18936 (define_expand "<mode>_stx"
18937   [(parallel [(unspec [(mem:<bnd_ptr>
18938                          (match_par_dup 3
18939                            [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
18940                             (match_operand:<bnd_ptr> 1 "register_operand")]))
18941                        (match_operand:BND 2 "register_operand")] UNSPEC_BNDSTX)
18942               (set (match_dup 4)
18943                    (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
18944   "TARGET_MPX"
18946   /* Avoid registers which connot be used as index.  */
18947   if (!index_register_operand (operands[1], Pmode))
18948     {
18949       rtx temp = gen_reg_rtx (Pmode);
18950       emit_move_insn (temp, operands[1]);
18951       operands[1] = temp;
18952     }
18954   /* If it was a register originally then it may have
18955      mode other than Pmode.  We need to extend in such
18956      case because bndstx may work only with Pmode regs.  */
18957   if (GET_MODE (operands[1]) != Pmode)
18958     operands[1] = ix86_zero_extend_to_Pmode (operands[1]);
18960   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
18961                                                   operands[1]),
18962                                 UNSPEC_BNDLDX_ADDR);
18963   operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
18964   MEM_VOLATILE_P (operands[4]) = 1;
18967 (define_insn "*<mode>_stx"
18968   [(parallel [(unspec [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18969                          [(unspec:<bnd_ptr>
18970                           [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
18971                            (match_operand:<bnd_ptr> 1 "register_operand" "l")]
18972                          UNSPEC_BNDLDX_ADDR)])
18973                        (match_operand:BND 2 "register_operand" "w")] UNSPEC_BNDSTX)
18974               (set (match_operand:BLK 4 "bnd_mem_operator")
18975                    (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
18976   "TARGET_MPX"
18977   "bndstx\t{%2, %3|%3, %2}"
18978   [(set_attr "type" "mpxst")])
18980 (define_insn "move_size_reloc_<mode>"
18981   [(set (match_operand:SWI48 0 "register_operand" "=r")
18982        (unspec:SWI48
18983         [(match_operand:SWI48 1 "symbol_operand")]
18984         UNSPEC_SIZEOF))]
18985   "TARGET_MPX"
18987   if (x86_64_immediate_size_operand (operands[1], VOIDmode))
18988     return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
18989   else
18990     return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
18992   [(set_attr "type" "imov")
18993    (set_attr "mode" "<MODE>")])
18995 (include "mmx.md")
18996 (include "sse.md")
18997 (include "sync.md")