Initial support for AVX-512{VL,BW,DQ}
[official-gcc.git] / gcc / config / i386 / i386.md
blob2a10862fec87f063d2cd65bd9428cab38df02d7e
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2014 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
67 (define_c_enum "unspec" [
68   ;; Relocation specifiers
69   UNSPEC_GOT
70   UNSPEC_GOTOFF
71   UNSPEC_GOTPCREL
72   UNSPEC_GOTTPOFF
73   UNSPEC_TPOFF
74   UNSPEC_NTPOFF
75   UNSPEC_DTPOFF
76   UNSPEC_GOTNTPOFF
77   UNSPEC_INDNTPOFF
78   UNSPEC_PLTOFF
79   UNSPEC_MACHOPIC_OFFSET
80   UNSPEC_PCREL
82   ;; Prologue support
83   UNSPEC_STACK_ALLOC
84   UNSPEC_SET_GOT
85   UNSPEC_SET_RIP
86   UNSPEC_SET_GOT_OFFSET
87   UNSPEC_MEMORY_BLOCKAGE
88   UNSPEC_STACK_CHECK
90   ;; TLS support
91   UNSPEC_TP
92   UNSPEC_TLS_GD
93   UNSPEC_TLS_LD_BASE
94   UNSPEC_TLSDESC
95   UNSPEC_TLS_IE_SUN
97   ;; Other random patterns
98   UNSPEC_SCAS
99   UNSPEC_FNSTSW
100   UNSPEC_SAHF
101   UNSPEC_PARITY
102   UNSPEC_FSTCW
103   UNSPEC_ADD_CARRY
104   UNSPEC_FLDCW
105   UNSPEC_REP
106   UNSPEC_LD_MPIC        ; load_macho_picbase
107   UNSPEC_TRUNC_NOOP
108   UNSPEC_DIV_ALREADY_SPLIT
109   UNSPEC_MS_TO_SYSV_CALL
110   UNSPEC_PAUSE
111   UNSPEC_LEA_ADDR
112   UNSPEC_XBEGIN_ABORT
113   UNSPEC_STOS
114   UNSPEC_PEEPSIB
116   ;; For SSE/MMX support:
117   UNSPEC_FIX_NOTRUNC
118   UNSPEC_MASKMOV
119   UNSPEC_MOVMSK
120   UNSPEC_RCP
121   UNSPEC_RSQRT
122   UNSPEC_PSADBW
124   ;; Generic math support
125   UNSPEC_COPYSIGN
126   UNSPEC_IEEE_MIN       ; not commutative
127   UNSPEC_IEEE_MAX       ; not commutative
129   ;; x87 Floating point
130   UNSPEC_SIN
131   UNSPEC_COS
132   UNSPEC_FPATAN
133   UNSPEC_FYL2X
134   UNSPEC_FYL2XP1
135   UNSPEC_FRNDINT
136   UNSPEC_FIST
137   UNSPEC_F2XM1
138   UNSPEC_TAN
139   UNSPEC_FXAM
141   ;; x87 Rounding
142   UNSPEC_FRNDINT_FLOOR
143   UNSPEC_FRNDINT_CEIL
144   UNSPEC_FRNDINT_TRUNC
145   UNSPEC_FRNDINT_MASK_PM
146   UNSPEC_FIST_FLOOR
147   UNSPEC_FIST_CEIL
149   ;; x87 Double output FP
150   UNSPEC_SINCOS_COS
151   UNSPEC_SINCOS_SIN
152   UNSPEC_XTRACT_FRACT
153   UNSPEC_XTRACT_EXP
154   UNSPEC_FSCALE_FRACT
155   UNSPEC_FSCALE_EXP
156   UNSPEC_FPREM_F
157   UNSPEC_FPREM_U
158   UNSPEC_FPREM1_F
159   UNSPEC_FPREM1_U
161   UNSPEC_C2_FLAG
162   UNSPEC_FXAM_MEM
164   ;; SSP patterns
165   UNSPEC_SP_SET
166   UNSPEC_SP_TEST
167   UNSPEC_SP_TLS_SET
168   UNSPEC_SP_TLS_TEST
170   ;; For ROUND support
171   UNSPEC_ROUND
173   ;; For CRC32 support
174   UNSPEC_CRC32
176   ;; For BMI support
177   UNSPEC_BEXTR
179   ;; For BMI2 support
180   UNSPEC_PDEP
181   UNSPEC_PEXT
183   ;; For AVX512F support
184   UNSPEC_KMOV
187 (define_c_enum "unspecv" [
188   UNSPECV_BLOCKAGE
189   UNSPECV_STACK_PROBE
190   UNSPECV_PROBE_STACK_RANGE
191   UNSPECV_ALIGN
192   UNSPECV_PROLOGUE_USE
193   UNSPECV_SPLIT_STACK_RETURN
194   UNSPECV_CLD
195   UNSPECV_NOPS
196   UNSPECV_RDTSC
197   UNSPECV_RDTSCP
198   UNSPECV_RDPMC
199   UNSPECV_LLWP_INTRINSIC
200   UNSPECV_SLWP_INTRINSIC
201   UNSPECV_LWPVAL_INTRINSIC
202   UNSPECV_LWPINS_INTRINSIC
203   UNSPECV_RDFSBASE
204   UNSPECV_RDGSBASE
205   UNSPECV_WRFSBASE
206   UNSPECV_WRGSBASE
207   UNSPECV_FXSAVE
208   UNSPECV_FXRSTOR
209   UNSPECV_FXSAVE64
210   UNSPECV_FXRSTOR64
211   UNSPECV_XSAVE
212   UNSPECV_XRSTOR
213   UNSPECV_XSAVE64
214   UNSPECV_XRSTOR64
215   UNSPECV_XSAVEOPT
216   UNSPECV_XSAVEOPT64
217   UNSPECV_XSAVES
218   UNSPECV_XRSTORS
219   UNSPECV_XSAVES64
220   UNSPECV_XRSTORS64
221   UNSPECV_XSAVEC
222   UNSPECV_XSAVEC64
224   ;; For atomic compound assignments.
225   UNSPECV_FNSTENV
226   UNSPECV_FLDENV
227   UNSPECV_FNSTSW
228   UNSPECV_FNCLEX
230   ;; For RDRAND support
231   UNSPECV_RDRAND
233   ;; For RDSEED support
234   UNSPECV_RDSEED
236   ;; For RTM support
237   UNSPECV_XBEGIN
238   UNSPECV_XEND
239   UNSPECV_XABORT
240   UNSPECV_XTEST
242   UNSPECV_NLGR
244   ;; For CLFLUSHOPT support
245   UNSPECV_CLFLUSHOPT
248 ;; Constants to represent rounding modes in the ROUND instruction
249 (define_constants
250   [(ROUND_FLOOR                 0x1)
251    (ROUND_CEIL                  0x2)
252    (ROUND_TRUNC                 0x3)
253    (ROUND_MXCSR                 0x4)
254    (ROUND_NO_EXC                0x8)
255   ])
257 ;; Constants to represent AVX512F embeded rounding
258 (define_constants
259   [(ROUND_NEAREST_INT                   0)
260    (ROUND_NEG_INF                       1)
261    (ROUND_POS_INF                       2)
262    (ROUND_ZERO                          3)
263    (NO_ROUND                            4)
264    (ROUND_SAE                           8)
265   ])
267 ;; Constants to represent pcomtrue/pcomfalse variants
268 (define_constants
269   [(PCOM_FALSE                  0)
270    (PCOM_TRUE                   1)
271    (COM_FALSE_S                 2)
272    (COM_FALSE_P                 3)
273    (COM_TRUE_S                  4)
274    (COM_TRUE_P                  5)
275   ])
277 ;; Constants used in the XOP pperm instruction
278 (define_constants
279   [(PPERM_SRC                   0x00)   /* copy source */
280    (PPERM_INVERT                0x20)   /* invert source */
281    (PPERM_REVERSE               0x40)   /* bit reverse source */
282    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
283    (PPERM_ZERO                  0x80)   /* all 0's */
284    (PPERM_ONES                  0xa0)   /* all 1's */
285    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
286    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
287    (PPERM_SRC1                  0x00)   /* use first source byte */
288    (PPERM_SRC2                  0x10)   /* use second source byte */
289    ])
291 ;; Registers by name.
292 (define_constants
293   [(AX_REG                       0)
294    (DX_REG                       1)
295    (CX_REG                       2)
296    (BX_REG                       3)
297    (SI_REG                       4)
298    (DI_REG                       5)
299    (BP_REG                       6)
300    (SP_REG                       7)
301    (ST0_REG                      8)
302    (ST1_REG                      9)
303    (ST2_REG                     10)
304    (ST3_REG                     11)
305    (ST4_REG                     12)
306    (ST5_REG                     13)
307    (ST6_REG                     14)
308    (ST7_REG                     15)
309    (FLAGS_REG                   17)
310    (FPSR_REG                    18)
311    (FPCR_REG                    19)
312    (XMM0_REG                    21)
313    (XMM1_REG                    22)
314    (XMM2_REG                    23)
315    (XMM3_REG                    24)
316    (XMM4_REG                    25)
317    (XMM5_REG                    26)
318    (XMM6_REG                    27)
319    (XMM7_REG                    28)
320    (MM0_REG                     29)
321    (MM1_REG                     30)
322    (MM2_REG                     31)
323    (MM3_REG                     32)
324    (MM4_REG                     33)
325    (MM5_REG                     34)
326    (MM6_REG                     35)
327    (MM7_REG                     36)
328    (R8_REG                      37)
329    (R9_REG                      38)
330    (R10_REG                     39)
331    (R11_REG                     40)
332    (R12_REG                     41)
333    (R13_REG                     42)
334    (R14_REG                     43)
335    (R15_REG                     44)
336    (XMM8_REG                    45)
337    (XMM9_REG                    46)
338    (XMM10_REG                   47)
339    (XMM11_REG                   48)
340    (XMM12_REG                   49)
341    (XMM13_REG                   50)
342    (XMM14_REG                   51)
343    (XMM15_REG                   52)
344    (XMM16_REG                   53)
345    (XMM17_REG                   54)
346    (XMM18_REG                   55)
347    (XMM19_REG                   56)
348    (XMM20_REG                   57)
349    (XMM21_REG                   58)
350    (XMM22_REG                   59)
351    (XMM23_REG                   60)
352    (XMM24_REG                   61)
353    (XMM25_REG                   62)
354    (XMM26_REG                   63)
355    (XMM27_REG                   64)
356    (XMM28_REG                   65)
357    (XMM29_REG                   66)
358    (XMM30_REG                   67)
359    (XMM31_REG                   68)
360    (MASK0_REG                   69)
361    (MASK1_REG                   70)
362    (MASK2_REG                   71)
363    (MASK3_REG                   72)
364    (MASK4_REG                   73)
365    (MASK5_REG                   74)
366    (MASK6_REG                   75)
367    (MASK7_REG                   76)
368   ])
370 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
371 ;; from i386.c.
373 ;; In C guard expressions, put expressions which may be compile-time
374 ;; constants first.  This allows for better optimization.  For
375 ;; example, write "TARGET_64BIT && reload_completed", not
376 ;; "reload_completed && TARGET_64BIT".
379 ;; Processor type.
380 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
381                     atom,slm,generic,amdfam10,bdver1,bdver2,bdver3,bdver4,
382                     btver2"
383   (const (symbol_ref "ix86_schedule")))
385 ;; A basic instruction type.  Refinements due to arguments to be
386 ;; provided in other attributes.
387 (define_attr "type"
388   "other,multi,
389    alu,alu1,negnot,imov,imovx,lea,
390    incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
391    imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
392    push,pop,call,callv,leave,
393    str,bitmanip,
394    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
395    fxch,fistp,fisttp,frndint,
396    sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
397    ssemul,sseimul,ssediv,sselog,sselog1,
398    sseishft,sseishft1,ssecmp,ssecomi,
399    ssecvt,ssecvt1,sseicvt,sseins,
400    sseshuf,sseshuf1,ssemuladd,sse4arg,
401    lwp,mskmov,msklog,
402    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
403   (const_string "other"))
405 ;; Main data type used by the insn
406 (define_attr "mode"
407   "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
408   V2DF,V2SF,V1DF,V8DF"
409   (const_string "unknown"))
411 ;; The CPU unit operations uses.
412 (define_attr "unit" "integer,i387,sse,mmx,unknown"
413   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
414                           fxch,fistp,fisttp,frndint")
415            (const_string "i387")
416          (eq_attr "type" "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,mskmov")
421            (const_string "sse")
422          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
423            (const_string "mmx")
424          (eq_attr "type" "other")
425            (const_string "unknown")]
426          (const_string "integer")))
428 ;; The minimum required alignment of vector mode memory operands of the SSE
429 ;; (non-VEX/EVEX) instruction in bits, if it is different from
430 ;; GET_MODE_ALIGNMENT of the operand, otherwise 0.  If an instruction has
431 ;; multiple alternatives, this should be conservative maximum of those minimum
432 ;; required alignments.
433 (define_attr "ssememalign" "" (const_int 0))
435 ;; The (bounding maximum) length of an instruction immediate.
436 (define_attr "length_immediate" ""
437   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
438                           bitmanip,imulx,msklog,mskmov")
439            (const_int 0)
440          (eq_attr "unit" "i387,sse,mmx")
441            (const_int 0)
442          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
443                           rotate,rotatex,rotate1,imul,icmp,push,pop")
444            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
445          (eq_attr "type" "imov,test")
446            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
447          (eq_attr "type" "call")
448            (if_then_else (match_operand 0 "constant_call_address_operand")
449              (const_int 4)
450              (const_int 0))
451          (eq_attr "type" "callv")
452            (if_then_else (match_operand 1 "constant_call_address_operand")
453              (const_int 4)
454              (const_int 0))
455          ;; We don't know the size before shorten_branches.  Expect
456          ;; the instruction to fit for better scheduling.
457          (eq_attr "type" "ibr")
458            (const_int 1)
459          ]
460          (symbol_ref "/* Update immediate_length and other attributes! */
461                       gcc_unreachable (),1")))
463 ;; The (bounding maximum) length of an instruction address.
464 (define_attr "length_address" ""
465   (cond [(eq_attr "type" "str,other,multi,fxch")
466            (const_int 0)
467          (and (eq_attr "type" "call")
468               (match_operand 0 "constant_call_address_operand"))
469              (const_int 0)
470          (and (eq_attr "type" "callv")
471               (match_operand 1 "constant_call_address_operand"))
472              (const_int 0)
473          ]
474          (symbol_ref "ix86_attr_length_address_default (insn)")))
476 ;; Set when length prefix is used.
477 (define_attr "prefix_data16" ""
478   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
479            (const_int 0)
480          (eq_attr "mode" "HI")
481            (const_int 1)
482          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
483            (const_int 1)
484         ]
485         (const_int 0)))
487 ;; Set when string REP prefix is used.
488 (define_attr "prefix_rep" ""
489   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
490            (const_int 0)
491          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
492            (const_int 1)
493         ]
494         (const_int 0)))
496 ;; Set when 0f opcode prefix is used.
497 (define_attr "prefix_0f" ""
498   (if_then_else
499     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov")
500          (eq_attr "unit" "sse,mmx"))
501     (const_int 1)
502     (const_int 0)))
504 ;; Set when REX opcode prefix is used.
505 (define_attr "prefix_rex" ""
506   (cond [(not (match_test "TARGET_64BIT"))
507            (const_int 0)
508          (and (eq_attr "mode" "DI")
509               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
510                    (eq_attr "unit" "!mmx")))
511            (const_int 1)
512          (and (eq_attr "mode" "QI")
513               (match_test "x86_extended_QIreg_mentioned_p (insn)"))
514            (const_int 1)
515          (match_test "x86_extended_reg_mentioned_p (insn)")
516            (const_int 1)
517          (and (eq_attr "type" "imovx")
518               (match_operand:QI 1 "ext_QIreg_operand"))
519            (const_int 1)
520         ]
521         (const_int 0)))
523 ;; There are also additional prefixes in 3DNOW, SSSE3.
524 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
525 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
526 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
527 (define_attr "prefix_extra" ""
528   (cond [(eq_attr "type" "ssemuladd,sse4arg")
529            (const_int 2)
530          (eq_attr "type" "sseiadd1,ssecvt1")
531            (const_int 1)
532         ]
533         (const_int 0)))
535 ;; Prefix used: original, VEX or maybe VEX.
536 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
537   (cond [(eq_attr "mode" "OI,V8SF,V4DF")
538            (const_string "vex")
539          (eq_attr "mode" "XI,V16SF,V8DF")
540            (const_string "evex")
541         ]
542         (const_string "orig")))
544 ;; VEX W bit is used.
545 (define_attr "prefix_vex_w" "" (const_int 0))
547 ;; The length of VEX prefix
548 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
549 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
550 ;; still prefix_0f 1, with prefix_extra 1.
551 (define_attr "length_vex" ""
552   (if_then_else (and (eq_attr "prefix_0f" "1")
553                      (eq_attr "prefix_extra" "0"))
554     (if_then_else (eq_attr "prefix_vex_w" "1")
555       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
556       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
557     (if_then_else (eq_attr "prefix_vex_w" "1")
558       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
559       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
561 ;; 4-bytes evex prefix and 1 byte opcode.
562 (define_attr "length_evex" "" (const_int 5))
564 ;; Set when modrm byte is used.
565 (define_attr "modrm" ""
566   (cond [(eq_attr "type" "str,leave")
567            (const_int 0)
568          (eq_attr "unit" "i387")
569            (const_int 0)
570          (and (eq_attr "type" "incdec")
571               (and (not (match_test "TARGET_64BIT"))
572                    (ior (match_operand:SI 1 "register_operand")
573                         (match_operand:HI 1 "register_operand"))))
574            (const_int 0)
575          (and (eq_attr "type" "push")
576               (not (match_operand 1 "memory_operand")))
577            (const_int 0)
578          (and (eq_attr "type" "pop")
579               (not (match_operand 0 "memory_operand")))
580            (const_int 0)
581          (and (eq_attr "type" "imov")
582               (and (not (eq_attr "mode" "DI"))
583                    (ior (and (match_operand 0 "register_operand")
584                              (match_operand 1 "immediate_operand"))
585                         (ior (and (match_operand 0 "ax_reg_operand")
586                                   (match_operand 1 "memory_displacement_only_operand"))
587                              (and (match_operand 0 "memory_displacement_only_operand")
588                                   (match_operand 1 "ax_reg_operand"))))))
589            (const_int 0)
590          (and (eq_attr "type" "call")
591               (match_operand 0 "constant_call_address_operand"))
592              (const_int 0)
593          (and (eq_attr "type" "callv")
594               (match_operand 1 "constant_call_address_operand"))
595              (const_int 0)
596          (and (eq_attr "type" "alu,alu1,icmp,test")
597               (match_operand 0 "ax_reg_operand"))
598              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
599          ]
600          (const_int 1)))
602 ;; The (bounding maximum) length of an instruction in bytes.
603 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
604 ;; Later we may want to split them and compute proper length as for
605 ;; other insns.
606 (define_attr "length" ""
607   (cond [(eq_attr "type" "other,multi,fistp,frndint")
608            (const_int 16)
609          (eq_attr "type" "fcmp")
610            (const_int 4)
611          (eq_attr "unit" "i387")
612            (plus (const_int 2)
613                  (plus (attr "prefix_data16")
614                        (attr "length_address")))
615          (ior (eq_attr "prefix" "evex")
616               (and (ior (eq_attr "prefix" "maybe_evex")
617                         (eq_attr "prefix" "maybe_vex"))
618                    (match_test "TARGET_AVX512F")))
619            (plus (attr "length_evex")
620                  (plus (attr "length_immediate")
621                        (plus (attr "modrm")
622                              (attr "length_address"))))
623          (ior (eq_attr "prefix" "vex")
624               (and (ior (eq_attr "prefix" "maybe_vex")
625                         (eq_attr "prefix" "maybe_evex"))
626                    (match_test "TARGET_AVX")))
627            (plus (attr "length_vex")
628                  (plus (attr "length_immediate")
629                        (plus (attr "modrm")
630                              (attr "length_address"))))]
631          (plus (plus (attr "modrm")
632                      (plus (attr "prefix_0f")
633                            (plus (attr "prefix_rex")
634                                  (plus (attr "prefix_extra")
635                                        (const_int 1)))))
636                (plus (attr "prefix_rep")
637                      (plus (attr "prefix_data16")
638                            (plus (attr "length_immediate")
639                                  (attr "length_address")))))))
641 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
642 ;; `store' if there is a simple memory reference therein, or `unknown'
643 ;; if the instruction is complex.
645 (define_attr "memory" "none,load,store,both,unknown"
646   (cond [(eq_attr "type" "other,multi,str,lwp")
647            (const_string "unknown")
648          (eq_attr "type" "lea,fcmov,fpspc")
649            (const_string "none")
650          (eq_attr "type" "fistp,leave")
651            (const_string "both")
652          (eq_attr "type" "frndint")
653            (const_string "load")
654          (eq_attr "type" "push")
655            (if_then_else (match_operand 1 "memory_operand")
656              (const_string "both")
657              (const_string "store"))
658          (eq_attr "type" "pop")
659            (if_then_else (match_operand 0 "memory_operand")
660              (const_string "both")
661              (const_string "load"))
662          (eq_attr "type" "setcc")
663            (if_then_else (match_operand 0 "memory_operand")
664              (const_string "store")
665              (const_string "none"))
666          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
667            (if_then_else (ior (match_operand 0 "memory_operand")
668                               (match_operand 1 "memory_operand"))
669              (const_string "load")
670              (const_string "none"))
671          (eq_attr "type" "ibr")
672            (if_then_else (match_operand 0 "memory_operand")
673              (const_string "load")
674              (const_string "none"))
675          (eq_attr "type" "call")
676            (if_then_else (match_operand 0 "constant_call_address_operand")
677              (const_string "none")
678              (const_string "load"))
679          (eq_attr "type" "callv")
680            (if_then_else (match_operand 1 "constant_call_address_operand")
681              (const_string "none")
682              (const_string "load"))
683          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
684               (match_operand 1 "memory_operand"))
685            (const_string "both")
686          (and (match_operand 0 "memory_operand")
687               (match_operand 1 "memory_operand"))
688            (const_string "both")
689          (match_operand 0 "memory_operand")
690            (const_string "store")
691          (match_operand 1 "memory_operand")
692            (const_string "load")
693          (and (eq_attr "type"
694                  "!alu1,negnot,ishift1,
695                    imov,imovx,icmp,test,bitmanip,
696                    fmov,fcmp,fsgn,
697                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
698                    sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
699                    mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog")
700               (match_operand 2 "memory_operand"))
701            (const_string "load")
702          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
703               (match_operand 3 "memory_operand"))
704            (const_string "load")
705         ]
706         (const_string "none")))
708 ;; Indicates if an instruction has both an immediate and a displacement.
710 (define_attr "imm_disp" "false,true,unknown"
711   (cond [(eq_attr "type" "other,multi")
712            (const_string "unknown")
713          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
714               (and (match_operand 0 "memory_displacement_operand")
715                    (match_operand 1 "immediate_operand")))
716            (const_string "true")
717          (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
718               (and (match_operand 0 "memory_displacement_operand")
719                    (match_operand 2 "immediate_operand")))
720            (const_string "true")
721         ]
722         (const_string "false")))
724 ;; Indicates if an FP operation has an integer source.
726 (define_attr "fp_int_src" "false,true"
727   (const_string "false"))
729 ;; Defines rounding mode of an FP operation.
731 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
732   (const_string "any"))
734 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
735 (define_attr "use_carry" "0,1" (const_string "0"))
737 ;; Define attribute to indicate unaligned ssemov insns
738 (define_attr "movu" "0,1" (const_string "0"))
740 ;; Used to control the "enabled" attribute on a per-instruction basis.
741 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
742                     sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
743                     avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
744                     fma_avx512f,avx512bw,noavx512bw,avx512dq,noavx512dq"
745   (const_string "base"))
747 (define_attr "enabled" ""
748   (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
749          (eq_attr "isa" "x64_sse4")
750            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
751          (eq_attr "isa" "x64_sse4_noavx")
752            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
753          (eq_attr "isa" "x64_avx")
754            (symbol_ref "TARGET_64BIT && TARGET_AVX")
755          (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
756          (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
757          (eq_attr "isa" "sse2_noavx")
758            (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
759          (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
760          (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
761          (eq_attr "isa" "sse4_noavx")
762            (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
763          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
764          (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
765          (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
766          (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
767          (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
768          (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
769          (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
770          (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
771          (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
772          (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
773          (eq_attr "isa" "fma_avx512f")
774            (symbol_ref "TARGET_FMA || TARGET_AVX512F")
775          (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
776          (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
777          (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
778          (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
779         ]
780         (const_int 1)))
782 ;; Describe a user's asm statement.
783 (define_asm_attributes
784   [(set_attr "length" "128")
785    (set_attr "type" "multi")])
787 (define_code_iterator plusminus [plus minus])
789 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
791 (define_code_iterator multdiv [mult div])
793 ;; Base name for define_insn
794 (define_code_attr plusminus_insn
795   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
796    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
798 ;; Base name for insn mnemonic.
799 (define_code_attr plusminus_mnemonic
800   [(plus "add") (ss_plus "adds") (us_plus "addus")
801    (minus "sub") (ss_minus "subs") (us_minus "subus")])
802 (define_code_attr plusminus_carry_mnemonic
803   [(plus "adc") (minus "sbb")])
804 (define_code_attr multdiv_mnemonic
805   [(mult "mul") (div "div")])
807 ;; Mark commutative operators as such in constraints.
808 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
809                         (minus "") (ss_minus "") (us_minus "")])
811 ;; Mapping of max and min
812 (define_code_iterator maxmin [smax smin umax umin])
814 ;; Mapping of signed max and min
815 (define_code_iterator smaxmin [smax smin])
817 ;; Mapping of unsigned max and min
818 (define_code_iterator umaxmin [umax umin])
820 ;; Base name for integer and FP insn mnemonic
821 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
822                               (umax "maxu") (umin "minu")])
823 (define_code_attr maxmin_float [(smax "max") (smin "min")])
825 ;; Mapping of logic operators
826 (define_code_iterator any_logic [and ior xor])
827 (define_code_iterator any_or [ior xor])
828 (define_code_iterator fpint_logic [and xor])
830 ;; Base name for insn mnemonic.
831 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
833 ;; Mapping of logic-shift operators
834 (define_code_iterator any_lshift [ashift lshiftrt])
836 ;; Mapping of shift-right operators
837 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
839 ;; Mapping of all shift operators
840 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
842 ;; Base name for define_insn
843 (define_code_attr shift_insn
844   [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
846 ;; Base name for insn mnemonic.
847 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
848 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
850 ;; Mapping of rotate operators
851 (define_code_iterator any_rotate [rotate rotatert])
853 ;; Base name for define_insn
854 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
856 ;; Base name for insn mnemonic.
857 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
859 ;; Mapping of abs neg operators
860 (define_code_iterator absneg [abs neg])
862 ;; Base name for x87 insn mnemonic.
863 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
865 ;; Used in signed and unsigned widening multiplications.
866 (define_code_iterator any_extend [sign_extend zero_extend])
868 ;; Prefix for insn menmonic.
869 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
871 ;; Prefix for define_insn
872 (define_code_attr u [(sign_extend "") (zero_extend "u")])
873 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
874 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
876 ;; Used in signed and unsigned truncations.
877 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
878 ;; Instruction suffix for truncations.
879 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
881 ;; Used in signed and unsigned fix.
882 (define_code_iterator any_fix [fix unsigned_fix])
883 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
884 (define_code_attr ufix_bool [(fix "false") (unsigned_fix "true")])
886 ;; Used in signed and unsigned float.
887 (define_code_iterator any_float [float unsigned_float])
888 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
890 ;; All integer modes.
891 (define_mode_iterator SWI1248x [QI HI SI DI])
893 ;; All integer modes without QImode.
894 (define_mode_iterator SWI248x [HI SI DI])
896 ;; All integer modes without QImode and HImode.
897 (define_mode_iterator SWI48x [SI DI])
899 ;; All integer modes without SImode and DImode.
900 (define_mode_iterator SWI12 [QI HI])
902 ;; All integer modes without DImode.
903 (define_mode_iterator SWI124 [QI HI SI])
905 ;; All integer modes without QImode and DImode.
906 (define_mode_iterator SWI24 [HI SI])
908 ;; Single word integer modes.
909 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
911 ;; Single word integer modes without QImode.
912 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
914 ;; Single word integer modes without QImode and HImode.
915 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
917 ;; All math-dependant single and double word integer modes.
918 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
919                              (HI "TARGET_HIMODE_MATH")
920                              SI DI (TI "TARGET_64BIT")])
922 ;; Math-dependant single word integer modes.
923 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
924                             (HI "TARGET_HIMODE_MATH")
925                             SI (DI "TARGET_64BIT")])
927 ;; Math-dependant integer modes without DImode.
928 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
929                                (HI "TARGET_HIMODE_MATH")
930                                SI])
932 ;; Math-dependant single word integer modes without QImode.
933 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
934                                SI (DI "TARGET_64BIT")])
936 ;; Double word integer modes.
937 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
938                            (TI "TARGET_64BIT")])
940 ;; GET_MODE_SIZE for selected modes.  As GET_MODE_SIZE is not
941 ;; compile time constant, it is faster to use <MODE_SIZE> than
942 ;; GET_MODE_SIZE (<MODE>mode).  For XFmode which depends on
943 ;; command line options just use GET_MODE_SIZE macro.
944 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
945                              (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
946                              (V16QI "16") (V32QI "32") (V64QI "64")
947                              (V8HI "16") (V16HI "32") (V32HI "64")
948                              (V4SI "16") (V8SI "32") (V16SI "64")
949                              (V2DI "16") (V4DI "32") (V8DI "64")
950                              (V1TI "16") (V2TI "32") (V4TI "64")
951                              (V2DF "16") (V4DF "32") (V8DF "64")
952                              (V4SF "16") (V8SF "32") (V16SF "64")])
954 ;; Double word integer modes as mode attribute.
955 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
956 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
958 ;; Half mode for double word integer modes.
959 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
960                             (DI "TARGET_64BIT")])
962 ;; Instruction suffix for integer modes.
963 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
965 ;; Instruction suffix for masks.
966 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
968 ;; Pointer size prefix for integer modes (Intel asm dialect)
969 (define_mode_attr iptrsize [(QI "BYTE")
970                             (HI "WORD")
971                             (SI "DWORD")
972                             (DI "QWORD")])
974 ;; Register class for integer modes.
975 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
977 ;; Immediate operand constraint for integer modes.
978 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
980 ;; General operand constraint for word modes.
981 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
983 ;; Immediate operand constraint for double integer modes.
984 (define_mode_attr di [(SI "nF") (DI "e")])
986 ;; Immediate operand constraint for shifts.
987 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
989 ;; General operand predicate for integer modes.
990 (define_mode_attr general_operand
991         [(QI "general_operand")
992          (HI "general_operand")
993          (SI "x86_64_general_operand")
994          (DI "x86_64_general_operand")
995          (TI "x86_64_general_operand")])
997 ;; General sign extend operand predicate for integer modes,
998 ;; which disallows VOIDmode operands and thus it is suitable
999 ;; for use inside sign_extend.
1000 (define_mode_attr general_sext_operand
1001         [(QI "sext_operand")
1002          (HI "sext_operand")
1003          (SI "x86_64_sext_operand")
1004          (DI "x86_64_sext_operand")])
1006 ;; General sign/zero extend operand predicate for integer modes.
1007 (define_mode_attr general_szext_operand
1008         [(QI "general_operand")
1009          (HI "general_operand")
1010          (SI "x86_64_szext_general_operand")
1011          (DI "x86_64_szext_general_operand")])
1013 ;; Immediate operand predicate for integer modes.
1014 (define_mode_attr immediate_operand
1015         [(QI "immediate_operand")
1016          (HI "immediate_operand")
1017          (SI "x86_64_immediate_operand")
1018          (DI "x86_64_immediate_operand")])
1020 ;; Nonmemory operand predicate for integer modes.
1021 (define_mode_attr nonmemory_operand
1022         [(QI "nonmemory_operand")
1023          (HI "nonmemory_operand")
1024          (SI "x86_64_nonmemory_operand")
1025          (DI "x86_64_nonmemory_operand")])
1027 ;; Operand predicate for shifts.
1028 (define_mode_attr shift_operand
1029         [(QI "nonimmediate_operand")
1030          (HI "nonimmediate_operand")
1031          (SI "nonimmediate_operand")
1032          (DI "shiftdi_operand")
1033          (TI "register_operand")])
1035 ;; Operand predicate for shift argument.
1036 (define_mode_attr shift_immediate_operand
1037         [(QI "const_1_to_31_operand")
1038          (HI "const_1_to_31_operand")
1039          (SI "const_1_to_31_operand")
1040          (DI "const_1_to_63_operand")])
1042 ;; Input operand predicate for arithmetic left shifts.
1043 (define_mode_attr ashl_input_operand
1044         [(QI "nonimmediate_operand")
1045          (HI "nonimmediate_operand")
1046          (SI "nonimmediate_operand")
1047          (DI "ashldi_input_operand")
1048          (TI "reg_or_pm1_operand")])
1050 ;; SSE and x87 SFmode and DFmode floating point modes
1051 (define_mode_iterator MODEF [SF DF])
1053 ;; All x87 floating point modes
1054 (define_mode_iterator X87MODEF [SF DF XF])
1056 ;; SSE instruction suffix for various modes
1057 (define_mode_attr ssemodesuffix
1058   [(SF "ss") (DF "sd")
1059    (V16SF "ps") (V8DF "pd")
1060    (V8SF "ps") (V4DF "pd")
1061    (V4SF "ps") (V2DF "pd")
1062    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1063    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1064    (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1066 ;; SSE vector suffix for floating point modes
1067 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1069 ;; SSE vector mode corresponding to a scalar mode
1070 (define_mode_attr ssevecmode
1071   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1072 (define_mode_attr ssevecmodelower
1073   [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1075 ;; Instruction suffix for REX 64bit operators.
1076 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1078 ;; This mode iterator allows :P to be used for patterns that operate on
1079 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
1080 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1082 ;; This mode iterator allows :W to be used for patterns that operate on
1083 ;; word_mode sized quantities.
1084 (define_mode_iterator W
1085   [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1087 ;; This mode iterator allows :PTR to be used for patterns that operate on
1088 ;; ptr_mode sized quantities.
1089 (define_mode_iterator PTR
1090   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1092 ;; Scheduling descriptions
1094 (include "pentium.md")
1095 (include "ppro.md")
1096 (include "k6.md")
1097 (include "athlon.md")
1098 (include "bdver1.md")
1099 (include "bdver3.md")
1100 (include "btver2.md")
1101 (include "geode.md")
1102 (include "atom.md")
1103 (include "slm.md")
1104 (include "core2.md")
1107 ;; Operand and operator predicates and constraints
1109 (include "predicates.md")
1110 (include "constraints.md")
1113 ;; Compare and branch/compare and store instructions.
1115 (define_expand "cbranch<mode>4"
1116   [(set (reg:CC FLAGS_REG)
1117         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1118                     (match_operand:SDWIM 2 "<general_operand>")))
1119    (set (pc) (if_then_else
1120                (match_operator 0 "ordered_comparison_operator"
1121                 [(reg:CC FLAGS_REG) (const_int 0)])
1122                (label_ref (match_operand 3))
1123                (pc)))]
1124   ""
1126   if (MEM_P (operands[1]) && MEM_P (operands[2]))
1127     operands[1] = force_reg (<MODE>mode, operands[1]);
1128   ix86_expand_branch (GET_CODE (operands[0]),
1129                       operands[1], operands[2], operands[3]);
1130   DONE;
1133 (define_expand "cstore<mode>4"
1134   [(set (reg:CC FLAGS_REG)
1135         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1136                     (match_operand:SWIM 3 "<general_operand>")))
1137    (set (match_operand:QI 0 "register_operand")
1138         (match_operator 1 "ordered_comparison_operator"
1139           [(reg:CC FLAGS_REG) (const_int 0)]))]
1140   ""
1142   if (MEM_P (operands[2]) && MEM_P (operands[3]))
1143     operands[2] = force_reg (<MODE>mode, operands[2]);
1144   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1145                      operands[2], operands[3]);
1146   DONE;
1149 (define_expand "cmp<mode>_1"
1150   [(set (reg:CC FLAGS_REG)
1151         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1152                     (match_operand:SWI48 1 "<general_operand>")))])
1154 (define_insn "*cmp<mode>_ccno_1"
1155   [(set (reg FLAGS_REG)
1156         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1157                  (match_operand:SWI 1 "const0_operand")))]
1158   "ix86_match_ccmode (insn, CCNOmode)"
1159   "@
1160    test{<imodesuffix>}\t%0, %0
1161    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1162   [(set_attr "type" "test,icmp")
1163    (set_attr "length_immediate" "0,1")
1164    (set_attr "mode" "<MODE>")])
1166 (define_insn "*cmp<mode>_1"
1167   [(set (reg FLAGS_REG)
1168         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1169                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1170   "ix86_match_ccmode (insn, CCmode)"
1171   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1172   [(set_attr "type" "icmp")
1173    (set_attr "mode" "<MODE>")])
1175 (define_insn "*cmp<mode>_minus_1"
1176   [(set (reg FLAGS_REG)
1177         (compare
1178           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1179                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1180           (const_int 0)))]
1181   "ix86_match_ccmode (insn, CCGOCmode)"
1182   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1183   [(set_attr "type" "icmp")
1184    (set_attr "mode" "<MODE>")])
1186 (define_insn "*cmpqi_ext_1"
1187   [(set (reg FLAGS_REG)
1188         (compare
1189           (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1190           (subreg:QI
1191             (zero_extract:SI
1192               (match_operand 1 "ext_register_operand" "Q,Q")
1193               (const_int 8)
1194               (const_int 8)) 0)))]
1195   "ix86_match_ccmode (insn, CCmode)"
1196   "cmp{b}\t{%h1, %0|%0, %h1}"
1197   [(set_attr "isa" "*,nox64")
1198    (set_attr "type" "icmp")
1199    (set_attr "mode" "QI")])
1201 (define_insn "*cmpqi_ext_2"
1202   [(set (reg FLAGS_REG)
1203         (compare
1204           (subreg:QI
1205             (zero_extract:SI
1206               (match_operand 0 "ext_register_operand" "Q")
1207               (const_int 8)
1208               (const_int 8)) 0)
1209           (match_operand:QI 1 "const0_operand")))]
1210   "ix86_match_ccmode (insn, CCNOmode)"
1211   "test{b}\t%h0, %h0"
1212   [(set_attr "type" "test")
1213    (set_attr "length_immediate" "0")
1214    (set_attr "mode" "QI")])
1216 (define_expand "cmpqi_ext_3"
1217   [(set (reg:CC FLAGS_REG)
1218         (compare:CC
1219           (subreg:QI
1220             (zero_extract:SI
1221               (match_operand 0 "ext_register_operand")
1222               (const_int 8)
1223               (const_int 8)) 0)
1224           (match_operand:QI 1 "const_int_operand")))])
1226 (define_insn "*cmpqi_ext_3"
1227   [(set (reg FLAGS_REG)
1228         (compare
1229           (subreg:QI
1230             (zero_extract:SI
1231               (match_operand 0 "ext_register_operand" "Q,Q")
1232               (const_int 8)
1233               (const_int 8)) 0)
1234           (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1235   "ix86_match_ccmode (insn, CCmode)"
1236   "cmp{b}\t{%1, %h0|%h0, %1}"
1237   [(set_attr "isa" "*,nox64")
1238    (set_attr "type" "icmp")
1239    (set_attr "modrm" "1")
1240    (set_attr "mode" "QI")])
1242 (define_insn "*cmpqi_ext_4"
1243   [(set (reg FLAGS_REG)
1244         (compare
1245           (subreg:QI
1246             (zero_extract:SI
1247               (match_operand 0 "ext_register_operand" "Q")
1248               (const_int 8)
1249               (const_int 8)) 0)
1250           (subreg:QI
1251             (zero_extract:SI
1252               (match_operand 1 "ext_register_operand" "Q")
1253               (const_int 8)
1254               (const_int 8)) 0)))]
1255   "ix86_match_ccmode (insn, CCmode)"
1256   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1257   [(set_attr "type" "icmp")
1258    (set_attr "mode" "QI")])
1260 ;; These implement float point compares.
1261 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1262 ;; which would allow mix and match FP modes on the compares.  Which is what
1263 ;; the old patterns did, but with many more of them.
1265 (define_expand "cbranchxf4"
1266   [(set (reg:CC FLAGS_REG)
1267         (compare:CC (match_operand:XF 1 "nonmemory_operand")
1268                     (match_operand:XF 2 "nonmemory_operand")))
1269    (set (pc) (if_then_else
1270               (match_operator 0 "ix86_fp_comparison_operator"
1271                [(reg:CC FLAGS_REG)
1272                 (const_int 0)])
1273               (label_ref (match_operand 3))
1274               (pc)))]
1275   "TARGET_80387"
1277   ix86_expand_branch (GET_CODE (operands[0]),
1278                       operands[1], operands[2], operands[3]);
1279   DONE;
1282 (define_expand "cstorexf4"
1283   [(set (reg:CC FLAGS_REG)
1284         (compare:CC (match_operand:XF 2 "nonmemory_operand")
1285                     (match_operand:XF 3 "nonmemory_operand")))
1286    (set (match_operand:QI 0 "register_operand")
1287               (match_operator 1 "ix86_fp_comparison_operator"
1288                [(reg:CC FLAGS_REG)
1289                 (const_int 0)]))]
1290   "TARGET_80387"
1292   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1293                      operands[2], operands[3]);
1294   DONE;
1297 (define_expand "cbranch<mode>4"
1298   [(set (reg:CC FLAGS_REG)
1299         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1300                     (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1301    (set (pc) (if_then_else
1302               (match_operator 0 "ix86_fp_comparison_operator"
1303                [(reg:CC FLAGS_REG)
1304                 (const_int 0)])
1305               (label_ref (match_operand 3))
1306               (pc)))]
1307   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1309   ix86_expand_branch (GET_CODE (operands[0]),
1310                       operands[1], operands[2], operands[3]);
1311   DONE;
1314 (define_expand "cstore<mode>4"
1315   [(set (reg:CC FLAGS_REG)
1316         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1317                     (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1318    (set (match_operand:QI 0 "register_operand")
1319               (match_operator 1 "ix86_fp_comparison_operator"
1320                [(reg:CC FLAGS_REG)
1321                 (const_int 0)]))]
1322   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1324   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1325                      operands[2], operands[3]);
1326   DONE;
1329 (define_expand "cbranchcc4"
1330   [(set (pc) (if_then_else
1331               (match_operator 0 "comparison_operator"
1332                [(match_operand 1 "flags_reg_operand")
1333                 (match_operand 2 "const0_operand")])
1334               (label_ref (match_operand 3))
1335               (pc)))]
1336   ""
1338   ix86_expand_branch (GET_CODE (operands[0]),
1339                       operands[1], operands[2], operands[3]);
1340   DONE;
1343 (define_expand "cstorecc4"
1344   [(set (match_operand:QI 0 "register_operand")
1345               (match_operator 1 "comparison_operator"
1346                [(match_operand 2 "flags_reg_operand")
1347                 (match_operand 3 "const0_operand")]))]
1348   ""
1350   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1351                      operands[2], operands[3]);
1352   DONE;
1356 ;; FP compares, step 1:
1357 ;; Set the FP condition codes.
1359 ;; CCFPmode     compare with exceptions
1360 ;; CCFPUmode    compare with no exceptions
1362 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1363 ;; used to manage the reg stack popping would not be preserved.
1365 (define_insn "*cmp<mode>_0_i387"
1366   [(set (match_operand:HI 0 "register_operand" "=a")
1367         (unspec:HI
1368           [(compare:CCFP
1369              (match_operand:X87MODEF 1 "register_operand" "f")
1370              (match_operand:X87MODEF 2 "const0_operand"))]
1371         UNSPEC_FNSTSW))]
1372   "TARGET_80387"
1373   "* return output_fp_compare (insn, operands, false, false);"
1374   [(set_attr "type" "multi")
1375    (set_attr "unit" "i387")
1376    (set_attr "mode" "<MODE>")])
1378 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1379   [(set (reg:CCFP FLAGS_REG)
1380         (compare:CCFP
1381           (match_operand:X87MODEF 1 "register_operand" "f")
1382           (match_operand:X87MODEF 2 "const0_operand")))
1383    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1384   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1385   "#"
1386   "&& reload_completed"
1387   [(set (match_dup 0)
1388         (unspec:HI
1389           [(compare:CCFP (match_dup 1)(match_dup 2))]
1390         UNSPEC_FNSTSW))
1391    (set (reg:CC FLAGS_REG)
1392         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1393   ""
1394   [(set_attr "type" "multi")
1395    (set_attr "unit" "i387")
1396    (set_attr "mode" "<MODE>")])
1398 (define_insn "*cmpxf_i387"
1399   [(set (match_operand:HI 0 "register_operand" "=a")
1400         (unspec:HI
1401           [(compare:CCFP
1402              (match_operand:XF 1 "register_operand" "f")
1403              (match_operand:XF 2 "register_operand" "f"))]
1404           UNSPEC_FNSTSW))]
1405   "TARGET_80387"
1406   "* return output_fp_compare (insn, operands, false, false);"
1407   [(set_attr "type" "multi")
1408    (set_attr "unit" "i387")
1409    (set_attr "mode" "XF")])
1411 (define_insn_and_split "*cmpxf_cc_i387"
1412   [(set (reg:CCFP FLAGS_REG)
1413         (compare:CCFP
1414           (match_operand:XF 1 "register_operand" "f")
1415           (match_operand:XF 2 "register_operand" "f")))
1416    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1417   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1418   "#"
1419   "&& reload_completed"
1420   [(set (match_dup 0)
1421         (unspec:HI
1422           [(compare:CCFP (match_dup 1)(match_dup 2))]
1423         UNSPEC_FNSTSW))
1424    (set (reg:CC FLAGS_REG)
1425         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1426   ""
1427   [(set_attr "type" "multi")
1428    (set_attr "unit" "i387")
1429    (set_attr "mode" "XF")])
1431 (define_insn "*cmp<mode>_i387"
1432   [(set (match_operand:HI 0 "register_operand" "=a")
1433         (unspec:HI
1434           [(compare:CCFP
1435              (match_operand:MODEF 1 "register_operand" "f")
1436              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1437           UNSPEC_FNSTSW))]
1438   "TARGET_80387"
1439   "* return output_fp_compare (insn, operands, false, false);"
1440   [(set_attr "type" "multi")
1441    (set_attr "unit" "i387")
1442    (set_attr "mode" "<MODE>")])
1444 (define_insn_and_split "*cmp<mode>_cc_i387"
1445   [(set (reg:CCFP FLAGS_REG)
1446         (compare:CCFP
1447           (match_operand:MODEF 1 "register_operand" "f")
1448           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1449    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1450   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1451   "#"
1452   "&& reload_completed"
1453   [(set (match_dup 0)
1454         (unspec:HI
1455           [(compare:CCFP (match_dup 1)(match_dup 2))]
1456         UNSPEC_FNSTSW))
1457    (set (reg:CC FLAGS_REG)
1458         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1459   ""
1460   [(set_attr "type" "multi")
1461    (set_attr "unit" "i387")
1462    (set_attr "mode" "<MODE>")])
1464 (define_insn "*cmpu<mode>_i387"
1465   [(set (match_operand:HI 0 "register_operand" "=a")
1466         (unspec:HI
1467           [(compare:CCFPU
1468              (match_operand:X87MODEF 1 "register_operand" "f")
1469              (match_operand:X87MODEF 2 "register_operand" "f"))]
1470           UNSPEC_FNSTSW))]
1471   "TARGET_80387"
1472   "* return output_fp_compare (insn, operands, false, true);"
1473   [(set_attr "type" "multi")
1474    (set_attr "unit" "i387")
1475    (set_attr "mode" "<MODE>")])
1477 (define_insn_and_split "*cmpu<mode>_cc_i387"
1478   [(set (reg:CCFPU FLAGS_REG)
1479         (compare:CCFPU
1480           (match_operand:X87MODEF 1 "register_operand" "f")
1481           (match_operand:X87MODEF 2 "register_operand" "f")))
1482    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1483   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1484   "#"
1485   "&& reload_completed"
1486   [(set (match_dup 0)
1487         (unspec:HI
1488           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1489         UNSPEC_FNSTSW))
1490    (set (reg:CC FLAGS_REG)
1491         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1492   ""
1493   [(set_attr "type" "multi")
1494    (set_attr "unit" "i387")
1495    (set_attr "mode" "<MODE>")])
1497 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1498   [(set (match_operand:HI 0 "register_operand" "=a")
1499         (unspec:HI
1500           [(compare:CCFP
1501              (match_operand:X87MODEF 1 "register_operand" "f")
1502              (match_operator:X87MODEF 3 "float_operator"
1503                [(match_operand:SWI24 2 "memory_operand" "m")]))]
1504           UNSPEC_FNSTSW))]
1505   "TARGET_80387
1506    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1507        || optimize_function_for_size_p (cfun))"
1508   "* return output_fp_compare (insn, operands, false, false);"
1509   [(set_attr "type" "multi")
1510    (set_attr "unit" "i387")
1511    (set_attr "fp_int_src" "true")
1512    (set_attr "mode" "<SWI24:MODE>")])
1514 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1515   [(set (reg:CCFP FLAGS_REG)
1516         (compare:CCFP
1517           (match_operand:X87MODEF 1 "register_operand" "f")
1518           (match_operator:X87MODEF 3 "float_operator"
1519             [(match_operand:SWI24 2 "memory_operand" "m")])))
1520    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1521   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1522    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1523        || optimize_function_for_size_p (cfun))"
1524   "#"
1525   "&& reload_completed"
1526   [(set (match_dup 0)
1527         (unspec:HI
1528           [(compare:CCFP
1529              (match_dup 1)
1530              (match_op_dup 3 [(match_dup 2)]))]
1531         UNSPEC_FNSTSW))
1532    (set (reg:CC FLAGS_REG)
1533         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1534   ""
1535   [(set_attr "type" "multi")
1536    (set_attr "unit" "i387")
1537    (set_attr "fp_int_src" "true")
1538    (set_attr "mode" "<SWI24:MODE>")])
1540 ;; FP compares, step 2
1541 ;; Move the fpsw to ax.
1543 (define_insn "x86_fnstsw_1"
1544   [(set (match_operand:HI 0 "register_operand" "=a")
1545         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1546   "TARGET_80387"
1547   "fnstsw\t%0"
1548   [(set_attr "length" "2")
1549    (set_attr "mode" "SI")
1550    (set_attr "unit" "i387")])
1552 ;; FP compares, step 3
1553 ;; Get ax into flags, general case.
1555 (define_insn "x86_sahf_1"
1556   [(set (reg:CC FLAGS_REG)
1557         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1558                    UNSPEC_SAHF))]
1559   "TARGET_SAHF"
1561 #ifndef HAVE_AS_IX86_SAHF
1562   if (TARGET_64BIT)
1563     return ASM_BYTE "0x9e";
1564   else
1565 #endif
1566   return "sahf";
1568   [(set_attr "length" "1")
1569    (set_attr "athlon_decode" "vector")
1570    (set_attr "amdfam10_decode" "direct")
1571    (set_attr "bdver1_decode" "direct")
1572    (set_attr "mode" "SI")])
1574 ;; Pentium Pro can do steps 1 through 3 in one go.
1575 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1576 ;; (these i387 instructions set flags directly)
1578 (define_mode_iterator FPCMP [CCFP CCFPU])
1579 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1581 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1582   [(set (reg:FPCMP FLAGS_REG)
1583         (compare:FPCMP
1584           (match_operand:MODEF 0 "register_operand" "f,x")
1585           (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1586   "TARGET_MIX_SSE_I387
1587    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1588   "* return output_fp_compare (insn, operands, true,
1589                                <FPCMP:MODE>mode == CCFPUmode);"
1590   [(set_attr "type" "fcmp,ssecomi")
1591    (set_attr "prefix" "orig,maybe_vex")
1592    (set_attr "mode" "<MODEF:MODE>")
1593    (set (attr "prefix_rep")
1594         (if_then_else (eq_attr "type" "ssecomi")
1595                       (const_string "0")
1596                       (const_string "*")))
1597    (set (attr "prefix_data16")
1598         (cond [(eq_attr "type" "fcmp")
1599                  (const_string "*")
1600                (eq_attr "mode" "DF")
1601                  (const_string "1")
1602               ]
1603               (const_string "0")))
1604    (set_attr "athlon_decode" "vector")
1605    (set_attr "amdfam10_decode" "direct")
1606    (set_attr "bdver1_decode" "double")])
1608 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1609   [(set (reg:FPCMP FLAGS_REG)
1610         (compare:FPCMP
1611           (match_operand:MODEF 0 "register_operand" "x")
1612           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1613   "TARGET_SSE_MATH
1614    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1615   "* return output_fp_compare (insn, operands, true,
1616                                <FPCMP:MODE>mode == CCFPUmode);"
1617   [(set_attr "type" "ssecomi")
1618    (set_attr "prefix" "maybe_vex")
1619    (set_attr "mode" "<MODEF:MODE>")
1620    (set_attr "prefix_rep" "0")
1621    (set (attr "prefix_data16")
1622         (if_then_else (eq_attr "mode" "DF")
1623                       (const_string "1")
1624                       (const_string "0")))
1625    (set_attr "athlon_decode" "vector")
1626    (set_attr "amdfam10_decode" "direct")
1627    (set_attr "bdver1_decode" "double")])
1629 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1630   [(set (reg:FPCMP FLAGS_REG)
1631         (compare:FPCMP
1632           (match_operand:X87MODEF 0 "register_operand" "f")
1633           (match_operand:X87MODEF 1 "register_operand" "f")))]
1634   "TARGET_80387 && TARGET_CMOVE
1635    && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1636   "* return output_fp_compare (insn, operands, true,
1637                                <FPCMP:MODE>mode == CCFPUmode);"
1638   [(set_attr "type" "fcmp")
1639    (set_attr "mode" "<X87MODEF:MODE>")
1640    (set_attr "athlon_decode" "vector")
1641    (set_attr "amdfam10_decode" "direct")
1642    (set_attr "bdver1_decode" "double")])
1644 ;; Push/pop instructions.
1646 (define_insn "*push<mode>2"
1647   [(set (match_operand:DWI 0 "push_operand" "=<")
1648         (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1649   ""
1650   "#"
1651   [(set_attr "type" "multi")
1652    (set_attr "mode" "<MODE>")])
1654 (define_split
1655   [(set (match_operand:TI 0 "push_operand")
1656         (match_operand:TI 1 "general_operand"))]
1657   "TARGET_64BIT && reload_completed
1658    && !SSE_REG_P (operands[1])"
1659   [(const_int 0)]
1660   "ix86_split_long_move (operands); DONE;")
1662 (define_insn "*pushdi2_rex64"
1663   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1664         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1665   "TARGET_64BIT"
1666   "@
1667    push{q}\t%1
1668    #"
1669   [(set_attr "type" "push,multi")
1670    (set_attr "mode" "DI")])
1672 ;; Convert impossible pushes of immediate to existing instructions.
1673 ;; First try to get scratch register and go through it.  In case this
1674 ;; fails, push sign extended lower part first and then overwrite
1675 ;; upper part by 32bit move.
1676 (define_peephole2
1677   [(match_scratch:DI 2 "r")
1678    (set (match_operand:DI 0 "push_operand")
1679         (match_operand:DI 1 "immediate_operand"))]
1680   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1681    && !x86_64_immediate_operand (operands[1], DImode)"
1682   [(set (match_dup 2) (match_dup 1))
1683    (set (match_dup 0) (match_dup 2))])
1685 ;; We need to define this as both peepholer and splitter for case
1686 ;; peephole2 pass is not run.
1687 ;; "&& 1" is needed to keep it from matching the previous pattern.
1688 (define_peephole2
1689   [(set (match_operand:DI 0 "push_operand")
1690         (match_operand:DI 1 "immediate_operand"))]
1691   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1692    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1693   [(set (match_dup 0) (match_dup 1))
1694    (set (match_dup 2) (match_dup 3))]
1696   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1698   operands[1] = gen_lowpart (DImode, operands[2]);
1699   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1700                                                    GEN_INT (4)));
1703 (define_split
1704   [(set (match_operand:DI 0 "push_operand")
1705         (match_operand:DI 1 "immediate_operand"))]
1706   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1707                     ? epilogue_completed : reload_completed)
1708    && !symbolic_operand (operands[1], DImode)
1709    && !x86_64_immediate_operand (operands[1], DImode)"
1710   [(set (match_dup 0) (match_dup 1))
1711    (set (match_dup 2) (match_dup 3))]
1713   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1715   operands[1] = gen_lowpart (DImode, operands[2]);
1716   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1717                                                    GEN_INT (4)));
1720 (define_split
1721   [(set (match_operand:DI 0 "push_operand")
1722         (match_operand:DI 1 "general_operand"))]
1723   "!TARGET_64BIT && reload_completed
1724    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1725   [(const_int 0)]
1726   "ix86_split_long_move (operands); DONE;")
1728 (define_insn "*pushsi2"
1729   [(set (match_operand:SI 0 "push_operand" "=<")
1730         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1731   "!TARGET_64BIT"
1732   "push{l}\t%1"
1733   [(set_attr "type" "push")
1734    (set_attr "mode" "SI")])
1736 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1737 ;; "push a byte/word".  But actually we use pushl, which has the effect
1738 ;; of rounding the amount pushed up to a word.
1740 ;; For TARGET_64BIT we always round up to 8 bytes.
1741 (define_insn "*push<mode>2_rex64"
1742   [(set (match_operand:SWI124 0 "push_operand" "=X")
1743         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1744   "TARGET_64BIT"
1745   "push{q}\t%q1"
1746   [(set_attr "type" "push")
1747    (set_attr "mode" "DI")])
1749 (define_insn "*push<mode>2"
1750   [(set (match_operand:SWI12 0 "push_operand" "=X")
1751         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1752   "!TARGET_64BIT"
1753   "push{l}\t%k1"
1754   [(set_attr "type" "push")
1755    (set_attr "mode" "SI")])
1757 (define_insn "*push<mode>2_prologue"
1758   [(set (match_operand:W 0 "push_operand" "=<")
1759         (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1760    (clobber (mem:BLK (scratch)))]
1761   ""
1762   "push{<imodesuffix>}\t%1"
1763   [(set_attr "type" "push")
1764    (set_attr "mode" "<MODE>")])
1766 (define_insn "*pop<mode>1"
1767   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1768         (match_operand:W 1 "pop_operand" ">"))]
1769   ""
1770   "pop{<imodesuffix>}\t%0"
1771   [(set_attr "type" "pop")
1772    (set_attr "mode" "<MODE>")])
1774 (define_insn "*pop<mode>1_epilogue"
1775   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1776         (match_operand:W 1 "pop_operand" ">"))
1777    (clobber (mem:BLK (scratch)))]
1778   ""
1779   "pop{<imodesuffix>}\t%0"
1780   [(set_attr "type" "pop")
1781    (set_attr "mode" "<MODE>")])
1783 (define_insn "*pushfl<mode>2"
1784   [(set (match_operand:W 0 "push_operand" "=<")
1785         (match_operand:W 1 "flags_reg_operand"))]
1786   ""
1787   "pushf{<imodesuffix>}"
1788   [(set_attr "type" "push")
1789    (set_attr "mode" "<MODE>")])
1791 (define_insn "*popfl<mode>1"
1792   [(set (match_operand:W 0 "flags_reg_operand")
1793         (match_operand:W 1 "pop_operand" ">"))]
1794   ""
1795   "popf{<imodesuffix>}"
1796   [(set_attr "type" "pop")
1797    (set_attr "mode" "<MODE>")])
1800 ;; Move instructions.
1802 (define_expand "movxi"
1803   [(set (match_operand:XI 0 "nonimmediate_operand")
1804         (match_operand:XI 1 "general_operand"))]
1805   "TARGET_AVX512F"
1806   "ix86_expand_move (XImode, operands); DONE;")
1808 ;; Reload patterns to support multi-word load/store
1809 ;; with non-offsetable address.
1810 (define_expand "reload_noff_store"
1811   [(parallel [(match_operand 0 "memory_operand" "=m")
1812               (match_operand 1 "register_operand" "r")
1813               (match_operand:DI 2 "register_operand" "=&r")])]
1814   "TARGET_64BIT"
1816   rtx mem = operands[0];
1817   rtx addr = XEXP (mem, 0);
1819   emit_move_insn (operands[2], addr);
1820   mem = replace_equiv_address_nv (mem, operands[2]);
1822   emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
1823   DONE;
1826 (define_expand "reload_noff_load"
1827   [(parallel [(match_operand 0 "register_operand" "=r")
1828               (match_operand 1 "memory_operand" "m")
1829               (match_operand:DI 2 "register_operand" "=r")])]
1830   "TARGET_64BIT"
1832   rtx mem = operands[1];
1833   rtx addr = XEXP (mem, 0);
1835   emit_move_insn (operands[2], addr);
1836   mem = replace_equiv_address_nv (mem, operands[2]);
1838   emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
1839   DONE;
1842 (define_expand "movoi"
1843   [(set (match_operand:OI 0 "nonimmediate_operand")
1844         (match_operand:OI 1 "general_operand"))]
1845   "TARGET_AVX"
1846   "ix86_expand_move (OImode, operands); DONE;")
1848 (define_expand "movti"
1849   [(set (match_operand:TI 0 "nonimmediate_operand")
1850         (match_operand:TI 1 "nonimmediate_operand"))]
1851   "TARGET_64BIT || TARGET_SSE"
1853   if (TARGET_64BIT)
1854     ix86_expand_move (TImode, operands);
1855   else
1856     ix86_expand_vector_move (TImode, operands);
1857   DONE;
1860 ;; This expands to what emit_move_complex would generate if we didn't
1861 ;; have a movti pattern.  Having this avoids problems with reload on
1862 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1863 ;; to have around all the time.
1864 (define_expand "movcdi"
1865   [(set (match_operand:CDI 0 "nonimmediate_operand")
1866         (match_operand:CDI 1 "general_operand"))]
1867   ""
1869   if (push_operand (operands[0], CDImode))
1870     emit_move_complex_push (CDImode, operands[0], operands[1]);
1871   else
1872     emit_move_complex_parts (operands[0], operands[1]);
1873   DONE;
1876 (define_expand "mov<mode>"
1877   [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1878         (match_operand:SWI1248x 1 "general_operand"))]
1879   ""
1880   "ix86_expand_move (<MODE>mode, operands); DONE;")
1882 (define_insn "*mov<mode>_xor"
1883   [(set (match_operand:SWI48 0 "register_operand" "=r")
1884         (match_operand:SWI48 1 "const0_operand"))
1885    (clobber (reg:CC FLAGS_REG))]
1886   "reload_completed"
1887   "xor{l}\t%k0, %k0"
1888   [(set_attr "type" "alu1")
1889    (set_attr "mode" "SI")
1890    (set_attr "length_immediate" "0")])
1892 (define_insn "*mov<mode>_or"
1893   [(set (match_operand:SWI48 0 "register_operand" "=r")
1894         (match_operand:SWI48 1 "const_int_operand"))
1895    (clobber (reg:CC FLAGS_REG))]
1896   "reload_completed
1897    && operands[1] == constm1_rtx"
1898   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1899   [(set_attr "type" "alu1")
1900    (set_attr "mode" "<MODE>")
1901    (set_attr "length_immediate" "1")])
1903 (define_insn "*movxi_internal_avx512f"
1904   [(set (match_operand:XI 0 "nonimmediate_operand" "=x,x ,m")
1905         (match_operand:XI 1 "vector_move_operand"  "C ,xm,x"))]
1906   "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1908   switch (which_alternative)
1909     {
1910     case 0:
1911       return standard_sse_constant_opcode (insn, operands[1]);
1912     case 1:
1913     case 2:
1914       if (misaligned_operand (operands[0], XImode)
1915           || misaligned_operand (operands[1], XImode))
1916         return "vmovdqu32\t{%1, %0|%0, %1}";
1917       else
1918         return "vmovdqa32\t{%1, %0|%0, %1}";
1919     default:
1920       gcc_unreachable ();
1921     }
1923   [(set_attr "type" "sselog1,ssemov,ssemov")
1924    (set_attr "prefix" "evex")
1925    (set_attr "mode" "XI")])
1927 (define_insn "*movoi_internal_avx"
1928   [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,m")
1929         (match_operand:OI 1 "vector_move_operand"  "C ,vm,v"))]
1930   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1932   switch (get_attr_type (insn))
1933     {
1934     case TYPE_SSELOG1:
1935       return standard_sse_constant_opcode (insn, operands[1]);
1937     case TYPE_SSEMOV:
1938       if (misaligned_operand (operands[0], OImode)
1939           || misaligned_operand (operands[1], OImode))
1940         {
1941           if (get_attr_mode (insn) == MODE_V8SF)
1942             return "vmovups\t{%1, %0|%0, %1}";
1943           else if (get_attr_mode (insn) == MODE_XI)
1944             return "vmovdqu32\t{%1, %0|%0, %1}";
1945           else
1946             return "vmovdqu\t{%1, %0|%0, %1}";
1947         }
1948       else
1949         {
1950           if (get_attr_mode (insn) == MODE_V8SF)
1951             return "vmovaps\t{%1, %0|%0, %1}";
1952           else if (get_attr_mode (insn) == MODE_XI)
1953             return "vmovdqa32\t{%1, %0|%0, %1}";
1954           else
1955             return "vmovdqa\t{%1, %0|%0, %1}";
1956         }
1958     default:
1959       gcc_unreachable ();
1960     }
1962   [(set_attr "type" "sselog1,ssemov,ssemov")
1963    (set_attr "prefix" "vex")
1964    (set (attr "mode")
1965         (cond [(ior (match_operand 0 "ext_sse_reg_operand")
1966                     (match_operand 1 "ext_sse_reg_operand"))
1967                  (const_string "XI")
1968                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1969                  (const_string "V8SF")
1970                (and (eq_attr "alternative" "2")
1971                     (match_test "TARGET_SSE_TYPELESS_STORES"))
1972                  (const_string "V8SF")
1973               ]
1974               (const_string "OI")))])
1976 (define_insn "*movti_internal"
1977   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,m")
1978         (match_operand:TI 1 "general_operand"      "riFo,re,C,vm,v"))]
1979   "(TARGET_64BIT || TARGET_SSE)
1980    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1982   switch (get_attr_type (insn))
1983     {
1984     case TYPE_MULTI:
1985       return "#";
1987     case TYPE_SSELOG1:
1988       return standard_sse_constant_opcode (insn, operands[1]);
1990     case TYPE_SSEMOV:
1991       /* TDmode values are passed as TImode on the stack.  Moving them
1992          to stack may result in unaligned memory access.  */
1993       if (misaligned_operand (operands[0], TImode)
1994           || misaligned_operand (operands[1], TImode))
1995         {
1996           if (get_attr_mode (insn) == MODE_V4SF)
1997             return "%vmovups\t{%1, %0|%0, %1}";
1998           else if (get_attr_mode (insn) == MODE_XI)
1999             return "vmovdqu32\t{%1, %0|%0, %1}";
2000           else
2001             return "%vmovdqu\t{%1, %0|%0, %1}";
2002         }
2003       else
2004         {
2005           if (get_attr_mode (insn) == MODE_V4SF)
2006             return "%vmovaps\t{%1, %0|%0, %1}";
2007           else if (get_attr_mode (insn) == MODE_XI)
2008             return "vmovdqa32\t{%1, %0|%0, %1}";
2009           else
2010             return "%vmovdqa\t{%1, %0|%0, %1}";
2011         }
2013     default:
2014       gcc_unreachable ();
2015     }
2017   [(set_attr "isa" "x64,x64,*,*,*")
2018    (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
2019    (set (attr "prefix")
2020      (if_then_else (eq_attr "type" "sselog1,ssemov")
2021        (const_string "maybe_vex")
2022        (const_string "orig")))
2023    (set (attr "mode")
2024         (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2025                     (match_operand 1 "ext_sse_reg_operand"))
2026                  (const_string "XI")
2027                (eq_attr "alternative" "0,1")
2028                  (const_string "DI")
2029                (ior (not (match_test "TARGET_SSE2"))
2030                     (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2031                  (const_string "V4SF")
2032                (and (eq_attr "alternative" "4")
2033                     (match_test "TARGET_SSE_TYPELESS_STORES"))
2034                  (const_string "V4SF")
2035                (match_test "TARGET_AVX")
2036                  (const_string "TI")
2037                (match_test "optimize_function_for_size_p (cfun)")
2038                  (const_string "V4SF")
2039                ]
2040                (const_string "TI")))])
2042 (define_split
2043   [(set (match_operand:TI 0 "nonimmediate_operand")
2044         (match_operand:TI 1 "general_operand"))]
2045   "reload_completed
2046    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
2047   [(const_int 0)]
2048   "ix86_split_long_move (operands); DONE;")
2050 (define_insn "*movdi_internal"
2051   [(set (match_operand:DI 0 "nonimmediate_operand"
2052     "=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")
2053         (match_operand:DI 1 "general_operand"
2054     "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"))]
2055   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2057   switch (get_attr_type (insn))
2058     {
2059     case TYPE_MSKMOV:
2060       return "kmovq\t{%1, %0|%0, %1}";
2062     case TYPE_MULTI:
2063       return "#";
2065     case TYPE_MMX:
2066       return "pxor\t%0, %0";
2068     case TYPE_MMXMOV:
2069       /* Handle broken assemblers that require movd instead of movq.  */
2070       if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2071           && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2072         return "movd\t{%1, %0|%0, %1}";
2073       return "movq\t{%1, %0|%0, %1}";
2075     case TYPE_SSELOG1:
2076       if (GENERAL_REG_P (operands[0]))
2077         return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2079       return standard_sse_constant_opcode (insn, operands[1]);
2081     case TYPE_SSEMOV:
2082       switch (get_attr_mode (insn))
2083         {
2084         case MODE_DI:
2085           /* Handle broken assemblers that require movd instead of movq.  */
2086           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2087               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2088             return "%vmovd\t{%1, %0|%0, %1}";
2089           return "%vmovq\t{%1, %0|%0, %1}";
2090         case MODE_TI:
2091           return "%vmovdqa\t{%1, %0|%0, %1}";
2092         case MODE_XI:
2093           return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2095         case MODE_V2SF:
2096           gcc_assert (!TARGET_AVX);
2097           return "movlps\t{%1, %0|%0, %1}";
2098         case MODE_V4SF:
2099           return "%vmovaps\t{%1, %0|%0, %1}";
2101         default:
2102           gcc_unreachable ();
2103         }
2105     case TYPE_SSECVT:
2106       if (SSE_REG_P (operands[0]))
2107         return "movq2dq\t{%1, %0|%0, %1}";
2108       else
2109         return "movdq2q\t{%1, %0|%0, %1}";
2111     case TYPE_LEA:
2112       return "lea{q}\t{%E1, %0|%0, %E1}";
2114     case TYPE_IMOV:
2115       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2116       if (get_attr_mode (insn) == MODE_SI)
2117         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2118       else if (which_alternative == 4)
2119         return "movabs{q}\t{%1, %0|%0, %1}";
2120       else if (ix86_use_lea_for_mov (insn, operands))
2121         return "lea{q}\t{%E1, %0|%0, %E1}";
2122       else
2123         return "mov{q}\t{%1, %0|%0, %1}";
2125     default:
2126       gcc_unreachable ();
2127     }
2129   [(set (attr "isa")
2130      (cond [(eq_attr "alternative" "0,1")
2131               (const_string "nox64")
2132             (eq_attr "alternative" "2,3,4,5,10,11,16,18,21,23")
2133               (const_string "x64")
2134             (eq_attr "alternative" "17")
2135               (const_string "x64_sse4")
2136            ]
2137            (const_string "*")))
2138    (set (attr "type")
2139      (cond [(eq_attr "alternative" "0,1")
2140               (const_string "multi")
2141             (eq_attr "alternative" "6")
2142               (const_string "mmx")
2143             (eq_attr "alternative" "7,8,9,10,11")
2144               (const_string "mmxmov")
2145             (eq_attr "alternative" "12,17")
2146               (const_string "sselog1")
2147             (eq_attr "alternative" "13,14,15,16,18")
2148               (const_string "ssemov")
2149             (eq_attr "alternative" "19,20")
2150               (const_string "ssecvt")
2151             (eq_attr "alternative" "21,22,23,24")
2152               (const_string "mskmov")
2153             (match_operand 1 "pic_32bit_operand")
2154               (const_string "lea")
2155            ]
2156            (const_string "imov")))
2157    (set (attr "modrm")
2158      (if_then_else
2159        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2160          (const_string "0")
2161          (const_string "*")))
2162    (set (attr "length_immediate")
2163      (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2164               (const_string "8")
2165             (eq_attr "alternative" "17")
2166               (const_string "1")
2167            ]
2168            (const_string "*")))
2169    (set (attr "prefix_rex")
2170      (if_then_else (eq_attr "alternative" "10,11,16,17,18")
2171        (const_string "1")
2172        (const_string "*")))
2173    (set (attr "prefix_extra")
2174      (if_then_else (eq_attr "alternative" "17")
2175        (const_string "1")
2176        (const_string "*")))
2177    (set (attr "prefix")
2178      (if_then_else (eq_attr "type" "sselog1,ssemov")
2179        (const_string "maybe_vex")
2180        (const_string "orig")))
2181    (set (attr "prefix_data16")
2182      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2183        (const_string "1")
2184        (const_string "*")))
2185    (set (attr "mode")
2186      (cond [(eq_attr "alternative" "2")
2187               (const_string "SI")
2188             (eq_attr "alternative" "12,13")
2189               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2190                           (match_operand 1 "ext_sse_reg_operand"))
2191                        (const_string "XI")
2192                      (ior (not (match_test "TARGET_SSE2"))
2193                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2194                        (const_string "V4SF")
2195                      (match_test "TARGET_AVX")
2196                        (const_string "TI")
2197                      (match_test "optimize_function_for_size_p (cfun)")
2198                        (const_string "V4SF")
2199                     ]
2200                     (const_string "TI"))
2202             (and (eq_attr "alternative" "14,15")
2203                  (not (match_test "TARGET_SSE2")))
2204               (const_string "V2SF")
2205             (eq_attr "alternative" "17")
2206               (const_string "TI")
2207            ]
2208            (const_string "DI")))])
2210 (define_split
2211   [(set (match_operand:DI 0 "nonimmediate_operand")
2212         (match_operand:DI 1 "general_operand"))]
2213   "!TARGET_64BIT && reload_completed
2214    && !(MMX_REG_P (operands[0])
2215         || SSE_REG_P (operands[0])
2216         || MASK_REG_P (operands[0]))
2217    && !(MMX_REG_P (operands[1])
2218         || SSE_REG_P (operands[1])
2219         || MASK_REG_P (operands[1]))"
2220   [(const_int 0)]
2221   "ix86_split_long_move (operands); DONE;")
2223 (define_insn "*movsi_internal"
2224   [(set (match_operand:SI 0 "nonimmediate_operand"
2225                         "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi,*k  ,*rm")
2226         (match_operand:SI 1 "general_operand"
2227                         "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r   ,*krm,*k"))]
2228   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2230   switch (get_attr_type (insn))
2231     {
2232     case TYPE_SSELOG1:
2233       if (GENERAL_REG_P (operands[0]))
2234         return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2236       return standard_sse_constant_opcode (insn, operands[1]);
2238     case TYPE_MSKMOV:
2239       return "kmovd\t{%1, %0|%0, %1}";
2241     case TYPE_SSEMOV:
2242       switch (get_attr_mode (insn))
2243         {
2244         case MODE_SI:
2245           return "%vmovd\t{%1, %0|%0, %1}";
2246         case MODE_TI:
2247           return "%vmovdqa\t{%1, %0|%0, %1}";
2248         case MODE_XI:
2249           return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2251         case MODE_V4SF:
2252           return "%vmovaps\t{%1, %0|%0, %1}";
2254         case MODE_SF:
2255           gcc_assert (!TARGET_AVX);
2256           return "movss\t{%1, %0|%0, %1}";
2258         default:
2259           gcc_unreachable ();
2260         }
2262     case TYPE_MMX:
2263       return "pxor\t%0, %0";
2265     case TYPE_MMXMOV:
2266       switch (get_attr_mode (insn))
2267         {
2268         case MODE_DI:
2269           return "movq\t{%1, %0|%0, %1}";
2270         case MODE_SI:
2271           return "movd\t{%1, %0|%0, %1}";
2273         default:
2274           gcc_unreachable ();
2275         }
2277     case TYPE_LEA:
2278       return "lea{l}\t{%E1, %0|%0, %E1}";
2280     case TYPE_IMOV:
2281       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2282       if (ix86_use_lea_for_mov (insn, operands))
2283         return "lea{l}\t{%E1, %0|%0, %E1}";
2284       else
2285         return "mov{l}\t{%1, %0|%0, %1}";
2287     default:
2288       gcc_unreachable ();
2289     }
2291   [(set (attr "isa")
2292      (if_then_else (eq_attr "alternative" "11")
2293        (const_string "sse4")
2294        (const_string "*")))
2295    (set (attr "type")
2296      (cond [(eq_attr "alternative" "2")
2297               (const_string "mmx")
2298             (eq_attr "alternative" "3,4,5")
2299               (const_string "mmxmov")
2300             (eq_attr "alternative" "6,11")
2301               (const_string "sselog1")
2302             (eq_attr "alternative" "7,8,9,10,12")
2303               (const_string "ssemov")
2304             (eq_attr "alternative" "13,14")
2305               (const_string "mskmov")
2306             (match_operand 1 "pic_32bit_operand")
2307               (const_string "lea")
2308            ]
2309            (const_string "imov")))
2310    (set (attr "length_immediate")
2311      (if_then_else (eq_attr "alternative" "11")
2312        (const_string "1")
2313        (const_string "*")))
2314    (set (attr "prefix_extra")
2315      (if_then_else (eq_attr "alternative" "11")
2316        (const_string "1")
2317        (const_string "*")))
2318    (set (attr "prefix")
2319      (if_then_else (eq_attr "type" "sselog1,ssemov")
2320        (const_string "maybe_vex")
2321        (const_string "orig")))
2322    (set (attr "prefix_data16")
2323      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2324        (const_string "1")
2325        (const_string "*")))
2326    (set (attr "mode")
2327      (cond [(eq_attr "alternative" "2,3")
2328               (const_string "DI")
2329             (eq_attr "alternative" "6,7")
2330               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2331                           (match_operand 1 "ext_sse_reg_operand"))
2332                        (const_string "XI")
2333                      (ior (not (match_test "TARGET_SSE2"))
2334                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2335                        (const_string "V4SF")
2336                      (match_test "TARGET_AVX")
2337                        (const_string "TI")
2338                      (match_test "optimize_function_for_size_p (cfun)")
2339                        (const_string "V4SF")
2340                     ]
2341                     (const_string "TI"))
2343             (and (eq_attr "alternative" "8,9")
2344                  (not (match_test "TARGET_SSE2")))
2345               (const_string "SF")
2346             (eq_attr "alternative" "11")
2347               (const_string "TI")
2348            ]
2349            (const_string "SI")))])
2351 (define_insn "kmovw"
2352   [(set (match_operand:HI 0 "nonimmediate_operand" "=k,k")
2353         (unspec:HI
2354           [(match_operand:HI 1 "nonimmediate_operand" "rm,k")]
2355           UNSPEC_KMOV))]
2356   "!(MEM_P (operands[0]) && MEM_P (operands[1])) && TARGET_AVX512F"
2357   "@
2358    kmovw\t{%k1, %0|%0, %k1}
2359    kmovw\t{%1, %0|%0, %1}";
2360   [(set_attr "mode" "HI")
2361    (set_attr "type" "mskmov")
2362    (set_attr "prefix" "vex")])
2365 (define_insn "*movhi_internal"
2366   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k,rm")
2367         (match_operand:HI 1 "general_operand"      "r ,rn,rm,rn,rm,k,k"))]
2368   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2370   switch (get_attr_type (insn))
2371     {
2372     case TYPE_IMOVX:
2373       /* movzwl is faster than movw on p2 due to partial word stalls,
2374          though not as fast as an aligned movl.  */
2375       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2377     case TYPE_MSKMOV:
2378       switch (which_alternative)
2379         {
2380         case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2381         case 5: return "kmovw\t{%1, %0|%0, %1}";
2382         case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2383         default: gcc_unreachable ();
2384         }
2386     default:
2387       if (get_attr_mode (insn) == MODE_SI)
2388         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2389       else
2390         return "mov{w}\t{%1, %0|%0, %1}";
2391     }
2393   [(set (attr "type")
2394      (cond [(match_test "optimize_function_for_size_p (cfun)")
2395               (const_string "imov")
2396             (and (eq_attr "alternative" "0")
2397                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2398                       (not (match_test "TARGET_HIMODE_MATH"))))
2399               (const_string "imov")
2400             (and (eq_attr "alternative" "1,2")
2401                  (match_operand:HI 1 "aligned_operand"))
2402               (const_string "imov")
2403             (eq_attr "alternative" "4,5,6")
2404               (const_string "mskmov")
2405             (and (match_test "TARGET_MOVX")
2406                  (eq_attr "alternative" "0,2"))
2407               (const_string "imovx")
2408            ]
2409            (const_string "imov")))
2410     (set (attr "prefix")
2411       (if_then_else (eq_attr "alternative" "4,5,6")
2412         (const_string "vex")
2413         (const_string "orig")))
2414     (set (attr "mode")
2415       (cond [(eq_attr "type" "imovx")
2416                (const_string "SI")
2417              (and (eq_attr "alternative" "1,2")
2418                   (match_operand:HI 1 "aligned_operand"))
2419                (const_string "SI")
2420              (and (eq_attr "alternative" "0")
2421                   (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2422                        (not (match_test "TARGET_HIMODE_MATH"))))
2423                (const_string "SI")
2424             ]
2425             (const_string "HI")))])
2427 ;; Situation is quite tricky about when to choose full sized (SImode) move
2428 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2429 ;; partial register dependency machines (such as AMD Athlon), where QImode
2430 ;; moves issue extra dependency and for partial register stalls machines
2431 ;; that don't use QImode patterns (and QImode move cause stall on the next
2432 ;; instruction).
2434 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2435 ;; register stall machines with, where we use QImode instructions, since
2436 ;; partial register stall can be caused there.  Then we use movzx.
2438 (define_insn "*movqi_internal"
2439   [(set (match_operand:QI 0 "nonimmediate_operand"
2440                         "=q,q ,q ,r,r ,?r,m ,k,k,r")
2441         (match_operand:QI 1 "general_operand"
2442                         "q ,qn,qm,q,rn,qm,qn,r ,k,k"))]
2443   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2445   switch (get_attr_type (insn))
2446     {
2447     case TYPE_IMOVX:
2448       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2449       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2451     case TYPE_MSKMOV:
2452       switch (which_alternative)
2453         {
2454         case 7: return TARGET_AVX512BW ? "kmovb\t{%k1, %0|%0, %k1}"
2455                                        : "kmovw\t{%k1, %0|%0, %k1}";
2456         case 8: return TARGET_AVX512BW ? "kmovb\t{%1, %0|%0, %1}"
2457                                        : "kmovw\t{%1, %0|%0, %1}";
2458         case 9: return TARGET_AVX512BW ? "kmovb\t{%1, %k0|%k0, %1}"
2459                                        : "kmovw\t{%1, %k0|%k0, %1}";
2460         default: gcc_unreachable ();
2461         }
2463     default:
2464       if (get_attr_mode (insn) == MODE_SI)
2465         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2466       else
2467         return "mov{b}\t{%1, %0|%0, %1}";
2468     }
2470   [(set (attr "type")
2471      (cond [(and (eq_attr "alternative" "5")
2472                  (not (match_operand:QI 1 "aligned_operand")))
2473               (const_string "imovx")
2474             (match_test "optimize_function_for_size_p (cfun)")
2475               (const_string "imov")
2476             (and (eq_attr "alternative" "3")
2477                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2478                       (not (match_test "TARGET_QIMODE_MATH"))))
2479               (const_string "imov")
2480             (eq_attr "alternative" "3,5")
2481               (const_string "imovx")
2482             (eq_attr "alternative" "7,8,9")
2483               (const_string "mskmov")
2484             (and (match_test "TARGET_MOVX")
2485                  (eq_attr "alternative" "2"))
2486               (const_string "imovx")
2487            ]
2488            (const_string "imov")))
2489    (set (attr "prefix")
2490      (if_then_else (eq_attr "alternative" "7,8,9")
2491        (const_string "vex")
2492        (const_string "orig")))
2493    (set (attr "mode")
2494       (cond [(eq_attr "alternative" "3,4,5")
2495                (const_string "SI")
2496              (eq_attr "alternative" "6")
2497                (const_string "QI")
2498              (eq_attr "type" "imovx")
2499                (const_string "SI")
2500              (and (eq_attr "type" "imov")
2501                   (and (eq_attr "alternative" "0,1")
2502                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2503                             (and (not (match_test "optimize_function_for_size_p (cfun)"))
2504                                  (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2505                (const_string "SI")
2506              ;; Avoid partial register stalls when not using QImode arithmetic
2507              (and (eq_attr "type" "imov")
2508                   (and (eq_attr "alternative" "0,1")
2509                        (and (match_test "TARGET_PARTIAL_REG_STALL")
2510                             (not (match_test "TARGET_QIMODE_MATH")))))
2511                (const_string "SI")
2512            ]
2513            (const_string "QI")))])
2515 ;; Stores and loads of ax to arbitrary constant address.
2516 ;; We fake an second form of instruction to force reload to load address
2517 ;; into register when rax is not available
2518 (define_insn "*movabs<mode>_1"
2519   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2520         (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2521   "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2522   "@
2523    movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2524    mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2525   [(set_attr "type" "imov")
2526    (set_attr "modrm" "0,*")
2527    (set_attr "length_address" "8,0")
2528    (set_attr "length_immediate" "0,*")
2529    (set_attr "memory" "store")
2530    (set_attr "mode" "<MODE>")])
2532 (define_insn "*movabs<mode>_2"
2533   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2534         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2535   "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2536   "@
2537    movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2538    mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2539   [(set_attr "type" "imov")
2540    (set_attr "modrm" "0,*")
2541    (set_attr "length_address" "8,0")
2542    (set_attr "length_immediate" "0")
2543    (set_attr "memory" "load")
2544    (set_attr "mode" "<MODE>")])
2546 (define_insn "*swap<mode>"
2547   [(set (match_operand:SWI48 0 "register_operand" "+r")
2548         (match_operand:SWI48 1 "register_operand" "+r"))
2549    (set (match_dup 1)
2550         (match_dup 0))]
2551   ""
2552   "xchg{<imodesuffix>}\t%1, %0"
2553   [(set_attr "type" "imov")
2554    (set_attr "mode" "<MODE>")
2555    (set_attr "pent_pair" "np")
2556    (set_attr "athlon_decode" "vector")
2557    (set_attr "amdfam10_decode" "double")
2558    (set_attr "bdver1_decode" "double")])
2560 (define_insn "*swap<mode>_1"
2561   [(set (match_operand:SWI12 0 "register_operand" "+r")
2562         (match_operand:SWI12 1 "register_operand" "+r"))
2563    (set (match_dup 1)
2564         (match_dup 0))]
2565   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2566   "xchg{l}\t%k1, %k0"
2567   [(set_attr "type" "imov")
2568    (set_attr "mode" "SI")
2569    (set_attr "pent_pair" "np")
2570    (set_attr "athlon_decode" "vector")
2571    (set_attr "amdfam10_decode" "double")
2572    (set_attr "bdver1_decode" "double")])
2574 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2575 ;; is disabled for AMDFAM10
2576 (define_insn "*swap<mode>_2"
2577   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2578         (match_operand:SWI12 1 "register_operand" "+<r>"))
2579    (set (match_dup 1)
2580         (match_dup 0))]
2581   "TARGET_PARTIAL_REG_STALL"
2582   "xchg{<imodesuffix>}\t%1, %0"
2583   [(set_attr "type" "imov")
2584    (set_attr "mode" "<MODE>")
2585    (set_attr "pent_pair" "np")
2586    (set_attr "athlon_decode" "vector")])
2588 (define_expand "movstrict<mode>"
2589   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2590         (match_operand:SWI12 1 "general_operand"))]
2591   ""
2593   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2594     FAIL;
2595   if (GET_CODE (operands[0]) == SUBREG
2596       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2597     FAIL;
2598   /* Don't generate memory->memory moves, go through a register */
2599   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2600     operands[1] = force_reg (<MODE>mode, operands[1]);
2603 (define_insn "*movstrict<mode>_1"
2604   [(set (strict_low_part
2605           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2606         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2607   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2608    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2609   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2610   [(set_attr "type" "imov")
2611    (set_attr "mode" "<MODE>")])
2613 (define_insn "*movstrict<mode>_xor"
2614   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2615         (match_operand:SWI12 1 "const0_operand"))
2616    (clobber (reg:CC FLAGS_REG))]
2617   "reload_completed"
2618   "xor{<imodesuffix>}\t%0, %0"
2619   [(set_attr "type" "alu1")
2620    (set_attr "mode" "<MODE>")
2621    (set_attr "length_immediate" "0")])
2623 (define_insn "*mov<mode>_extv_1"
2624   [(set (match_operand:SWI24 0 "register_operand" "=R")
2625         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2626                             (const_int 8)
2627                             (const_int 8)))]
2628   ""
2629   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2630   [(set_attr "type" "imovx")
2631    (set_attr "mode" "SI")])
2633 (define_insn "*movqi_extv_1"
2634   [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2635         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2636                          (const_int 8)
2637                          (const_int 8)))]
2638   ""
2640   switch (get_attr_type (insn))
2641     {
2642     case TYPE_IMOVX:
2643       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2644     default:
2645       return "mov{b}\t{%h1, %0|%0, %h1}";
2646     }
2648   [(set_attr "isa" "*,*,nox64")
2649    (set (attr "type")
2650      (if_then_else (and (match_operand:QI 0 "register_operand")
2651                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2652                              (match_test "TARGET_MOVX")))
2653         (const_string "imovx")
2654         (const_string "imov")))
2655    (set (attr "mode")
2656      (if_then_else (eq_attr "type" "imovx")
2657         (const_string "SI")
2658         (const_string "QI")))])
2660 (define_insn "*mov<mode>_extzv_1"
2661   [(set (match_operand:SWI48 0 "register_operand" "=R")
2662         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2663                             (const_int 8)
2664                             (const_int 8)))]
2665   ""
2666   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2667   [(set_attr "type" "imovx")
2668    (set_attr "mode" "SI")])
2670 (define_insn "*movqi_extzv_2"
2671   [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2672         (subreg:QI
2673           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2674                            (const_int 8)
2675                            (const_int 8)) 0))]
2676   ""
2678   switch (get_attr_type (insn))
2679     {
2680     case TYPE_IMOVX:
2681       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2682     default:
2683       return "mov{b}\t{%h1, %0|%0, %h1}";
2684     }
2686   [(set_attr "isa" "*,*,nox64")
2687    (set (attr "type")
2688      (if_then_else (and (match_operand:QI 0 "register_operand")
2689                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2690                              (match_test "TARGET_MOVX")))
2691         (const_string "imovx")
2692         (const_string "imov")))
2693    (set (attr "mode")
2694      (if_then_else (eq_attr "type" "imovx")
2695         (const_string "SI")
2696         (const_string "QI")))])
2698 (define_insn "mov<mode>_insv_1"
2699   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2700                              (const_int 8)
2701                              (const_int 8))
2702         (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2703   ""
2705   if (CONST_INT_P (operands[1]))
2706     operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2707   return "mov{b}\t{%b1, %h0|%h0, %b1}";
2709   [(set_attr "isa" "*,nox64")
2710    (set_attr "type" "imov")
2711    (set_attr "mode" "QI")])
2713 (define_insn "*movqi_insv_2"
2714   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2715                          (const_int 8)
2716                          (const_int 8))
2717         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2718                      (const_int 8)))]
2719   ""
2720   "mov{b}\t{%h1, %h0|%h0, %h1}"
2721   [(set_attr "type" "imov")
2722    (set_attr "mode" "QI")])
2724 ;; Floating point push instructions.
2726 (define_insn "*pushtf"
2727   [(set (match_operand:TF 0 "push_operand" "=<,<")
2728         (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2729   "TARGET_64BIT || TARGET_SSE"
2731   /* This insn should be already split before reg-stack.  */
2732   gcc_unreachable ();
2734   [(set_attr "isa" "*,x64")
2735    (set_attr "type" "multi")
2736    (set_attr "unit" "sse,*")
2737    (set_attr "mode" "TF,DI")])
2739 ;; %%% Kill this when call knows how to work this out.
2740 (define_split
2741   [(set (match_operand:TF 0 "push_operand")
2742         (match_operand:TF 1 "sse_reg_operand"))]
2743   "TARGET_SSE && reload_completed"
2744   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2745    (set (match_dup 0) (match_dup 1))]
2747   /* Preserve memory attributes. */
2748   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2751 (define_insn "*pushxf"
2752   [(set (match_operand:XF 0 "push_operand" "=<,<")
2753         (match_operand:XF 1 "general_no_elim_operand" "f,Yx*roF"))]
2754   ""
2756   /* This insn should be already split before reg-stack.  */
2757   gcc_unreachable ();
2759   [(set_attr "type" "multi")
2760    (set_attr "unit" "i387,*")
2761    (set (attr "mode")
2762         (cond [(eq_attr "alternative" "1")
2763                  (if_then_else (match_test "TARGET_64BIT")
2764                    (const_string "DI")
2765                    (const_string "SI"))
2766               ]
2767               (const_string "XF")))])
2769 ;; %%% Kill this when call knows how to work this out.
2770 (define_split
2771   [(set (match_operand:XF 0 "push_operand")
2772         (match_operand:XF 1 "fp_register_operand"))]
2773   "reload_completed"
2774   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2775    (set (match_dup 0) (match_dup 1))]
2777   operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
2778   /* Preserve memory attributes. */
2779   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2782 (define_insn "*pushdf"
2783   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2784         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*roF,rmF,x"))]
2785   ""
2787   /* This insn should be already split before reg-stack.  */
2788   gcc_unreachable ();
2790   [(set_attr "isa" "*,nox64,x64,sse2")
2791    (set_attr "type" "multi")
2792    (set_attr "unit" "i387,*,*,sse")
2793    (set_attr "mode" "DF,SI,DI,DF")])
2795 ;; %%% Kill this when call knows how to work this out.
2796 (define_split
2797   [(set (match_operand:DF 0 "push_operand")
2798         (match_operand:DF 1 "any_fp_register_operand"))]
2799   "reload_completed"
2800   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2801    (set (match_dup 0) (match_dup 1))]
2803   /* Preserve memory attributes. */
2804   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2807 (define_insn "*pushsf_rex64"
2808   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2809         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2810   "TARGET_64BIT"
2812   /* Anything else should be already split before reg-stack.  */
2813   gcc_assert (which_alternative == 1);
2814   return "push{q}\t%q1";
2816   [(set_attr "type" "multi,push,multi")
2817    (set_attr "unit" "i387,*,*")
2818    (set_attr "mode" "SF,DI,SF")])
2820 (define_insn "*pushsf"
2821   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2822         (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2823   "!TARGET_64BIT"
2825   /* Anything else should be already split before reg-stack.  */
2826   gcc_assert (which_alternative == 1);
2827   return "push{l}\t%1";
2829   [(set_attr "type" "multi,push,multi")
2830    (set_attr "unit" "i387,*,*")
2831    (set_attr "mode" "SF,SI,SF")])
2833 ;; %%% Kill this when call knows how to work this out.
2834 (define_split
2835   [(set (match_operand:SF 0 "push_operand")
2836         (match_operand:SF 1 "any_fp_register_operand"))]
2837   "reload_completed"
2838   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2839    (set (match_dup 0) (match_dup 1))]
2841   rtx op = XEXP (operands[0], 0);
2842   if (GET_CODE (op) == PRE_DEC)
2843     {
2844       gcc_assert (!TARGET_64BIT);
2845       op = GEN_INT (-4);
2846     }
2847   else
2848     {
2849       op = XEXP (XEXP (op, 1), 1);
2850       gcc_assert (CONST_INT_P (op));
2851     }
2852   operands[2] = op;
2853   /* Preserve memory attributes. */
2854   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2857 (define_split
2858   [(set (match_operand:SF 0 "push_operand")
2859         (match_operand:SF 1 "memory_operand"))]
2860   "reload_completed
2861    && (operands[2] = find_constant_src (insn))"
2862   [(set (match_dup 0) (match_dup 2))])
2864 (define_split
2865   [(set (match_operand 0 "push_operand")
2866         (match_operand 1 "general_operand"))]
2867   "reload_completed
2868    && (GET_MODE (operands[0]) == TFmode
2869        || GET_MODE (operands[0]) == XFmode
2870        || GET_MODE (operands[0]) == DFmode)
2871    && !ANY_FP_REG_P (operands[1])"
2872   [(const_int 0)]
2873   "ix86_split_long_move (operands); DONE;")
2875 ;; Floating point move instructions.
2877 (define_expand "movtf"
2878   [(set (match_operand:TF 0 "nonimmediate_operand")
2879         (match_operand:TF 1 "nonimmediate_operand"))]
2880   "TARGET_64BIT || TARGET_SSE"
2881   "ix86_expand_move (TFmode, operands); DONE;")
2883 (define_expand "mov<mode>"
2884   [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2885         (match_operand:X87MODEF 1 "general_operand"))]
2886   ""
2887   "ix86_expand_move (<MODE>mode, operands); DONE;")
2889 (define_insn "*movtf_internal"
2890   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2891         (match_operand:TF 1 "general_operand"      "C ,xm,x,*roF,*rC"))]
2892   "(TARGET_64BIT || TARGET_SSE)
2893    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2894    && (!can_create_pseudo_p ()
2895        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2896        || GET_CODE (operands[1]) != CONST_DOUBLE
2897        || (optimize_function_for_size_p (cfun)
2898            && standard_sse_constant_p (operands[1])
2899            && !memory_operand (operands[0], TFmode))
2900        || (!TARGET_MEMORY_MISMATCH_STALL
2901            && memory_operand (operands[0], TFmode)))"
2903   switch (get_attr_type (insn))
2904     {
2905     case TYPE_SSELOG1:
2906       return standard_sse_constant_opcode (insn, operands[1]);
2908     case TYPE_SSEMOV:
2909       /* Handle misaligned load/store since we
2910          don't have movmisaligntf pattern. */
2911       if (misaligned_operand (operands[0], TFmode)
2912           || misaligned_operand (operands[1], TFmode))
2913         {
2914           if (get_attr_mode (insn) == MODE_V4SF)
2915             return "%vmovups\t{%1, %0|%0, %1}";
2916           else
2917             return "%vmovdqu\t{%1, %0|%0, %1}";
2918         }
2919       else
2920         {
2921           if (get_attr_mode (insn) == MODE_V4SF)
2922             return "%vmovaps\t{%1, %0|%0, %1}";
2923           else
2924             return "%vmovdqa\t{%1, %0|%0, %1}";
2925         }
2927     case TYPE_MULTI:
2928         return "#";
2930     default:
2931       gcc_unreachable ();
2932     }
2934   [(set_attr "isa" "*,*,*,x64,x64")
2935    (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
2936    (set (attr "prefix")
2937      (if_then_else (eq_attr "type" "sselog1,ssemov")
2938        (const_string "maybe_vex")
2939        (const_string "orig")))
2940    (set (attr "mode")
2941         (cond [(eq_attr "alternative" "3,4")
2942                  (const_string "DI")
2943                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2944                  (const_string "V4SF")
2945                (and (eq_attr "alternative" "2")
2946                     (match_test "TARGET_SSE_TYPELESS_STORES"))
2947                  (const_string "V4SF")
2948                (match_test "TARGET_AVX")
2949                  (const_string "TI")
2950                (ior (not (match_test "TARGET_SSE2"))
2951                     (match_test "optimize_function_for_size_p (cfun)"))
2952                  (const_string "V4SF")
2953                ]
2954                (const_string "TI")))])
2956 ;; Possible store forwarding (partial memory) stall in alternatives 4 and 5.
2957 (define_insn "*movxf_internal"
2958   [(set (match_operand:XF 0 "nonimmediate_operand"
2959          "=f,m,f,?Yx*r ,!o   ,!o")
2960         (match_operand:XF 1 "general_operand"
2961          "fm,f,G,Yx*roF,Yx*rF,Yx*rC"))]
2962   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2963    && (!can_create_pseudo_p ()
2964        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2965        || GET_CODE (operands[1]) != CONST_DOUBLE
2966        || (optimize_function_for_size_p (cfun)
2967            && standard_80387_constant_p (operands[1]) > 0
2968            && !memory_operand (operands[0], XFmode))
2969        || (!TARGET_MEMORY_MISMATCH_STALL
2970            && memory_operand (operands[0], XFmode)))"
2972   switch (get_attr_type (insn))
2973     {
2974     case TYPE_FMOV:
2975       if (which_alternative == 2)
2976         return standard_80387_constant_opcode (operands[1]);
2977       return output_387_reg_move (insn, operands);
2979     case TYPE_MULTI:
2980       return "#";
2982     default:
2983       gcc_unreachable ();
2984     }
2986   [(set_attr "isa" "*,*,*,*,nox64,x64")
2987    (set_attr "type" "fmov,fmov,fmov,multi,multi,multi")
2988    (set (attr "mode")
2989         (cond [(eq_attr "alternative" "3,4,5")
2990                  (if_then_else (match_test "TARGET_64BIT")
2991                    (const_string "DI")
2992                    (const_string "SI"))
2993               ]
2994               (const_string "XF")))])
2996 ;; Possible store forwarding (partial memory) stall in alternative 4.
2997 (define_insn "*movdf_internal"
2998   [(set (match_operand:DF 0 "nonimmediate_operand"
2999     "=Yf*f,m   ,Yf*f,?Yd*r ,!o   ,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi")
3000         (match_operand:DF 1 "general_operand"
3001     "Yf*fm,Yf*f,G   ,Yd*roF,Yd*rF,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))]
3002   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3003    && (!can_create_pseudo_p ()
3004        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3005        || GET_CODE (operands[1]) != CONST_DOUBLE
3006        || (optimize_function_for_size_p (cfun)
3007            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3008                 && standard_80387_constant_p (operands[1]) > 0)
3009                || (TARGET_SSE2 && TARGET_SSE_MATH
3010                    && standard_sse_constant_p (operands[1])))
3011            && !memory_operand (operands[0], DFmode))
3012        || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3013            && memory_operand (operands[0], DFmode)))"
3015   switch (get_attr_type (insn))
3016     {
3017     case TYPE_FMOV:
3018       if (which_alternative == 2)
3019         return standard_80387_constant_opcode (operands[1]);
3020       return output_387_reg_move (insn, operands);
3022     case TYPE_MULTI:
3023       return "#";
3025     case TYPE_IMOV:
3026       if (get_attr_mode (insn) == MODE_SI)
3027         return "mov{l}\t{%1, %k0|%k0, %1}";
3028       else if (which_alternative == 8)
3029         return "movabs{q}\t{%1, %0|%0, %1}";
3030       else
3031         return "mov{q}\t{%1, %0|%0, %1}";
3033     case TYPE_SSELOG1:
3034       return standard_sse_constant_opcode (insn, operands[1]);
3036     case TYPE_SSEMOV:
3037       switch (get_attr_mode (insn))
3038         {
3039         case MODE_DF:
3040           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3041             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3042           return "%vmovsd\t{%1, %0|%0, %1}";
3044         case MODE_V4SF:
3045           return "%vmovaps\t{%1, %0|%0, %1}";
3046         case MODE_V8DF:
3047           return "vmovapd\t{%g1, %g0|%g0, %g1}";
3048         case MODE_V2DF:
3049           return "%vmovapd\t{%1, %0|%0, %1}";
3051         case MODE_V2SF:
3052           gcc_assert (!TARGET_AVX);
3053           return "movlps\t{%1, %0|%0, %1}";
3054         case MODE_V1DF:
3055           gcc_assert (!TARGET_AVX);
3056           return "movlpd\t{%1, %0|%0, %1}";
3058         case MODE_DI:
3059           /* Handle broken assemblers that require movd instead of movq.  */
3060           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3061               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3062             return "%vmovd\t{%1, %0|%0, %1}";
3063           return "%vmovq\t{%1, %0|%0, %1}";
3065         default:
3066           gcc_unreachable ();
3067         }
3069     default:
3070       gcc_unreachable ();
3071     }
3073   [(set (attr "isa")
3074         (cond [(eq_attr "alternative" "3,4")
3075                  (const_string "nox64")
3076                (eq_attr "alternative" "5,6,7,8,17,18")
3077                  (const_string "x64")
3078                (eq_attr "alternative" "9,10,11,12")
3079                  (const_string "sse2")
3080               ]
3081               (const_string "*")))
3082    (set (attr "type")
3083         (cond [(eq_attr "alternative" "0,1,2")
3084                  (const_string "fmov")
3085                (eq_attr "alternative" "3,4")
3086                  (const_string "multi")
3087                (eq_attr "alternative" "5,6,7,8")
3088                  (const_string "imov")
3089                (eq_attr "alternative" "9,13")
3090                  (const_string "sselog1")
3091               ]
3092               (const_string "ssemov")))
3093    (set (attr "modrm")
3094      (if_then_else (eq_attr "alternative" "8")
3095        (const_string "0")
3096        (const_string "*")))
3097    (set (attr "length_immediate")
3098      (if_then_else (eq_attr "alternative" "8")
3099        (const_string "8")
3100        (const_string "*")))
3101    (set (attr "prefix")
3102      (if_then_else (eq_attr "type" "sselog1,ssemov")
3103        (const_string "maybe_vex")
3104        (const_string "orig")))
3105    (set (attr "prefix_data16")
3106      (if_then_else
3107        (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3108             (eq_attr "mode" "V1DF"))
3109        (const_string "1")
3110        (const_string "*")))
3111    (set (attr "mode")
3112         (cond [(eq_attr "alternative" "3,4,7")
3113                  (const_string "SI")
3114                (eq_attr "alternative" "5,6,8,17,18")
3115                  (const_string "DI")
3117                /* xorps is one byte shorter for non-AVX targets.  */
3118                (eq_attr "alternative" "9,13")
3119                  (cond [(not (match_test "TARGET_SSE2"))
3120                           (const_string "V4SF")
3121                         (match_test "TARGET_AVX512F")
3122                           (const_string "XI")
3123                         (match_test "TARGET_AVX")
3124                           (const_string "V2DF")
3125                         (match_test "optimize_function_for_size_p (cfun)")
3126                           (const_string "V4SF")
3127                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3128                           (const_string "TI")
3129                        ]
3130                        (const_string "V2DF"))
3132                /* For architectures resolving dependencies on
3133                   whole SSE registers use movapd to break dependency
3134                   chains, otherwise use short move to avoid extra work.  */
3136                /* movaps is one byte shorter for non-AVX targets.  */
3137                (eq_attr "alternative" "10,14")
3138                  (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3139                              (match_operand 1 "ext_sse_reg_operand"))
3140                           (const_string "V8DF")
3141                         (ior (not (match_test "TARGET_SSE2"))
3142                              (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3143                           (const_string "V4SF")
3144                         (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3145                           (const_string "V2DF")
3146                         (match_test "TARGET_AVX")
3147                           (const_string "DF")
3148                         (match_test "optimize_function_for_size_p (cfun)")
3149                           (const_string "V4SF")
3150                        ]
3151                        (const_string "DF"))
3153                /* For architectures resolving dependencies on register
3154                   parts we may avoid extra work to zero out upper part
3155                   of register.  */
3156                (eq_attr "alternative" "11,15")
3157                  (cond [(not (match_test "TARGET_SSE2"))
3158                           (const_string "V2SF")
3159                         (match_test "TARGET_AVX")
3160                           (const_string "DF")
3161                         (match_test "TARGET_SSE_SPLIT_REGS")
3162                           (const_string "V1DF")
3163                        ]
3164                        (const_string "DF"))
3166                (and (eq_attr "alternative" "12,16")
3167                     (not (match_test "TARGET_SSE2")))
3168                  (const_string "V2SF")
3169               ]
3170               (const_string "DF")))])
3172 (define_insn "*movsf_internal"
3173   [(set (match_operand:SF 0 "nonimmediate_operand"
3174           "=Yf*f,m   ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
3175         (match_operand:SF 1 "general_operand"
3176           "Yf*fm,Yf*f,G   ,rmF,rF,C,v,m,v,Yj,r  ,*y ,m  ,*y,*Yn,r"))]
3177   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3178    && (!can_create_pseudo_p ()
3179        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3180        || GET_CODE (operands[1]) != CONST_DOUBLE
3181        || (optimize_function_for_size_p (cfun)
3182            && ((!TARGET_SSE_MATH
3183                 && standard_80387_constant_p (operands[1]) > 0)
3184                || (TARGET_SSE_MATH
3185                    && standard_sse_constant_p (operands[1]))))
3186        || memory_operand (operands[0], SFmode))"
3188   switch (get_attr_type (insn))
3189     {
3190     case TYPE_FMOV:
3191       if (which_alternative == 2)
3192         return standard_80387_constant_opcode (operands[1]);
3193       return output_387_reg_move (insn, operands);
3195     case TYPE_IMOV:
3196       return "mov{l}\t{%1, %0|%0, %1}";
3198     case TYPE_SSELOG1:
3199       return standard_sse_constant_opcode (insn, operands[1]);
3201     case TYPE_SSEMOV:
3202       switch (get_attr_mode (insn))
3203         {
3204         case MODE_SF:
3205           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3206             return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3207           return "%vmovss\t{%1, %0|%0, %1}";
3209         case MODE_V16SF:
3210           return "vmovaps\t{%g1, %g0|%g0, %g1}";
3211         case MODE_V4SF:
3212           return "%vmovaps\t{%1, %0|%0, %1}";
3214         case MODE_SI:
3215           return "%vmovd\t{%1, %0|%0, %1}";
3217         default:
3218           gcc_unreachable ();
3219         }
3221     case TYPE_MMXMOV:
3222       switch (get_attr_mode (insn))
3223         {
3224         case MODE_DI:
3225           return "movq\t{%1, %0|%0, %1}";
3226         case MODE_SI:
3227           return "movd\t{%1, %0|%0, %1}";
3229         default:
3230           gcc_unreachable ();
3231         }
3233     default:
3234       gcc_unreachable ();
3235     }
3237   [(set (attr "type")
3238         (cond [(eq_attr "alternative" "0,1,2")
3239                  (const_string "fmov")
3240                (eq_attr "alternative" "3,4")
3241                  (const_string "imov")
3242                (eq_attr "alternative" "5")
3243                  (const_string "sselog1")
3244                (eq_attr "alternative" "11,12,13,14,15")
3245                  (const_string "mmxmov")
3246               ]
3247               (const_string "ssemov")))
3248    (set (attr "prefix")
3249      (if_then_else (eq_attr "type" "sselog1,ssemov")
3250        (const_string "maybe_vex")
3251        (const_string "orig")))
3252    (set (attr "prefix_data16")
3253      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3254        (const_string "1")
3255        (const_string "*")))
3256    (set (attr "mode")
3257         (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15")
3258                  (const_string "SI")
3259                (eq_attr "alternative" "11")
3260                  (const_string "DI")
3261                (eq_attr "alternative" "5")
3262                  (cond [(not (match_test "TARGET_SSE2"))
3263                           (const_string "V4SF")
3264                         (match_test "TARGET_AVX512F")
3265                           (const_string "V16SF")
3266                         (match_test "TARGET_AVX")
3267                           (const_string "V4SF")
3268                         (match_test "optimize_function_for_size_p (cfun)")
3269                           (const_string "V4SF")
3270                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3271                           (const_string "TI")
3272                        ]
3273                        (const_string "V4SF"))
3275                /* For architectures resolving dependencies on
3276                   whole SSE registers use APS move to break dependency
3277                   chains, otherwise use short move to avoid extra work.
3279                   Do the same for architectures resolving dependencies on
3280                   the parts.  While in DF mode it is better to always handle
3281                   just register parts, the SF mode is different due to lack
3282                   of instructions to load just part of the register.  It is
3283                   better to maintain the whole registers in single format
3284                   to avoid problems on using packed logical operations.  */
3285                (eq_attr "alternative" "6")
3286                  (cond [(ior  (match_operand 0 "ext_sse_reg_operand")
3287                               (match_operand 1 "ext_sse_reg_operand"))
3288                           (const_string "V16SF")
3289                         (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3290                              (match_test "TARGET_SSE_SPLIT_REGS"))
3291                           (const_string "V4SF")
3292                        ]
3293                        (const_string "SF"))
3294               ]
3295               (const_string "SF")))])
3297 (define_split
3298   [(set (match_operand 0 "any_fp_register_operand")
3299         (match_operand 1 "memory_operand"))]
3300   "reload_completed
3301    && (GET_MODE (operands[0]) == TFmode
3302        || GET_MODE (operands[0]) == XFmode
3303        || GET_MODE (operands[0]) == DFmode
3304        || GET_MODE (operands[0]) == SFmode)
3305    && (operands[2] = find_constant_src (insn))"
3306   [(set (match_dup 0) (match_dup 2))]
3308   rtx c = operands[2];
3309   int r = REGNO (operands[0]);
3311   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3312       || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3313     FAIL;
3316 (define_split
3317   [(set (match_operand 0 "any_fp_register_operand")
3318         (float_extend (match_operand 1 "memory_operand")))]
3319   "reload_completed
3320    && (GET_MODE (operands[0]) == TFmode
3321        || GET_MODE (operands[0]) == XFmode
3322        || GET_MODE (operands[0]) == DFmode)
3323    && (operands[2] = find_constant_src (insn))"
3324   [(set (match_dup 0) (match_dup 2))]
3326   rtx c = operands[2];
3327   int r = REGNO (operands[0]);
3329   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3330       || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3331     FAIL;
3334 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3335 (define_split
3336   [(set (match_operand:X87MODEF 0 "fp_register_operand")
3337         (match_operand:X87MODEF 1 "immediate_operand"))]
3338   "reload_completed
3339    && (standard_80387_constant_p (operands[1]) == 8
3340        || standard_80387_constant_p (operands[1]) == 9)"
3341   [(set (match_dup 0)(match_dup 1))
3342    (set (match_dup 0)
3343         (neg:X87MODEF (match_dup 0)))]
3345   REAL_VALUE_TYPE r;
3347   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3348   if (real_isnegzero (&r))
3349     operands[1] = CONST0_RTX (<MODE>mode);
3350   else
3351     operands[1] = CONST1_RTX (<MODE>mode);
3354 (define_split
3355   [(set (match_operand 0 "nonimmediate_operand")
3356         (match_operand 1 "general_operand"))]
3357   "reload_completed
3358    && (GET_MODE (operands[0]) == TFmode
3359        || GET_MODE (operands[0]) == XFmode
3360        || GET_MODE (operands[0]) == DFmode)
3361    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3362   [(const_int 0)]
3363   "ix86_split_long_move (operands); DONE;")
3365 (define_insn "swapxf"
3366   [(set (match_operand:XF 0 "register_operand" "+f")
3367         (match_operand:XF 1 "register_operand" "+f"))
3368    (set (match_dup 1)
3369         (match_dup 0))]
3370   "TARGET_80387"
3372   if (STACK_TOP_P (operands[0]))
3373     return "fxch\t%1";
3374   else
3375     return "fxch\t%0";
3377   [(set_attr "type" "fxch")
3378    (set_attr "mode" "XF")])
3380 (define_insn "*swap<mode>"
3381   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3382         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3383    (set (match_dup 1)
3384         (match_dup 0))]
3385   "TARGET_80387 || reload_completed"
3387   if (STACK_TOP_P (operands[0]))
3388     return "fxch\t%1";
3389   else
3390     return "fxch\t%0";
3392   [(set_attr "type" "fxch")
3393    (set_attr "mode" "<MODE>")])
3395 ;; Zero extension instructions
3397 (define_expand "zero_extendsidi2"
3398   [(set (match_operand:DI 0 "nonimmediate_operand")
3399         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3401 (define_insn "*zero_extendsidi2"
3402   [(set (match_operand:DI 0 "nonimmediate_operand"
3403                         "=r,?r,?o,r   ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3404         (zero_extend:DI
3405          (match_operand:SI 1 "x86_64_zext_operand"
3406                         "0 ,rm,r ,rmWz,0,r   ,m   ,*Yj,*x,r   ,m")))]
3407   ""
3409   switch (get_attr_type (insn))
3410     {
3411     case TYPE_IMOVX:
3412       if (ix86_use_lea_for_mov (insn, operands))
3413         return "lea{l}\t{%E1, %k0|%k0, %E1}";
3414       else
3415         return "mov{l}\t{%1, %k0|%k0, %1}";
3417     case TYPE_MULTI:
3418       return "#";
3420     case TYPE_MMXMOV:
3421       return "movd\t{%1, %0|%0, %1}";
3423     case TYPE_SSELOG1:
3424       return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3426     case TYPE_SSEMOV:
3427       if (GENERAL_REG_P (operands[0]))
3428         return "%vmovd\t{%1, %k0|%k0, %1}";
3430       return "%vmovd\t{%1, %0|%0, %1}";
3432     default:
3433       gcc_unreachable ();
3434     }
3436   [(set (attr "isa")
3437      (cond [(eq_attr "alternative" "0,1,2")
3438               (const_string "nox64")
3439             (eq_attr "alternative" "3,7")
3440               (const_string "x64")
3441             (eq_attr "alternative" "8")
3442               (const_string "x64_sse4")
3443             (eq_attr "alternative" "10")
3444               (const_string "sse2")
3445            ]
3446            (const_string "*")))
3447    (set (attr "type")
3448      (cond [(eq_attr "alternative" "0,1,2,4")
3449               (const_string "multi")
3450             (eq_attr "alternative" "5,6")
3451               (const_string "mmxmov")
3452             (eq_attr "alternative" "7,9,10")
3453               (const_string "ssemov")
3454             (eq_attr "alternative" "8")
3455               (const_string "sselog1")
3456            ]
3457            (const_string "imovx")))
3458    (set (attr "prefix_extra")
3459      (if_then_else (eq_attr "alternative" "8")
3460        (const_string "1")
3461        (const_string "*")))
3462    (set (attr "length_immediate")
3463      (if_then_else (eq_attr "alternative" "8")
3464        (const_string "1")
3465        (const_string "*")))
3466    (set (attr "prefix")
3467      (if_then_else (eq_attr "type" "ssemov,sselog1")
3468        (const_string "maybe_vex")
3469        (const_string "orig")))
3470    (set (attr "prefix_0f")
3471      (if_then_else (eq_attr "type" "imovx")
3472        (const_string "0")
3473        (const_string "*")))
3474    (set (attr "mode")
3475      (cond [(eq_attr "alternative" "5,6")
3476               (const_string "DI")
3477             (eq_attr "alternative" "7,8,9")
3478               (const_string "TI")
3479            ]
3480            (const_string "SI")))])
3482 (define_split
3483   [(set (match_operand:DI 0 "memory_operand")
3484         (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3485   "reload_completed"
3486   [(set (match_dup 4) (const_int 0))]
3487   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3489 (define_split
3490   [(set (match_operand:DI 0 "register_operand")
3491         (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3492   "!TARGET_64BIT && reload_completed
3493    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3494    && true_regnum (operands[0]) == true_regnum (operands[1])"
3495   [(set (match_dup 4) (const_int 0))]
3496   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3498 (define_split
3499   [(set (match_operand:DI 0 "nonimmediate_operand")
3500         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3501   "!TARGET_64BIT && reload_completed
3502    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3503    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3504   [(set (match_dup 3) (match_dup 1))
3505    (set (match_dup 4) (const_int 0))]
3506   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3508 (define_insn "zero_extend<mode>di2"
3509   [(set (match_operand:DI 0 "register_operand" "=r")
3510         (zero_extend:DI
3511          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3512   "TARGET_64BIT"
3513   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3514   [(set_attr "type" "imovx")
3515    (set_attr "mode" "SI")])
3517 (define_expand "zero_extend<mode>si2"
3518   [(set (match_operand:SI 0 "register_operand")
3519         (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3520   ""
3522   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3523     {
3524       operands[1] = force_reg (<MODE>mode, operands[1]);
3525       emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3526       DONE;
3527     }
3530 (define_insn_and_split "zero_extend<mode>si2_and"
3531   [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3532         (zero_extend:SI
3533           (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3534    (clobber (reg:CC FLAGS_REG))]
3535   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3536   "#"
3537   "&& reload_completed"
3538   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3539               (clobber (reg:CC FLAGS_REG))])]
3541   if (true_regnum (operands[0]) != true_regnum (operands[1]))
3542     {
3543       ix86_expand_clear (operands[0]);
3545       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3546       emit_insn (gen_movstrict<mode>
3547                   (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3548       DONE;
3549     }
3551   operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3553   [(set_attr "type" "alu1")
3554    (set_attr "mode" "SI")])
3556 (define_insn "*zero_extend<mode>si2"
3557   [(set (match_operand:SI 0 "register_operand" "=r")
3558         (zero_extend:SI
3559           (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3560   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3561   "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3562   [(set_attr "type" "imovx")
3563    (set_attr "mode" "SI")])
3565 (define_expand "zero_extendqihi2"
3566   [(set (match_operand:HI 0 "register_operand")
3567         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3568   ""
3570   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3571     {
3572       operands[1] = force_reg (QImode, operands[1]);
3573       emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3574       DONE;
3575     }
3578 (define_insn_and_split "zero_extendqihi2_and"
3579   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3580         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3581    (clobber (reg:CC FLAGS_REG))]
3582   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3583   "#"
3584   "&& reload_completed"
3585   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3586               (clobber (reg:CC FLAGS_REG))])]
3588   if (true_regnum (operands[0]) != true_regnum (operands[1]))
3589     {
3590       ix86_expand_clear (operands[0]);
3592       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3593       emit_insn (gen_movstrictqi
3594                   (gen_lowpart (QImode, operands[0]), operands[1]));
3595       DONE;
3596     }
3598   operands[0] = gen_lowpart (SImode, operands[0]);
3600   [(set_attr "type" "alu1")
3601    (set_attr "mode" "SI")])
3603 ; zero extend to SImode to avoid partial register stalls
3604 (define_insn "*zero_extendqihi2"
3605   [(set (match_operand:HI 0 "register_operand" "=r")
3606         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3607   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3608   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3609   [(set_attr "type" "imovx")
3610    (set_attr "mode" "SI")])
3612 ;; Sign extension instructions
3614 (define_expand "extendsidi2"
3615   [(set (match_operand:DI 0 "register_operand")
3616         (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3617   ""
3619   if (!TARGET_64BIT)
3620     {
3621       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3622       DONE;
3623     }
3626 (define_insn "*extendsidi2_rex64"
3627   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3628         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3629   "TARGET_64BIT"
3630   "@
3631    {cltq|cdqe}
3632    movs{lq|x}\t{%1, %0|%0, %1}"
3633   [(set_attr "type" "imovx")
3634    (set_attr "mode" "DI")
3635    (set_attr "prefix_0f" "0")
3636    (set_attr "modrm" "0,1")])
3638 (define_insn "extendsidi2_1"
3639   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3640         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3641    (clobber (reg:CC FLAGS_REG))
3642    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3643   "!TARGET_64BIT"
3644   "#")
3646 ;; Split the memory case.  If the source register doesn't die, it will stay
3647 ;; this way, if it does die, following peephole2s take care of it.
3648 (define_split
3649   [(set (match_operand:DI 0 "memory_operand")
3650         (sign_extend:DI (match_operand:SI 1 "register_operand")))
3651    (clobber (reg:CC FLAGS_REG))
3652    (clobber (match_operand:SI 2 "register_operand"))]
3653   "reload_completed"
3654   [(const_int 0)]
3656   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3658   emit_move_insn (operands[3], operands[1]);
3660   /* Generate a cltd if possible and doing so it profitable.  */
3661   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3662       && true_regnum (operands[1]) == AX_REG
3663       && true_regnum (operands[2]) == DX_REG)
3664     {
3665       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3666     }
3667   else
3668     {
3669       emit_move_insn (operands[2], operands[1]);
3670       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3671     }
3672   emit_move_insn (operands[4], operands[2]);
3673   DONE;
3676 ;; Peepholes for the case where the source register does die, after
3677 ;; being split with the above splitter.
3678 (define_peephole2
3679   [(set (match_operand:SI 0 "memory_operand")
3680         (match_operand:SI 1 "register_operand"))
3681    (set (match_operand:SI 2 "register_operand") (match_dup 1))
3682    (parallel [(set (match_dup 2)
3683                    (ashiftrt:SI (match_dup 2) (const_int 31)))
3684                (clobber (reg:CC FLAGS_REG))])
3685    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3686   "REGNO (operands[1]) != REGNO (operands[2])
3687    && peep2_reg_dead_p (2, operands[1])
3688    && peep2_reg_dead_p (4, operands[2])
3689    && !reg_mentioned_p (operands[2], operands[3])"
3690   [(set (match_dup 0) (match_dup 1))
3691    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3692               (clobber (reg:CC FLAGS_REG))])
3693    (set (match_dup 3) (match_dup 1))])
3695 (define_peephole2
3696   [(set (match_operand:SI 0 "memory_operand")
3697         (match_operand:SI 1 "register_operand"))
3698    (parallel [(set (match_operand:SI 2 "register_operand")
3699                    (ashiftrt:SI (match_dup 1) (const_int 31)))
3700                (clobber (reg:CC FLAGS_REG))])
3701    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3702   "/* cltd is shorter than sarl $31, %eax */
3703    !optimize_function_for_size_p (cfun)
3704    && true_regnum (operands[1]) == AX_REG
3705    && true_regnum (operands[2]) == DX_REG
3706    && peep2_reg_dead_p (2, operands[1])
3707    && peep2_reg_dead_p (3, operands[2])
3708    && !reg_mentioned_p (operands[2], operands[3])"
3709   [(set (match_dup 0) (match_dup 1))
3710    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3711               (clobber (reg:CC FLAGS_REG))])
3712    (set (match_dup 3) (match_dup 1))])
3714 ;; Extend to register case.  Optimize case where source and destination
3715 ;; registers match and cases where we can use cltd.
3716 (define_split
3717   [(set (match_operand:DI 0 "register_operand")
3718         (sign_extend:DI (match_operand:SI 1 "register_operand")))
3719    (clobber (reg:CC FLAGS_REG))
3720    (clobber (match_scratch:SI 2))]
3721   "reload_completed"
3722   [(const_int 0)]
3724   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3726   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3727     emit_move_insn (operands[3], operands[1]);
3729   /* Generate a cltd if possible and doing so it profitable.  */
3730   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3731       && true_regnum (operands[3]) == AX_REG
3732       && true_regnum (operands[4]) == DX_REG)
3733     {
3734       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3735       DONE;
3736     }
3738   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3739     emit_move_insn (operands[4], operands[1]);
3741   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3742   DONE;
3745 (define_insn "extend<mode>di2"
3746   [(set (match_operand:DI 0 "register_operand" "=r")
3747         (sign_extend:DI
3748          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3749   "TARGET_64BIT"
3750   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3751   [(set_attr "type" "imovx")
3752    (set_attr "mode" "DI")])
3754 (define_insn "extendhisi2"
3755   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3756         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3757   ""
3759   switch (get_attr_prefix_0f (insn))
3760     {
3761     case 0:
3762       return "{cwtl|cwde}";
3763     default:
3764       return "movs{wl|x}\t{%1, %0|%0, %1}";
3765     }
3767   [(set_attr "type" "imovx")
3768    (set_attr "mode" "SI")
3769    (set (attr "prefix_0f")
3770      ;; movsx is short decodable while cwtl is vector decoded.
3771      (if_then_else (and (eq_attr "cpu" "!k6")
3772                         (eq_attr "alternative" "0"))
3773         (const_string "0")
3774         (const_string "1")))
3775    (set (attr "modrm")
3776      (if_then_else (eq_attr "prefix_0f" "0")
3777         (const_string "0")
3778         (const_string "1")))])
3780 (define_insn "*extendhisi2_zext"
3781   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3782         (zero_extend:DI
3783          (sign_extend:SI
3784           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3785   "TARGET_64BIT"
3787   switch (get_attr_prefix_0f (insn))
3788     {
3789     case 0:
3790       return "{cwtl|cwde}";
3791     default:
3792       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3793     }
3795   [(set_attr "type" "imovx")
3796    (set_attr "mode" "SI")
3797    (set (attr "prefix_0f")
3798      ;; movsx is short decodable while cwtl is vector decoded.
3799      (if_then_else (and (eq_attr "cpu" "!k6")
3800                         (eq_attr "alternative" "0"))
3801         (const_string "0")
3802         (const_string "1")))
3803    (set (attr "modrm")
3804      (if_then_else (eq_attr "prefix_0f" "0")
3805         (const_string "0")
3806         (const_string "1")))])
3808 (define_insn "extendqisi2"
3809   [(set (match_operand:SI 0 "register_operand" "=r")
3810         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3811   ""
3812   "movs{bl|x}\t{%1, %0|%0, %1}"
3813    [(set_attr "type" "imovx")
3814     (set_attr "mode" "SI")])
3816 (define_insn "*extendqisi2_zext"
3817   [(set (match_operand:DI 0 "register_operand" "=r")
3818         (zero_extend:DI
3819           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3820   "TARGET_64BIT"
3821   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3822    [(set_attr "type" "imovx")
3823     (set_attr "mode" "SI")])
3825 (define_insn "extendqihi2"
3826   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3827         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3828   ""
3830   switch (get_attr_prefix_0f (insn))
3831     {
3832     case 0:
3833       return "{cbtw|cbw}";
3834     default:
3835       return "movs{bw|x}\t{%1, %0|%0, %1}";
3836     }
3838   [(set_attr "type" "imovx")
3839    (set_attr "mode" "HI")
3840    (set (attr "prefix_0f")
3841      ;; movsx is short decodable while cwtl is vector decoded.
3842      (if_then_else (and (eq_attr "cpu" "!k6")
3843                         (eq_attr "alternative" "0"))
3844         (const_string "0")
3845         (const_string "1")))
3846    (set (attr "modrm")
3847      (if_then_else (eq_attr "prefix_0f" "0")
3848         (const_string "0")
3849         (const_string "1")))])
3851 ;; Conversions between float and double.
3853 ;; These are all no-ops in the model used for the 80387.
3854 ;; So just emit moves.
3856 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3857 (define_split
3858   [(set (match_operand:DF 0 "push_operand")
3859         (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3860   "reload_completed"
3861   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3862    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3864 (define_split
3865   [(set (match_operand:XF 0 "push_operand")
3866         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3867   "reload_completed"
3868   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3869    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3870   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3872 (define_expand "extendsfdf2"
3873   [(set (match_operand:DF 0 "nonimmediate_operand")
3874         (float_extend:DF (match_operand:SF 1 "general_operand")))]
3875   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3877   /* ??? Needed for compress_float_constant since all fp constants
3878      are TARGET_LEGITIMATE_CONSTANT_P.  */
3879   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3880     {
3881       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3882           && standard_80387_constant_p (operands[1]) > 0)
3883         {
3884           operands[1] = simplify_const_unary_operation
3885             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3886           emit_move_insn_1 (operands[0], operands[1]);
3887           DONE;
3888         }
3889       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3890     }
3893 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3894    cvtss2sd:
3895       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3896       cvtps2pd xmm2,xmm1
3897    We do the conversion post reload to avoid producing of 128bit spills
3898    that might lead to ICE on 32bit target.  The sequence unlikely combine
3899    anyway.  */
3900 (define_split
3901   [(set (match_operand:DF 0 "register_operand")
3902         (float_extend:DF
3903           (match_operand:SF 1 "nonimmediate_operand")))]
3904   "TARGET_USE_VECTOR_FP_CONVERTS
3905    && optimize_insn_for_speed_p ()
3906    && reload_completed && SSE_REG_P (operands[0])"
3907    [(set (match_dup 2)
3908          (float_extend:V2DF
3909            (vec_select:V2SF
3910              (match_dup 3)
3911              (parallel [(const_int 0) (const_int 1)]))))]
3913   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3914   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3915   /* Use movss for loading from memory, unpcklps reg, reg for registers.
3916      Try to avoid move when unpacking can be done in source.  */
3917   if (REG_P (operands[1]))
3918     {
3919       /* If it is unsafe to overwrite upper half of source, we need
3920          to move to destination and unpack there.  */
3921       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3922            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3923           && true_regnum (operands[0]) != true_regnum (operands[1]))
3924         {
3925           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3926           emit_move_insn (tmp, operands[1]);
3927         }
3928       else
3929         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3930       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3931                                              operands[3]));
3932     }
3933   else
3934     emit_insn (gen_vec_setv4sf_0 (operands[3],
3935                                   CONST0_RTX (V4SFmode), operands[1]));
3938 ;; It's more profitable to split and then extend in the same register.
3939 (define_peephole2
3940   [(set (match_operand:DF 0 "register_operand")
3941         (float_extend:DF
3942           (match_operand:SF 1 "memory_operand")))]
3943   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
3944    && optimize_insn_for_speed_p ()
3945    && SSE_REG_P (operands[0])"
3946   [(set (match_dup 2) (match_dup 1))
3947    (set (match_dup 0) (float_extend:DF (match_dup 2)))]
3948   "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
3950 (define_insn "*extendsfdf2_mixed"
3951   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3952         (float_extend:DF
3953           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3954   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3956   switch (which_alternative)
3957     {
3958     case 0:
3959     case 1:
3960       return output_387_reg_move (insn, operands);
3962     case 2:
3963       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3965     default:
3966       gcc_unreachable ();
3967     }
3969   [(set_attr "type" "fmov,fmov,ssecvt")
3970    (set_attr "prefix" "orig,orig,maybe_vex")
3971    (set_attr "mode" "SF,XF,DF")])
3973 (define_insn "*extendsfdf2_sse"
3974   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3975         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3976   "TARGET_SSE2 && TARGET_SSE_MATH"
3977   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3978   [(set_attr "type" "ssecvt")
3979    (set_attr "prefix" "maybe_vex")
3980    (set_attr "mode" "DF")])
3982 (define_insn "*extendsfdf2_i387"
3983   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3984         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3985   "TARGET_80387"
3986   "* return output_387_reg_move (insn, operands);"
3987   [(set_attr "type" "fmov")
3988    (set_attr "mode" "SF,XF")])
3990 (define_expand "extend<mode>xf2"
3991   [(set (match_operand:XF 0 "nonimmediate_operand")
3992         (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
3993   "TARGET_80387"
3995   /* ??? Needed for compress_float_constant since all fp constants
3996      are TARGET_LEGITIMATE_CONSTANT_P.  */
3997   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3998     {
3999       if (standard_80387_constant_p (operands[1]) > 0)
4000         {
4001           operands[1] = simplify_const_unary_operation
4002             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4003           emit_move_insn_1 (operands[0], operands[1]);
4004           DONE;
4005         }
4006       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4007     }
4010 (define_insn "*extend<mode>xf2_i387"
4011   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4012         (float_extend:XF
4013           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4014   "TARGET_80387"
4015   "* return output_387_reg_move (insn, operands);"
4016   [(set_attr "type" "fmov")
4017    (set_attr "mode" "<MODE>,XF")])
4019 ;; %%% This seems bad bad news.
4020 ;; This cannot output into an f-reg because there is no way to be sure
4021 ;; of truncating in that case.  Otherwise this is just like a simple move
4022 ;; insn.  So we pretend we can output to a reg in order to get better
4023 ;; register preferencing, but we really use a stack slot.
4025 ;; Conversion from DFmode to SFmode.
4027 (define_expand "truncdfsf2"
4028   [(set (match_operand:SF 0 "nonimmediate_operand")
4029         (float_truncate:SF
4030           (match_operand:DF 1 "nonimmediate_operand")))]
4031   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4033   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4034     ;
4035   else if (flag_unsafe_math_optimizations)
4036     ;
4037   else
4038     {
4039       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4040       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4041       DONE;
4042     }
4045 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4046    cvtsd2ss:
4047       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4048       cvtpd2ps xmm2,xmm1
4049    We do the conversion post reload to avoid producing of 128bit spills
4050    that might lead to ICE on 32bit target.  The sequence unlikely combine
4051    anyway.  */
4052 (define_split
4053   [(set (match_operand:SF 0 "register_operand")
4054         (float_truncate:SF
4055           (match_operand:DF 1 "nonimmediate_operand")))]
4056   "TARGET_USE_VECTOR_FP_CONVERTS
4057    && optimize_insn_for_speed_p ()
4058    && reload_completed && SSE_REG_P (operands[0])"
4059    [(set (match_dup 2)
4060          (vec_concat:V4SF
4061            (float_truncate:V2SF
4062              (match_dup 4))
4063            (match_dup 3)))]
4065   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4066   operands[3] = CONST0_RTX (V2SFmode);
4067   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4068   /* Use movsd for loading from memory, unpcklpd for registers.
4069      Try to avoid move when unpacking can be done in source, or SSE3
4070      movddup is available.  */
4071   if (REG_P (operands[1]))
4072     {
4073       if (!TARGET_SSE3
4074           && true_regnum (operands[0]) != true_regnum (operands[1])
4075           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4076               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4077         {
4078           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4079           emit_move_insn (tmp, operands[1]);
4080           operands[1] = tmp;
4081         }
4082       else if (!TARGET_SSE3)
4083         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4084       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4085     }
4086   else
4087     emit_insn (gen_sse2_loadlpd (operands[4],
4088                                  CONST0_RTX (V2DFmode), operands[1]));
4091 ;; It's more profitable to split and then extend in the same register.
4092 (define_peephole2
4093   [(set (match_operand:SF 0 "register_operand")
4094         (float_truncate:SF
4095           (match_operand:DF 1 "memory_operand")))]
4096   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4097    && optimize_insn_for_speed_p ()
4098    && SSE_REG_P (operands[0])"
4099   [(set (match_dup 2) (match_dup 1))
4100    (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4101   "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
4103 (define_expand "truncdfsf2_with_temp"
4104   [(parallel [(set (match_operand:SF 0)
4105                    (float_truncate:SF (match_operand:DF 1)))
4106               (clobber (match_operand:SF 2))])])
4108 (define_insn "*truncdfsf_fast_mixed"
4109   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4110         (float_truncate:SF
4111           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4112   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4114   switch (which_alternative)
4115     {
4116     case 0:
4117       return output_387_reg_move (insn, operands);
4118     case 1:
4119       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4120     default:
4121       gcc_unreachable ();
4122     }
4124   [(set_attr "type" "fmov,ssecvt")
4125    (set_attr "prefix" "orig,maybe_vex")
4126    (set_attr "mode" "SF")])
4128 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4129 ;; because nothing we do here is unsafe.
4130 (define_insn "*truncdfsf_fast_sse"
4131   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4132         (float_truncate:SF
4133           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4134   "TARGET_SSE2 && TARGET_SSE_MATH"
4135   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4136   [(set_attr "type" "ssecvt")
4137    (set_attr "prefix" "maybe_vex")
4138    (set_attr "mode" "SF")])
4140 (define_insn "*truncdfsf_fast_i387"
4141   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4142         (float_truncate:SF
4143           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4144   "TARGET_80387 && flag_unsafe_math_optimizations"
4145   "* return output_387_reg_move (insn, operands);"
4146   [(set_attr "type" "fmov")
4147    (set_attr "mode" "SF")])
4149 (define_insn "*truncdfsf_mixed"
4150   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,x ,?f,?x,?*r")
4151         (float_truncate:SF
4152           (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4153    (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
4154   "TARGET_MIX_SSE_I387"
4156   switch (which_alternative)
4157     {
4158     case 0:
4159       return output_387_reg_move (insn, operands);
4160     case 1:
4161       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4163     default:
4164       return "#";
4165     }
4167   [(set_attr "isa" "*,sse2,*,*,*")
4168    (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4169    (set_attr "unit" "*,*,i387,i387,i387")
4170    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4171    (set_attr "mode" "SF")])
4173 (define_insn "*truncdfsf_i387"
4174   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4175         (float_truncate:SF
4176           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4177    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4178   "TARGET_80387"
4180   switch (which_alternative)
4181     {
4182     case 0:
4183       return output_387_reg_move (insn, operands);
4185     default:
4186       return "#";
4187     }
4189   [(set_attr "type" "fmov,multi,multi,multi")
4190    (set_attr "unit" "*,i387,i387,i387")
4191    (set_attr "mode" "SF")])
4193 (define_insn "*truncdfsf2_i387_1"
4194   [(set (match_operand:SF 0 "memory_operand" "=m")
4195         (float_truncate:SF
4196           (match_operand:DF 1 "register_operand" "f")))]
4197   "TARGET_80387
4198    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4199    && !TARGET_MIX_SSE_I387"
4200   "* return output_387_reg_move (insn, operands);"
4201   [(set_attr "type" "fmov")
4202    (set_attr "mode" "SF")])
4204 (define_split
4205   [(set (match_operand:SF 0 "register_operand")
4206         (float_truncate:SF
4207          (match_operand:DF 1 "fp_register_operand")))
4208    (clobber (match_operand 2))]
4209   "reload_completed"
4210   [(set (match_dup 2) (match_dup 1))
4211    (set (match_dup 0) (match_dup 2))]
4212   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4214 ;; Conversion from XFmode to {SF,DF}mode
4216 (define_expand "truncxf<mode>2"
4217   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4218                    (float_truncate:MODEF
4219                      (match_operand:XF 1 "register_operand")))
4220               (clobber (match_dup 2))])]
4221   "TARGET_80387"
4223   if (flag_unsafe_math_optimizations)
4224     {
4225       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4226       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4227       if (reg != operands[0])
4228         emit_move_insn (operands[0], reg);
4229       DONE;
4230     }
4231   else
4232     operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4235 (define_insn "*truncxfsf2_mixed"
4236   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4237         (float_truncate:SF
4238           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4239    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4240   "TARGET_80387"
4242   gcc_assert (!which_alternative);
4243   return output_387_reg_move (insn, operands);
4245   [(set_attr "type" "fmov,multi,multi,multi")
4246    (set_attr "unit" "*,i387,i387,i387")
4247    (set_attr "mode" "SF")])
4249 (define_insn "*truncxfdf2_mixed"
4250   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4251         (float_truncate:DF
4252           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4253    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4254   "TARGET_80387"
4256   gcc_assert (!which_alternative);
4257   return output_387_reg_move (insn, operands);
4259   [(set_attr "isa" "*,*,sse2,*")
4260    (set_attr "type" "fmov,multi,multi,multi")
4261    (set_attr "unit" "*,i387,i387,i387")
4262    (set_attr "mode" "DF")])
4264 (define_insn "truncxf<mode>2_i387_noop"
4265   [(set (match_operand:MODEF 0 "register_operand" "=f")
4266         (float_truncate:MODEF
4267           (match_operand:XF 1 "register_operand" "f")))]
4268   "TARGET_80387 && flag_unsafe_math_optimizations"
4269   "* return output_387_reg_move (insn, operands);"
4270   [(set_attr "type" "fmov")
4271    (set_attr "mode" "<MODE>")])
4273 (define_insn "*truncxf<mode>2_i387"
4274   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4275         (float_truncate:MODEF
4276           (match_operand:XF 1 "register_operand" "f")))]
4277   "TARGET_80387"
4278   "* return output_387_reg_move (insn, operands);"
4279   [(set_attr "type" "fmov")
4280    (set_attr "mode" "<MODE>")])
4282 (define_split
4283   [(set (match_operand:MODEF 0 "register_operand")
4284         (float_truncate:MODEF
4285           (match_operand:XF 1 "register_operand")))
4286    (clobber (match_operand:MODEF 2 "memory_operand"))]
4287   "TARGET_80387 && reload_completed"
4288   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4289    (set (match_dup 0) (match_dup 2))])
4291 (define_split
4292   [(set (match_operand:MODEF 0 "memory_operand")
4293         (float_truncate:MODEF
4294           (match_operand:XF 1 "register_operand")))
4295    (clobber (match_operand:MODEF 2 "memory_operand"))]
4296   "TARGET_80387"
4297   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4299 ;; Signed conversion to DImode.
4301 (define_expand "fix_truncxfdi2"
4302   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4303                    (fix:DI (match_operand:XF 1 "register_operand")))
4304               (clobber (reg:CC FLAGS_REG))])]
4305   "TARGET_80387"
4307   if (TARGET_FISTTP)
4308    {
4309      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4310      DONE;
4311    }
4314 (define_expand "fix_trunc<mode>di2"
4315   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4316                    (fix:DI (match_operand:MODEF 1 "register_operand")))
4317               (clobber (reg:CC FLAGS_REG))])]
4318   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4320   if (TARGET_FISTTP
4321       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4322    {
4323      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4324      DONE;
4325    }
4326   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4327    {
4328      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4329      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4330      if (out != operands[0])
4331         emit_move_insn (operands[0], out);
4332      DONE;
4333    }
4336 ;; Signed conversion to SImode.
4338 (define_expand "fix_truncxfsi2"
4339   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4340                    (fix:SI (match_operand:XF 1 "register_operand")))
4341               (clobber (reg:CC FLAGS_REG))])]
4342   "TARGET_80387"
4344   if (TARGET_FISTTP)
4345    {
4346      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4347      DONE;
4348    }
4351 (define_expand "fix_trunc<mode>si2"
4352   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4353                    (fix:SI (match_operand:MODEF 1 "register_operand")))
4354               (clobber (reg:CC FLAGS_REG))])]
4355   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4357   if (TARGET_FISTTP
4358       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4359    {
4360      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4361      DONE;
4362    }
4363   if (SSE_FLOAT_MODE_P (<MODE>mode))
4364    {
4365      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4366      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4367      if (out != operands[0])
4368         emit_move_insn (operands[0], out);
4369      DONE;
4370    }
4373 ;; Signed conversion to HImode.
4375 (define_expand "fix_trunc<mode>hi2"
4376   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4377                    (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4378               (clobber (reg:CC FLAGS_REG))])]
4379   "TARGET_80387
4380    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4382   if (TARGET_FISTTP)
4383    {
4384      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4385      DONE;
4386    }
4389 ;; Unsigned conversion to SImode.
4391 (define_expand "fixuns_trunc<mode>si2"
4392   [(parallel
4393     [(set (match_operand:SI 0 "register_operand")
4394           (unsigned_fix:SI
4395             (match_operand:MODEF 1 "nonimmediate_operand")))
4396      (use (match_dup 2))
4397      (clobber (match_scratch:<ssevecmode> 3))
4398      (clobber (match_scratch:<ssevecmode> 4))])]
4399   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4401   enum machine_mode mode = <MODE>mode;
4402   enum machine_mode vecmode = <ssevecmode>mode;
4403   REAL_VALUE_TYPE TWO31r;
4404   rtx two31;
4406   if (optimize_insn_for_size_p ())
4407     FAIL;
4409   real_ldexp (&TWO31r, &dconst1, 31);
4410   two31 = const_double_from_real_value (TWO31r, mode);
4411   two31 = ix86_build_const_vector (vecmode, true, two31);
4412   operands[2] = force_reg (vecmode, two31);
4415 (define_insn_and_split "*fixuns_trunc<mode>_1"
4416   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4417         (unsigned_fix:SI
4418           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4419    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4420    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4421    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4422   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4423    && optimize_function_for_speed_p (cfun)"
4424   "#"
4425   "&& reload_completed"
4426   [(const_int 0)]
4428   ix86_split_convert_uns_si_sse (operands);
4429   DONE;
4432 ;; Unsigned conversion to HImode.
4433 ;; Without these patterns, we'll try the unsigned SI conversion which
4434 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4436 (define_expand "fixuns_trunc<mode>hi2"
4437   [(set (match_dup 2)
4438         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4439    (set (match_operand:HI 0 "nonimmediate_operand")
4440         (subreg:HI (match_dup 2) 0))]
4441   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4442   "operands[2] = gen_reg_rtx (SImode);")
4444 ;; When SSE is available, it is always faster to use it!
4445 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4446   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4447         (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4448   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4449    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4450   "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4451   [(set_attr "type" "sseicvt")
4452    (set_attr "prefix" "maybe_vex")
4453    (set (attr "prefix_rex")
4454         (if_then_else
4455           (match_test "<SWI48:MODE>mode == DImode")
4456           (const_string "1")
4457           (const_string "*")))
4458    (set_attr "mode" "<MODEF:MODE>")
4459    (set_attr "athlon_decode" "double,vector")
4460    (set_attr "amdfam10_decode" "double,double")
4461    (set_attr "bdver1_decode" "double,double")])
4463 ;; Avoid vector decoded forms of the instruction.
4464 (define_peephole2
4465   [(match_scratch:MODEF 2 "x")
4466    (set (match_operand:SWI48 0 "register_operand")
4467         (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4468   "TARGET_AVOID_VECTOR_DECODE
4469    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4470    && optimize_insn_for_speed_p ()"
4471   [(set (match_dup 2) (match_dup 1))
4472    (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4474 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4475   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4476         (fix:SWI248x (match_operand 1 "register_operand")))]
4477   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4478    && TARGET_FISTTP
4479    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4480          && (TARGET_64BIT || <MODE>mode != DImode))
4481         && TARGET_SSE_MATH)
4482    && can_create_pseudo_p ()"
4483   "#"
4484   "&& 1"
4485   [(const_int 0)]
4487   if (memory_operand (operands[0], VOIDmode))
4488     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4489   else
4490     {
4491       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4492       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4493                                                             operands[1],
4494                                                             operands[2]));
4495     }
4496   DONE;
4498   [(set_attr "type" "fisttp")
4499    (set_attr "mode" "<MODE>")])
4501 (define_insn "fix_trunc<mode>_i387_fisttp"
4502   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4503         (fix:SWI248x (match_operand 1 "register_operand" "f")))
4504    (clobber (match_scratch:XF 2 "=&1f"))]
4505   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4506    && TARGET_FISTTP
4507    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4508          && (TARGET_64BIT || <MODE>mode != DImode))
4509         && TARGET_SSE_MATH)"
4510   "* return output_fix_trunc (insn, operands, true);"
4511   [(set_attr "type" "fisttp")
4512    (set_attr "mode" "<MODE>")])
4514 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4515   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4516         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4517    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4518    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4519   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4520    && TARGET_FISTTP
4521    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4522         && (TARGET_64BIT || <MODE>mode != DImode))
4523         && TARGET_SSE_MATH)"
4524   "#"
4525   [(set_attr "type" "fisttp")
4526    (set_attr "mode" "<MODE>")])
4528 (define_split
4529   [(set (match_operand:SWI248x 0 "register_operand")
4530         (fix:SWI248x (match_operand 1 "register_operand")))
4531    (clobber (match_operand:SWI248x 2 "memory_operand"))
4532    (clobber (match_scratch 3))]
4533   "reload_completed"
4534   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4535               (clobber (match_dup 3))])
4536    (set (match_dup 0) (match_dup 2))])
4538 (define_split
4539   [(set (match_operand:SWI248x 0 "memory_operand")
4540         (fix:SWI248x (match_operand 1 "register_operand")))
4541    (clobber (match_operand:SWI248x 2 "memory_operand"))
4542    (clobber (match_scratch 3))]
4543   "reload_completed"
4544   [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4545               (clobber (match_dup 3))])])
4547 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4548 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4549 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4550 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4551 ;; function in i386.c.
4552 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4553   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4554         (fix:SWI248x (match_operand 1 "register_operand")))
4555    (clobber (reg:CC FLAGS_REG))]
4556   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4557    && !TARGET_FISTTP
4558    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4559          && (TARGET_64BIT || <MODE>mode != DImode))
4560    && can_create_pseudo_p ()"
4561   "#"
4562   "&& 1"
4563   [(const_int 0)]
4565   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4567   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4568   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4569   if (memory_operand (operands[0], VOIDmode))
4570     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4571                                          operands[2], operands[3]));
4572   else
4573     {
4574       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4575       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4576                                                      operands[2], operands[3],
4577                                                      operands[4]));
4578     }
4579   DONE;
4581   [(set_attr "type" "fistp")
4582    (set_attr "i387_cw" "trunc")
4583    (set_attr "mode" "<MODE>")])
4585 (define_insn "fix_truncdi_i387"
4586   [(set (match_operand:DI 0 "memory_operand" "=m")
4587         (fix:DI (match_operand 1 "register_operand" "f")))
4588    (use (match_operand:HI 2 "memory_operand" "m"))
4589    (use (match_operand:HI 3 "memory_operand" "m"))
4590    (clobber (match_scratch:XF 4 "=&1f"))]
4591   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4592    && !TARGET_FISTTP
4593    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4594   "* return output_fix_trunc (insn, operands, false);"
4595   [(set_attr "type" "fistp")
4596    (set_attr "i387_cw" "trunc")
4597    (set_attr "mode" "DI")])
4599 (define_insn "fix_truncdi_i387_with_temp"
4600   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4601         (fix:DI (match_operand 1 "register_operand" "f,f")))
4602    (use (match_operand:HI 2 "memory_operand" "m,m"))
4603    (use (match_operand:HI 3 "memory_operand" "m,m"))
4604    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4605    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4606   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4607    && !TARGET_FISTTP
4608    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4609   "#"
4610   [(set_attr "type" "fistp")
4611    (set_attr "i387_cw" "trunc")
4612    (set_attr "mode" "DI")])
4614 (define_split
4615   [(set (match_operand:DI 0 "register_operand")
4616         (fix:DI (match_operand 1 "register_operand")))
4617    (use (match_operand:HI 2 "memory_operand"))
4618    (use (match_operand:HI 3 "memory_operand"))
4619    (clobber (match_operand:DI 4 "memory_operand"))
4620    (clobber (match_scratch 5))]
4621   "reload_completed"
4622   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4623               (use (match_dup 2))
4624               (use (match_dup 3))
4625               (clobber (match_dup 5))])
4626    (set (match_dup 0) (match_dup 4))])
4628 (define_split
4629   [(set (match_operand:DI 0 "memory_operand")
4630         (fix:DI (match_operand 1 "register_operand")))
4631    (use (match_operand:HI 2 "memory_operand"))
4632    (use (match_operand:HI 3 "memory_operand"))
4633    (clobber (match_operand:DI 4 "memory_operand"))
4634    (clobber (match_scratch 5))]
4635   "reload_completed"
4636   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4637               (use (match_dup 2))
4638               (use (match_dup 3))
4639               (clobber (match_dup 5))])])
4641 (define_insn "fix_trunc<mode>_i387"
4642   [(set (match_operand:SWI24 0 "memory_operand" "=m")
4643         (fix:SWI24 (match_operand 1 "register_operand" "f")))
4644    (use (match_operand:HI 2 "memory_operand" "m"))
4645    (use (match_operand:HI 3 "memory_operand" "m"))]
4646   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4647    && !TARGET_FISTTP
4648    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4649   "* return output_fix_trunc (insn, operands, false);"
4650   [(set_attr "type" "fistp")
4651    (set_attr "i387_cw" "trunc")
4652    (set_attr "mode" "<MODE>")])
4654 (define_insn "fix_trunc<mode>_i387_with_temp"
4655   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4656         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4657    (use (match_operand:HI 2 "memory_operand" "m,m"))
4658    (use (match_operand:HI 3 "memory_operand" "m,m"))
4659    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4660   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4661    && !TARGET_FISTTP
4662    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4663   "#"
4664   [(set_attr "type" "fistp")
4665    (set_attr "i387_cw" "trunc")
4666    (set_attr "mode" "<MODE>")])
4668 (define_split
4669   [(set (match_operand:SWI24 0 "register_operand")
4670         (fix:SWI24 (match_operand 1 "register_operand")))
4671    (use (match_operand:HI 2 "memory_operand"))
4672    (use (match_operand:HI 3 "memory_operand"))
4673    (clobber (match_operand:SWI24 4 "memory_operand"))]
4674   "reload_completed"
4675   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4676               (use (match_dup 2))
4677               (use (match_dup 3))])
4678    (set (match_dup 0) (match_dup 4))])
4680 (define_split
4681   [(set (match_operand:SWI24 0 "memory_operand")
4682         (fix:SWI24 (match_operand 1 "register_operand")))
4683    (use (match_operand:HI 2 "memory_operand"))
4684    (use (match_operand:HI 3 "memory_operand"))
4685    (clobber (match_operand:SWI24 4 "memory_operand"))]
4686   "reload_completed"
4687   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4688               (use (match_dup 2))
4689               (use (match_dup 3))])])
4691 (define_insn "x86_fnstcw_1"
4692   [(set (match_operand:HI 0 "memory_operand" "=m")
4693         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4694   "TARGET_80387"
4695   "fnstcw\t%0"
4696   [(set (attr "length")
4697         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4698    (set_attr "mode" "HI")
4699    (set_attr "unit" "i387")
4700    (set_attr "bdver1_decode" "vector")])
4702 (define_insn "x86_fldcw_1"
4703   [(set (reg:HI FPCR_REG)
4704         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4705   "TARGET_80387"
4706   "fldcw\t%0"
4707   [(set (attr "length")
4708         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4709    (set_attr "mode" "HI")
4710    (set_attr "unit" "i387")
4711    (set_attr "athlon_decode" "vector")
4712    (set_attr "amdfam10_decode" "vector")
4713    (set_attr "bdver1_decode" "vector")])
4715 ;; Conversion between fixed point and floating point.
4717 ;; Even though we only accept memory inputs, the backend _really_
4718 ;; wants to be able to do this between registers.  Thankfully, LRA
4719 ;; will fix this up for us during register allocation.
4721 (define_insn "floathi<mode>2"
4722   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4723         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
4724   "TARGET_80387
4725    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4726        || TARGET_MIX_SSE_I387)"
4727   "fild%Z1\t%1"
4728   [(set_attr "type" "fmov")
4729    (set_attr "mode" "<MODE>")
4730    (set_attr "fp_int_src" "true")])
4732 (define_insn "float<SWI48x:mode>xf2"
4733   [(set (match_operand:XF 0 "register_operand" "=f")
4734         (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4735   "TARGET_80387"
4736   "fild%Z1\t%1"
4737   [(set_attr "type" "fmov")
4738    (set_attr "mode" "XF")
4739    (set_attr "fp_int_src" "true")])
4741 (define_expand "float<SWI48:mode><MODEF:mode>2"
4742   [(set (match_operand:MODEF 0 "register_operand")
4743         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4744   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
4746   if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
4747       && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
4748     {
4749       rtx reg = gen_reg_rtx (XFmode);
4750       rtx (*insn)(rtx, rtx);
4752       emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
4754       if (<MODEF:MODE>mode == SFmode)
4755         insn = gen_truncxfsf2;
4756       else if (<MODEF:MODE>mode == DFmode)
4757         insn = gen_truncxfdf2;
4758       else
4759         gcc_unreachable ();
4761       emit_insn (insn (operands[0], reg));
4762       DONE;
4763     }
4766 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse"
4767   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4768         (float:MODEF
4769           (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4770   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4771   "@
4772    fild%Z1\t%1
4773    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4774    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4775   [(set_attr "type" "fmov,sseicvt,sseicvt")
4776    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4777    (set_attr "mode" "<MODEF:MODE>")
4778    (set (attr "prefix_rex")
4779      (if_then_else
4780        (and (eq_attr "prefix" "maybe_vex")
4781             (match_test "<SWI48:MODE>mode == DImode"))
4782        (const_string "1")
4783        (const_string "*")))
4784    (set_attr "unit" "i387,*,*")
4785    (set_attr "athlon_decode" "*,double,direct")
4786    (set_attr "amdfam10_decode" "*,vector,double")
4787    (set_attr "bdver1_decode" "*,double,direct")
4788    (set_attr "fp_int_src" "true")
4789    (set (attr "enabled")
4790      (cond [(eq_attr "alternative" "0")
4791               (symbol_ref "TARGET_MIX_SSE_I387
4792                            && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
4793                                                 <SWI48:MODE>mode)")
4794             (eq_attr "alternative" "1")
4795               /* ??? For sched1 we need constrain_operands to be able to
4796                  select an alternative.  Leave this enabled before RA.  */
4797               (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS
4798                            || optimize_function_for_size_p (cfun)
4799                            || !(reload_completed
4800                                 || reload_in_progress
4801                                 || lra_in_progress)")
4802            ]
4803            (symbol_ref "true")))
4804    ])
4806 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
4807   [(set (match_operand:MODEF 0 "register_operand" "=f")
4808         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4809   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
4810   "fild%Z1\t%1"
4811   [(set_attr "type" "fmov")
4812    (set_attr "mode" "<MODEF:MODE>")
4813    (set_attr "fp_int_src" "true")])
4815 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
4816 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
4817 ;; alternative in sse2_loadld.
4818 (define_split
4819   [(set (match_operand:MODEF 0 "register_operand")
4820         (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
4821   "TARGET_SSE2 && TARGET_SSE_MATH
4822    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4823    && reload_completed && SSE_REG_P (operands[0])
4824    && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)"
4825   [(const_int 0)]
4827   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4828                                      <MODE>mode, 0);
4829   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4831   emit_insn (gen_sse2_loadld (operands[4],
4832                               CONST0_RTX (V4SImode), operands[1]));
4834   if (<ssevecmode>mode == V4SFmode)
4835     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4836   else
4837     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4838   DONE;
4841 ;; Avoid partial SSE register dependency stalls
4842 (define_split
4843   [(set (match_operand:MODEF 0 "register_operand")
4844         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4845   "TARGET_SSE2 && TARGET_SSE_MATH
4846    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4847    && optimize_function_for_speed_p (cfun)
4848    && reload_completed && SSE_REG_P (operands[0])"
4849   [(const_int 0)]
4851   const enum machine_mode vmode = <MODEF:ssevecmode>mode;
4852   const enum machine_mode mode = <MODEF:MODE>mode;
4853   rtx t, op0 = simplify_gen_subreg (vmode, operands[0], mode, 0);
4855   emit_move_insn (op0, CONST0_RTX (vmode));
4857   t = gen_rtx_FLOAT (mode, operands[1]);
4858   t = gen_rtx_VEC_DUPLICATE (vmode, t);
4859   t = gen_rtx_VEC_MERGE (vmode, t, op0, const1_rtx);
4860   emit_insn (gen_rtx_SET (VOIDmode, op0, t));
4861   DONE;
4864 ;; Break partial reg stall for cvtsd2ss.
4866 (define_peephole2
4867   [(set (match_operand:SF 0 "register_operand")
4868         (float_truncate:SF
4869           (match_operand:DF 1 "nonimmediate_operand")))]
4870   "TARGET_SSE2 && TARGET_SSE_MATH
4871    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4872    && optimize_function_for_speed_p (cfun)
4873    && SSE_REG_P (operands[0])
4874    && (!SSE_REG_P (operands[1])
4875        || REGNO (operands[0]) != REGNO (operands[1]))"
4876   [(set (match_dup 0)
4877         (vec_merge:V4SF
4878           (vec_duplicate:V4SF
4879             (float_truncate:V2SF
4880               (match_dup 1)))
4881           (match_dup 0)
4882           (const_int 1)))]
4884   operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
4885                                      SFmode, 0);
4886   operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
4887                                      DFmode, 0);
4888   emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
4891 ;; Break partial reg stall for cvtss2sd.
4893 (define_peephole2
4894   [(set (match_operand:DF 0 "register_operand")
4895         (float_extend:DF
4896           (match_operand:SF 1 "nonimmediate_operand")))]
4897   "TARGET_SSE2 && TARGET_SSE_MATH
4898    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4899    && optimize_function_for_speed_p (cfun)
4900    && SSE_REG_P (operands[0])
4901    && (!SSE_REG_P (operands[1])
4902        || REGNO (operands[0]) != REGNO (operands[1]))"
4903   [(set (match_dup 0)
4904         (vec_merge:V2DF
4905           (float_extend:V2DF
4906             (vec_select:V2SF
4907               (match_dup 1)
4908               (parallel [(const_int 0) (const_int 1)])))
4909           (match_dup 0)
4910           (const_int 1)))]
4912   operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
4913                                      DFmode, 0);
4914   operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
4915                                      SFmode, 0);
4916   emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
4919 ;; Avoid store forwarding (partial memory) stall penalty
4920 ;; by passing DImode value through XMM registers.  */
4922 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
4923   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4924         (float:X87MODEF
4925           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
4926    (clobber (match_scratch:V4SI 3 "=X,x"))
4927    (clobber (match_scratch:V4SI 4 "=X,x"))
4928    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
4929   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4930    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4931    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
4932   "#"
4933   [(set_attr "type" "multi")
4934    (set_attr "mode" "<X87MODEF:MODE>")
4935    (set_attr "unit" "i387")
4936    (set_attr "fp_int_src" "true")])
4938 (define_split
4939   [(set (match_operand:X87MODEF 0 "fp_register_operand")
4940         (float:X87MODEF (match_operand:DI 1 "register_operand")))
4941    (clobber (match_scratch:V4SI 3))
4942    (clobber (match_scratch:V4SI 4))
4943    (clobber (match_operand:DI 2 "memory_operand"))]
4944   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4945    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4946    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
4947    && reload_completed"
4948   [(set (match_dup 2) (match_dup 3))
4949    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
4951   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
4952      Assemble the 64-bit DImode value in an xmm register.  */
4953   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
4954                               gen_rtx_SUBREG (SImode, operands[1], 0)));
4955   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
4956                               gen_rtx_SUBREG (SImode, operands[1], 4)));
4957   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
4958                                          operands[4]));
4960   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
4963 (define_split
4964   [(set (match_operand:X87MODEF 0 "fp_register_operand")
4965         (float:X87MODEF (match_operand:DI 1 "memory_operand")))
4966    (clobber (match_scratch:V4SI 3))
4967    (clobber (match_scratch:V4SI 4))
4968    (clobber (match_operand:DI 2 "memory_operand"))]
4969   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4970    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4971    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
4972    && reload_completed"
4973   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4975 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
4976   [(set (match_operand:MODEF 0 "register_operand")
4977         (unsigned_float:MODEF
4978           (match_operand:SWI12 1 "nonimmediate_operand")))]
4979   "!TARGET_64BIT
4980    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4982   operands[1] = convert_to_mode (SImode, operands[1], 1);
4983   emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
4984   DONE;
4987 ;; Avoid store forwarding (partial memory) stall penalty by extending
4988 ;; SImode value to DImode through XMM register instead of pushing two
4989 ;; SImode values to stack. Also note that fild loads from memory only.
4991 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
4992   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4993         (unsigned_float:X87MODEF
4994           (match_operand:SI 1 "nonimmediate_operand" "rm")))
4995    (clobber (match_scratch:DI 3 "=x"))
4996    (clobber (match_operand:DI 2 "memory_operand" "=m"))]
4997   "!TARGET_64BIT
4998    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4999    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5000   "#"
5001   "&& reload_completed"
5002   [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5003    (set (match_dup 2) (match_dup 3))
5004    (set (match_dup 0)
5005         (float:X87MODEF (match_dup 2)))]
5006   ""
5007   [(set_attr "type" "multi")
5008    (set_attr "mode" "<MODE>")])
5010 (define_expand "floatunssi<mode>2"
5011   [(parallel
5012      [(set (match_operand:X87MODEF 0 "register_operand")
5013            (unsigned_float:X87MODEF
5014              (match_operand:SI 1 "nonimmediate_operand")))
5015       (clobber (match_scratch:DI 3))
5016       (clobber (match_dup 2))])]
5017   "!TARGET_64BIT
5018    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5019         && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5020        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5022   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5023     {
5024       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5025       DONE;
5026     }
5027   else
5028     operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5031 (define_expand "floatunsdisf2"
5032   [(use (match_operand:SF 0 "register_operand"))
5033    (use (match_operand:DI 1 "nonimmediate_operand"))]
5034   "TARGET_64BIT && TARGET_SSE_MATH"
5035   "x86_emit_floatuns (operands); DONE;")
5037 (define_expand "floatunsdidf2"
5038   [(use (match_operand:DF 0 "register_operand"))
5039    (use (match_operand:DI 1 "nonimmediate_operand"))]
5040   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5041    && TARGET_SSE2 && TARGET_SSE_MATH"
5043   if (TARGET_64BIT)
5044     x86_emit_floatuns (operands);
5045   else
5046     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5047   DONE;
5050 ;; Load effective address instructions
5052 (define_insn_and_split "*lea<mode>"
5053   [(set (match_operand:SWI48 0 "register_operand" "=r")
5054         (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5055   ""
5057   if (SImode_address_operand (operands[1], VOIDmode))
5058     {
5059       gcc_assert (TARGET_64BIT);
5060       return "lea{l}\t{%E1, %k0|%k0, %E1}";
5061     }
5062   else 
5063     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5065   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5066   [(const_int 0)]
5068   enum machine_mode mode = <MODE>mode;
5069   rtx pat;
5071   /* ix86_avoid_lea_for_addr re-recognizes insn and may
5072      change operands[] array behind our back.  */
5073   pat = PATTERN (curr_insn);
5075   operands[0] = SET_DEST (pat);
5076   operands[1] = SET_SRC (pat);
5078   /* Emit all operations in SImode for zero-extended addresses.  */
5079   if (SImode_address_operand (operands[1], VOIDmode))
5080     mode = SImode;
5082   ix86_split_lea_for_addr (curr_insn, operands, mode);
5084   /* Zero-extend return register to DImode for zero-extended addresses.  */
5085   if (mode != <MODE>mode)
5086     emit_insn (gen_zero_extendsidi2
5087                (operands[0], gen_lowpart (mode, operands[0])));
5089   DONE;
5091   [(set_attr "type" "lea")
5092    (set (attr "mode")
5093      (if_then_else
5094        (match_operand 1 "SImode_address_operand")
5095        (const_string "SI")
5096        (const_string "<MODE>")))])
5098 ;; Add instructions
5100 (define_expand "add<mode>3"
5101   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5102         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5103                     (match_operand:SDWIM 2 "<general_operand>")))]
5104   ""
5105   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5107 (define_insn_and_split "*add<dwi>3_doubleword"
5108   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5109         (plus:<DWI>
5110           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5111           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5112    (clobber (reg:CC FLAGS_REG))]
5113   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5114   "#"
5115   "reload_completed"
5116   [(parallel [(set (reg:CC FLAGS_REG)
5117                    (unspec:CC [(match_dup 1) (match_dup 2)]
5118                               UNSPEC_ADD_CARRY))
5119               (set (match_dup 0)
5120                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5121    (parallel [(set (match_dup 3)
5122                    (plus:DWIH
5123                      (match_dup 4)
5124                      (plus:DWIH
5125                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5126                        (match_dup 5))))
5127               (clobber (reg:CC FLAGS_REG))])]
5128   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5130 (define_insn "*add<mode>3_cc"
5131   [(set (reg:CC FLAGS_REG)
5132         (unspec:CC
5133           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5134            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5135           UNSPEC_ADD_CARRY))
5136    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5137         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5138   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5139   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5140   [(set_attr "type" "alu")
5141    (set_attr "mode" "<MODE>")])
5143 (define_insn "addqi3_cc"
5144   [(set (reg:CC FLAGS_REG)
5145         (unspec:CC
5146           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5147            (match_operand:QI 2 "general_operand" "qn,qm")]
5148           UNSPEC_ADD_CARRY))
5149    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5150         (plus:QI (match_dup 1) (match_dup 2)))]
5151   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5152   "add{b}\t{%2, %0|%0, %2}"
5153   [(set_attr "type" "alu")
5154    (set_attr "mode" "QI")])
5156 (define_insn "*add<mode>_1"
5157   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5158         (plus:SWI48
5159           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5160           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5161    (clobber (reg:CC FLAGS_REG))]
5162   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5164   switch (get_attr_type (insn))
5165     {
5166     case TYPE_LEA:
5167       return "#";
5169     case TYPE_INCDEC:
5170       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5171       if (operands[2] == const1_rtx)
5172         return "inc{<imodesuffix>}\t%0";
5173       else
5174         {
5175           gcc_assert (operands[2] == constm1_rtx);
5176           return "dec{<imodesuffix>}\t%0";
5177         }
5179     default:
5180       /* For most processors, ADD is faster than LEA.  This alternative
5181          was added to use ADD as much as possible.  */
5182       if (which_alternative == 2)
5183         {
5184           rtx tmp;
5185           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5186         }
5187         
5188       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5189       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5190         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5192       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5193     }
5195   [(set (attr "type")
5196      (cond [(eq_attr "alternative" "3")
5197               (const_string "lea")
5198             (match_operand:SWI48 2 "incdec_operand")
5199               (const_string "incdec")
5200            ]
5201            (const_string "alu")))
5202    (set (attr "length_immediate")
5203       (if_then_else
5204         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5205         (const_string "1")
5206         (const_string "*")))
5207    (set_attr "mode" "<MODE>")])
5209 ;; It may seem that nonimmediate operand is proper one for operand 1.
5210 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5211 ;; we take care in ix86_binary_operator_ok to not allow two memory
5212 ;; operands so proper swapping will be done in reload.  This allow
5213 ;; patterns constructed from addsi_1 to match.
5215 (define_insn "addsi_1_zext"
5216   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5217         (zero_extend:DI
5218           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5219                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5220    (clobber (reg:CC FLAGS_REG))]
5221   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5223   switch (get_attr_type (insn))
5224     {
5225     case TYPE_LEA:
5226       return "#";
5228     case TYPE_INCDEC:
5229       if (operands[2] == const1_rtx)
5230         return "inc{l}\t%k0";
5231       else
5232         {
5233           gcc_assert (operands[2] == constm1_rtx);
5234           return "dec{l}\t%k0";
5235         }
5237     default:
5238       /* For most processors, ADD is faster than LEA.  This alternative
5239          was added to use ADD as much as possible.  */
5240       if (which_alternative == 1)
5241         {
5242           rtx tmp;
5243           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5244         }
5246       if (x86_maybe_negate_const_int (&operands[2], SImode))
5247         return "sub{l}\t{%2, %k0|%k0, %2}";
5249       return "add{l}\t{%2, %k0|%k0, %2}";
5250     }
5252   [(set (attr "type")
5253      (cond [(eq_attr "alternative" "2")
5254               (const_string "lea")
5255             (match_operand:SI 2 "incdec_operand")
5256               (const_string "incdec")
5257            ]
5258            (const_string "alu")))
5259    (set (attr "length_immediate")
5260       (if_then_else
5261         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5262         (const_string "1")
5263         (const_string "*")))
5264    (set_attr "mode" "SI")])
5266 (define_insn "*addhi_1"
5267   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5268         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5269                  (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5270    (clobber (reg:CC FLAGS_REG))]
5271   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5273   switch (get_attr_type (insn))
5274     {
5275     case TYPE_LEA:
5276       return "#";
5278     case TYPE_INCDEC:
5279       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5280       if (operands[2] == const1_rtx)
5281         return "inc{w}\t%0";
5282       else
5283         {
5284           gcc_assert (operands[2] == constm1_rtx);
5285           return "dec{w}\t%0";
5286         }
5288     default:
5289       /* For most processors, ADD is faster than LEA.  This alternative
5290          was added to use ADD as much as possible.  */
5291       if (which_alternative == 2)
5292         {
5293           rtx tmp;
5294           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5295         }
5297       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5298       if (x86_maybe_negate_const_int (&operands[2], HImode))
5299         return "sub{w}\t{%2, %0|%0, %2}";
5301       return "add{w}\t{%2, %0|%0, %2}";
5302     }
5304   [(set (attr "type")
5305      (cond [(eq_attr "alternative" "3")
5306               (const_string "lea")
5307             (match_operand:HI 2 "incdec_operand")
5308               (const_string "incdec")
5309            ]
5310            (const_string "alu")))
5311    (set (attr "length_immediate")
5312       (if_then_else
5313         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5314         (const_string "1")
5315         (const_string "*")))
5316    (set_attr "mode" "HI,HI,HI,SI")])
5318 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5319 (define_insn "*addqi_1"
5320   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5321         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5322                  (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5323    (clobber (reg:CC FLAGS_REG))]
5324   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5326   bool widen = (which_alternative == 3 || which_alternative == 4);
5328   switch (get_attr_type (insn))
5329     {
5330     case TYPE_LEA:
5331       return "#";
5333     case TYPE_INCDEC:
5334       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5335       if (operands[2] == const1_rtx)
5336         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5337       else
5338         {
5339           gcc_assert (operands[2] == constm1_rtx);
5340           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5341         }
5343     default:
5344       /* For most processors, ADD is faster than LEA.  These alternatives
5345          were added to use ADD as much as possible.  */
5346       if (which_alternative == 2 || which_alternative == 4)
5347         {
5348           rtx tmp;
5349           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5350         }
5352       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5353       if (x86_maybe_negate_const_int (&operands[2], QImode))
5354         {
5355           if (widen)
5356             return "sub{l}\t{%2, %k0|%k0, %2}";
5357           else
5358             return "sub{b}\t{%2, %0|%0, %2}";
5359         }
5360       if (widen)
5361         return "add{l}\t{%k2, %k0|%k0, %k2}";
5362       else
5363         return "add{b}\t{%2, %0|%0, %2}";
5364     }
5366   [(set (attr "type")
5367      (cond [(eq_attr "alternative" "5")
5368               (const_string "lea")
5369             (match_operand:QI 2 "incdec_operand")
5370               (const_string "incdec")
5371            ]
5372            (const_string "alu")))
5373    (set (attr "length_immediate")
5374       (if_then_else
5375         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5376         (const_string "1")
5377         (const_string "*")))
5378    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5380 (define_insn "*addqi_1_slp"
5381   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5382         (plus:QI (match_dup 0)
5383                  (match_operand:QI 1 "general_operand" "qn,qm")))
5384    (clobber (reg:CC FLAGS_REG))]
5385   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5386    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5388   switch (get_attr_type (insn))
5389     {
5390     case TYPE_INCDEC:
5391       if (operands[1] == const1_rtx)
5392         return "inc{b}\t%0";
5393       else
5394         {
5395           gcc_assert (operands[1] == constm1_rtx);
5396           return "dec{b}\t%0";
5397         }
5399     default:
5400       if (x86_maybe_negate_const_int (&operands[1], QImode))
5401         return "sub{b}\t{%1, %0|%0, %1}";
5403       return "add{b}\t{%1, %0|%0, %1}";
5404     }
5406   [(set (attr "type")
5407      (if_then_else (match_operand:QI 1 "incdec_operand")
5408         (const_string "incdec")
5409         (const_string "alu1")))
5410    (set (attr "memory")
5411      (if_then_else (match_operand 1 "memory_operand")
5412         (const_string "load")
5413         (const_string "none")))
5414    (set_attr "mode" "QI")])
5416 ;; Split non destructive adds if we cannot use lea.
5417 (define_split
5418   [(set (match_operand:SWI48 0 "register_operand")
5419         (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5420                     (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5421    (clobber (reg:CC FLAGS_REG))]
5422   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5423   [(set (match_dup 0) (match_dup 1))
5424    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5425               (clobber (reg:CC FLAGS_REG))])])
5427 ;; Convert add to the lea pattern to avoid flags dependency.
5428 (define_split
5429   [(set (match_operand:SWI 0 "register_operand")
5430         (plus:SWI (match_operand:SWI 1 "register_operand")
5431                   (match_operand:SWI 2 "<nonmemory_operand>")))
5432    (clobber (reg:CC FLAGS_REG))]
5433   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5434   [(const_int 0)]
5436   enum machine_mode mode = <MODE>mode;
5437   rtx pat;
5439   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
5440     { 
5441       mode = SImode; 
5442       operands[0] = gen_lowpart (mode, operands[0]);
5443       operands[1] = gen_lowpart (mode, operands[1]);
5444       operands[2] = gen_lowpart (mode, operands[2]);
5445     }
5447   pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5449   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5450   DONE;
5453 ;; Split non destructive adds if we cannot use lea.
5454 (define_split
5455   [(set (match_operand:DI 0 "register_operand")
5456         (zero_extend:DI
5457           (plus:SI (match_operand:SI 1 "register_operand")
5458                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5459    (clobber (reg:CC FLAGS_REG))]
5460   "TARGET_64BIT
5461    && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5462   [(set (match_dup 3) (match_dup 1))
5463    (parallel [(set (match_dup 0)
5464                    (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5465               (clobber (reg:CC FLAGS_REG))])]
5466   "operands[3] = gen_lowpart (SImode, operands[0]);")
5468 ;; Convert add to the lea pattern to avoid flags dependency.
5469 (define_split
5470   [(set (match_operand:DI 0 "register_operand")
5471         (zero_extend:DI
5472           (plus:SI (match_operand:SI 1 "register_operand")
5473                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5474    (clobber (reg:CC FLAGS_REG))]
5475   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5476   [(set (match_dup 0)
5477         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5479 (define_insn "*add<mode>_2"
5480   [(set (reg FLAGS_REG)
5481         (compare
5482           (plus:SWI
5483             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5484             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5485           (const_int 0)))
5486    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5487         (plus:SWI (match_dup 1) (match_dup 2)))]
5488   "ix86_match_ccmode (insn, CCGOCmode)
5489    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5491   switch (get_attr_type (insn))
5492     {
5493     case TYPE_INCDEC:
5494       if (operands[2] == const1_rtx)
5495         return "inc{<imodesuffix>}\t%0";
5496       else
5497         {
5498           gcc_assert (operands[2] == constm1_rtx);
5499           return "dec{<imodesuffix>}\t%0";
5500         }
5502     default:
5503       if (which_alternative == 2)
5504         {
5505           rtx tmp;
5506           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5507         }
5508         
5509       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5510       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5511         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5513       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5514     }
5516   [(set (attr "type")
5517      (if_then_else (match_operand:SWI 2 "incdec_operand")
5518         (const_string "incdec")
5519         (const_string "alu")))
5520    (set (attr "length_immediate")
5521       (if_then_else
5522         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5523         (const_string "1")
5524         (const_string "*")))
5525    (set_attr "mode" "<MODE>")])
5527 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5528 (define_insn "*addsi_2_zext"
5529   [(set (reg FLAGS_REG)
5530         (compare
5531           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5532                    (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5533           (const_int 0)))
5534    (set (match_operand:DI 0 "register_operand" "=r,r")
5535         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5536   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5537    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5539   switch (get_attr_type (insn))
5540     {
5541     case TYPE_INCDEC:
5542       if (operands[2] == const1_rtx)
5543         return "inc{l}\t%k0";
5544       else
5545         {
5546           gcc_assert (operands[2] == constm1_rtx);
5547           return "dec{l}\t%k0";
5548         }
5550     default:
5551       if (which_alternative == 1)
5552         {
5553           rtx tmp;
5554           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5555         }
5557       if (x86_maybe_negate_const_int (&operands[2], SImode))
5558         return "sub{l}\t{%2, %k0|%k0, %2}";
5560       return "add{l}\t{%2, %k0|%k0, %2}";
5561     }
5563   [(set (attr "type")
5564      (if_then_else (match_operand:SI 2 "incdec_operand")
5565         (const_string "incdec")
5566         (const_string "alu")))
5567    (set (attr "length_immediate")
5568       (if_then_else
5569         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5570         (const_string "1")
5571         (const_string "*")))
5572    (set_attr "mode" "SI")])
5574 (define_insn "*add<mode>_3"
5575   [(set (reg FLAGS_REG)
5576         (compare
5577           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5578           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5579    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5580   "ix86_match_ccmode (insn, CCZmode)
5581    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5583   switch (get_attr_type (insn))
5584     {
5585     case TYPE_INCDEC:
5586       if (operands[2] == const1_rtx)
5587         return "inc{<imodesuffix>}\t%0";
5588       else
5589         {
5590           gcc_assert (operands[2] == constm1_rtx);
5591           return "dec{<imodesuffix>}\t%0";
5592         }
5594     default:
5595       if (which_alternative == 1)
5596         {
5597           rtx tmp;
5598           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5599         }
5601       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5602       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5603         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5605       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5606     }
5608   [(set (attr "type")
5609      (if_then_else (match_operand:SWI 2 "incdec_operand")
5610         (const_string "incdec")
5611         (const_string "alu")))
5612    (set (attr "length_immediate")
5613       (if_then_else
5614         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5615         (const_string "1")
5616         (const_string "*")))
5617    (set_attr "mode" "<MODE>")])
5619 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5620 (define_insn "*addsi_3_zext"
5621   [(set (reg FLAGS_REG)
5622         (compare
5623           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5624           (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5625    (set (match_operand:DI 0 "register_operand" "=r,r")
5626         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5627   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5628    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5630   switch (get_attr_type (insn))
5631     {
5632     case TYPE_INCDEC:
5633       if (operands[2] == const1_rtx)
5634         return "inc{l}\t%k0";
5635       else
5636         {
5637           gcc_assert (operands[2] == constm1_rtx);
5638           return "dec{l}\t%k0";
5639         }
5641     default:
5642       if (which_alternative == 1)
5643         {
5644           rtx tmp;
5645           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5646         }
5648       if (x86_maybe_negate_const_int (&operands[2], SImode))
5649         return "sub{l}\t{%2, %k0|%k0, %2}";
5651       return "add{l}\t{%2, %k0|%k0, %2}";
5652     }
5654   [(set (attr "type")
5655      (if_then_else (match_operand:SI 2 "incdec_operand")
5656         (const_string "incdec")
5657         (const_string "alu")))
5658    (set (attr "length_immediate")
5659       (if_then_else
5660         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5661         (const_string "1")
5662         (const_string "*")))
5663    (set_attr "mode" "SI")])
5665 ; For comparisons against 1, -1 and 128, we may generate better code
5666 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5667 ; is matched then.  We can't accept general immediate, because for
5668 ; case of overflows,  the result is messed up.
5669 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5670 ; only for comparisons not depending on it.
5672 (define_insn "*adddi_4"
5673   [(set (reg FLAGS_REG)
5674         (compare
5675           (match_operand:DI 1 "nonimmediate_operand" "0")
5676           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5677    (clobber (match_scratch:DI 0 "=rm"))]
5678   "TARGET_64BIT
5679    && ix86_match_ccmode (insn, CCGCmode)"
5681   switch (get_attr_type (insn))
5682     {
5683     case TYPE_INCDEC:
5684       if (operands[2] == constm1_rtx)
5685         return "inc{q}\t%0";
5686       else
5687         {
5688           gcc_assert (operands[2] == const1_rtx);
5689           return "dec{q}\t%0";
5690         }
5692     default:
5693       if (x86_maybe_negate_const_int (&operands[2], DImode))
5694         return "add{q}\t{%2, %0|%0, %2}";
5696       return "sub{q}\t{%2, %0|%0, %2}";
5697     }
5699   [(set (attr "type")
5700      (if_then_else (match_operand:DI 2 "incdec_operand")
5701         (const_string "incdec")
5702         (const_string "alu")))
5703    (set (attr "length_immediate")
5704       (if_then_else
5705         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5706         (const_string "1")
5707         (const_string "*")))
5708    (set_attr "mode" "DI")])
5710 ; For comparisons against 1, -1 and 128, we may generate better code
5711 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5712 ; is matched then.  We can't accept general immediate, because for
5713 ; case of overflows,  the result is messed up.
5714 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5715 ; only for comparisons not depending on it.
5717 (define_insn "*add<mode>_4"
5718   [(set (reg FLAGS_REG)
5719         (compare
5720           (match_operand:SWI124 1 "nonimmediate_operand" "0")
5721           (match_operand:SWI124 2 "const_int_operand" "n")))
5722    (clobber (match_scratch:SWI124 0 "=<r>m"))]
5723   "ix86_match_ccmode (insn, CCGCmode)"
5725   switch (get_attr_type (insn))
5726     {
5727     case TYPE_INCDEC:
5728       if (operands[2] == constm1_rtx)
5729         return "inc{<imodesuffix>}\t%0";
5730       else
5731         {
5732           gcc_assert (operands[2] == const1_rtx);
5733           return "dec{<imodesuffix>}\t%0";
5734         }
5736     default:
5737       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5738         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5740       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5741     }
5743   [(set (attr "type")
5744      (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5745         (const_string "incdec")
5746         (const_string "alu")))
5747    (set (attr "length_immediate")
5748       (if_then_else
5749         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5750         (const_string "1")
5751         (const_string "*")))
5752    (set_attr "mode" "<MODE>")])
5754 (define_insn "*add<mode>_5"
5755   [(set (reg FLAGS_REG)
5756         (compare
5757           (plus:SWI
5758             (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5759             (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5760           (const_int 0)))
5761    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5762   "ix86_match_ccmode (insn, CCGOCmode)
5763    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5765   switch (get_attr_type (insn))
5766     {
5767     case TYPE_INCDEC:
5768       if (operands[2] == const1_rtx)
5769         return "inc{<imodesuffix>}\t%0";
5770       else
5771         {
5772           gcc_assert (operands[2] == constm1_rtx);
5773           return "dec{<imodesuffix>}\t%0";
5774         }
5776     default:
5777       if (which_alternative == 1)
5778         {
5779           rtx tmp;
5780           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5781         }
5783       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5784       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5785         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5787       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5788     }
5790   [(set (attr "type")
5791      (if_then_else (match_operand:SWI 2 "incdec_operand")
5792         (const_string "incdec")
5793         (const_string "alu")))
5794    (set (attr "length_immediate")
5795       (if_then_else
5796         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5797         (const_string "1")
5798         (const_string "*")))
5799    (set_attr "mode" "<MODE>")])
5801 (define_insn "addqi_ext_1"
5802   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
5803                          (const_int 8)
5804                          (const_int 8))
5805         (plus:SI
5806           (zero_extract:SI
5807             (match_operand 1 "ext_register_operand" "0,0")
5808             (const_int 8)
5809             (const_int 8))
5810           (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
5811    (clobber (reg:CC FLAGS_REG))]
5812   ""
5814   switch (get_attr_type (insn))
5815     {
5816     case TYPE_INCDEC:
5817       if (operands[2] == const1_rtx)
5818         return "inc{b}\t%h0";
5819       else
5820         {
5821           gcc_assert (operands[2] == constm1_rtx);
5822           return "dec{b}\t%h0";
5823         }
5825     default:
5826       return "add{b}\t{%2, %h0|%h0, %2}";
5827     }
5829   [(set_attr "isa" "*,nox64")
5830    (set (attr "type")
5831      (if_then_else (match_operand:QI 2 "incdec_operand")
5832         (const_string "incdec")
5833         (const_string "alu")))
5834    (set_attr "modrm" "1")
5835    (set_attr "mode" "QI")])
5837 (define_insn "*addqi_ext_2"
5838   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5839                          (const_int 8)
5840                          (const_int 8))
5841         (plus:SI
5842           (zero_extract:SI
5843             (match_operand 1 "ext_register_operand" "%0")
5844             (const_int 8)
5845             (const_int 8))
5846           (zero_extract:SI
5847             (match_operand 2 "ext_register_operand" "Q")
5848             (const_int 8)
5849             (const_int 8))))
5850    (clobber (reg:CC FLAGS_REG))]
5851   ""
5852   "add{b}\t{%h2, %h0|%h0, %h2}"
5853   [(set_attr "type" "alu")
5854    (set_attr "mode" "QI")])
5856 ;; Add with jump on overflow.
5857 (define_expand "addv<mode>4"
5858   [(parallel [(set (reg:CCO FLAGS_REG)
5859                    (eq:CCO (plus:<DWI>
5860                               (sign_extend:<DWI>
5861                                  (match_operand:SWI 1 "nonimmediate_operand"))
5862                               (match_dup 4))
5863                            (sign_extend:<DWI>
5864                               (plus:SWI (match_dup 1)
5865                                         (match_operand:SWI 2
5866                                            "<general_operand>")))))
5867               (set (match_operand:SWI 0 "register_operand")
5868                    (plus:SWI (match_dup 1) (match_dup 2)))])
5869    (set (pc) (if_then_else
5870                (eq (reg:CCO FLAGS_REG) (const_int 0))
5871                (label_ref (match_operand 3))
5872                (pc)))]
5873   ""
5875   ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
5876   if (CONST_INT_P (operands[2]))
5877     operands[4] = operands[2];
5878   else
5879     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
5882 (define_insn "*addv<mode>4"
5883   [(set (reg:CCO FLAGS_REG)
5884         (eq:CCO (plus:<DWI>
5885                    (sign_extend:<DWI>
5886                       (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
5887                    (sign_extend:<DWI>
5888                       (match_operand:SWI 2 "<general_sext_operand>"
5889                                            "<r>mWe,<r>We")))
5890                 (sign_extend:<DWI>
5891                    (plus:SWI (match_dup 1) (match_dup 2)))))
5892    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5893         (plus:SWI (match_dup 1) (match_dup 2)))]
5894   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5895   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5896   [(set_attr "type" "alu")
5897    (set_attr "mode" "<MODE>")])
5899 (define_insn "*addv<mode>4_1"
5900   [(set (reg:CCO FLAGS_REG)
5901         (eq:CCO (plus:<DWI>
5902                    (sign_extend:<DWI>
5903                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
5904                    (match_operand:<DWI> 3 "const_int_operand" "i"))
5905                 (sign_extend:<DWI>
5906                    (plus:SWI (match_dup 1)
5907                              (match_operand:SWI 2 "x86_64_immediate_operand"
5908                                                   "<i>")))))
5909    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
5910         (plus:SWI (match_dup 1) (match_dup 2)))]
5911   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
5912    && CONST_INT_P (operands[2])
5913    && INTVAL (operands[2]) == INTVAL (operands[3])"
5914   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5915   [(set_attr "type" "alu")
5916    (set_attr "mode" "<MODE>")
5917    (set (attr "length_immediate")
5918         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
5919                   (const_string "1")
5920                (match_test "<MODE_SIZE> == 8")
5921                   (const_string "4")]
5922               (const_string "<MODE_SIZE>")))])
5924 ;; The lea patterns for modes less than 32 bits need to be matched by
5925 ;; several insns converted to real lea by splitters.
5927 (define_insn_and_split "*lea_general_1"
5928   [(set (match_operand 0 "register_operand" "=r")
5929         (plus (plus (match_operand 1 "index_register_operand" "l")
5930                     (match_operand 2 "register_operand" "r"))
5931               (match_operand 3 "immediate_operand" "i")))]
5932   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5933    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5934    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5935    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5936    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5937        || GET_MODE (operands[3]) == VOIDmode)"
5938   "#"
5939   "&& reload_completed"
5940   [(const_int 0)]
5942   enum machine_mode mode = SImode;
5943   rtx pat;
5945   operands[0] = gen_lowpart (mode, operands[0]);
5946   operands[1] = gen_lowpart (mode, operands[1]);
5947   operands[2] = gen_lowpart (mode, operands[2]);
5948   operands[3] = gen_lowpart (mode, operands[3]);
5950   pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
5951                       operands[3]);
5953   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5954   DONE;
5956   [(set_attr "type" "lea")
5957    (set_attr "mode" "SI")])
5959 (define_insn_and_split "*lea_general_2"
5960   [(set (match_operand 0 "register_operand" "=r")
5961         (plus (mult (match_operand 1 "index_register_operand" "l")
5962                     (match_operand 2 "const248_operand" "n"))
5963               (match_operand 3 "nonmemory_operand" "ri")))]
5964   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5965    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5966    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5967    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5968        || GET_MODE (operands[3]) == VOIDmode)"
5969   "#"
5970   "&& reload_completed"
5971   [(const_int 0)]
5973   enum machine_mode mode = SImode;
5974   rtx pat;
5976   operands[0] = gen_lowpart (mode, operands[0]);
5977   operands[1] = gen_lowpart (mode, operands[1]);
5978   operands[3] = gen_lowpart (mode, operands[3]);
5980   pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
5981                       operands[3]);
5983   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5984   DONE;
5986   [(set_attr "type" "lea")
5987    (set_attr "mode" "SI")])
5989 (define_insn_and_split "*lea_general_3"
5990   [(set (match_operand 0 "register_operand" "=r")
5991         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5992                           (match_operand 2 "const248_operand" "n"))
5993                     (match_operand 3 "register_operand" "r"))
5994               (match_operand 4 "immediate_operand" "i")))]
5995   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5996    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5997    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5998    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5999   "#"
6000   "&& reload_completed"
6001   [(const_int 0)]
6003   enum machine_mode mode = SImode;
6004   rtx pat;
6006   operands[0] = gen_lowpart (mode, operands[0]);
6007   operands[1] = gen_lowpart (mode, operands[1]);
6008   operands[3] = gen_lowpart (mode, operands[3]);
6009   operands[4] = gen_lowpart (mode, operands[4]);
6011   pat = gen_rtx_PLUS (mode,
6012                       gen_rtx_PLUS (mode,
6013                                     gen_rtx_MULT (mode, operands[1],
6014                                                         operands[2]),
6015                                     operands[3]),
6016                       operands[4]);
6018   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6019   DONE;
6021   [(set_attr "type" "lea")
6022    (set_attr "mode" "SI")])
6024 (define_insn_and_split "*lea_general_4"
6025   [(set (match_operand 0 "register_operand" "=r")
6026         (any_or (ashift
6027                   (match_operand 1 "index_register_operand" "l")
6028                   (match_operand 2 "const_int_operand" "n"))
6029                 (match_operand 3 "const_int_operand" "n")))]
6030   "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6031       && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6032     || GET_MODE (operands[0]) == SImode
6033     || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6034    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6035    && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6036    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6037        < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6038   "#"
6039   "&& reload_completed"
6040   [(const_int 0)]
6042   enum machine_mode mode = GET_MODE (operands[0]);
6043   rtx pat;
6045   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6046     { 
6047       mode = SImode; 
6048       operands[0] = gen_lowpart (mode, operands[0]);
6049       operands[1] = gen_lowpart (mode, operands[1]);
6050     }
6052   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6054   pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6055                        INTVAL (operands[3]));
6057   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6058   DONE;
6060   [(set_attr "type" "lea")
6061    (set (attr "mode")
6062       (if_then_else (match_operand:DI 0)
6063         (const_string "DI")
6064         (const_string "SI")))])
6066 ;; Subtract instructions
6068 (define_expand "sub<mode>3"
6069   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6070         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6071                      (match_operand:SDWIM 2 "<general_operand>")))]
6072   ""
6073   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6075 (define_insn_and_split "*sub<dwi>3_doubleword"
6076   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6077         (minus:<DWI>
6078           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6079           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6080    (clobber (reg:CC FLAGS_REG))]
6081   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6082   "#"
6083   "reload_completed"
6084   [(parallel [(set (reg:CC FLAGS_REG)
6085                    (compare:CC (match_dup 1) (match_dup 2)))
6086               (set (match_dup 0)
6087                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6088    (parallel [(set (match_dup 3)
6089                    (minus:DWIH
6090                      (match_dup 4)
6091                      (plus:DWIH
6092                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6093                        (match_dup 5))))
6094               (clobber (reg:CC FLAGS_REG))])]
6095   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6097 (define_insn "*sub<mode>_1"
6098   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6099         (minus:SWI
6100           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6101           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6102    (clobber (reg:CC FLAGS_REG))]
6103   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6104   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6105   [(set_attr "type" "alu")
6106    (set_attr "mode" "<MODE>")])
6108 (define_insn "*subsi_1_zext"
6109   [(set (match_operand:DI 0 "register_operand" "=r")
6110         (zero_extend:DI
6111           (minus:SI (match_operand:SI 1 "register_operand" "0")
6112                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6113    (clobber (reg:CC FLAGS_REG))]
6114   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6115   "sub{l}\t{%2, %k0|%k0, %2}"
6116   [(set_attr "type" "alu")
6117    (set_attr "mode" "SI")])
6119 (define_insn "*subqi_1_slp"
6120   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6121         (minus:QI (match_dup 0)
6122                   (match_operand:QI 1 "general_operand" "qn,qm")))
6123    (clobber (reg:CC FLAGS_REG))]
6124   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6125    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6126   "sub{b}\t{%1, %0|%0, %1}"
6127   [(set_attr "type" "alu1")
6128    (set_attr "mode" "QI")])
6130 (define_insn "*sub<mode>_2"
6131   [(set (reg FLAGS_REG)
6132         (compare
6133           (minus:SWI
6134             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6135             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6136           (const_int 0)))
6137    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6138         (minus:SWI (match_dup 1) (match_dup 2)))]
6139   "ix86_match_ccmode (insn, CCGOCmode)
6140    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6141   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6142   [(set_attr "type" "alu")
6143    (set_attr "mode" "<MODE>")])
6145 (define_insn "*subsi_2_zext"
6146   [(set (reg FLAGS_REG)
6147         (compare
6148           (minus:SI (match_operand:SI 1 "register_operand" "0")
6149                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6150           (const_int 0)))
6151    (set (match_operand:DI 0 "register_operand" "=r")
6152         (zero_extend:DI
6153           (minus:SI (match_dup 1)
6154                     (match_dup 2))))]
6155   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6156    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6157   "sub{l}\t{%2, %k0|%k0, %2}"
6158   [(set_attr "type" "alu")
6159    (set_attr "mode" "SI")])
6161 ;; Subtract with jump on overflow.
6162 (define_expand "subv<mode>4"
6163   [(parallel [(set (reg:CCO FLAGS_REG)
6164                    (eq:CCO (minus:<DWI>
6165                               (sign_extend:<DWI>
6166                                  (match_operand:SWI 1 "nonimmediate_operand"))
6167                               (match_dup 4))
6168                            (sign_extend:<DWI>
6169                               (minus:SWI (match_dup 1)
6170                                          (match_operand:SWI 2
6171                                             "<general_operand>")))))
6172               (set (match_operand:SWI 0 "register_operand")
6173                    (minus:SWI (match_dup 1) (match_dup 2)))])
6174    (set (pc) (if_then_else
6175                (eq (reg:CCO FLAGS_REG) (const_int 0))
6176                (label_ref (match_operand 3))
6177                (pc)))]
6178   ""
6180   ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6181   if (CONST_INT_P (operands[2]))
6182     operands[4] = operands[2];
6183   else
6184     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6187 (define_insn "*subv<mode>4"
6188   [(set (reg:CCO FLAGS_REG)
6189         (eq:CCO (minus:<DWI>
6190                    (sign_extend:<DWI>
6191                       (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6192                    (sign_extend:<DWI>
6193                       (match_operand:SWI 2 "<general_sext_operand>"
6194                                            "<r>We,<r>m")))
6195                 (sign_extend:<DWI>
6196                    (minus:SWI (match_dup 1) (match_dup 2)))))
6197    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6198         (minus:SWI (match_dup 1) (match_dup 2)))]
6199   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6200   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6201   [(set_attr "type" "alu")
6202    (set_attr "mode" "<MODE>")])
6204 (define_insn "*subv<mode>4_1"
6205   [(set (reg:CCO FLAGS_REG)
6206         (eq:CCO (minus:<DWI>
6207                    (sign_extend:<DWI>
6208                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
6209                    (match_operand:<DWI> 3 "const_int_operand" "i"))
6210                 (sign_extend:<DWI>
6211                    (minus:SWI (match_dup 1)
6212                               (match_operand:SWI 2 "x86_64_immediate_operand"
6213                                                    "<i>")))))
6214    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6215         (minus:SWI (match_dup 1) (match_dup 2)))]
6216   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6217    && CONST_INT_P (operands[2])
6218    && INTVAL (operands[2]) == INTVAL (operands[3])"
6219   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6220   [(set_attr "type" "alu")
6221    (set_attr "mode" "<MODE>")
6222    (set (attr "length_immediate")
6223         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6224                   (const_string "1")
6225                (match_test "<MODE_SIZE> == 8")
6226                   (const_string "4")]
6227               (const_string "<MODE_SIZE>")))])
6229 (define_insn "*sub<mode>_3"
6230   [(set (reg FLAGS_REG)
6231         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6232                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6233    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6234         (minus:SWI (match_dup 1) (match_dup 2)))]
6235   "ix86_match_ccmode (insn, CCmode)
6236    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6237   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6238   [(set_attr "type" "alu")
6239    (set_attr "mode" "<MODE>")])
6241 (define_insn "*subsi_3_zext"
6242   [(set (reg FLAGS_REG)
6243         (compare (match_operand:SI 1 "register_operand" "0")
6244                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6245    (set (match_operand:DI 0 "register_operand" "=r")
6246         (zero_extend:DI
6247           (minus:SI (match_dup 1)
6248                     (match_dup 2))))]
6249   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6250    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6251   "sub{l}\t{%2, %1|%1, %2}"
6252   [(set_attr "type" "alu")
6253    (set_attr "mode" "SI")])
6255 ;; Add with carry and subtract with borrow
6257 (define_expand "<plusminus_insn><mode>3_carry"
6258   [(parallel
6259     [(set (match_operand:SWI 0 "nonimmediate_operand")
6260           (plusminus:SWI
6261             (match_operand:SWI 1 "nonimmediate_operand")
6262             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6263                        [(match_operand 3 "flags_reg_operand")
6264                         (const_int 0)])
6265                       (match_operand:SWI 2 "<general_operand>"))))
6266      (clobber (reg:CC FLAGS_REG))])]
6267   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6269 (define_insn "*<plusminus_insn><mode>3_carry"
6270   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6271         (plusminus:SWI
6272           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6273           (plus:SWI
6274             (match_operator 3 "ix86_carry_flag_operator"
6275              [(reg FLAGS_REG) (const_int 0)])
6276             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6277    (clobber (reg:CC FLAGS_REG))]
6278   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6279   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6280   [(set_attr "type" "alu")
6281    (set_attr "use_carry" "1")
6282    (set_attr "pent_pair" "pu")
6283    (set_attr "mode" "<MODE>")])
6285 (define_insn "*addsi3_carry_zext"
6286   [(set (match_operand:DI 0 "register_operand" "=r")
6287         (zero_extend:DI
6288           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6289                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6290                              [(reg FLAGS_REG) (const_int 0)])
6291                             (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6292    (clobber (reg:CC FLAGS_REG))]
6293   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6294   "adc{l}\t{%2, %k0|%k0, %2}"
6295   [(set_attr "type" "alu")
6296    (set_attr "use_carry" "1")
6297    (set_attr "pent_pair" "pu")
6298    (set_attr "mode" "SI")])
6300 (define_insn "*subsi3_carry_zext"
6301   [(set (match_operand:DI 0 "register_operand" "=r")
6302         (zero_extend:DI
6303           (minus:SI (match_operand:SI 1 "register_operand" "0")
6304                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6305                               [(reg FLAGS_REG) (const_int 0)])
6306                              (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6307    (clobber (reg:CC FLAGS_REG))]
6308   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6309   "sbb{l}\t{%2, %k0|%k0, %2}"
6310   [(set_attr "type" "alu")
6311    (set_attr "pent_pair" "pu")
6312    (set_attr "mode" "SI")])
6314 ;; ADCX instruction
6316 (define_insn "adcx<mode>3"
6317   [(set (reg:CCC FLAGS_REG)
6318         (compare:CCC
6319           (plus:SWI48
6320             (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6321             (plus:SWI48
6322               (match_operator 4 "ix86_carry_flag_operator"
6323                [(match_operand 3 "flags_reg_operand") (const_int 0)])
6324               (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6325           (const_int 0)))
6326    (set (match_operand:SWI48 0 "register_operand" "=r")
6327         (plus:SWI48 (match_dup 1)
6328                     (plus:SWI48 (match_op_dup 4
6329                                  [(match_dup 3) (const_int 0)])
6330                                 (match_dup 2))))]
6331   "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6332   "adcx\t{%2, %0|%0, %2}"
6333   [(set_attr "type" "alu")
6334    (set_attr "use_carry" "1")
6335    (set_attr "mode" "<MODE>")])
6337 ;; Overflow setting add instructions
6339 (define_insn "*add<mode>3_cconly_overflow"
6340   [(set (reg:CCC FLAGS_REG)
6341         (compare:CCC
6342           (plus:SWI
6343             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6344             (match_operand:SWI 2 "<general_operand>" "<g>"))
6345           (match_dup 1)))
6346    (clobber (match_scratch:SWI 0 "=<r>"))]
6347   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6348   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6349   [(set_attr "type" "alu")
6350    (set_attr "mode" "<MODE>")])
6352 (define_insn "*add<mode>3_cc_overflow"
6353   [(set (reg:CCC FLAGS_REG)
6354         (compare:CCC
6355             (plus:SWI
6356                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6357                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6358             (match_dup 1)))
6359    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6360         (plus:SWI (match_dup 1) (match_dup 2)))]
6361   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6362   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6363   [(set_attr "type" "alu")
6364    (set_attr "mode" "<MODE>")])
6366 (define_insn "*addsi3_zext_cc_overflow"
6367   [(set (reg:CCC FLAGS_REG)
6368         (compare:CCC
6369           (plus:SI
6370             (match_operand:SI 1 "nonimmediate_operand" "%0")
6371             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6372           (match_dup 1)))
6373    (set (match_operand:DI 0 "register_operand" "=r")
6374         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6375   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6376   "add{l}\t{%2, %k0|%k0, %2}"
6377   [(set_attr "type" "alu")
6378    (set_attr "mode" "SI")])
6380 ;; The patterns that match these are at the end of this file.
6382 (define_expand "<plusminus_insn>xf3"
6383   [(set (match_operand:XF 0 "register_operand")
6384         (plusminus:XF
6385           (match_operand:XF 1 "register_operand")
6386           (match_operand:XF 2 "register_operand")))]
6387   "TARGET_80387")
6389 (define_expand "<plusminus_insn><mode>3"
6390   [(set (match_operand:MODEF 0 "register_operand")
6391         (plusminus:MODEF
6392           (match_operand:MODEF 1 "register_operand")
6393           (match_operand:MODEF 2 "nonimmediate_operand")))]
6394   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6395     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6397 ;; Multiply instructions
6399 (define_expand "mul<mode>3"
6400   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6401                    (mult:SWIM248
6402                      (match_operand:SWIM248 1 "register_operand")
6403                      (match_operand:SWIM248 2 "<general_operand>")))
6404               (clobber (reg:CC FLAGS_REG))])])
6406 (define_expand "mulqi3"
6407   [(parallel [(set (match_operand:QI 0 "register_operand")
6408                    (mult:QI
6409                      (match_operand:QI 1 "register_operand")
6410                      (match_operand:QI 2 "nonimmediate_operand")))
6411               (clobber (reg:CC FLAGS_REG))])]
6412   "TARGET_QIMODE_MATH")
6414 ;; On AMDFAM10
6415 ;; IMUL reg32/64, reg32/64, imm8        Direct
6416 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6417 ;; IMUL reg32/64, reg32/64, imm32       Direct
6418 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6419 ;; IMUL reg32/64, reg32/64              Direct
6420 ;; IMUL reg32/64, mem32/64              Direct
6422 ;; On BDVER1, all above IMULs use DirectPath
6424 (define_insn "*mul<mode>3_1"
6425   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6426         (mult:SWI48
6427           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6428           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6429    (clobber (reg:CC FLAGS_REG))]
6430   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6431   "@
6432    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6433    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6434    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6435   [(set_attr "type" "imul")
6436    (set_attr "prefix_0f" "0,0,1")
6437    (set (attr "athlon_decode")
6438         (cond [(eq_attr "cpu" "athlon")
6439                   (const_string "vector")
6440                (eq_attr "alternative" "1")
6441                   (const_string "vector")
6442                (and (eq_attr "alternative" "2")
6443                     (match_operand 1 "memory_operand"))
6444                   (const_string "vector")]
6445               (const_string "direct")))
6446    (set (attr "amdfam10_decode")
6447         (cond [(and (eq_attr "alternative" "0,1")
6448                     (match_operand 1 "memory_operand"))
6449                   (const_string "vector")]
6450               (const_string "direct")))
6451    (set_attr "bdver1_decode" "direct")
6452    (set_attr "mode" "<MODE>")])
6454 (define_insn "*mulsi3_1_zext"
6455   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6456         (zero_extend:DI
6457           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6458                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6459    (clobber (reg:CC FLAGS_REG))]
6460   "TARGET_64BIT
6461    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6462   "@
6463    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6464    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6465    imul{l}\t{%2, %k0|%k0, %2}"
6466   [(set_attr "type" "imul")
6467    (set_attr "prefix_0f" "0,0,1")
6468    (set (attr "athlon_decode")
6469         (cond [(eq_attr "cpu" "athlon")
6470                   (const_string "vector")
6471                (eq_attr "alternative" "1")
6472                   (const_string "vector")
6473                (and (eq_attr "alternative" "2")
6474                     (match_operand 1 "memory_operand"))
6475                   (const_string "vector")]
6476               (const_string "direct")))
6477    (set (attr "amdfam10_decode")
6478         (cond [(and (eq_attr "alternative" "0,1")
6479                     (match_operand 1 "memory_operand"))
6480                   (const_string "vector")]
6481               (const_string "direct")))
6482    (set_attr "bdver1_decode" "direct")
6483    (set_attr "mode" "SI")])
6485 ;; On AMDFAM10
6486 ;; IMUL reg16, reg16, imm8      VectorPath
6487 ;; IMUL reg16, mem16, imm8      VectorPath
6488 ;; IMUL reg16, reg16, imm16     VectorPath
6489 ;; IMUL reg16, mem16, imm16     VectorPath
6490 ;; IMUL reg16, reg16            Direct
6491 ;; IMUL reg16, mem16            Direct
6493 ;; On BDVER1, all HI MULs use DoublePath
6495 (define_insn "*mulhi3_1"
6496   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6497         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6498                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6499    (clobber (reg:CC FLAGS_REG))]
6500   "TARGET_HIMODE_MATH
6501    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6502   "@
6503    imul{w}\t{%2, %1, %0|%0, %1, %2}
6504    imul{w}\t{%2, %1, %0|%0, %1, %2}
6505    imul{w}\t{%2, %0|%0, %2}"
6506   [(set_attr "type" "imul")
6507    (set_attr "prefix_0f" "0,0,1")
6508    (set (attr "athlon_decode")
6509         (cond [(eq_attr "cpu" "athlon")
6510                   (const_string "vector")
6511                (eq_attr "alternative" "1,2")
6512                   (const_string "vector")]
6513               (const_string "direct")))
6514    (set (attr "amdfam10_decode")
6515         (cond [(eq_attr "alternative" "0,1")
6516                   (const_string "vector")]
6517               (const_string "direct")))
6518    (set_attr "bdver1_decode" "double")
6519    (set_attr "mode" "HI")])
6521 ;;On AMDFAM10 and BDVER1
6522 ;; MUL reg8     Direct
6523 ;; MUL mem8     Direct
6525 (define_insn "*mulqi3_1"
6526   [(set (match_operand:QI 0 "register_operand" "=a")
6527         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6528                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6529    (clobber (reg:CC FLAGS_REG))]
6530   "TARGET_QIMODE_MATH
6531    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6532   "mul{b}\t%2"
6533   [(set_attr "type" "imul")
6534    (set_attr "length_immediate" "0")
6535    (set (attr "athlon_decode")
6536      (if_then_else (eq_attr "cpu" "athlon")
6537         (const_string "vector")
6538         (const_string "direct")))
6539    (set_attr "amdfam10_decode" "direct")
6540    (set_attr "bdver1_decode" "direct")
6541    (set_attr "mode" "QI")])
6543 ;; Multiply with jump on overflow.
6544 (define_expand "mulv<mode>4"
6545   [(parallel [(set (reg:CCO FLAGS_REG)
6546                    (eq:CCO (mult:<DWI>
6547                               (sign_extend:<DWI>
6548                                  (match_operand:SWI48 1 "register_operand"))
6549                               (match_dup 4))
6550                            (sign_extend:<DWI>
6551                               (mult:SWI48 (match_dup 1)
6552                                           (match_operand:SWI48 2
6553                                              "<general_operand>")))))
6554               (set (match_operand:SWI48 0 "register_operand")
6555                    (mult:SWI48 (match_dup 1) (match_dup 2)))])
6556    (set (pc) (if_then_else
6557                (eq (reg:CCO FLAGS_REG) (const_int 0))
6558                (label_ref (match_operand 3))
6559                (pc)))]
6560   ""
6562   if (CONST_INT_P (operands[2]))
6563     operands[4] = operands[2];
6564   else
6565     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6568 (define_insn "*mulv<mode>4"
6569   [(set (reg:CCO FLAGS_REG)
6570         (eq:CCO (mult:<DWI>
6571                    (sign_extend:<DWI>
6572                       (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6573                    (sign_extend:<DWI>
6574                       (match_operand:SWI48 2 "<general_sext_operand>"
6575                                              "We,mr")))
6576                 (sign_extend:<DWI>
6577                    (mult:SWI48 (match_dup 1) (match_dup 2)))))
6578    (set (match_operand:SWI48 0 "register_operand" "=r,r")
6579         (mult:SWI48 (match_dup 1) (match_dup 2)))]
6580   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6581   "@
6582    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6583    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6584   [(set_attr "type" "imul")
6585    (set_attr "prefix_0f" "0,1")
6586    (set (attr "athlon_decode")
6587         (cond [(eq_attr "cpu" "athlon")
6588                   (const_string "vector")
6589                (eq_attr "alternative" "0")
6590                   (const_string "vector")
6591                (and (eq_attr "alternative" "1")
6592                     (match_operand 1 "memory_operand"))
6593                   (const_string "vector")]
6594               (const_string "direct")))
6595    (set (attr "amdfam10_decode")
6596         (cond [(and (eq_attr "alternative" "1")
6597                     (match_operand 1 "memory_operand"))
6598                   (const_string "vector")]
6599               (const_string "direct")))
6600    (set_attr "bdver1_decode" "direct")
6601    (set_attr "mode" "<MODE>")])
6603 (define_insn "*mulv<mode>4_1"
6604   [(set (reg:CCO FLAGS_REG)
6605         (eq:CCO (mult:<DWI>
6606                    (sign_extend:<DWI>
6607                       (match_operand:SWI48 1 "nonimmediate_operand" "rm,rm"))
6608                    (match_operand:<DWI> 3 "const_int_operand" "K,i"))
6609                 (sign_extend:<DWI>
6610                    (mult:SWI48 (match_dup 1)
6611                                (match_operand:SWI 2 "x86_64_immediate_operand"
6612                                                     "K,<i>")))))
6613    (set (match_operand:SWI48 0 "register_operand" "=r,r")
6614         (mult:SWI48 (match_dup 1) (match_dup 2)))]
6615   "!(MEM_P (operands[1]) && MEM_P (operands[2]))
6616    && CONST_INT_P (operands[2])
6617    && INTVAL (operands[2]) == INTVAL (operands[3])"
6618   "@
6619    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6620    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6621   [(set_attr "type" "imul")
6622    (set (attr "athlon_decode")
6623         (cond [(eq_attr "cpu" "athlon")
6624                   (const_string "vector")
6625                (eq_attr "alternative" "1")
6626                   (const_string "vector")]
6627               (const_string "direct")))
6628    (set (attr "amdfam10_decode")
6629         (cond [(match_operand 1 "memory_operand")
6630                   (const_string "vector")]
6631               (const_string "direct")))
6632    (set_attr "bdver1_decode" "direct")
6633    (set_attr "mode" "<MODE>")
6634    (set (attr "length_immediate")
6635         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6636                   (const_string "1")
6637                (match_test "<MODE_SIZE> == 8")
6638                   (const_string "4")]
6639               (const_string "<MODE_SIZE>")))])
6641 (define_expand "<u>mul<mode><dwi>3"
6642   [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6643                    (mult:<DWI>
6644                      (any_extend:<DWI>
6645                        (match_operand:DWIH 1 "nonimmediate_operand"))
6646                      (any_extend:<DWI>
6647                        (match_operand:DWIH 2 "register_operand"))))
6648               (clobber (reg:CC FLAGS_REG))])])
6650 (define_expand "<u>mulqihi3"
6651   [(parallel [(set (match_operand:HI 0 "register_operand")
6652                    (mult:HI
6653                      (any_extend:HI
6654                        (match_operand:QI 1 "nonimmediate_operand"))
6655                      (any_extend:HI
6656                        (match_operand:QI 2 "register_operand"))))
6657               (clobber (reg:CC FLAGS_REG))])]
6658   "TARGET_QIMODE_MATH")
6660 (define_insn "*bmi2_umulditi3_1"
6661   [(set (match_operand:DI 0 "register_operand" "=r")
6662         (mult:DI
6663           (match_operand:DI 2 "nonimmediate_operand" "%d")
6664           (match_operand:DI 3 "nonimmediate_operand" "rm")))
6665    (set (match_operand:DI 1 "register_operand" "=r")
6666         (truncate:DI
6667           (lshiftrt:TI
6668             (mult:TI (zero_extend:TI (match_dup 2))
6669                      (zero_extend:TI (match_dup 3)))
6670             (const_int 64))))]
6671   "TARGET_64BIT && TARGET_BMI2
6672    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6673   "mulx\t{%3, %0, %1|%1, %0, %3}"
6674   [(set_attr "type" "imulx")
6675    (set_attr "prefix" "vex")
6676    (set_attr "mode" "DI")])
6678 (define_insn "*bmi2_umulsidi3_1"
6679   [(set (match_operand:SI 0 "register_operand" "=r")
6680         (mult:SI
6681           (match_operand:SI 2 "nonimmediate_operand" "%d")
6682           (match_operand:SI 3 "nonimmediate_operand" "rm")))
6683    (set (match_operand:SI 1 "register_operand" "=r")
6684         (truncate:SI
6685           (lshiftrt:DI
6686             (mult:DI (zero_extend:DI (match_dup 2))
6687                      (zero_extend:DI (match_dup 3)))
6688             (const_int 32))))]
6689   "!TARGET_64BIT && TARGET_BMI2
6690    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6691   "mulx\t{%3, %0, %1|%1, %0, %3}"
6692   [(set_attr "type" "imulx")
6693    (set_attr "prefix" "vex")
6694    (set_attr "mode" "SI")])
6696 (define_insn "*umul<mode><dwi>3_1"
6697   [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6698         (mult:<DWI>
6699           (zero_extend:<DWI>
6700             (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6701           (zero_extend:<DWI>
6702             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6703    (clobber (reg:CC FLAGS_REG))]
6704   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6705   "@
6706    #
6707    mul{<imodesuffix>}\t%2"
6708   [(set_attr "isa" "bmi2,*")
6709    (set_attr "type" "imulx,imul")
6710    (set_attr "length_immediate" "*,0")
6711    (set (attr "athlon_decode")
6712         (cond [(eq_attr "alternative" "1")
6713                  (if_then_else (eq_attr "cpu" "athlon")
6714                    (const_string "vector")
6715                    (const_string "double"))]
6716               (const_string "*")))
6717    (set_attr "amdfam10_decode" "*,double")
6718    (set_attr "bdver1_decode" "*,direct")
6719    (set_attr "prefix" "vex,orig")
6720    (set_attr "mode" "<MODE>")])
6722 ;; Convert mul to the mulx pattern to avoid flags dependency.
6723 (define_split
6724  [(set (match_operand:<DWI> 0 "register_operand")
6725        (mult:<DWI>
6726          (zero_extend:<DWI>
6727            (match_operand:DWIH 1 "register_operand"))
6728          (zero_extend:<DWI>
6729            (match_operand:DWIH 2 "nonimmediate_operand"))))
6730   (clobber (reg:CC FLAGS_REG))]
6731  "TARGET_BMI2 && reload_completed
6732   && true_regnum (operands[1]) == DX_REG"
6733   [(parallel [(set (match_dup 3)
6734                    (mult:DWIH (match_dup 1) (match_dup 2)))
6735               (set (match_dup 4)
6736                    (truncate:DWIH
6737                      (lshiftrt:<DWI>
6738                        (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6739                                    (zero_extend:<DWI> (match_dup 2)))
6740                        (match_dup 5))))])]
6742   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6744   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6747 (define_insn "*mul<mode><dwi>3_1"
6748   [(set (match_operand:<DWI> 0 "register_operand" "=A")
6749         (mult:<DWI>
6750           (sign_extend:<DWI>
6751             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6752           (sign_extend:<DWI>
6753             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6754    (clobber (reg:CC FLAGS_REG))]
6755   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6756   "imul{<imodesuffix>}\t%2"
6757   [(set_attr "type" "imul")
6758    (set_attr "length_immediate" "0")
6759    (set (attr "athlon_decode")
6760      (if_then_else (eq_attr "cpu" "athlon")
6761         (const_string "vector")
6762         (const_string "double")))
6763    (set_attr "amdfam10_decode" "double")
6764    (set_attr "bdver1_decode" "direct")
6765    (set_attr "mode" "<MODE>")])
6767 (define_insn "*<u>mulqihi3_1"
6768   [(set (match_operand:HI 0 "register_operand" "=a")
6769         (mult:HI
6770           (any_extend:HI
6771             (match_operand:QI 1 "nonimmediate_operand" "%0"))
6772           (any_extend:HI
6773             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6774    (clobber (reg:CC FLAGS_REG))]
6775   "TARGET_QIMODE_MATH
6776    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6777   "<sgnprefix>mul{b}\t%2"
6778   [(set_attr "type" "imul")
6779    (set_attr "length_immediate" "0")
6780    (set (attr "athlon_decode")
6781      (if_then_else (eq_attr "cpu" "athlon")
6782         (const_string "vector")
6783         (const_string "direct")))
6784    (set_attr "amdfam10_decode" "direct")
6785    (set_attr "bdver1_decode" "direct")
6786    (set_attr "mode" "QI")])
6788 (define_expand "<s>mul<mode>3_highpart"
6789   [(parallel [(set (match_operand:SWI48 0 "register_operand")
6790                    (truncate:SWI48
6791                      (lshiftrt:<DWI>
6792                        (mult:<DWI>
6793                          (any_extend:<DWI>
6794                            (match_operand:SWI48 1 "nonimmediate_operand"))
6795                          (any_extend:<DWI>
6796                            (match_operand:SWI48 2 "register_operand")))
6797                        (match_dup 4))))
6798               (clobber (match_scratch:SWI48 3))
6799               (clobber (reg:CC FLAGS_REG))])]
6800   ""
6801   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6803 (define_insn "*<s>muldi3_highpart_1"
6804   [(set (match_operand:DI 0 "register_operand" "=d")
6805         (truncate:DI
6806           (lshiftrt:TI
6807             (mult:TI
6808               (any_extend:TI
6809                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6810               (any_extend:TI
6811                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6812             (const_int 64))))
6813    (clobber (match_scratch:DI 3 "=1"))
6814    (clobber (reg:CC FLAGS_REG))]
6815   "TARGET_64BIT
6816    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6817   "<sgnprefix>mul{q}\t%2"
6818   [(set_attr "type" "imul")
6819    (set_attr "length_immediate" "0")
6820    (set (attr "athlon_decode")
6821      (if_then_else (eq_attr "cpu" "athlon")
6822         (const_string "vector")
6823         (const_string "double")))
6824    (set_attr "amdfam10_decode" "double")
6825    (set_attr "bdver1_decode" "direct")
6826    (set_attr "mode" "DI")])
6828 (define_insn "*<s>mulsi3_highpart_1"
6829   [(set (match_operand:SI 0 "register_operand" "=d")
6830         (truncate:SI
6831           (lshiftrt:DI
6832             (mult:DI
6833               (any_extend:DI
6834                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6835               (any_extend:DI
6836                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6837             (const_int 32))))
6838    (clobber (match_scratch:SI 3 "=1"))
6839    (clobber (reg:CC FLAGS_REG))]
6840   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6841   "<sgnprefix>mul{l}\t%2"
6842   [(set_attr "type" "imul")
6843    (set_attr "length_immediate" "0")
6844    (set (attr "athlon_decode")
6845      (if_then_else (eq_attr "cpu" "athlon")
6846         (const_string "vector")
6847         (const_string "double")))
6848    (set_attr "amdfam10_decode" "double")
6849    (set_attr "bdver1_decode" "direct")
6850    (set_attr "mode" "SI")])
6852 (define_insn "*<s>mulsi3_highpart_zext"
6853   [(set (match_operand:DI 0 "register_operand" "=d")
6854         (zero_extend:DI (truncate:SI
6855           (lshiftrt:DI
6856             (mult:DI (any_extend:DI
6857                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
6858                      (any_extend:DI
6859                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
6860             (const_int 32)))))
6861    (clobber (match_scratch:SI 3 "=1"))
6862    (clobber (reg:CC FLAGS_REG))]
6863   "TARGET_64BIT
6864    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6865   "<sgnprefix>mul{l}\t%2"
6866   [(set_attr "type" "imul")
6867    (set_attr "length_immediate" "0")
6868    (set (attr "athlon_decode")
6869      (if_then_else (eq_attr "cpu" "athlon")
6870         (const_string "vector")
6871         (const_string "double")))
6872    (set_attr "amdfam10_decode" "double")
6873    (set_attr "bdver1_decode" "direct")
6874    (set_attr "mode" "SI")])
6876 ;; The patterns that match these are at the end of this file.
6878 (define_expand "mulxf3"
6879   [(set (match_operand:XF 0 "register_operand")
6880         (mult:XF (match_operand:XF 1 "register_operand")
6881                  (match_operand:XF 2 "register_operand")))]
6882   "TARGET_80387")
6884 (define_expand "mul<mode>3"
6885   [(set (match_operand:MODEF 0 "register_operand")
6886         (mult:MODEF (match_operand:MODEF 1 "register_operand")
6887                     (match_operand:MODEF 2 "nonimmediate_operand")))]
6888   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6889     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6891 ;; Divide instructions
6893 ;; The patterns that match these are at the end of this file.
6895 (define_expand "divxf3"
6896   [(set (match_operand:XF 0 "register_operand")
6897         (div:XF (match_operand:XF 1 "register_operand")
6898                 (match_operand:XF 2 "register_operand")))]
6899   "TARGET_80387")
6901 (define_expand "divdf3"
6902   [(set (match_operand:DF 0 "register_operand")
6903         (div:DF (match_operand:DF 1 "register_operand")
6904                 (match_operand:DF 2 "nonimmediate_operand")))]
6905    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6906     || (TARGET_SSE2 && TARGET_SSE_MATH)")
6908 (define_expand "divsf3"
6909   [(set (match_operand:SF 0 "register_operand")
6910         (div:SF (match_operand:SF 1 "register_operand")
6911                 (match_operand:SF 2 "nonimmediate_operand")))]
6912   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
6913     || TARGET_SSE_MATH"
6915   if (TARGET_SSE_MATH
6916       && TARGET_RECIP_DIV
6917       && optimize_insn_for_speed_p ()
6918       && flag_finite_math_only && !flag_trapping_math
6919       && flag_unsafe_math_optimizations)
6920     {
6921       ix86_emit_swdivsf (operands[0], operands[1],
6922                          operands[2], SFmode);
6923       DONE;
6924     }
6927 ;; Divmod instructions.
6929 (define_expand "divmod<mode>4"
6930   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6931                    (div:SWIM248
6932                      (match_operand:SWIM248 1 "register_operand")
6933                      (match_operand:SWIM248 2 "nonimmediate_operand")))
6934               (set (match_operand:SWIM248 3 "register_operand")
6935                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
6936               (clobber (reg:CC FLAGS_REG))])])
6938 ;; Split with 8bit unsigned divide:
6939 ;;      if (dividend an divisor are in [0-255])
6940 ;;         use 8bit unsigned integer divide
6941 ;;       else
6942 ;;         use original integer divide
6943 (define_split
6944   [(set (match_operand:SWI48 0 "register_operand")
6945         (div:SWI48 (match_operand:SWI48 2 "register_operand")
6946                     (match_operand:SWI48 3 "nonimmediate_operand")))
6947    (set (match_operand:SWI48 1 "register_operand")
6948         (mod:SWI48 (match_dup 2) (match_dup 3)))
6949    (clobber (reg:CC FLAGS_REG))]
6950   "TARGET_USE_8BIT_IDIV
6951    && TARGET_QIMODE_MATH
6952    && can_create_pseudo_p ()
6953    && !optimize_insn_for_size_p ()"
6954   [(const_int 0)]
6955   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
6957 (define_insn_and_split "divmod<mode>4_1"
6958   [(set (match_operand:SWI48 0 "register_operand" "=a")
6959         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
6960                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
6961    (set (match_operand:SWI48 1 "register_operand" "=&d")
6962         (mod:SWI48 (match_dup 2) (match_dup 3)))
6963    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
6964    (clobber (reg:CC FLAGS_REG))]
6965   ""
6966   "#"
6967   "reload_completed"
6968   [(parallel [(set (match_dup 1)
6969                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
6970               (clobber (reg:CC FLAGS_REG))])
6971    (parallel [(set (match_dup 0)
6972                    (div:SWI48 (match_dup 2) (match_dup 3)))
6973               (set (match_dup 1)
6974                    (mod:SWI48 (match_dup 2) (match_dup 3)))
6975               (use (match_dup 1))
6976               (clobber (reg:CC FLAGS_REG))])]
6978   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
6980   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
6981     operands[4] = operands[2];
6982   else
6983     {
6984       /* Avoid use of cltd in favor of a mov+shift.  */
6985       emit_move_insn (operands[1], operands[2]);
6986       operands[4] = operands[1];
6987     }
6989   [(set_attr "type" "multi")
6990    (set_attr "mode" "<MODE>")])
6992 (define_insn_and_split "*divmod<mode>4"
6993   [(set (match_operand:SWIM248 0 "register_operand" "=a")
6994         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
6995                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
6996    (set (match_operand:SWIM248 1 "register_operand" "=&d")
6997         (mod:SWIM248 (match_dup 2) (match_dup 3)))
6998    (clobber (reg:CC FLAGS_REG))]
6999   ""
7000   "#"
7001   "reload_completed"
7002   [(parallel [(set (match_dup 1)
7003                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7004               (clobber (reg:CC FLAGS_REG))])
7005    (parallel [(set (match_dup 0)
7006                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7007               (set (match_dup 1)
7008                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7009               (use (match_dup 1))
7010               (clobber (reg:CC FLAGS_REG))])]
7012   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7014   if (<MODE>mode != HImode
7015       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7016     operands[4] = operands[2];
7017   else
7018     {
7019       /* Avoid use of cltd in favor of a mov+shift.  */
7020       emit_move_insn (operands[1], operands[2]);
7021       operands[4] = operands[1];
7022     }
7024   [(set_attr "type" "multi")
7025    (set_attr "mode" "<MODE>")])
7027 (define_insn "*divmod<mode>4_noext"
7028   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7029         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7030                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7031    (set (match_operand:SWIM248 1 "register_operand" "=d")
7032         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7033    (use (match_operand:SWIM248 4 "register_operand" "1"))
7034    (clobber (reg:CC FLAGS_REG))]
7035   ""
7036   "idiv{<imodesuffix>}\t%3"
7037   [(set_attr "type" "idiv")
7038    (set_attr "mode" "<MODE>")])
7040 (define_expand "divmodqi4"
7041   [(parallel [(set (match_operand:QI 0 "register_operand")
7042                    (div:QI
7043                      (match_operand:QI 1 "register_operand")
7044                      (match_operand:QI 2 "nonimmediate_operand")))
7045               (set (match_operand:QI 3 "register_operand")
7046                    (mod:QI (match_dup 1) (match_dup 2)))
7047               (clobber (reg:CC FLAGS_REG))])]
7048   "TARGET_QIMODE_MATH"
7050   rtx div, mod, insn;
7051   rtx tmp0, tmp1;
7052   
7053   tmp0 = gen_reg_rtx (HImode);
7054   tmp1 = gen_reg_rtx (HImode);
7056   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7057      in AX.  */
7058   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7059   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7061   /* Extract remainder from AH.  */
7062   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7063   insn = emit_move_insn (operands[3], tmp1);
7065   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7066   set_unique_reg_note (insn, REG_EQUAL, mod);
7068   /* Extract quotient from AL.  */
7069   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7071   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7072   set_unique_reg_note (insn, REG_EQUAL, div);
7074   DONE;
7077 ;; Divide AX by r/m8, with result stored in
7078 ;; AL <- Quotient
7079 ;; AH <- Remainder
7080 ;; Change div/mod to HImode and extend the second argument to HImode
7081 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7082 ;; combine may fail.
7083 (define_insn "divmodhiqi3"
7084   [(set (match_operand:HI 0 "register_operand" "=a")
7085         (ior:HI
7086           (ashift:HI
7087             (zero_extend:HI
7088               (truncate:QI
7089                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7090                         (sign_extend:HI
7091                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7092             (const_int 8))
7093           (zero_extend:HI
7094             (truncate:QI
7095               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7096    (clobber (reg:CC FLAGS_REG))]
7097   "TARGET_QIMODE_MATH"
7098   "idiv{b}\t%2"
7099   [(set_attr "type" "idiv")
7100    (set_attr "mode" "QI")])
7102 (define_expand "udivmod<mode>4"
7103   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7104                    (udiv:SWIM248
7105                      (match_operand:SWIM248 1 "register_operand")
7106                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7107               (set (match_operand:SWIM248 3 "register_operand")
7108                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7109               (clobber (reg:CC FLAGS_REG))])])
7111 ;; Split with 8bit unsigned divide:
7112 ;;      if (dividend an divisor are in [0-255])
7113 ;;         use 8bit unsigned integer divide
7114 ;;       else
7115 ;;         use original integer divide
7116 (define_split
7117   [(set (match_operand:SWI48 0 "register_operand")
7118         (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7119                     (match_operand:SWI48 3 "nonimmediate_operand")))
7120    (set (match_operand:SWI48 1 "register_operand")
7121         (umod:SWI48 (match_dup 2) (match_dup 3)))
7122    (clobber (reg:CC FLAGS_REG))]
7123   "TARGET_USE_8BIT_IDIV
7124    && TARGET_QIMODE_MATH
7125    && can_create_pseudo_p ()
7126    && !optimize_insn_for_size_p ()"
7127   [(const_int 0)]
7128   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7130 (define_insn_and_split "udivmod<mode>4_1"
7131   [(set (match_operand:SWI48 0 "register_operand" "=a")
7132         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7133                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7134    (set (match_operand:SWI48 1 "register_operand" "=&d")
7135         (umod:SWI48 (match_dup 2) (match_dup 3)))
7136    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7137    (clobber (reg:CC FLAGS_REG))]
7138   ""
7139   "#"
7140   "reload_completed"
7141   [(set (match_dup 1) (const_int 0))
7142    (parallel [(set (match_dup 0)
7143                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7144               (set (match_dup 1)
7145                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7146               (use (match_dup 1))
7147               (clobber (reg:CC FLAGS_REG))])]
7148   ""
7149   [(set_attr "type" "multi")
7150    (set_attr "mode" "<MODE>")])
7152 (define_insn_and_split "*udivmod<mode>4"
7153   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7154         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7155                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7156    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7157         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7158    (clobber (reg:CC FLAGS_REG))]
7159   ""
7160   "#"
7161   "reload_completed"
7162   [(set (match_dup 1) (const_int 0))
7163    (parallel [(set (match_dup 0)
7164                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7165               (set (match_dup 1)
7166                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7167               (use (match_dup 1))
7168               (clobber (reg:CC FLAGS_REG))])]
7169   ""
7170   [(set_attr "type" "multi")
7171    (set_attr "mode" "<MODE>")])
7173 (define_insn "*udivmod<mode>4_noext"
7174   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7175         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7176                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7177    (set (match_operand:SWIM248 1 "register_operand" "=d")
7178         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7179    (use (match_operand:SWIM248 4 "register_operand" "1"))
7180    (clobber (reg:CC FLAGS_REG))]
7181   ""
7182   "div{<imodesuffix>}\t%3"
7183   [(set_attr "type" "idiv")
7184    (set_attr "mode" "<MODE>")])
7186 (define_expand "udivmodqi4"
7187   [(parallel [(set (match_operand:QI 0 "register_operand")
7188                    (udiv:QI
7189                      (match_operand:QI 1 "register_operand")
7190                      (match_operand:QI 2 "nonimmediate_operand")))
7191               (set (match_operand:QI 3 "register_operand")
7192                    (umod:QI (match_dup 1) (match_dup 2)))
7193               (clobber (reg:CC FLAGS_REG))])]
7194   "TARGET_QIMODE_MATH"
7196   rtx div, mod, insn;
7197   rtx tmp0, tmp1;
7198   
7199   tmp0 = gen_reg_rtx (HImode);
7200   tmp1 = gen_reg_rtx (HImode);
7202   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7203      in AX.  */
7204   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7205   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7207   /* Extract remainder from AH.  */
7208   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7209   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7210   insn = emit_move_insn (operands[3], tmp1);
7212   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7213   set_unique_reg_note (insn, REG_EQUAL, mod);
7215   /* Extract quotient from AL.  */
7216   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7218   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7219   set_unique_reg_note (insn, REG_EQUAL, div);
7221   DONE;
7224 (define_insn "udivmodhiqi3"
7225   [(set (match_operand:HI 0 "register_operand" "=a")
7226         (ior:HI
7227           (ashift:HI
7228             (zero_extend:HI
7229               (truncate:QI
7230                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7231                         (zero_extend:HI
7232                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7233             (const_int 8))
7234           (zero_extend:HI
7235             (truncate:QI
7236               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7237    (clobber (reg:CC FLAGS_REG))]
7238   "TARGET_QIMODE_MATH"
7239   "div{b}\t%2"
7240   [(set_attr "type" "idiv")
7241    (set_attr "mode" "QI")])
7243 ;; We cannot use div/idiv for double division, because it causes
7244 ;; "division by zero" on the overflow and that's not what we expect
7245 ;; from truncate.  Because true (non truncating) double division is
7246 ;; never generated, we can't create this insn anyway.
7248 ;(define_insn ""
7249 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7250 ;       (truncate:SI
7251 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7252 ;                  (zero_extend:DI
7253 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7254 ;   (set (match_operand:SI 3 "register_operand" "=d")
7255 ;       (truncate:SI
7256 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7257 ;   (clobber (reg:CC FLAGS_REG))]
7258 ;  ""
7259 ;  "div{l}\t{%2, %0|%0, %2}"
7260 ;  [(set_attr "type" "idiv")])
7262 ;;- Logical AND instructions
7264 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7265 ;; Note that this excludes ah.
7267 (define_expand "testsi_ccno_1"
7268   [(set (reg:CCNO FLAGS_REG)
7269         (compare:CCNO
7270           (and:SI (match_operand:SI 0 "nonimmediate_operand")
7271                   (match_operand:SI 1 "x86_64_nonmemory_operand"))
7272           (const_int 0)))])
7274 (define_expand "testqi_ccz_1"
7275   [(set (reg:CCZ FLAGS_REG)
7276         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7277                              (match_operand:QI 1 "nonmemory_operand"))
7278                  (const_int 0)))])
7280 (define_expand "testdi_ccno_1"
7281   [(set (reg:CCNO FLAGS_REG)
7282         (compare:CCNO
7283           (and:DI (match_operand:DI 0 "nonimmediate_operand")
7284                   (match_operand:DI 1 "x86_64_szext_general_operand"))
7285           (const_int 0)))]
7286   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7288 (define_insn "*testdi_1"
7289   [(set (reg FLAGS_REG)
7290         (compare
7291          (and:DI
7292           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7293           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7294          (const_int 0)))]
7295   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7296    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7297   "@
7298    test{l}\t{%k1, %k0|%k0, %k1}
7299    test{l}\t{%k1, %k0|%k0, %k1}
7300    test{q}\t{%1, %0|%0, %1}
7301    test{q}\t{%1, %0|%0, %1}
7302    test{q}\t{%1, %0|%0, %1}"
7303   [(set_attr "type" "test")
7304    (set_attr "modrm" "0,1,0,1,1")
7305    (set_attr "mode" "SI,SI,DI,DI,DI")])
7307 (define_insn "*testqi_1_maybe_si"
7308   [(set (reg FLAGS_REG)
7309         (compare
7310           (and:QI
7311             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7312             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7313           (const_int 0)))]
7314    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7315     && ix86_match_ccmode (insn,
7316                          CONST_INT_P (operands[1])
7317                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7319   if (which_alternative == 3)
7320     {
7321       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7322         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7323       return "test{l}\t{%1, %k0|%k0, %1}";
7324     }
7325   return "test{b}\t{%1, %0|%0, %1}";
7327   [(set_attr "type" "test")
7328    (set_attr "modrm" "0,1,1,1")
7329    (set_attr "mode" "QI,QI,QI,SI")
7330    (set_attr "pent_pair" "uv,np,uv,np")])
7332 (define_insn "*test<mode>_1"
7333   [(set (reg FLAGS_REG)
7334         (compare
7335          (and:SWI124
7336           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7337           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7338          (const_int 0)))]
7339   "ix86_match_ccmode (insn, CCNOmode)
7340    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7341   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7342   [(set_attr "type" "test")
7343    (set_attr "modrm" "0,1,1")
7344    (set_attr "mode" "<MODE>")
7345    (set_attr "pent_pair" "uv,np,uv")])
7347 (define_expand "testqi_ext_ccno_0"
7348   [(set (reg:CCNO FLAGS_REG)
7349         (compare:CCNO
7350           (and:SI
7351             (zero_extract:SI
7352               (match_operand 0 "ext_register_operand")
7353               (const_int 8)
7354               (const_int 8))
7355             (match_operand 1 "const_int_operand"))
7356           (const_int 0)))])
7358 (define_insn "*testqi_ext_0"
7359   [(set (reg FLAGS_REG)
7360         (compare
7361           (and:SI
7362             (zero_extract:SI
7363               (match_operand 0 "ext_register_operand" "Q")
7364               (const_int 8)
7365               (const_int 8))
7366             (match_operand 1 "const_int_operand" "n"))
7367           (const_int 0)))]
7368   "ix86_match_ccmode (insn, CCNOmode)"
7369   "test{b}\t{%1, %h0|%h0, %1}"
7370   [(set_attr "type" "test")
7371    (set_attr "mode" "QI")
7372    (set_attr "length_immediate" "1")
7373    (set_attr "modrm" "1")
7374    (set_attr "pent_pair" "np")])
7376 (define_insn "*testqi_ext_1"
7377   [(set (reg FLAGS_REG)
7378         (compare
7379           (and:SI
7380             (zero_extract:SI
7381               (match_operand 0 "ext_register_operand" "Q,Q")
7382               (const_int 8)
7383               (const_int 8))
7384             (zero_extend:SI
7385               (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7386           (const_int 0)))]
7387   "ix86_match_ccmode (insn, CCNOmode)"
7388   "test{b}\t{%1, %h0|%h0, %1}"
7389   [(set_attr "isa" "*,nox64")
7390    (set_attr "type" "test")
7391    (set_attr "mode" "QI")])
7393 (define_insn "*testqi_ext_2"
7394   [(set (reg FLAGS_REG)
7395         (compare
7396           (and:SI
7397             (zero_extract:SI
7398               (match_operand 0 "ext_register_operand" "Q")
7399               (const_int 8)
7400               (const_int 8))
7401             (zero_extract:SI
7402               (match_operand 1 "ext_register_operand" "Q")
7403               (const_int 8)
7404               (const_int 8)))
7405           (const_int 0)))]
7406   "ix86_match_ccmode (insn, CCNOmode)"
7407   "test{b}\t{%h1, %h0|%h0, %h1}"
7408   [(set_attr "type" "test")
7409    (set_attr "mode" "QI")])
7411 ;; Combine likes to form bit extractions for some tests.  Humor it.
7412 (define_insn "*testqi_ext_3"
7413   [(set (reg FLAGS_REG)
7414         (compare (zero_extract:SWI48
7415                    (match_operand 0 "nonimmediate_operand" "rm")
7416                    (match_operand:SWI48 1 "const_int_operand")
7417                    (match_operand:SWI48 2 "const_int_operand"))
7418                  (const_int 0)))]
7419   "ix86_match_ccmode (insn, CCNOmode)
7420    && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7421        || GET_MODE (operands[0]) == SImode
7422        || GET_MODE (operands[0]) == HImode
7423        || GET_MODE (operands[0]) == QImode)
7424    /* Ensure that resulting mask is zero or sign extended operand.  */
7425    && INTVAL (operands[2]) >= 0
7426    && ((INTVAL (operands[1]) > 0
7427         && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7428        || (<MODE>mode == DImode
7429            && INTVAL (operands[1]) > 32
7430            && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7431   "#")
7433 (define_split
7434   [(set (match_operand 0 "flags_reg_operand")
7435         (match_operator 1 "compare_operator"
7436           [(zero_extract
7437              (match_operand 2 "nonimmediate_operand")
7438              (match_operand 3 "const_int_operand")
7439              (match_operand 4 "const_int_operand"))
7440            (const_int 0)]))]
7441   "ix86_match_ccmode (insn, CCNOmode)"
7442   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7444   rtx val = operands[2];
7445   HOST_WIDE_INT len = INTVAL (operands[3]);
7446   HOST_WIDE_INT pos = INTVAL (operands[4]);
7447   HOST_WIDE_INT mask;
7448   enum machine_mode mode, submode;
7450   mode = GET_MODE (val);
7451   if (MEM_P (val))
7452     {
7453       /* ??? Combine likes to put non-volatile mem extractions in QImode
7454          no matter the size of the test.  So find a mode that works.  */
7455       if (! MEM_VOLATILE_P (val))
7456         {
7457           mode = smallest_mode_for_size (pos + len, MODE_INT);
7458           val = adjust_address (val, mode, 0);
7459         }
7460     }
7461   else if (GET_CODE (val) == SUBREG
7462            && (submode = GET_MODE (SUBREG_REG (val)),
7463                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7464            && pos + len <= GET_MODE_BITSIZE (submode)
7465            && GET_MODE_CLASS (submode) == MODE_INT)
7466     {
7467       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7468       mode = submode;
7469       val = SUBREG_REG (val);
7470     }
7471   else if (mode == HImode && pos + len <= 8)
7472     {
7473       /* Small HImode tests can be converted to QImode.  */
7474       mode = QImode;
7475       val = gen_lowpart (QImode, val);
7476     }
7478   if (len == HOST_BITS_PER_WIDE_INT)
7479     mask = -1;
7480   else
7481     mask = ((HOST_WIDE_INT)1 << len) - 1;
7482   mask <<= pos;
7484   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7487 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7488 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7489 ;; this is relatively important trick.
7490 ;; Do the conversion only post-reload to avoid limiting of the register class
7491 ;; to QI regs.
7492 (define_split
7493   [(set (match_operand 0 "flags_reg_operand")
7494         (match_operator 1 "compare_operator"
7495           [(and (match_operand 2 "register_operand")
7496                 (match_operand 3 "const_int_operand"))
7497            (const_int 0)]))]
7498    "reload_completed
7499     && QI_REG_P (operands[2])
7500     && GET_MODE (operands[2]) != QImode
7501     && ((ix86_match_ccmode (insn, CCZmode)
7502          && !(INTVAL (operands[3]) & ~(255 << 8)))
7503         || (ix86_match_ccmode (insn, CCNOmode)
7504             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7505   [(set (match_dup 0)
7506         (match_op_dup 1
7507           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7508                    (match_dup 3))
7509            (const_int 0)]))]
7511   operands[2] = gen_lowpart (SImode, operands[2]);
7512   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7515 (define_split
7516   [(set (match_operand 0 "flags_reg_operand")
7517         (match_operator 1 "compare_operator"
7518           [(and (match_operand 2 "nonimmediate_operand")
7519                 (match_operand 3 "const_int_operand"))
7520            (const_int 0)]))]
7521    "reload_completed
7522     && GET_MODE (operands[2]) != QImode
7523     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7524     && ((ix86_match_ccmode (insn, CCZmode)
7525          && !(INTVAL (operands[3]) & ~255))
7526         || (ix86_match_ccmode (insn, CCNOmode)
7527             && !(INTVAL (operands[3]) & ~127)))"
7528   [(set (match_dup 0)
7529         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7530                          (const_int 0)]))]
7532   operands[2] = gen_lowpart (QImode, operands[2]);
7533   operands[3] = gen_lowpart (QImode, operands[3]);
7536 (define_split
7537   [(set (match_operand:SWI1248x 0 "mask_reg_operand")
7538         (any_logic:SWI1248x (match_operand:SWI1248x 1 "mask_reg_operand")
7539                             (match_operand:SWI1248x 2 "mask_reg_operand")))
7540    (clobber (reg:CC FLAGS_REG))]
7541 ;;TODO removed avx512f check because mask_reg implies it.
7542   "reload_completed"
7543   [(set (match_dup 0)
7544         (any_logic:SWI1248x (match_dup 1)
7545                             (match_dup 2)))])
7547 (define_insn "*k<logic>qi"
7548   [(set (match_operand:QI 0 "mask_reg_operand" "=k")
7549         (any_logic:QI (match_operand:QI 1 "mask_reg_operand" "k")
7550                       (match_operand:QI 2 "mask_reg_operand" "k")))]
7551   "TARGET_AVX512F"
7553   return TARGET_AVX512DQ ? "k<logic>b\t{%2, %1, %0|%0, %1, %2}"
7554                          : "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7556   [(set_attr "mode" "QI")
7557    (set_attr "type" "msklog")
7558    (set_attr "prefix" "vex")])
7560 (define_insn "*k<logic>hi"
7561   [(set (match_operand:HI 0 "mask_reg_operand" "=k")
7562         (any_logic:HI (match_operand:HI 1 "mask_reg_operand" "k")
7563                       (match_operand:HI 2 "mask_reg_operand" "k")))]
7564   "TARGET_AVX512F"
7565   "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7566   [(set_attr "mode" "HI")
7567    (set_attr "type" "msklog")
7568    (set_attr "prefix" "vex")])
7570 (define_insn "*k<logic><mode>"
7571   [(set (match_operand:SWI48x 0 "mask_reg_operand" "=k")
7572         (any_logic:SWI48x (match_operand:SWI48x 1 "mask_reg_operand" "k")
7573                           (match_operand:SWI48x 2 "mask_reg_operand" "k")))]
7574   "TARGET_AVX512BW"
7575   "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
7576   [(set_attr "mode" "<MODE>")
7577    (set_attr "type" "msklog")
7578    (set_attr "prefix" "vex")])
7580 ;; %%% This used to optimize known byte-wide and operations to memory,
7581 ;; and sometimes to QImode registers.  If this is considered useful,
7582 ;; it should be done with splitters.
7584 (define_expand "and<mode>3"
7585   [(set (match_operand:SWIM 0 "nonimmediate_operand")
7586         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7587                   (match_operand:SWIM 2 "<general_szext_operand>")))]
7588   ""
7590   enum machine_mode mode = <MODE>mode;
7591   rtx (*insn) (rtx, rtx);
7593   if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7594     {
7595       HOST_WIDE_INT ival = INTVAL (operands[2]);
7597       if (ival == (HOST_WIDE_INT) 0xffffffff)
7598         mode = SImode;
7599       else if (ival == 0xffff)
7600         mode = HImode;
7601       else if (ival == 0xff)
7602         mode = QImode;
7603       }
7605   if (mode == <MODE>mode)
7606     {
7607       ix86_expand_binary_operator (AND, <MODE>mode, operands);
7608       DONE;
7609     }
7611   if (<MODE>mode == DImode)
7612     insn = (mode == SImode)
7613            ? gen_zero_extendsidi2
7614            : (mode == HImode)
7615            ? gen_zero_extendhidi2
7616            : gen_zero_extendqidi2;
7617   else if (<MODE>mode == SImode)
7618     insn = (mode == HImode)
7619            ? gen_zero_extendhisi2
7620            : gen_zero_extendqisi2;
7621   else if (<MODE>mode == HImode)
7622     insn = gen_zero_extendqihi2;
7623   else
7624     gcc_unreachable ();
7626   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7627   DONE;
7630 (define_insn "*anddi_1"
7631   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,!k")
7632         (and:DI
7633          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
7634          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L,k")))
7635    (clobber (reg:CC FLAGS_REG))]
7636   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7638   switch (get_attr_type (insn))
7639     {
7640     case TYPE_IMOVX:
7641       return "#";
7643     case TYPE_MSKLOG:
7644       return "kandq\t{%2, %1, %0|%0, %1, %2}";
7646     default:
7647       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7648       if (get_attr_mode (insn) == MODE_SI)
7649         return "and{l}\t{%k2, %k0|%k0, %k2}";
7650       else
7651         return "and{q}\t{%2, %0|%0, %2}";
7652     }
7654   [(set_attr "type" "alu,alu,alu,imovx,msklog")
7655    (set_attr "length_immediate" "*,*,*,0,0")
7656    (set (attr "prefix_rex")
7657      (if_then_else
7658        (and (eq_attr "type" "imovx")
7659             (and (match_test "INTVAL (operands[2]) == 0xff")
7660                  (match_operand 1 "ext_QIreg_operand")))
7661        (const_string "1")
7662        (const_string "*")))
7663    (set_attr "mode" "SI,DI,DI,SI,DI")])
7665 (define_insn "*andsi_1"
7666   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7667         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm,k")
7668                 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L,k")))
7669    (clobber (reg:CC FLAGS_REG))]
7670   "ix86_binary_operator_ok (AND, SImode, operands)"
7672   switch (get_attr_type (insn))
7673     {
7674     case TYPE_IMOVX:
7675       return "#";
7677     case TYPE_MSKLOG:
7678       return "kandd\t{%2, %1, %0|%0, %1, %2}";
7680     default:
7681       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7682       return "and{l}\t{%2, %0|%0, %2}";
7683     }
7685   [(set_attr "type" "alu,alu,imovx,msklog")
7686    (set (attr "prefix_rex")
7687      (if_then_else
7688        (and (eq_attr "type" "imovx")
7689             (and (match_test "INTVAL (operands[2]) == 0xff")
7690                  (match_operand 1 "ext_QIreg_operand")))
7691        (const_string "1")
7692        (const_string "*")))
7693    (set_attr "length_immediate" "*,*,0,0")
7694    (set_attr "mode" "SI")])
7696 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7697 (define_insn "*andsi_1_zext"
7698   [(set (match_operand:DI 0 "register_operand" "=r")
7699         (zero_extend:DI
7700           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7701                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7702    (clobber (reg:CC FLAGS_REG))]
7703   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7704   "and{l}\t{%2, %k0|%k0, %2}"
7705   [(set_attr "type" "alu")
7706    (set_attr "mode" "SI")])
7708 (define_insn "*andhi_1"
7709   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7710         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k")
7711                 (match_operand:HI 2 "general_operand" "rn,rm,L,k")))
7712    (clobber (reg:CC FLAGS_REG))]
7713   "ix86_binary_operator_ok (AND, HImode, operands)"
7715   switch (get_attr_type (insn))
7716     {
7717     case TYPE_IMOVX:
7718       return "#";
7720     case TYPE_MSKLOG:
7721       return "kandw\t{%2, %1, %0|%0, %1, %2}";
7723     default:
7724       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7725       return "and{w}\t{%2, %0|%0, %2}";
7726     }
7728   [(set_attr "type" "alu,alu,imovx,msklog")
7729    (set_attr "length_immediate" "*,*,0,*")
7730    (set (attr "prefix_rex")
7731      (if_then_else
7732        (and (eq_attr "type" "imovx")
7733             (match_operand 1 "ext_QIreg_operand"))
7734        (const_string "1")
7735        (const_string "*")))
7736    (set_attr "mode" "HI,HI,SI,HI")])
7738 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7739 (define_insn "*andqi_1"
7740   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
7741         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
7742                 (match_operand:QI 2 "general_operand" "qn,qmn,rn,k")))
7743    (clobber (reg:CC FLAGS_REG))]
7744   "ix86_binary_operator_ok (AND, QImode, operands)"
7746   switch (which_alternative)
7747     {
7748     case 0:
7749     case 1:
7750       return "and{b}\t{%2, %0|%0, %2}";
7751     case 2:
7752       return "and{l}\t{%k2, %k0|%k0, %k2}";
7753     case 3:
7754       return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}"
7755                              : "kandw\t{%2, %1, %0|%0, %1, %2}";
7756     default:
7757       gcc_unreachable ();
7758     }
7760   [(set_attr "type" "alu,alu,alu,msklog")
7761    (set_attr "mode" "QI,QI,SI,HI")])
7763 (define_insn "*andqi_1_slp"
7764   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7765         (and:QI (match_dup 0)
7766                 (match_operand:QI 1 "general_operand" "qn,qmn")))
7767    (clobber (reg:CC FLAGS_REG))]
7768   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7769    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7770   "and{b}\t{%1, %0|%0, %1}"
7771   [(set_attr "type" "alu1")
7772    (set_attr "mode" "QI")])
7774 (define_insn "kandn<mode>"
7775   [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k")
7776         (and:SWI12
7777           (not:SWI12
7778             (match_operand:SWI12 1 "register_operand" "r,0,k"))
7779           (match_operand:SWI12 2 "register_operand" "r,r,k")))
7780    (clobber (reg:CC FLAGS_REG))]
7781   "TARGET_AVX512F"
7783   switch (which_alternative)
7784     {
7785     case 0:
7786       return "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}";
7787     case 1:
7788       return "#";
7789     case 2:
7790       if (TARGET_AVX512DQ && <MODE>mode == QImode)
7791         return "kandnb\t{%2, %1, %0|%0, %1, %2}";
7792       else
7793         return "kandnw\t{%2, %1, %0|%0, %1, %2}";
7794     default:
7795       gcc_unreachable ();
7796     }
7798   [(set_attr "isa" "bmi,*,avx512f")
7799    (set_attr "type" "bitmanip,*,msklog")
7800    (set_attr "prefix" "*,*,vex")
7801    (set_attr "btver2_decode" "direct,*,*")
7802    (set_attr "mode" "<MODE>")])
7804 (define_split
7805   [(set (match_operand:SWI12 0 "general_reg_operand")
7806         (and:SWI12
7807           (not:SWI12
7808             (match_dup 0))
7809           (match_operand:SWI12 1 "general_reg_operand")))
7810    (clobber (reg:CC FLAGS_REG))]
7811   "TARGET_AVX512F && !TARGET_BMI && reload_completed"
7812   [(set (match_dup 0)
7813         (not:HI (match_dup 0)))
7814    (parallel [(set (match_dup 0)
7815                    (and:HI (match_dup 0)
7816                            (match_dup 1)))
7817               (clobber (reg:CC FLAGS_REG))])])
7819 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7820 (define_split
7821   [(set (match_operand:DI 0 "register_operand")
7822         (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7823                 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7824    (clobber (reg:CC FLAGS_REG))]
7825   "TARGET_64BIT"
7826   [(parallel [(set (match_dup 0)
7827                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7828               (clobber (reg:CC FLAGS_REG))])]
7829   "operands[2] = gen_lowpart (SImode, operands[2]);")
7831 (define_split
7832   [(set (match_operand:SWI248 0 "register_operand")
7833         (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7834                     (match_operand:SWI248 2 "const_int_operand")))
7835    (clobber (reg:CC FLAGS_REG))]
7836   "reload_completed
7837    && true_regnum (operands[0]) != true_regnum (operands[1])"
7838   [(const_int 0)]
7840   HOST_WIDE_INT ival = INTVAL (operands[2]);
7841   enum machine_mode mode;
7842   rtx (*insn) (rtx, rtx);
7844   if (ival == (HOST_WIDE_INT) 0xffffffff)
7845     mode = SImode;
7846   else if (ival == 0xffff)
7847     mode = HImode;
7848   else
7849     {
7850       gcc_assert (ival == 0xff);
7851       mode = QImode;
7852     }
7854   if (<MODE>mode == DImode)
7855     insn = (mode == SImode)
7856            ? gen_zero_extendsidi2
7857            : (mode == HImode)
7858            ? gen_zero_extendhidi2
7859            : gen_zero_extendqidi2;
7860   else
7861     {
7862       if (<MODE>mode != SImode)
7863         /* Zero extend to SImode to avoid partial register stalls.  */
7864         operands[0] = gen_lowpart (SImode, operands[0]);
7866       insn = (mode == HImode)
7867              ? gen_zero_extendhisi2
7868              : gen_zero_extendqisi2;
7869     }
7870   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7871   DONE;
7874 (define_split
7875   [(set (match_operand 0 "register_operand")
7876         (and (match_dup 0)
7877              (const_int -65536)))
7878    (clobber (reg:CC FLAGS_REG))]
7879   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7880     || optimize_function_for_size_p (cfun)"
7881   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7882   "operands[1] = gen_lowpart (HImode, operands[0]);")
7884 (define_split
7885   [(set (match_operand 0 "ext_register_operand")
7886         (and (match_dup 0)
7887              (const_int -256)))
7888    (clobber (reg:CC FLAGS_REG))]
7889   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7890    && reload_completed"
7891   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7892   "operands[1] = gen_lowpart (QImode, operands[0]);")
7894 (define_split
7895   [(set (match_operand 0 "ext_register_operand")
7896         (and (match_dup 0)
7897              (const_int -65281)))
7898    (clobber (reg:CC FLAGS_REG))]
7899   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7900    && reload_completed"
7901   [(parallel [(set (zero_extract:SI (match_dup 0)
7902                                     (const_int 8)
7903                                     (const_int 8))
7904                    (xor:SI
7905                      (zero_extract:SI (match_dup 0)
7906                                       (const_int 8)
7907                                       (const_int 8))
7908                      (zero_extract:SI (match_dup 0)
7909                                       (const_int 8)
7910                                       (const_int 8))))
7911               (clobber (reg:CC FLAGS_REG))])]
7912   "operands[0] = gen_lowpart (SImode, operands[0]);")
7914 (define_insn "*anddi_2"
7915   [(set (reg FLAGS_REG)
7916         (compare
7917          (and:DI
7918           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7919           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7920          (const_int 0)))
7921    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7922         (and:DI (match_dup 1) (match_dup 2)))]
7923   "TARGET_64BIT
7924    && ix86_match_ccmode
7925         (insn,
7926          /* If we are going to emit andl instead of andq, and the operands[2]
7927             constant might have the SImode sign bit set, make sure the sign
7928             flag isn't tested, because the instruction will set the sign flag
7929             based on bit 31 rather than bit 63.  If it isn't CONST_INT,
7930             conservatively assume it might have bit 31 set.  */
7931          (satisfies_constraint_Z (operands[2])
7932           && (!CONST_INT_P (operands[2])
7933               || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
7934          ? CCZmode : CCNOmode)
7935    && ix86_binary_operator_ok (AND, DImode, operands)"
7936   "@
7937    and{l}\t{%k2, %k0|%k0, %k2}
7938    and{q}\t{%2, %0|%0, %2}
7939    and{q}\t{%2, %0|%0, %2}"
7940   [(set_attr "type" "alu")
7941    (set_attr "mode" "SI,DI,DI")])
7943 (define_insn "*andqi_2_maybe_si"
7944   [(set (reg FLAGS_REG)
7945         (compare (and:QI
7946                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7947                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7948                  (const_int 0)))
7949    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7950         (and:QI (match_dup 1) (match_dup 2)))]
7951   "ix86_binary_operator_ok (AND, QImode, operands)
7952    && ix86_match_ccmode (insn,
7953                          CONST_INT_P (operands[2])
7954                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7956   if (which_alternative == 2)
7957     {
7958       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7959         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7960       return "and{l}\t{%2, %k0|%k0, %2}";
7961     }
7962   return "and{b}\t{%2, %0|%0, %2}";
7964   [(set_attr "type" "alu")
7965    (set_attr "mode" "QI,QI,SI")])
7967 (define_insn "*and<mode>_2"
7968   [(set (reg FLAGS_REG)
7969         (compare (and:SWI124
7970                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7971                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7972                  (const_int 0)))
7973    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7974         (and:SWI124 (match_dup 1) (match_dup 2)))]
7975   "ix86_match_ccmode (insn, CCNOmode)
7976    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7977   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7978   [(set_attr "type" "alu")
7979    (set_attr "mode" "<MODE>")])
7981 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7982 (define_insn "*andsi_2_zext"
7983   [(set (reg FLAGS_REG)
7984         (compare (and:SI
7985                   (match_operand:SI 1 "nonimmediate_operand" "%0")
7986                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
7987                  (const_int 0)))
7988    (set (match_operand:DI 0 "register_operand" "=r")
7989         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7990   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7991    && ix86_binary_operator_ok (AND, SImode, operands)"
7992   "and{l}\t{%2, %k0|%k0, %2}"
7993   [(set_attr "type" "alu")
7994    (set_attr "mode" "SI")])
7996 (define_insn "*andqi_2_slp"
7997   [(set (reg FLAGS_REG)
7998         (compare (and:QI
7999                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8000                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8001                  (const_int 0)))
8002    (set (strict_low_part (match_dup 0))
8003         (and:QI (match_dup 0) (match_dup 1)))]
8004   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8005    && ix86_match_ccmode (insn, CCNOmode)
8006    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8007   "and{b}\t{%1, %0|%0, %1}"
8008   [(set_attr "type" "alu1")
8009    (set_attr "mode" "QI")])
8011 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8012 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8013 ;; for a QImode operand, which of course failed.
8014 (define_insn "andqi_ext_0"
8015   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8016                          (const_int 8)
8017                          (const_int 8))
8018         (and:SI
8019           (zero_extract:SI
8020             (match_operand 1 "ext_register_operand" "0")
8021             (const_int 8)
8022             (const_int 8))
8023           (match_operand 2 "const_int_operand" "n")))
8024    (clobber (reg:CC FLAGS_REG))]
8025   ""
8026   "and{b}\t{%2, %h0|%h0, %2}"
8027   [(set_attr "type" "alu")
8028    (set_attr "length_immediate" "1")
8029    (set_attr "modrm" "1")
8030    (set_attr "mode" "QI")])
8032 ;; Generated by peephole translating test to and.  This shows up
8033 ;; often in fp comparisons.
8034 (define_insn "*andqi_ext_0_cc"
8035   [(set (reg FLAGS_REG)
8036         (compare
8037           (and:SI
8038             (zero_extract:SI
8039               (match_operand 1 "ext_register_operand" "0")
8040               (const_int 8)
8041               (const_int 8))
8042             (match_operand 2 "const_int_operand" "n"))
8043           (const_int 0)))
8044    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8045                          (const_int 8)
8046                          (const_int 8))
8047         (and:SI
8048           (zero_extract:SI
8049             (match_dup 1)
8050             (const_int 8)
8051             (const_int 8))
8052           (match_dup 2)))]
8053   "ix86_match_ccmode (insn, CCNOmode)"
8054   "and{b}\t{%2, %h0|%h0, %2}"
8055   [(set_attr "type" "alu")
8056    (set_attr "length_immediate" "1")
8057    (set_attr "modrm" "1")
8058    (set_attr "mode" "QI")])
8060 (define_insn "*andqi_ext_1"
8061   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8062                          (const_int 8)
8063                          (const_int 8))
8064         (and:SI
8065           (zero_extract:SI
8066             (match_operand 1 "ext_register_operand" "0,0")
8067             (const_int 8)
8068             (const_int 8))
8069           (zero_extend:SI
8070             (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8071    (clobber (reg:CC FLAGS_REG))]
8072   ""
8073   "and{b}\t{%2, %h0|%h0, %2}"
8074   [(set_attr "isa" "*,nox64")
8075    (set_attr "type" "alu")
8076    (set_attr "length_immediate" "0")
8077    (set_attr "mode" "QI")])
8079 (define_insn "*andqi_ext_2"
8080   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8081                          (const_int 8)
8082                          (const_int 8))
8083         (and:SI
8084           (zero_extract:SI
8085             (match_operand 1 "ext_register_operand" "%0")
8086             (const_int 8)
8087             (const_int 8))
8088           (zero_extract:SI
8089             (match_operand 2 "ext_register_operand" "Q")
8090             (const_int 8)
8091             (const_int 8))))
8092    (clobber (reg:CC FLAGS_REG))]
8093   ""
8094   "and{b}\t{%h2, %h0|%h0, %h2}"
8095   [(set_attr "type" "alu")
8096    (set_attr "length_immediate" "0")
8097    (set_attr "mode" "QI")])
8099 ;; Convert wide AND instructions with immediate operand to shorter QImode
8100 ;; equivalents when possible.
8101 ;; Don't do the splitting with memory operands, since it introduces risk
8102 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8103 ;; for size, but that can (should?) be handled by generic code instead.
8104 (define_split
8105   [(set (match_operand 0 "register_operand")
8106         (and (match_operand 1 "register_operand")
8107              (match_operand 2 "const_int_operand")))
8108    (clobber (reg:CC FLAGS_REG))]
8109    "reload_completed
8110     && QI_REG_P (operands[0])
8111     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8112     && !(~INTVAL (operands[2]) & ~(255 << 8))
8113     && GET_MODE (operands[0]) != QImode"
8114   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8115                    (and:SI (zero_extract:SI (match_dup 1)
8116                                             (const_int 8) (const_int 8))
8117                            (match_dup 2)))
8118               (clobber (reg:CC FLAGS_REG))])]
8120   operands[0] = gen_lowpart (SImode, operands[0]);
8121   operands[1] = gen_lowpart (SImode, operands[1]);
8122   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8125 ;; Since AND can be encoded with sign extended immediate, this is only
8126 ;; profitable when 7th bit is not set.
8127 (define_split
8128   [(set (match_operand 0 "register_operand")
8129         (and (match_operand 1 "general_operand")
8130              (match_operand 2 "const_int_operand")))
8131    (clobber (reg:CC FLAGS_REG))]
8132    "reload_completed
8133     && ANY_QI_REG_P (operands[0])
8134     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8135     && !(~INTVAL (operands[2]) & ~255)
8136     && !(INTVAL (operands[2]) & 128)
8137     && GET_MODE (operands[0]) != QImode"
8138   [(parallel [(set (strict_low_part (match_dup 0))
8139                    (and:QI (match_dup 1)
8140                            (match_dup 2)))
8141               (clobber (reg:CC FLAGS_REG))])]
8143   operands[0] = gen_lowpart (QImode, operands[0]);
8144   operands[1] = gen_lowpart (QImode, operands[1]);
8145   operands[2] = gen_lowpart (QImode, operands[2]);
8148 ;; Logical inclusive and exclusive OR instructions
8150 ;; %%% This used to optimize known byte-wide and operations to memory.
8151 ;; If this is considered useful, it should be done with splitters.
8153 (define_expand "<code><mode>3"
8154   [(set (match_operand:SWIM 0 "nonimmediate_operand")
8155         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8156                      (match_operand:SWIM 2 "<general_operand>")))]
8157   ""
8158   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8160 (define_insn "*<code><mode>_1"
8161   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,k")
8162         (any_or:SWI48
8163          (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,k")
8164          (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,k")))
8165    (clobber (reg:CC FLAGS_REG))]
8166   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8167   "@
8168    <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8169    <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8170    k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8171   [(set_attr "type" "alu,alu,msklog")
8172    (set_attr "mode" "<MODE>")])
8174 (define_insn "*<code>hi_1"
8175   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
8176         (any_or:HI
8177          (match_operand:HI 1 "nonimmediate_operand" "%0,0,k")
8178          (match_operand:HI 2 "general_operand" "<g>,r<i>,k")))
8179    (clobber (reg:CC FLAGS_REG))]
8180   "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8181   "@
8182   <logic>{w}\t{%2, %0|%0, %2}
8183   <logic>{w}\t{%2, %0|%0, %2}
8184   k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8185   [(set_attr "type" "alu,alu,msklog")
8186    (set_attr "mode" "HI")])
8188 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8189 (define_insn "*<code>qi_1"
8190   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
8191         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8192                    (match_operand:QI 2 "general_operand" "qmn,qn,rn,k")))
8193    (clobber (reg:CC FLAGS_REG))]
8194   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8195   "@
8196    <logic>{b}\t{%2, %0|%0, %2}
8197    <logic>{b}\t{%2, %0|%0, %2}
8198    <logic>{l}\t{%k2, %k0|%k0, %k2}
8199    k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8200   [(set_attr "type" "alu,alu,alu,msklog")
8201    (set_attr "mode" "QI,QI,SI,HI")])
8203 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8204 (define_insn "*<code>si_1_zext"
8205   [(set (match_operand:DI 0 "register_operand" "=r")
8206         (zero_extend:DI
8207          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8208                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8209    (clobber (reg:CC FLAGS_REG))]
8210   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8211   "<logic>{l}\t{%2, %k0|%k0, %2}"
8212   [(set_attr "type" "alu")
8213    (set_attr "mode" "SI")])
8215 (define_insn "*<code>si_1_zext_imm"
8216   [(set (match_operand:DI 0 "register_operand" "=r")
8217         (any_or:DI
8218          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8219          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8220    (clobber (reg:CC FLAGS_REG))]
8221   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8222   "<logic>{l}\t{%2, %k0|%k0, %2}"
8223   [(set_attr "type" "alu")
8224    (set_attr "mode" "SI")])
8226 (define_insn "*<code>qi_1_slp"
8227   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8228         (any_or:QI (match_dup 0)
8229                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8230    (clobber (reg:CC FLAGS_REG))]
8231   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8232    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8233   "<logic>{b}\t{%1, %0|%0, %1}"
8234   [(set_attr "type" "alu1")
8235    (set_attr "mode" "QI")])
8237 (define_insn "*<code><mode>_2"
8238   [(set (reg FLAGS_REG)
8239         (compare (any_or:SWI
8240                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8241                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8242                  (const_int 0)))
8243    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8244         (any_or:SWI (match_dup 1) (match_dup 2)))]
8245   "ix86_match_ccmode (insn, CCNOmode)
8246    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8247   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8248   [(set_attr "type" "alu")
8249    (set_attr "mode" "<MODE>")])
8251 (define_insn "kxnor<mode>"
8252   [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
8253         (not:SWI12
8254           (xor:SWI12
8255             (match_operand:SWI12 1 "register_operand" "0,k")
8256             (match_operand:SWI12 2 "register_operand" "r,k"))))
8257    (clobber (reg:CC FLAGS_REG))]
8258   "TARGET_AVX512F"
8260   if (which_alternative == 1 && <MODE>mode == QImode && TARGET_AVX512DQ)
8261     return "kxnorb\t{%2, %1, %0|%0, %1, %2}";
8262   return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
8264   [(set_attr "type" "*,msklog")
8265    (set_attr "prefix" "*,vex")
8266    (set_attr "mode" "<MODE>")])
8268 (define_insn "kxnor<mode>"
8269   [(set (match_operand:SWI48x 0 "register_operand" "=r,!k")
8270         (not:SWI48x
8271           (xor:SWI48x
8272             (match_operand:SWI48x 1 "register_operand" "0,k")
8273             (match_operand:SWI48x 2 "register_operand" "r,k"))))
8274    (clobber (reg:CC FLAGS_REG))]
8275   "TARGET_AVX512BW"
8276   "@
8277    #
8278    kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8279   [(set_attr "type" "*,msklog")
8280    (set_attr "prefix" "*,vex")
8281    (set_attr "mode" "<MODE>")])
8283 (define_split
8284   [(set (match_operand:SWI1248x 0 "general_reg_operand")
8285         (not:SWI1248x
8286           (xor:SWI1248x
8287             (match_dup 0)
8288             (match_operand:SWI1248x 1 "general_reg_operand"))))
8289    (clobber (reg:CC FLAGS_REG))]
8290   "TARGET_AVX512F && reload_completed"
8291    [(parallel [(set (match_dup 0)
8292                     (xor:HI (match_dup 0)
8293                             (match_dup 1)))
8294                (clobber (reg:CC FLAGS_REG))])
8295     (set (match_dup 0)
8296          (not:HI (match_dup 0)))])
8298 ;;There are kortrest[bdq] but no intrinsics for them.
8299 ;;We probably don't need to implement them.
8300 (define_insn "kortestzhi"
8301   [(set (reg:CCZ FLAGS_REG)
8302         (compare:CCZ
8303           (ior:HI
8304             (match_operand:HI 0 "register_operand" "k")
8305             (match_operand:HI 1 "register_operand" "k"))
8306           (const_int 0)))]
8307   "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8308   "kortestw\t{%1, %0|%0, %1}"
8309   [(set_attr "mode" "HI")
8310    (set_attr "type" "msklog")
8311    (set_attr "prefix" "vex")])
8313 (define_insn "kortestchi"
8314   [(set (reg:CCC FLAGS_REG)
8315         (compare:CCC
8316           (ior:HI
8317             (match_operand:HI 0 "register_operand" "k")
8318             (match_operand:HI 1 "register_operand" "k"))
8319           (const_int -1)))]
8320   "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8321   "kortestw\t{%1, %0|%0, %1}"
8322   [(set_attr "mode" "HI")
8323    (set_attr "type" "msklog")
8324    (set_attr "prefix" "vex")])
8326 (define_insn "kunpckhi"
8327   [(set (match_operand:HI 0 "register_operand" "=k")
8328         (ior:HI
8329           (ashift:HI
8330             (match_operand:HI 1 "register_operand" "k")
8331             (const_int 8))
8332           (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
8333   "TARGET_AVX512F"
8334   "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8335   [(set_attr "mode" "HI")
8336    (set_attr "type" "msklog")
8337    (set_attr "prefix" "vex")])
8339 (define_insn "kunpcksi"
8340   [(set (match_operand:SI 0 "register_operand" "=k")
8341         (ior:SI
8342           (ashift:SI
8343             (match_operand:SI 1 "register_operand" "k")
8344             (const_int 16))
8345           (zero_extend:SI (subreg:HI (match_operand:SI 2 "register_operand" "k") 0))))]
8346   "TARGET_AVX512BW"
8347   "kunpckwd\t{%2, %1, %0|%0, %1, %2}"
8348   [(set_attr "mode" "SI")])
8350 (define_insn "kunpckdi"
8351   [(set (match_operand:DI 0 "register_operand" "=k")
8352         (ior:DI
8353           (ashift:DI
8354             (match_operand:DI 1 "register_operand" "k")
8355             (const_int 32))
8356           (zero_extend:DI (subreg:SI (match_operand:DI 2 "register_operand" "k") 0))))]
8357   "TARGET_AVX512BW"
8358   "kunpckdq\t{%2, %1, %0|%0, %1, %2}"
8359   [(set_attr "mode" "DI")])
8361 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8362 ;; ??? Special case for immediate operand is missing - it is tricky.
8363 (define_insn "*<code>si_2_zext"
8364   [(set (reg FLAGS_REG)
8365         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8366                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
8367                  (const_int 0)))
8368    (set (match_operand:DI 0 "register_operand" "=r")
8369         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8370   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8371    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8372   "<logic>{l}\t{%2, %k0|%k0, %2}"
8373   [(set_attr "type" "alu")
8374    (set_attr "mode" "SI")])
8376 (define_insn "*<code>si_2_zext_imm"
8377   [(set (reg FLAGS_REG)
8378         (compare (any_or:SI
8379                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8380                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8381                  (const_int 0)))
8382    (set (match_operand:DI 0 "register_operand" "=r")
8383         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8384   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8385    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8386   "<logic>{l}\t{%2, %k0|%k0, %2}"
8387   [(set_attr "type" "alu")
8388    (set_attr "mode" "SI")])
8390 (define_insn "*<code>qi_2_slp"
8391   [(set (reg FLAGS_REG)
8392         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8393                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8394                  (const_int 0)))
8395    (set (strict_low_part (match_dup 0))
8396         (any_or:QI (match_dup 0) (match_dup 1)))]
8397   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8398    && ix86_match_ccmode (insn, CCNOmode)
8399    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8400   "<logic>{b}\t{%1, %0|%0, %1}"
8401   [(set_attr "type" "alu1")
8402    (set_attr "mode" "QI")])
8404 (define_insn "*<code><mode>_3"
8405   [(set (reg FLAGS_REG)
8406         (compare (any_or:SWI
8407                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8408                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8409                  (const_int 0)))
8410    (clobber (match_scratch:SWI 0 "=<r>"))]
8411   "ix86_match_ccmode (insn, CCNOmode)
8412    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8413   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8414   [(set_attr "type" "alu")
8415    (set_attr "mode" "<MODE>")])
8417 (define_insn "*<code>qi_ext_0"
8418   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8419                          (const_int 8)
8420                          (const_int 8))
8421         (any_or:SI
8422           (zero_extract:SI
8423             (match_operand 1 "ext_register_operand" "0")
8424             (const_int 8)
8425             (const_int 8))
8426           (match_operand 2 "const_int_operand" "n")))
8427    (clobber (reg:CC FLAGS_REG))]
8428   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8429   "<logic>{b}\t{%2, %h0|%h0, %2}"
8430   [(set_attr "type" "alu")
8431    (set_attr "length_immediate" "1")
8432    (set_attr "modrm" "1")
8433    (set_attr "mode" "QI")])
8435 (define_insn "*<code>qi_ext_1"
8436   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8437                          (const_int 8)
8438                          (const_int 8))
8439         (any_or:SI
8440           (zero_extract:SI
8441             (match_operand 1 "ext_register_operand" "0,0")
8442             (const_int 8)
8443             (const_int 8))
8444           (zero_extend:SI
8445             (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8446    (clobber (reg:CC FLAGS_REG))]
8447   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8448   "<logic>{b}\t{%2, %h0|%h0, %2}"
8449   [(set_attr "isa" "*,nox64")
8450    (set_attr "type" "alu")
8451    (set_attr "length_immediate" "0")
8452    (set_attr "mode" "QI")])
8454 (define_insn "*<code>qi_ext_2"
8455   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8456                          (const_int 8)
8457                          (const_int 8))
8458         (any_or:SI
8459           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8460                            (const_int 8)
8461                            (const_int 8))
8462           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8463                            (const_int 8)
8464                            (const_int 8))))
8465    (clobber (reg:CC FLAGS_REG))]
8466   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8467   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8468   [(set_attr "type" "alu")
8469    (set_attr "length_immediate" "0")
8470    (set_attr "mode" "QI")])
8472 (define_split
8473   [(set (match_operand 0 "register_operand")
8474         (any_or (match_operand 1 "register_operand")
8475                 (match_operand 2 "const_int_operand")))
8476    (clobber (reg:CC FLAGS_REG))]
8477    "reload_completed
8478     && QI_REG_P (operands[0])
8479     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8480     && !(INTVAL (operands[2]) & ~(255 << 8))
8481     && GET_MODE (operands[0]) != QImode"
8482   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8483                    (any_or:SI (zero_extract:SI (match_dup 1)
8484                                                (const_int 8) (const_int 8))
8485                               (match_dup 2)))
8486               (clobber (reg:CC FLAGS_REG))])]
8488   operands[0] = gen_lowpart (SImode, operands[0]);
8489   operands[1] = gen_lowpart (SImode, operands[1]);
8490   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8493 ;; Since OR can be encoded with sign extended immediate, this is only
8494 ;; profitable when 7th bit is set.
8495 (define_split
8496   [(set (match_operand 0 "register_operand")
8497         (any_or (match_operand 1 "general_operand")
8498                 (match_operand 2 "const_int_operand")))
8499    (clobber (reg:CC FLAGS_REG))]
8500    "reload_completed
8501     && ANY_QI_REG_P (operands[0])
8502     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8503     && !(INTVAL (operands[2]) & ~255)
8504     && (INTVAL (operands[2]) & 128)
8505     && GET_MODE (operands[0]) != QImode"
8506   [(parallel [(set (strict_low_part (match_dup 0))
8507                    (any_or:QI (match_dup 1)
8508                               (match_dup 2)))
8509               (clobber (reg:CC FLAGS_REG))])]
8511   operands[0] = gen_lowpart (QImode, operands[0]);
8512   operands[1] = gen_lowpart (QImode, operands[1]);
8513   operands[2] = gen_lowpart (QImode, operands[2]);
8516 (define_expand "xorqi_cc_ext_1"
8517   [(parallel [
8518      (set (reg:CCNO FLAGS_REG)
8519           (compare:CCNO
8520             (xor:SI
8521               (zero_extract:SI
8522                 (match_operand 1 "ext_register_operand")
8523                 (const_int 8)
8524                 (const_int 8))
8525               (match_operand:QI 2 "const_int_operand"))
8526             (const_int 0)))
8527      (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8528                            (const_int 8)
8529                            (const_int 8))
8530           (xor:SI
8531             (zero_extract:SI
8532              (match_dup 1)
8533              (const_int 8)
8534              (const_int 8))
8535             (match_dup 2)))])])
8537 (define_insn "*xorqi_cc_ext_1"
8538   [(set (reg FLAGS_REG)
8539         (compare
8540           (xor:SI
8541             (zero_extract:SI
8542               (match_operand 1 "ext_register_operand" "0,0")
8543               (const_int 8)
8544               (const_int 8))
8545             (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8546           (const_int 0)))
8547    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8548                          (const_int 8)
8549                          (const_int 8))
8550         (xor:SI
8551           (zero_extract:SI
8552            (match_dup 1)
8553            (const_int 8)
8554            (const_int 8))
8555           (match_dup 2)))]
8556   "ix86_match_ccmode (insn, CCNOmode)"
8557   "xor{b}\t{%2, %h0|%h0, %2}"
8558   [(set_attr "isa" "*,nox64")
8559    (set_attr "type" "alu")
8560    (set_attr "modrm" "1")
8561    (set_attr "mode" "QI")])
8563 ;; Negation instructions
8565 (define_expand "neg<mode>2"
8566   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8567         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8568   ""
8569   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8571 (define_insn_and_split "*neg<dwi>2_doubleword"
8572   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8573         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8574    (clobber (reg:CC FLAGS_REG))]
8575   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8576   "#"
8577   "reload_completed"
8578   [(parallel
8579     [(set (reg:CCZ FLAGS_REG)
8580           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8581      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8582    (parallel
8583     [(set (match_dup 2)
8584           (plus:DWIH (match_dup 3)
8585                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8586                                 (const_int 0))))
8587      (clobber (reg:CC FLAGS_REG))])
8588    (parallel
8589     [(set (match_dup 2)
8590           (neg:DWIH (match_dup 2)))
8591      (clobber (reg:CC FLAGS_REG))])]
8592   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8594 (define_insn "*neg<mode>2_1"
8595   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8596         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8597    (clobber (reg:CC FLAGS_REG))]
8598   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8599   "neg{<imodesuffix>}\t%0"
8600   [(set_attr "type" "negnot")
8601    (set_attr "mode" "<MODE>")])
8603 ;; Combine is quite creative about this pattern.
8604 (define_insn "*negsi2_1_zext"
8605   [(set (match_operand:DI 0 "register_operand" "=r")
8606         (lshiftrt:DI
8607           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8608                              (const_int 32)))
8609         (const_int 32)))
8610    (clobber (reg:CC FLAGS_REG))]
8611   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8612   "neg{l}\t%k0"
8613   [(set_attr "type" "negnot")
8614    (set_attr "mode" "SI")])
8616 ;; The problem with neg is that it does not perform (compare x 0),
8617 ;; it really performs (compare 0 x), which leaves us with the zero
8618 ;; flag being the only useful item.
8620 (define_insn "*neg<mode>2_cmpz"
8621   [(set (reg:CCZ FLAGS_REG)
8622         (compare:CCZ
8623           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8624                    (const_int 0)))
8625    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8626         (neg:SWI (match_dup 1)))]
8627   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8628   "neg{<imodesuffix>}\t%0"
8629   [(set_attr "type" "negnot")
8630    (set_attr "mode" "<MODE>")])
8632 (define_insn "*negsi2_cmpz_zext"
8633   [(set (reg:CCZ FLAGS_REG)
8634         (compare:CCZ
8635           (lshiftrt:DI
8636             (neg:DI (ashift:DI
8637                       (match_operand:DI 1 "register_operand" "0")
8638                       (const_int 32)))
8639             (const_int 32))
8640           (const_int 0)))
8641    (set (match_operand:DI 0 "register_operand" "=r")
8642         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8643                                         (const_int 32)))
8644                      (const_int 32)))]
8645   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8646   "neg{l}\t%k0"
8647   [(set_attr "type" "negnot")
8648    (set_attr "mode" "SI")])
8650 ;; Negate with jump on overflow.
8651 (define_expand "negv<mode>3"
8652   [(parallel [(set (reg:CCO FLAGS_REG)
8653                    (ne:CCO (match_operand:SWI 1 "register_operand")
8654                            (match_dup 3)))
8655               (set (match_operand:SWI 0 "register_operand")
8656                    (neg:SWI (match_dup 1)))])
8657    (set (pc) (if_then_else
8658                (eq (reg:CCO FLAGS_REG) (const_int 0))
8659                (label_ref (match_operand 2))
8660                (pc)))]
8661   ""
8663   operands[3]
8664     = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
8665                     <MODE>mode);
8668 (define_insn "*negv<mode>3"
8669   [(set (reg:CCO FLAGS_REG)
8670         (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
8671                 (match_operand:SWI 2 "const_int_operand")))
8672    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8673         (neg:SWI (match_dup 1)))]
8674   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
8675    && mode_signbit_p (<MODE>mode, operands[2])"
8676   "neg{<imodesuffix>}\t%0"
8677   [(set_attr "type" "negnot")
8678    (set_attr "mode" "<MODE>")])
8680 ;; Changing of sign for FP values is doable using integer unit too.
8682 (define_expand "<code><mode>2"
8683   [(set (match_operand:X87MODEF 0 "register_operand")
8684         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8685   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8686   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8688 (define_insn "*absneg<mode>2_mixed"
8689   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8690         (match_operator:MODEF 3 "absneg_operator"
8691           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8692    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8693    (clobber (reg:CC FLAGS_REG))]
8694   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8695   "#")
8697 (define_insn "*absneg<mode>2_sse"
8698   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8699         (match_operator:MODEF 3 "absneg_operator"
8700           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8701    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8702    (clobber (reg:CC FLAGS_REG))]
8703   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8704   "#")
8706 (define_insn "*absneg<mode>2_i387"
8707   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8708         (match_operator:X87MODEF 3 "absneg_operator"
8709           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8710    (use (match_operand 2))
8711    (clobber (reg:CC FLAGS_REG))]
8712   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8713   "#")
8715 (define_expand "<code>tf2"
8716   [(set (match_operand:TF 0 "register_operand")
8717         (absneg:TF (match_operand:TF 1 "register_operand")))]
8718   "TARGET_SSE"
8719   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8721 (define_insn "*absnegtf2_sse"
8722   [(set (match_operand:TF 0 "register_operand" "=x,x")
8723         (match_operator:TF 3 "absneg_operator"
8724           [(match_operand:TF 1 "register_operand" "0,x")]))
8725    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8726    (clobber (reg:CC FLAGS_REG))]
8727   "TARGET_SSE"
8728   "#")
8730 ;; Splitters for fp abs and neg.
8732 (define_split
8733   [(set (match_operand 0 "fp_register_operand")
8734         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8735    (use (match_operand 2))
8736    (clobber (reg:CC FLAGS_REG))]
8737   "reload_completed"
8738   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8740 (define_split
8741   [(set (match_operand 0 "register_operand")
8742         (match_operator 3 "absneg_operator"
8743           [(match_operand 1 "register_operand")]))
8744    (use (match_operand 2 "nonimmediate_operand"))
8745    (clobber (reg:CC FLAGS_REG))]
8746   "reload_completed && SSE_REG_P (operands[0])"
8747   [(set (match_dup 0) (match_dup 3))]
8749   enum machine_mode mode = GET_MODE (operands[0]);
8750   enum machine_mode vmode = GET_MODE (operands[2]);
8751   rtx tmp;
8753   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8754   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8755   if (operands_match_p (operands[0], operands[2]))
8756     {
8757       tmp = operands[1];
8758       operands[1] = operands[2];
8759       operands[2] = tmp;
8760     }
8761   if (GET_CODE (operands[3]) == ABS)
8762     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8763   else
8764     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8765   operands[3] = tmp;
8768 (define_split
8769   [(set (match_operand:SF 0 "register_operand")
8770         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8771    (use (match_operand:V4SF 2))
8772    (clobber (reg:CC FLAGS_REG))]
8773   "reload_completed"
8774   [(parallel [(set (match_dup 0) (match_dup 1))
8775               (clobber (reg:CC FLAGS_REG))])]
8777   rtx tmp;
8778   operands[0] = gen_lowpart (SImode, operands[0]);
8779   if (GET_CODE (operands[1]) == ABS)
8780     {
8781       tmp = gen_int_mode (0x7fffffff, SImode);
8782       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8783     }
8784   else
8785     {
8786       tmp = gen_int_mode (0x80000000, SImode);
8787       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8788     }
8789   operands[1] = tmp;
8792 (define_split
8793   [(set (match_operand:DF 0 "register_operand")
8794         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8795    (use (match_operand 2))
8796    (clobber (reg:CC FLAGS_REG))]
8797   "reload_completed"
8798   [(parallel [(set (match_dup 0) (match_dup 1))
8799               (clobber (reg:CC FLAGS_REG))])]
8801   rtx tmp;
8802   if (TARGET_64BIT)
8803     {
8804       tmp = gen_lowpart (DImode, operands[0]);
8805       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8806       operands[0] = tmp;
8808       if (GET_CODE (operands[1]) == ABS)
8809         tmp = const0_rtx;
8810       else
8811         tmp = gen_rtx_NOT (DImode, tmp);
8812     }
8813   else
8814     {
8815       operands[0] = gen_highpart (SImode, operands[0]);
8816       if (GET_CODE (operands[1]) == ABS)
8817         {
8818           tmp = gen_int_mode (0x7fffffff, SImode);
8819           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8820         }
8821       else
8822         {
8823           tmp = gen_int_mode (0x80000000, SImode);
8824           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8825         }
8826     }
8827   operands[1] = tmp;
8830 (define_split
8831   [(set (match_operand:XF 0 "register_operand")
8832         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8833    (use (match_operand 2))
8834    (clobber (reg:CC FLAGS_REG))]
8835   "reload_completed"
8836   [(parallel [(set (match_dup 0) (match_dup 1))
8837               (clobber (reg:CC FLAGS_REG))])]
8839   rtx tmp;
8840   operands[0] = gen_rtx_REG (SImode,
8841                              true_regnum (operands[0])
8842                              + (TARGET_64BIT ? 1 : 2));
8843   if (GET_CODE (operands[1]) == ABS)
8844     {
8845       tmp = GEN_INT (0x7fff);
8846       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8847     }
8848   else
8849     {
8850       tmp = GEN_INT (0x8000);
8851       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8852     }
8853   operands[1] = tmp;
8856 ;; Conditionalize these after reload. If they match before reload, we
8857 ;; lose the clobber and ability to use integer instructions.
8859 (define_insn "*<code><mode>2_1"
8860   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8861         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8862   "TARGET_80387
8863    && (reload_completed
8864        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8865   "f<absneg_mnemonic>"
8866   [(set_attr "type" "fsgn")
8867    (set_attr "mode" "<MODE>")])
8869 (define_insn "*<code>extendsfdf2"
8870   [(set (match_operand:DF 0 "register_operand" "=f")
8871         (absneg:DF (float_extend:DF
8872                      (match_operand:SF 1 "register_operand" "0"))))]
8873   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8874   "f<absneg_mnemonic>"
8875   [(set_attr "type" "fsgn")
8876    (set_attr "mode" "DF")])
8878 (define_insn "*<code>extendsfxf2"
8879   [(set (match_operand:XF 0 "register_operand" "=f")
8880         (absneg:XF (float_extend:XF
8881                      (match_operand:SF 1 "register_operand" "0"))))]
8882   "TARGET_80387"
8883   "f<absneg_mnemonic>"
8884   [(set_attr "type" "fsgn")
8885    (set_attr "mode" "XF")])
8887 (define_insn "*<code>extenddfxf2"
8888   [(set (match_operand:XF 0 "register_operand" "=f")
8889         (absneg:XF (float_extend:XF
8890                      (match_operand:DF 1 "register_operand" "0"))))]
8891   "TARGET_80387"
8892   "f<absneg_mnemonic>"
8893   [(set_attr "type" "fsgn")
8894    (set_attr "mode" "XF")])
8896 ;; Copysign instructions
8898 (define_mode_iterator CSGNMODE [SF DF TF])
8899 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8901 (define_expand "copysign<mode>3"
8902   [(match_operand:CSGNMODE 0 "register_operand")
8903    (match_operand:CSGNMODE 1 "nonmemory_operand")
8904    (match_operand:CSGNMODE 2 "register_operand")]
8905   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8906    || (TARGET_SSE && (<MODE>mode == TFmode))"
8907   "ix86_expand_copysign (operands); DONE;")
8909 (define_insn_and_split "copysign<mode>3_const"
8910   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8911         (unspec:CSGNMODE
8912           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8913            (match_operand:CSGNMODE 2 "register_operand" "0")
8914            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8915           UNSPEC_COPYSIGN))]
8916   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8917    || (TARGET_SSE && (<MODE>mode == TFmode))"
8918   "#"
8919   "&& reload_completed"
8920   [(const_int 0)]
8921   "ix86_split_copysign_const (operands); DONE;")
8923 (define_insn "copysign<mode>3_var"
8924   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8925         (unspec:CSGNMODE
8926           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8927            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8928            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8929            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8930           UNSPEC_COPYSIGN))
8931    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8932   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8933    || (TARGET_SSE && (<MODE>mode == TFmode))"
8934   "#")
8936 (define_split
8937   [(set (match_operand:CSGNMODE 0 "register_operand")
8938         (unspec:CSGNMODE
8939           [(match_operand:CSGNMODE 2 "register_operand")
8940            (match_operand:CSGNMODE 3 "register_operand")
8941            (match_operand:<CSGNVMODE> 4)
8942            (match_operand:<CSGNVMODE> 5)]
8943           UNSPEC_COPYSIGN))
8944    (clobber (match_scratch:<CSGNVMODE> 1))]
8945   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8946     || (TARGET_SSE && (<MODE>mode == TFmode)))
8947    && reload_completed"
8948   [(const_int 0)]
8949   "ix86_split_copysign_var (operands); DONE;")
8951 ;; One complement instructions
8953 (define_expand "one_cmpl<mode>2"
8954   [(set (match_operand:SWIM 0 "nonimmediate_operand")
8955         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8956   ""
8957   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8959 (define_insn "*one_cmpl<mode>2_1"
8960   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,k")
8961         (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,k")))]
8962   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8963   "@
8964    not{<imodesuffix>}\t%0
8965    knot<mskmodesuffix>\t{%1, %0|%0, %1}"
8966   [(set_attr "isa" "*,avx512bw")
8967    (set_attr "type" "negnot,msklog")
8968    (set_attr "prefix" "*,vex")
8969    (set_attr "mode" "<MODE>")])
8971 (define_insn "*one_cmplhi2_1"
8972   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k")
8973         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))]
8974   "ix86_unary_operator_ok (NOT, HImode, operands)"
8975   "@
8976    not{w}\t%0
8977    knotw\t{%1, %0|%0, %1}"
8978   [(set_attr "isa" "*,avx512f")
8979    (set_attr "type" "negnot,msklog")
8980    (set_attr "prefix" "*,vex")
8981    (set_attr "mode" "HI")])
8983 ;; %%% Potential partial reg stall on alternative 1.  What to do?
8984 (define_insn "*one_cmplqi2_1"
8985   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
8986         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
8987   "ix86_unary_operator_ok (NOT, QImode, operands)"
8989   switch (which_alternative)
8990     {
8991     case 0:
8992       return "not{b}\t%0";
8993     case 1:
8994       return "not{l}\t%k0";
8995     case 2:
8996       if (TARGET_AVX512DQ)
8997         return "knotb\t{%1, %0|%0, %1}";
8998       return "knotw\t{%1, %0|%0, %1}";
8999     default:
9000       gcc_unreachable ();
9001     }
9003   [(set_attr "isa" "*,*,avx512f")
9004    (set_attr "type" "negnot,negnot,msklog")
9005    (set_attr "prefix" "*,*,vex")
9006    (set_attr "mode" "QI,SI,QI")])
9008 ;; ??? Currently never generated - xor is used instead.
9009 (define_insn "*one_cmplsi2_1_zext"
9010   [(set (match_operand:DI 0 "register_operand" "=r")
9011         (zero_extend:DI
9012           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9013   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9014   "not{l}\t%k0"
9015   [(set_attr "type" "negnot")
9016    (set_attr "mode" "SI")])
9018 (define_insn "*one_cmpl<mode>2_2"
9019   [(set (reg FLAGS_REG)
9020         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9021                  (const_int 0)))
9022    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9023         (not:SWI (match_dup 1)))]
9024   "ix86_match_ccmode (insn, CCNOmode)
9025    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9026   "#"
9027   [(set_attr "type" "alu1")
9028    (set_attr "mode" "<MODE>")])
9030 (define_split
9031   [(set (match_operand 0 "flags_reg_operand")
9032         (match_operator 2 "compare_operator"
9033           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9034            (const_int 0)]))
9035    (set (match_operand:SWI 1 "nonimmediate_operand")
9036         (not:SWI (match_dup 3)))]
9037   "ix86_match_ccmode (insn, CCNOmode)"
9038   [(parallel [(set (match_dup 0)
9039                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9040                                     (const_int 0)]))
9041               (set (match_dup 1)
9042                    (xor:SWI (match_dup 3) (const_int -1)))])])
9044 ;; ??? Currently never generated - xor is used instead.
9045 (define_insn "*one_cmplsi2_2_zext"
9046   [(set (reg FLAGS_REG)
9047         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9048                  (const_int 0)))
9049    (set (match_operand:DI 0 "register_operand" "=r")
9050         (zero_extend:DI (not:SI (match_dup 1))))]
9051   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9052    && ix86_unary_operator_ok (NOT, SImode, operands)"
9053   "#"
9054   [(set_attr "type" "alu1")
9055    (set_attr "mode" "SI")])
9057 (define_split
9058   [(set (match_operand 0 "flags_reg_operand")
9059         (match_operator 2 "compare_operator"
9060           [(not:SI (match_operand:SI 3 "register_operand"))
9061            (const_int 0)]))
9062    (set (match_operand:DI 1 "register_operand")
9063         (zero_extend:DI (not:SI (match_dup 3))))]
9064   "ix86_match_ccmode (insn, CCNOmode)"
9065   [(parallel [(set (match_dup 0)
9066                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9067                                     (const_int 0)]))
9068               (set (match_dup 1)
9069                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9071 ;; Shift instructions
9073 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9074 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9075 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9076 ;; from the assembler input.
9078 ;; This instruction shifts the target reg/mem as usual, but instead of
9079 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9080 ;; is a left shift double, bits are taken from the high order bits of
9081 ;; reg, else if the insn is a shift right double, bits are taken from the
9082 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9083 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9085 ;; Since sh[lr]d does not change the `reg' operand, that is done
9086 ;; separately, making all shifts emit pairs of shift double and normal
9087 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9088 ;; support a 63 bit shift, each shift where the count is in a reg expands
9089 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9091 ;; If the shift count is a constant, we need never emit more than one
9092 ;; shift pair, instead using moves and sign extension for counts greater
9093 ;; than 31.
9095 (define_expand "ashl<mode>3"
9096   [(set (match_operand:SDWIM 0 "<shift_operand>")
9097         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9098                       (match_operand:QI 2 "nonmemory_operand")))]
9099   ""
9100   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9102 (define_insn "*ashl<mode>3_doubleword"
9103   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9104         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9105                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9106    (clobber (reg:CC FLAGS_REG))]
9107   ""
9108   "#"
9109   [(set_attr "type" "multi")])
9111 (define_split
9112   [(set (match_operand:DWI 0 "register_operand")
9113         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9114                     (match_operand:QI 2 "nonmemory_operand")))
9115    (clobber (reg:CC FLAGS_REG))]
9116   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9117   [(const_int 0)]
9118   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9120 ;; By default we don't ask for a scratch register, because when DWImode
9121 ;; values are manipulated, registers are already at a premium.  But if
9122 ;; we have one handy, we won't turn it away.
9124 (define_peephole2
9125   [(match_scratch:DWIH 3 "r")
9126    (parallel [(set (match_operand:<DWI> 0 "register_operand")
9127                    (ashift:<DWI>
9128                      (match_operand:<DWI> 1 "nonmemory_operand")
9129                      (match_operand:QI 2 "nonmemory_operand")))
9130               (clobber (reg:CC FLAGS_REG))])
9131    (match_dup 3)]
9132   "TARGET_CMOVE"
9133   [(const_int 0)]
9134   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9136 (define_insn "x86_64_shld"
9137   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9138         (ior:DI (ashift:DI (match_dup 0)
9139                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9140                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9141                   (minus:QI (const_int 64) (match_dup 2)))))
9142    (clobber (reg:CC FLAGS_REG))]
9143   "TARGET_64BIT"
9144   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9145   [(set_attr "type" "ishift")
9146    (set_attr "prefix_0f" "1")
9147    (set_attr "mode" "DI")
9148    (set_attr "athlon_decode" "vector")
9149    (set_attr "amdfam10_decode" "vector")
9150    (set_attr "bdver1_decode" "vector")])
9152 (define_insn "x86_shld"
9153   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9154         (ior:SI (ashift:SI (match_dup 0)
9155                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9156                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9157                   (minus:QI (const_int 32) (match_dup 2)))))
9158    (clobber (reg:CC FLAGS_REG))]
9159   ""
9160   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9161   [(set_attr "type" "ishift")
9162    (set_attr "prefix_0f" "1")
9163    (set_attr "mode" "SI")
9164    (set_attr "pent_pair" "np")
9165    (set_attr "athlon_decode" "vector")
9166    (set_attr "amdfam10_decode" "vector")
9167    (set_attr "bdver1_decode" "vector")])
9169 (define_expand "x86_shift<mode>_adj_1"
9170   [(set (reg:CCZ FLAGS_REG)
9171         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9172                              (match_dup 4))
9173                      (const_int 0)))
9174    (set (match_operand:SWI48 0 "register_operand")
9175         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9176                             (match_operand:SWI48 1 "register_operand")
9177                             (match_dup 0)))
9178    (set (match_dup 1)
9179         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9180                             (match_operand:SWI48 3 "register_operand")
9181                             (match_dup 1)))]
9182   "TARGET_CMOVE"
9183   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9185 (define_expand "x86_shift<mode>_adj_2"
9186   [(use (match_operand:SWI48 0 "register_operand"))
9187    (use (match_operand:SWI48 1 "register_operand"))
9188    (use (match_operand:QI 2 "register_operand"))]
9189   ""
9191   rtx label = gen_label_rtx ();
9192   rtx tmp;
9194   emit_insn (gen_testqi_ccz_1 (operands[2],
9195                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9197   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9198   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9199   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9200                               gen_rtx_LABEL_REF (VOIDmode, label),
9201                               pc_rtx);
9202   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9203   JUMP_LABEL (tmp) = label;
9205   emit_move_insn (operands[0], operands[1]);
9206   ix86_expand_clear (operands[1]);
9208   emit_label (label);
9209   LABEL_NUSES (label) = 1;
9211   DONE;
9214 ;; Avoid useless masking of count operand.
9215 (define_insn "*ashl<mode>3_mask"
9216   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9217         (ashift:SWI48
9218           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9219           (subreg:QI
9220             (and:SI
9221               (match_operand:SI 2 "register_operand" "c")
9222               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9223    (clobber (reg:CC FLAGS_REG))]
9224   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9225    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9226       == GET_MODE_BITSIZE (<MODE>mode)-1"
9228   return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9230   [(set_attr "type" "ishift")
9231    (set_attr "mode" "<MODE>")])
9233 (define_insn "*bmi2_ashl<mode>3_1"
9234   [(set (match_operand:SWI48 0 "register_operand" "=r")
9235         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9236                       (match_operand:SWI48 2 "register_operand" "r")))]
9237   "TARGET_BMI2"
9238   "shlx\t{%2, %1, %0|%0, %1, %2}"
9239   [(set_attr "type" "ishiftx")
9240    (set_attr "mode" "<MODE>")])
9242 (define_insn "*ashl<mode>3_1"
9243   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9244         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9245                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9246    (clobber (reg:CC FLAGS_REG))]
9247   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9249   switch (get_attr_type (insn))
9250     {
9251     case TYPE_LEA:
9252     case TYPE_ISHIFTX:
9253       return "#";
9255     case TYPE_ALU:
9256       gcc_assert (operands[2] == const1_rtx);
9257       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9258       return "add{<imodesuffix>}\t%0, %0";
9260     default:
9261       if (operands[2] == const1_rtx
9262           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9263         return "sal{<imodesuffix>}\t%0";
9264       else
9265         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9266     }
9268   [(set_attr "isa" "*,*,bmi2")
9269    (set (attr "type")
9270      (cond [(eq_attr "alternative" "1")
9271               (const_string "lea")
9272             (eq_attr "alternative" "2")
9273               (const_string "ishiftx")
9274             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9275                       (match_operand 0 "register_operand"))
9276                  (match_operand 2 "const1_operand"))
9277               (const_string "alu")
9278            ]
9279            (const_string "ishift")))
9280    (set (attr "length_immediate")
9281      (if_then_else
9282        (ior (eq_attr "type" "alu")
9283             (and (eq_attr "type" "ishift")
9284                  (and (match_operand 2 "const1_operand")
9285                       (ior (match_test "TARGET_SHIFT1")
9286                            (match_test "optimize_function_for_size_p (cfun)")))))
9287        (const_string "0")
9288        (const_string "*")))
9289    (set_attr "mode" "<MODE>")])
9291 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9292 (define_split
9293   [(set (match_operand:SWI48 0 "register_operand")
9294         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9295                       (match_operand:QI 2 "register_operand")))
9296    (clobber (reg:CC FLAGS_REG))]
9297   "TARGET_BMI2 && reload_completed"
9298   [(set (match_dup 0)
9299         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9300   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9302 (define_insn "*bmi2_ashlsi3_1_zext"
9303   [(set (match_operand:DI 0 "register_operand" "=r")
9304         (zero_extend:DI
9305           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9306                      (match_operand:SI 2 "register_operand" "r"))))]
9307   "TARGET_64BIT && TARGET_BMI2"
9308   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9309   [(set_attr "type" "ishiftx")
9310    (set_attr "mode" "SI")])
9312 (define_insn "*ashlsi3_1_zext"
9313   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9314         (zero_extend:DI
9315           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9316                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9317    (clobber (reg:CC FLAGS_REG))]
9318   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9320   switch (get_attr_type (insn))
9321     {
9322     case TYPE_LEA:
9323     case TYPE_ISHIFTX:
9324       return "#";
9326     case TYPE_ALU:
9327       gcc_assert (operands[2] == const1_rtx);
9328       return "add{l}\t%k0, %k0";
9330     default:
9331       if (operands[2] == const1_rtx
9332           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9333         return "sal{l}\t%k0";
9334       else
9335         return "sal{l}\t{%2, %k0|%k0, %2}";
9336     }
9338   [(set_attr "isa" "*,*,bmi2")
9339    (set (attr "type")
9340      (cond [(eq_attr "alternative" "1")
9341               (const_string "lea")
9342             (eq_attr "alternative" "2")
9343               (const_string "ishiftx")
9344             (and (match_test "TARGET_DOUBLE_WITH_ADD")
9345                  (match_operand 2 "const1_operand"))
9346               (const_string "alu")
9347            ]
9348            (const_string "ishift")))
9349    (set (attr "length_immediate")
9350      (if_then_else
9351        (ior (eq_attr "type" "alu")
9352             (and (eq_attr "type" "ishift")
9353                  (and (match_operand 2 "const1_operand")
9354                       (ior (match_test "TARGET_SHIFT1")
9355                            (match_test "optimize_function_for_size_p (cfun)")))))
9356        (const_string "0")
9357        (const_string "*")))
9358    (set_attr "mode" "SI")])
9360 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9361 (define_split
9362   [(set (match_operand:DI 0 "register_operand")
9363         (zero_extend:DI
9364           (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9365                      (match_operand:QI 2 "register_operand"))))
9366    (clobber (reg:CC FLAGS_REG))]
9367   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9368   [(set (match_dup 0)
9369         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9370   "operands[2] = gen_lowpart (SImode, operands[2]);")
9372 (define_insn "*ashlhi3_1"
9373   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9374         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9375                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9376    (clobber (reg:CC FLAGS_REG))]
9377   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9379   switch (get_attr_type (insn))
9380     {
9381     case TYPE_LEA:
9382       return "#";
9384     case TYPE_ALU:
9385       gcc_assert (operands[2] == const1_rtx);
9386       return "add{w}\t%0, %0";
9388     default:
9389       if (operands[2] == const1_rtx
9390           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9391         return "sal{w}\t%0";
9392       else
9393         return "sal{w}\t{%2, %0|%0, %2}";
9394     }
9396   [(set (attr "type")
9397      (cond [(eq_attr "alternative" "1")
9398               (const_string "lea")
9399             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9400                       (match_operand 0 "register_operand"))
9401                  (match_operand 2 "const1_operand"))
9402               (const_string "alu")
9403            ]
9404            (const_string "ishift")))
9405    (set (attr "length_immediate")
9406      (if_then_else
9407        (ior (eq_attr "type" "alu")
9408             (and (eq_attr "type" "ishift")
9409                  (and (match_operand 2 "const1_operand")
9410                       (ior (match_test "TARGET_SHIFT1")
9411                            (match_test "optimize_function_for_size_p (cfun)")))))
9412        (const_string "0")
9413        (const_string "*")))
9414    (set_attr "mode" "HI,SI")])
9416 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9417 (define_insn "*ashlqi3_1"
9418   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9419         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9420                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9421    (clobber (reg:CC FLAGS_REG))]
9422   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9424   switch (get_attr_type (insn))
9425     {
9426     case TYPE_LEA:
9427       return "#";
9429     case TYPE_ALU:
9430       gcc_assert (operands[2] == const1_rtx);
9431       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9432         return "add{l}\t%k0, %k0";
9433       else
9434         return "add{b}\t%0, %0";
9436     default:
9437       if (operands[2] == const1_rtx
9438           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9439         {
9440           if (get_attr_mode (insn) == MODE_SI)
9441             return "sal{l}\t%k0";
9442           else
9443             return "sal{b}\t%0";
9444         }
9445       else
9446         {
9447           if (get_attr_mode (insn) == MODE_SI)
9448             return "sal{l}\t{%2, %k0|%k0, %2}";
9449           else
9450             return "sal{b}\t{%2, %0|%0, %2}";
9451         }
9452     }
9454   [(set (attr "type")
9455      (cond [(eq_attr "alternative" "2")
9456               (const_string "lea")
9457             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9458                       (match_operand 0 "register_operand"))
9459                  (match_operand 2 "const1_operand"))
9460               (const_string "alu")
9461            ]
9462            (const_string "ishift")))
9463    (set (attr "length_immediate")
9464      (if_then_else
9465        (ior (eq_attr "type" "alu")
9466             (and (eq_attr "type" "ishift")
9467                  (and (match_operand 2 "const1_operand")
9468                       (ior (match_test "TARGET_SHIFT1")
9469                            (match_test "optimize_function_for_size_p (cfun)")))))
9470        (const_string "0")
9471        (const_string "*")))
9472    (set_attr "mode" "QI,SI,SI")])
9474 (define_insn "*ashlqi3_1_slp"
9475   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9476         (ashift:QI (match_dup 0)
9477                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9478    (clobber (reg:CC FLAGS_REG))]
9479   "(optimize_function_for_size_p (cfun)
9480     || !TARGET_PARTIAL_FLAG_REG_STALL
9481     || (operands[1] == const1_rtx
9482         && (TARGET_SHIFT1
9483             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9485   switch (get_attr_type (insn))
9486     {
9487     case TYPE_ALU:
9488       gcc_assert (operands[1] == const1_rtx);
9489       return "add{b}\t%0, %0";
9491     default:
9492       if (operands[1] == const1_rtx
9493           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9494         return "sal{b}\t%0";
9495       else
9496         return "sal{b}\t{%1, %0|%0, %1}";
9497     }
9499   [(set (attr "type")
9500      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9501                       (match_operand 0 "register_operand"))
9502                  (match_operand 1 "const1_operand"))
9503               (const_string "alu")
9504            ]
9505            (const_string "ishift1")))
9506    (set (attr "length_immediate")
9507      (if_then_else
9508        (ior (eq_attr "type" "alu")
9509             (and (eq_attr "type" "ishift1")
9510                  (and (match_operand 1 "const1_operand")
9511                       (ior (match_test "TARGET_SHIFT1")
9512                            (match_test "optimize_function_for_size_p (cfun)")))))
9513        (const_string "0")
9514        (const_string "*")))
9515    (set_attr "mode" "QI")])
9517 ;; Convert ashift to the lea pattern to avoid flags dependency.
9518 (define_split
9519   [(set (match_operand 0 "register_operand")
9520         (ashift (match_operand 1 "index_register_operand")
9521                 (match_operand:QI 2 "const_int_operand")))
9522    (clobber (reg:CC FLAGS_REG))]
9523   "GET_MODE (operands[0]) == GET_MODE (operands[1])
9524    && reload_completed
9525    && true_regnum (operands[0]) != true_regnum (operands[1])"
9526   [(const_int 0)]
9528   enum machine_mode mode = GET_MODE (operands[0]);
9529   rtx pat;
9531   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9532     { 
9533       mode = SImode; 
9534       operands[0] = gen_lowpart (mode, operands[0]);
9535       operands[1] = gen_lowpart (mode, operands[1]);
9536     }
9538   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9540   pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9542   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9543   DONE;
9546 ;; Convert ashift to the lea pattern to avoid flags dependency.
9547 (define_split
9548   [(set (match_operand:DI 0 "register_operand")
9549         (zero_extend:DI
9550           (ashift:SI (match_operand:SI 1 "index_register_operand")
9551                      (match_operand:QI 2 "const_int_operand"))))
9552    (clobber (reg:CC FLAGS_REG))]
9553   "TARGET_64BIT && reload_completed
9554    && true_regnum (operands[0]) != true_regnum (operands[1])"
9555   [(set (match_dup 0)
9556         (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9558   operands[1] = gen_lowpart (SImode, operands[1]);
9559   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9562 ;; This pattern can't accept a variable shift count, since shifts by
9563 ;; zero don't affect the flags.  We assume that shifts by constant
9564 ;; zero are optimized away.
9565 (define_insn "*ashl<mode>3_cmp"
9566   [(set (reg FLAGS_REG)
9567         (compare
9568           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9569                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9570           (const_int 0)))
9571    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9572         (ashift:SWI (match_dup 1) (match_dup 2)))]
9573   "(optimize_function_for_size_p (cfun)
9574     || !TARGET_PARTIAL_FLAG_REG_STALL
9575     || (operands[2] == const1_rtx
9576         && (TARGET_SHIFT1
9577             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9578    && ix86_match_ccmode (insn, CCGOCmode)
9579    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9581   switch (get_attr_type (insn))
9582     {
9583     case TYPE_ALU:
9584       gcc_assert (operands[2] == const1_rtx);
9585       return "add{<imodesuffix>}\t%0, %0";
9587     default:
9588       if (operands[2] == const1_rtx
9589           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9590         return "sal{<imodesuffix>}\t%0";
9591       else
9592         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9593     }
9595   [(set (attr "type")
9596      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9597                       (match_operand 0 "register_operand"))
9598                  (match_operand 2 "const1_operand"))
9599               (const_string "alu")
9600            ]
9601            (const_string "ishift")))
9602    (set (attr "length_immediate")
9603      (if_then_else
9604        (ior (eq_attr "type" "alu")
9605             (and (eq_attr "type" "ishift")
9606                  (and (match_operand 2 "const1_operand")
9607                       (ior (match_test "TARGET_SHIFT1")
9608                            (match_test "optimize_function_for_size_p (cfun)")))))
9609        (const_string "0")
9610        (const_string "*")))
9611    (set_attr "mode" "<MODE>")])
9613 (define_insn "*ashlsi3_cmp_zext"
9614   [(set (reg FLAGS_REG)
9615         (compare
9616           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9617                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9618           (const_int 0)))
9619    (set (match_operand:DI 0 "register_operand" "=r")
9620         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9621   "TARGET_64BIT
9622    && (optimize_function_for_size_p (cfun)
9623        || !TARGET_PARTIAL_FLAG_REG_STALL
9624        || (operands[2] == const1_rtx
9625            && (TARGET_SHIFT1
9626                || TARGET_DOUBLE_WITH_ADD)))
9627    && ix86_match_ccmode (insn, CCGOCmode)
9628    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9630   switch (get_attr_type (insn))
9631     {
9632     case TYPE_ALU:
9633       gcc_assert (operands[2] == const1_rtx);
9634       return "add{l}\t%k0, %k0";
9636     default:
9637       if (operands[2] == const1_rtx
9638           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9639         return "sal{l}\t%k0";
9640       else
9641         return "sal{l}\t{%2, %k0|%k0, %2}";
9642     }
9644   [(set (attr "type")
9645      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9646                  (match_operand 2 "const1_operand"))
9647               (const_string "alu")
9648            ]
9649            (const_string "ishift")))
9650    (set (attr "length_immediate")
9651      (if_then_else
9652        (ior (eq_attr "type" "alu")
9653             (and (eq_attr "type" "ishift")
9654                  (and (match_operand 2 "const1_operand")
9655                       (ior (match_test "TARGET_SHIFT1")
9656                            (match_test "optimize_function_for_size_p (cfun)")))))
9657        (const_string "0")
9658        (const_string "*")))
9659    (set_attr "mode" "SI")])
9661 (define_insn "*ashl<mode>3_cconly"
9662   [(set (reg FLAGS_REG)
9663         (compare
9664           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9665                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9666           (const_int 0)))
9667    (clobber (match_scratch:SWI 0 "=<r>"))]
9668   "(optimize_function_for_size_p (cfun)
9669     || !TARGET_PARTIAL_FLAG_REG_STALL
9670     || (operands[2] == const1_rtx
9671         && (TARGET_SHIFT1
9672             || TARGET_DOUBLE_WITH_ADD)))
9673    && ix86_match_ccmode (insn, CCGOCmode)"
9675   switch (get_attr_type (insn))
9676     {
9677     case TYPE_ALU:
9678       gcc_assert (operands[2] == const1_rtx);
9679       return "add{<imodesuffix>}\t%0, %0";
9681     default:
9682       if (operands[2] == const1_rtx
9683           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9684         return "sal{<imodesuffix>}\t%0";
9685       else
9686         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9687     }
9689   [(set (attr "type")
9690      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9691                       (match_operand 0 "register_operand"))
9692                  (match_operand 2 "const1_operand"))
9693               (const_string "alu")
9694            ]
9695            (const_string "ishift")))
9696    (set (attr "length_immediate")
9697      (if_then_else
9698        (ior (eq_attr "type" "alu")
9699             (and (eq_attr "type" "ishift")
9700                  (and (match_operand 2 "const1_operand")
9701                       (ior (match_test "TARGET_SHIFT1")
9702                            (match_test "optimize_function_for_size_p (cfun)")))))
9703        (const_string "0")
9704        (const_string "*")))
9705    (set_attr "mode" "<MODE>")])
9707 ;; See comment above `ashl<mode>3' about how this works.
9709 (define_expand "<shift_insn><mode>3"
9710   [(set (match_operand:SDWIM 0 "<shift_operand>")
9711         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9712                            (match_operand:QI 2 "nonmemory_operand")))]
9713   ""
9714   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9716 ;; Avoid useless masking of count operand.
9717 (define_insn "*<shift_insn><mode>3_mask"
9718   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9719         (any_shiftrt:SWI48
9720           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9721           (subreg:QI
9722             (and:SI
9723               (match_operand:SI 2 "register_operand" "c")
9724               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9725    (clobber (reg:CC FLAGS_REG))]
9726   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9727    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9728       == GET_MODE_BITSIZE (<MODE>mode)-1"
9730   return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9732   [(set_attr "type" "ishift")
9733    (set_attr "mode" "<MODE>")])
9735 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9736   [(set (match_operand:DWI 0 "register_operand" "=r")
9737         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9738                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9739    (clobber (reg:CC FLAGS_REG))]
9740   ""
9741   "#"
9742   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9743   [(const_int 0)]
9744   "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9745   [(set_attr "type" "multi")])
9747 ;; By default we don't ask for a scratch register, because when DWImode
9748 ;; values are manipulated, registers are already at a premium.  But if
9749 ;; we have one handy, we won't turn it away.
9751 (define_peephole2
9752   [(match_scratch:DWIH 3 "r")
9753    (parallel [(set (match_operand:<DWI> 0 "register_operand")
9754                    (any_shiftrt:<DWI>
9755                      (match_operand:<DWI> 1 "register_operand")
9756                      (match_operand:QI 2 "nonmemory_operand")))
9757               (clobber (reg:CC FLAGS_REG))])
9758    (match_dup 3)]
9759   "TARGET_CMOVE"
9760   [(const_int 0)]
9761   "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9763 (define_insn "x86_64_shrd"
9764   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9765         (ior:DI (lshiftrt:DI (match_dup 0)
9766                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9767                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9768                   (minus:QI (const_int 64) (match_dup 2)))))
9769    (clobber (reg:CC FLAGS_REG))]
9770   "TARGET_64BIT"
9771   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9772   [(set_attr "type" "ishift")
9773    (set_attr "prefix_0f" "1")
9774    (set_attr "mode" "DI")
9775    (set_attr "athlon_decode" "vector")
9776    (set_attr "amdfam10_decode" "vector")
9777    (set_attr "bdver1_decode" "vector")])
9779 (define_insn "x86_shrd"
9780   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9781         (ior:SI (lshiftrt:SI (match_dup 0)
9782                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9783                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9784                   (minus:QI (const_int 32) (match_dup 2)))))
9785    (clobber (reg:CC FLAGS_REG))]
9786   ""
9787   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9788   [(set_attr "type" "ishift")
9789    (set_attr "prefix_0f" "1")
9790    (set_attr "mode" "SI")
9791    (set_attr "pent_pair" "np")
9792    (set_attr "athlon_decode" "vector")
9793    (set_attr "amdfam10_decode" "vector")
9794    (set_attr "bdver1_decode" "vector")])
9796 (define_insn "ashrdi3_cvt"
9797   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9798         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9799                      (match_operand:QI 2 "const_int_operand")))
9800    (clobber (reg:CC FLAGS_REG))]
9801   "TARGET_64BIT && INTVAL (operands[2]) == 63
9802    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9803    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9804   "@
9805    {cqto|cqo}
9806    sar{q}\t{%2, %0|%0, %2}"
9807   [(set_attr "type" "imovx,ishift")
9808    (set_attr "prefix_0f" "0,*")
9809    (set_attr "length_immediate" "0,*")
9810    (set_attr "modrm" "0,1")
9811    (set_attr "mode" "DI")])
9813 (define_insn "ashrsi3_cvt"
9814   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9815         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9816                      (match_operand:QI 2 "const_int_operand")))
9817    (clobber (reg:CC FLAGS_REG))]
9818   "INTVAL (operands[2]) == 31
9819    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9820    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9821   "@
9822    {cltd|cdq}
9823    sar{l}\t{%2, %0|%0, %2}"
9824   [(set_attr "type" "imovx,ishift")
9825    (set_attr "prefix_0f" "0,*")
9826    (set_attr "length_immediate" "0,*")
9827    (set_attr "modrm" "0,1")
9828    (set_attr "mode" "SI")])
9830 (define_insn "*ashrsi3_cvt_zext"
9831   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9832         (zero_extend:DI
9833           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9834                        (match_operand:QI 2 "const_int_operand"))))
9835    (clobber (reg:CC FLAGS_REG))]
9836   "TARGET_64BIT && INTVAL (operands[2]) == 31
9837    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9838    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9839   "@
9840    {cltd|cdq}
9841    sar{l}\t{%2, %k0|%k0, %2}"
9842   [(set_attr "type" "imovx,ishift")
9843    (set_attr "prefix_0f" "0,*")
9844    (set_attr "length_immediate" "0,*")
9845    (set_attr "modrm" "0,1")
9846    (set_attr "mode" "SI")])
9848 (define_expand "x86_shift<mode>_adj_3"
9849   [(use (match_operand:SWI48 0 "register_operand"))
9850    (use (match_operand:SWI48 1 "register_operand"))
9851    (use (match_operand:QI 2 "register_operand"))]
9852   ""
9854   rtx label = gen_label_rtx ();
9855   rtx tmp;
9857   emit_insn (gen_testqi_ccz_1 (operands[2],
9858                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9860   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9861   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9862   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9863                               gen_rtx_LABEL_REF (VOIDmode, label),
9864                               pc_rtx);
9865   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9866   JUMP_LABEL (tmp) = label;
9868   emit_move_insn (operands[0], operands[1]);
9869   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9870                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9871   emit_label (label);
9872   LABEL_NUSES (label) = 1;
9874   DONE;
9877 (define_insn "*bmi2_<shift_insn><mode>3_1"
9878   [(set (match_operand:SWI48 0 "register_operand" "=r")
9879         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9880                            (match_operand:SWI48 2 "register_operand" "r")))]
9881   "TARGET_BMI2"
9882   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9883   [(set_attr "type" "ishiftx")
9884    (set_attr "mode" "<MODE>")])
9886 (define_insn "*<shift_insn><mode>3_1"
9887   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9888         (any_shiftrt:SWI48
9889           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9890           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9891    (clobber (reg:CC FLAGS_REG))]
9892   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9894   switch (get_attr_type (insn))
9895     {
9896     case TYPE_ISHIFTX:
9897       return "#";
9899     default:
9900       if (operands[2] == const1_rtx
9901           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9902         return "<shift>{<imodesuffix>}\t%0";
9903       else
9904         return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9905     }
9907   [(set_attr "isa" "*,bmi2")
9908    (set_attr "type" "ishift,ishiftx")
9909    (set (attr "length_immediate")
9910      (if_then_else
9911        (and (match_operand 2 "const1_operand")
9912             (ior (match_test "TARGET_SHIFT1")
9913                  (match_test "optimize_function_for_size_p (cfun)")))
9914        (const_string "0")
9915        (const_string "*")))
9916    (set_attr "mode" "<MODE>")])
9918 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9919 (define_split
9920   [(set (match_operand:SWI48 0 "register_operand")
9921         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9922                            (match_operand:QI 2 "register_operand")))
9923    (clobber (reg:CC FLAGS_REG))]
9924   "TARGET_BMI2 && reload_completed"
9925   [(set (match_dup 0)
9926         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9927   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9929 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9930   [(set (match_operand:DI 0 "register_operand" "=r")
9931         (zero_extend:DI
9932           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9933                           (match_operand:SI 2 "register_operand" "r"))))]
9934   "TARGET_64BIT && TARGET_BMI2"
9935   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9936   [(set_attr "type" "ishiftx")
9937    (set_attr "mode" "SI")])
9939 (define_insn "*<shift_insn>si3_1_zext"
9940   [(set (match_operand:DI 0 "register_operand" "=r,r")
9941         (zero_extend:DI
9942           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9943                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9944    (clobber (reg:CC FLAGS_REG))]
9945   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9947   switch (get_attr_type (insn))
9948     {
9949     case TYPE_ISHIFTX:
9950       return "#";
9952     default:
9953       if (operands[2] == const1_rtx
9954           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9955         return "<shift>{l}\t%k0";
9956       else
9957         return "<shift>{l}\t{%2, %k0|%k0, %2}";
9958     }
9960   [(set_attr "isa" "*,bmi2")
9961    (set_attr "type" "ishift,ishiftx")
9962    (set (attr "length_immediate")
9963      (if_then_else
9964        (and (match_operand 2 "const1_operand")
9965             (ior (match_test "TARGET_SHIFT1")
9966                  (match_test "optimize_function_for_size_p (cfun)")))
9967        (const_string "0")
9968        (const_string "*")))
9969    (set_attr "mode" "SI")])
9971 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9972 (define_split
9973   [(set (match_operand:DI 0 "register_operand")
9974         (zero_extend:DI
9975           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9976                           (match_operand:QI 2 "register_operand"))))
9977    (clobber (reg:CC FLAGS_REG))]
9978   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9979   [(set (match_dup 0)
9980         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9981   "operands[2] = gen_lowpart (SImode, operands[2]);")
9983 (define_insn "*<shift_insn><mode>3_1"
9984   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9985         (any_shiftrt:SWI12
9986           (match_operand:SWI12 1 "nonimmediate_operand" "0")
9987           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9988    (clobber (reg:CC FLAGS_REG))]
9989   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9991   if (operands[2] == const1_rtx
9992       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9993     return "<shift>{<imodesuffix>}\t%0";
9994   else
9995     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9997   [(set_attr "type" "ishift")
9998    (set (attr "length_immediate")
9999      (if_then_else
10000        (and (match_operand 2 "const1_operand")
10001             (ior (match_test "TARGET_SHIFT1")
10002                  (match_test "optimize_function_for_size_p (cfun)")))
10003        (const_string "0")
10004        (const_string "*")))
10005    (set_attr "mode" "<MODE>")])
10007 (define_insn "*<shift_insn>qi3_1_slp"
10008   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10009         (any_shiftrt:QI (match_dup 0)
10010                         (match_operand:QI 1 "nonmemory_operand" "cI")))
10011    (clobber (reg:CC FLAGS_REG))]
10012   "(optimize_function_for_size_p (cfun)
10013     || !TARGET_PARTIAL_REG_STALL
10014     || (operands[1] == const1_rtx
10015         && TARGET_SHIFT1))"
10017   if (operands[1] == const1_rtx
10018       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10019     return "<shift>{b}\t%0";
10020   else
10021     return "<shift>{b}\t{%1, %0|%0, %1}";
10023   [(set_attr "type" "ishift1")
10024    (set (attr "length_immediate")
10025      (if_then_else
10026        (and (match_operand 1 "const1_operand")
10027             (ior (match_test "TARGET_SHIFT1")
10028                  (match_test "optimize_function_for_size_p (cfun)")))
10029        (const_string "0")
10030        (const_string "*")))
10031    (set_attr "mode" "QI")])
10033 ;; This pattern can't accept a variable shift count, since shifts by
10034 ;; zero don't affect the flags.  We assume that shifts by constant
10035 ;; zero are optimized away.
10036 (define_insn "*<shift_insn><mode>3_cmp"
10037   [(set (reg FLAGS_REG)
10038         (compare
10039           (any_shiftrt:SWI
10040             (match_operand:SWI 1 "nonimmediate_operand" "0")
10041             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10042           (const_int 0)))
10043    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10044         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10045   "(optimize_function_for_size_p (cfun)
10046     || !TARGET_PARTIAL_FLAG_REG_STALL
10047     || (operands[2] == const1_rtx
10048         && TARGET_SHIFT1))
10049    && ix86_match_ccmode (insn, CCGOCmode)
10050    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10052   if (operands[2] == const1_rtx
10053       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10054     return "<shift>{<imodesuffix>}\t%0";
10055   else
10056     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10058   [(set_attr "type" "ishift")
10059    (set (attr "length_immediate")
10060      (if_then_else
10061        (and (match_operand 2 "const1_operand")
10062             (ior (match_test "TARGET_SHIFT1")
10063                  (match_test "optimize_function_for_size_p (cfun)")))
10064        (const_string "0")
10065        (const_string "*")))
10066    (set_attr "mode" "<MODE>")])
10068 (define_insn "*<shift_insn>si3_cmp_zext"
10069   [(set (reg FLAGS_REG)
10070         (compare
10071           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10072                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
10073           (const_int 0)))
10074    (set (match_operand:DI 0 "register_operand" "=r")
10075         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10076   "TARGET_64BIT
10077    && (optimize_function_for_size_p (cfun)
10078        || !TARGET_PARTIAL_FLAG_REG_STALL
10079        || (operands[2] == const1_rtx
10080            && TARGET_SHIFT1))
10081    && ix86_match_ccmode (insn, CCGOCmode)
10082    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10084   if (operands[2] == const1_rtx
10085       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10086     return "<shift>{l}\t%k0";
10087   else
10088     return "<shift>{l}\t{%2, %k0|%k0, %2}";
10090   [(set_attr "type" "ishift")
10091    (set (attr "length_immediate")
10092      (if_then_else
10093        (and (match_operand 2 "const1_operand")
10094             (ior (match_test "TARGET_SHIFT1")
10095                  (match_test "optimize_function_for_size_p (cfun)")))
10096        (const_string "0")
10097        (const_string "*")))
10098    (set_attr "mode" "SI")])
10100 (define_insn "*<shift_insn><mode>3_cconly"
10101   [(set (reg FLAGS_REG)
10102         (compare
10103           (any_shiftrt:SWI
10104             (match_operand:SWI 1 "register_operand" "0")
10105             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10106           (const_int 0)))
10107    (clobber (match_scratch:SWI 0 "=<r>"))]
10108   "(optimize_function_for_size_p (cfun)
10109     || !TARGET_PARTIAL_FLAG_REG_STALL
10110     || (operands[2] == const1_rtx
10111         && TARGET_SHIFT1))
10112    && ix86_match_ccmode (insn, CCGOCmode)"
10114   if (operands[2] == const1_rtx
10115       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10116     return "<shift>{<imodesuffix>}\t%0";
10117   else
10118     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10120   [(set_attr "type" "ishift")
10121    (set (attr "length_immediate")
10122      (if_then_else
10123        (and (match_operand 2 "const1_operand")
10124             (ior (match_test "TARGET_SHIFT1")
10125                  (match_test "optimize_function_for_size_p (cfun)")))
10126        (const_string "0")
10127        (const_string "*")))
10128    (set_attr "mode" "<MODE>")])
10130 ;; Rotate instructions
10132 (define_expand "<rotate_insn>ti3"
10133   [(set (match_operand:TI 0 "register_operand")
10134         (any_rotate:TI (match_operand:TI 1 "register_operand")
10135                        (match_operand:QI 2 "nonmemory_operand")))]
10136   "TARGET_64BIT"
10138   if (const_1_to_63_operand (operands[2], VOIDmode))
10139     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10140                 (operands[0], operands[1], operands[2]));
10141   else
10142     FAIL;
10144   DONE;
10147 (define_expand "<rotate_insn>di3"
10148   [(set (match_operand:DI 0 "shiftdi_operand")
10149         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10150                        (match_operand:QI 2 "nonmemory_operand")))]
10151  ""
10153   if (TARGET_64BIT)
10154     ix86_expand_binary_operator (<CODE>, DImode, operands);
10155   else if (const_1_to_31_operand (operands[2], VOIDmode))
10156     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10157                 (operands[0], operands[1], operands[2]));
10158   else
10159     FAIL;
10161   DONE;
10164 (define_expand "<rotate_insn><mode>3"
10165   [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10166         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10167                             (match_operand:QI 2 "nonmemory_operand")))]
10168   ""
10169   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10171 ;; Avoid useless masking of count operand.
10172 (define_insn "*<rotate_insn><mode>3_mask"
10173   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10174         (any_rotate:SWI48
10175           (match_operand:SWI48 1 "nonimmediate_operand" "0")
10176           (subreg:QI
10177             (and:SI
10178               (match_operand:SI 2 "register_operand" "c")
10179               (match_operand:SI 3 "const_int_operand" "n")) 0)))
10180    (clobber (reg:CC FLAGS_REG))]
10181   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10182    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10183       == GET_MODE_BITSIZE (<MODE>mode)-1"
10185   return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10187   [(set_attr "type" "rotate")
10188    (set_attr "mode" "<MODE>")])
10190 ;; Implement rotation using two double-precision
10191 ;; shift instructions and a scratch register.
10193 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10194  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10195        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10196                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10197   (clobber (reg:CC FLAGS_REG))
10198   (clobber (match_scratch:DWIH 3 "=&r"))]
10199  ""
10200  "#"
10201  "reload_completed"
10202  [(set (match_dup 3) (match_dup 4))
10203   (parallel
10204    [(set (match_dup 4)
10205          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10206                    (lshiftrt:DWIH (match_dup 5)
10207                                   (minus:QI (match_dup 6) (match_dup 2)))))
10208     (clobber (reg:CC FLAGS_REG))])
10209   (parallel
10210    [(set (match_dup 5)
10211          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10212                    (lshiftrt:DWIH (match_dup 3)
10213                                   (minus:QI (match_dup 6) (match_dup 2)))))
10214     (clobber (reg:CC FLAGS_REG))])]
10216   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10218   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10221 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10222  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10223        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10224                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10225   (clobber (reg:CC FLAGS_REG))
10226   (clobber (match_scratch:DWIH 3 "=&r"))]
10227  ""
10228  "#"
10229  "reload_completed"
10230  [(set (match_dup 3) (match_dup 4))
10231   (parallel
10232    [(set (match_dup 4)
10233          (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10234                    (ashift:DWIH (match_dup 5)
10235                                 (minus:QI (match_dup 6) (match_dup 2)))))
10236     (clobber (reg:CC FLAGS_REG))])
10237   (parallel
10238    [(set (match_dup 5)
10239          (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10240                    (ashift:DWIH (match_dup 3)
10241                                 (minus:QI (match_dup 6) (match_dup 2)))))
10242     (clobber (reg:CC FLAGS_REG))])]
10244   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10246   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10249 (define_insn "*bmi2_rorx<mode>3_1"
10250   [(set (match_operand:SWI48 0 "register_operand" "=r")
10251         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10252                         (match_operand:QI 2 "immediate_operand" "<S>")))]
10253   "TARGET_BMI2"
10254   "rorx\t{%2, %1, %0|%0, %1, %2}"
10255   [(set_attr "type" "rotatex")
10256    (set_attr "mode" "<MODE>")])
10258 (define_insn "*<rotate_insn><mode>3_1"
10259   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10260         (any_rotate:SWI48
10261           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10262           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10263    (clobber (reg:CC FLAGS_REG))]
10264   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10266   switch (get_attr_type (insn))
10267     {
10268     case TYPE_ROTATEX:
10269       return "#";
10271     default:
10272       if (operands[2] == const1_rtx
10273           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10274         return "<rotate>{<imodesuffix>}\t%0";
10275       else
10276         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10277     }
10279   [(set_attr "isa" "*,bmi2")
10280    (set_attr "type" "rotate,rotatex")
10281    (set (attr "length_immediate")
10282      (if_then_else
10283        (and (eq_attr "type" "rotate")
10284             (and (match_operand 2 "const1_operand")
10285                  (ior (match_test "TARGET_SHIFT1")
10286                       (match_test "optimize_function_for_size_p (cfun)"))))
10287        (const_string "0")
10288        (const_string "*")))
10289    (set_attr "mode" "<MODE>")])
10291 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10292 (define_split
10293   [(set (match_operand:SWI48 0 "register_operand")
10294         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10295                       (match_operand:QI 2 "immediate_operand")))
10296    (clobber (reg:CC FLAGS_REG))]
10297   "TARGET_BMI2 && reload_completed"
10298   [(set (match_dup 0)
10299         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10301   operands[2]
10302     = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10305 (define_split
10306   [(set (match_operand:SWI48 0 "register_operand")
10307         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10308                         (match_operand:QI 2 "immediate_operand")))
10309    (clobber (reg:CC FLAGS_REG))]
10310   "TARGET_BMI2 && reload_completed"
10311   [(set (match_dup 0)
10312         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10314 (define_insn "*bmi2_rorxsi3_1_zext"
10315   [(set (match_operand:DI 0 "register_operand" "=r")
10316         (zero_extend:DI
10317           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10318                        (match_operand:QI 2 "immediate_operand" "I"))))]
10319   "TARGET_64BIT && TARGET_BMI2"
10320   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10321   [(set_attr "type" "rotatex")
10322    (set_attr "mode" "SI")])
10324 (define_insn "*<rotate_insn>si3_1_zext"
10325   [(set (match_operand:DI 0 "register_operand" "=r,r")
10326         (zero_extend:DI
10327           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10328                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10329    (clobber (reg:CC FLAGS_REG))]
10330   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10332   switch (get_attr_type (insn))
10333     {
10334     case TYPE_ROTATEX:
10335       return "#";
10337     default:
10338       if (operands[2] == const1_rtx
10339           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10340         return "<rotate>{l}\t%k0";
10341       else
10342         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10343     }
10345   [(set_attr "isa" "*,bmi2")
10346    (set_attr "type" "rotate,rotatex")
10347    (set (attr "length_immediate")
10348      (if_then_else
10349        (and (eq_attr "type" "rotate")
10350             (and (match_operand 2 "const1_operand")
10351                  (ior (match_test "TARGET_SHIFT1")
10352                       (match_test "optimize_function_for_size_p (cfun)"))))
10353        (const_string "0")
10354        (const_string "*")))
10355    (set_attr "mode" "SI")])
10357 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10358 (define_split
10359   [(set (match_operand:DI 0 "register_operand")
10360         (zero_extend:DI
10361           (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10362                      (match_operand:QI 2 "immediate_operand"))))
10363    (clobber (reg:CC FLAGS_REG))]
10364   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10365   [(set (match_dup 0)
10366         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10368   operands[2]
10369     = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10372 (define_split
10373   [(set (match_operand:DI 0 "register_operand")
10374         (zero_extend:DI
10375           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10376                        (match_operand:QI 2 "immediate_operand"))))
10377    (clobber (reg:CC FLAGS_REG))]
10378   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10379   [(set (match_dup 0)
10380         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10382 (define_insn "*<rotate_insn><mode>3_1"
10383   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10384         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10385                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10386    (clobber (reg:CC FLAGS_REG))]
10387   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10389   if (operands[2] == const1_rtx
10390       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10391     return "<rotate>{<imodesuffix>}\t%0";
10392   else
10393     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10395   [(set_attr "type" "rotate")
10396    (set (attr "length_immediate")
10397      (if_then_else
10398        (and (match_operand 2 "const1_operand")
10399             (ior (match_test "TARGET_SHIFT1")
10400                  (match_test "optimize_function_for_size_p (cfun)")))
10401        (const_string "0")
10402        (const_string "*")))
10403    (set_attr "mode" "<MODE>")])
10405 (define_insn "*<rotate_insn>qi3_1_slp"
10406   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10407         (any_rotate:QI (match_dup 0)
10408                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10409    (clobber (reg:CC FLAGS_REG))]
10410   "(optimize_function_for_size_p (cfun)
10411     || !TARGET_PARTIAL_REG_STALL
10412     || (operands[1] == const1_rtx
10413         && TARGET_SHIFT1))"
10415   if (operands[1] == const1_rtx
10416       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10417     return "<rotate>{b}\t%0";
10418   else
10419     return "<rotate>{b}\t{%1, %0|%0, %1}";
10421   [(set_attr "type" "rotate1")
10422    (set (attr "length_immediate")
10423      (if_then_else
10424        (and (match_operand 1 "const1_operand")
10425             (ior (match_test "TARGET_SHIFT1")
10426                  (match_test "optimize_function_for_size_p (cfun)")))
10427        (const_string "0")
10428        (const_string "*")))
10429    (set_attr "mode" "QI")])
10431 (define_split
10432  [(set (match_operand:HI 0 "register_operand")
10433        (any_rotate:HI (match_dup 0) (const_int 8)))
10434   (clobber (reg:CC FLAGS_REG))]
10435  "reload_completed
10436   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10437  [(parallel [(set (strict_low_part (match_dup 0))
10438                   (bswap:HI (match_dup 0)))
10439              (clobber (reg:CC FLAGS_REG))])])
10441 ;; Bit set / bit test instructions
10443 (define_expand "extv"
10444   [(set (match_operand:SI 0 "register_operand")
10445         (sign_extract:SI (match_operand:SI 1 "register_operand")
10446                          (match_operand:SI 2 "const8_operand")
10447                          (match_operand:SI 3 "const8_operand")))]
10448   ""
10450   /* Handle extractions from %ah et al.  */
10451   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10452     FAIL;
10454   /* From mips.md: extract_bit_field doesn't verify that our source
10455      matches the predicate, so check it again here.  */
10456   if (! ext_register_operand (operands[1], VOIDmode))
10457     FAIL;
10460 (define_expand "extzv"
10461   [(set (match_operand:SI 0 "register_operand")
10462         (zero_extract:SI (match_operand 1 "ext_register_operand")
10463                          (match_operand:SI 2 "const8_operand")
10464                          (match_operand:SI 3 "const8_operand")))]
10465   ""
10467   /* Handle extractions from %ah et al.  */
10468   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10469     FAIL;
10471   /* From mips.md: extract_bit_field doesn't verify that our source
10472      matches the predicate, so check it again here.  */
10473   if (! ext_register_operand (operands[1], VOIDmode))
10474     FAIL;
10477 (define_expand "insv"
10478   [(set (zero_extract (match_operand 0 "register_operand")
10479                       (match_operand 1 "const_int_operand")
10480                       (match_operand 2 "const_int_operand"))
10481         (match_operand 3 "register_operand"))]
10482   ""
10484   rtx (*gen_mov_insv_1) (rtx, rtx);
10486   if (ix86_expand_pinsr (operands))
10487     DONE;
10489   /* Handle insertions to %ah et al.  */
10490   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10491     FAIL;
10493   /* From mips.md: insert_bit_field doesn't verify that our source
10494      matches the predicate, so check it again here.  */
10495   if (! ext_register_operand (operands[0], VOIDmode))
10496     FAIL;
10498   gen_mov_insv_1 = (TARGET_64BIT
10499                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10501   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10502   DONE;
10505 ;; %%% bts, btr, btc, bt.
10506 ;; In general these instructions are *slow* when applied to memory,
10507 ;; since they enforce atomic operation.  When applied to registers,
10508 ;; it depends on the cpu implementation.  They're never faster than
10509 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10510 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10511 ;; within the instruction itself, so operating on bits in the high
10512 ;; 32-bits of a register becomes easier.
10514 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10515 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10516 ;; negdf respectively, so they can never be disabled entirely.
10518 (define_insn "*btsq"
10519   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10520                          (const_int 1)
10521                          (match_operand:DI 1 "const_0_to_63_operand"))
10522         (const_int 1))
10523    (clobber (reg:CC FLAGS_REG))]
10524   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10525   "bts{q}\t{%1, %0|%0, %1}"
10526   [(set_attr "type" "alu1")
10527    (set_attr "prefix_0f" "1")
10528    (set_attr "mode" "DI")])
10530 (define_insn "*btrq"
10531   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10532                          (const_int 1)
10533                          (match_operand:DI 1 "const_0_to_63_operand"))
10534         (const_int 0))
10535    (clobber (reg:CC FLAGS_REG))]
10536   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10537   "btr{q}\t{%1, %0|%0, %1}"
10538   [(set_attr "type" "alu1")
10539    (set_attr "prefix_0f" "1")
10540    (set_attr "mode" "DI")])
10542 (define_insn "*btcq"
10543   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10544                          (const_int 1)
10545                          (match_operand:DI 1 "const_0_to_63_operand"))
10546         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10547    (clobber (reg:CC FLAGS_REG))]
10548   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10549   "btc{q}\t{%1, %0|%0, %1}"
10550   [(set_attr "type" "alu1")
10551    (set_attr "prefix_0f" "1")
10552    (set_attr "mode" "DI")])
10554 ;; Allow Nocona to avoid these instructions if a register is available.
10556 (define_peephole2
10557   [(match_scratch:DI 2 "r")
10558    (parallel [(set (zero_extract:DI
10559                      (match_operand:DI 0 "register_operand")
10560                      (const_int 1)
10561                      (match_operand:DI 1 "const_0_to_63_operand"))
10562                    (const_int 1))
10563               (clobber (reg:CC FLAGS_REG))])]
10564   "TARGET_64BIT && !TARGET_USE_BT"
10565   [(const_int 0)]
10567   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10568   rtx op1;
10570   if (HOST_BITS_PER_WIDE_INT >= 64)
10571     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10572   else if (i < HOST_BITS_PER_WIDE_INT)
10573     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10574   else
10575     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10577   op1 = immed_double_const (lo, hi, DImode);
10578   if (i >= 31)
10579     {
10580       emit_move_insn (operands[2], op1);
10581       op1 = operands[2];
10582     }
10584   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10585   DONE;
10588 (define_peephole2
10589   [(match_scratch:DI 2 "r")
10590    (parallel [(set (zero_extract:DI
10591                      (match_operand:DI 0 "register_operand")
10592                      (const_int 1)
10593                      (match_operand:DI 1 "const_0_to_63_operand"))
10594                    (const_int 0))
10595               (clobber (reg:CC FLAGS_REG))])]
10596   "TARGET_64BIT && !TARGET_USE_BT"
10597   [(const_int 0)]
10599   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10600   rtx op1;
10602   if (HOST_BITS_PER_WIDE_INT >= 64)
10603     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10604   else if (i < HOST_BITS_PER_WIDE_INT)
10605     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10606   else
10607     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10609   op1 = immed_double_const (~lo, ~hi, DImode);
10610   if (i >= 32)
10611     {
10612       emit_move_insn (operands[2], op1);
10613       op1 = operands[2];
10614     }
10616   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10617   DONE;
10620 (define_peephole2
10621   [(match_scratch:DI 2 "r")
10622    (parallel [(set (zero_extract:DI
10623                      (match_operand:DI 0 "register_operand")
10624                      (const_int 1)
10625                      (match_operand:DI 1 "const_0_to_63_operand"))
10626               (not:DI (zero_extract:DI
10627                         (match_dup 0) (const_int 1) (match_dup 1))))
10628               (clobber (reg:CC FLAGS_REG))])]
10629   "TARGET_64BIT && !TARGET_USE_BT"
10630   [(const_int 0)]
10632   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10633   rtx op1;
10635   if (HOST_BITS_PER_WIDE_INT >= 64)
10636     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10637   else if (i < HOST_BITS_PER_WIDE_INT)
10638     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10639   else
10640     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10642   op1 = immed_double_const (lo, hi, DImode);
10643   if (i >= 31)
10644     {
10645       emit_move_insn (operands[2], op1);
10646       op1 = operands[2];
10647     }
10649   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10650   DONE;
10653 (define_insn "*bt<mode>"
10654   [(set (reg:CCC FLAGS_REG)
10655         (compare:CCC
10656           (zero_extract:SWI48
10657             (match_operand:SWI48 0 "register_operand" "r")
10658             (const_int 1)
10659             (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10660           (const_int 0)))]
10661   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10662   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10663   [(set_attr "type" "alu1")
10664    (set_attr "prefix_0f" "1")
10665    (set_attr "mode" "<MODE>")])
10667 ;; Store-flag instructions.
10669 ;; For all sCOND expanders, also expand the compare or test insn that
10670 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10672 (define_insn_and_split "*setcc_di_1"
10673   [(set (match_operand:DI 0 "register_operand" "=q")
10674         (match_operator:DI 1 "ix86_comparison_operator"
10675           [(reg FLAGS_REG) (const_int 0)]))]
10676   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10677   "#"
10678   "&& reload_completed"
10679   [(set (match_dup 2) (match_dup 1))
10680    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10682   PUT_MODE (operands[1], QImode);
10683   operands[2] = gen_lowpart (QImode, operands[0]);
10686 (define_insn_and_split "*setcc_si_1_and"
10687   [(set (match_operand:SI 0 "register_operand" "=q")
10688         (match_operator:SI 1 "ix86_comparison_operator"
10689           [(reg FLAGS_REG) (const_int 0)]))
10690    (clobber (reg:CC FLAGS_REG))]
10691   "!TARGET_PARTIAL_REG_STALL
10692    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10693   "#"
10694   "&& reload_completed"
10695   [(set (match_dup 2) (match_dup 1))
10696    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10697               (clobber (reg:CC FLAGS_REG))])]
10699   PUT_MODE (operands[1], QImode);
10700   operands[2] = gen_lowpart (QImode, operands[0]);
10703 (define_insn_and_split "*setcc_si_1_movzbl"
10704   [(set (match_operand:SI 0 "register_operand" "=q")
10705         (match_operator:SI 1 "ix86_comparison_operator"
10706           [(reg FLAGS_REG) (const_int 0)]))]
10707   "!TARGET_PARTIAL_REG_STALL
10708    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10709   "#"
10710   "&& reload_completed"
10711   [(set (match_dup 2) (match_dup 1))
10712    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10714   PUT_MODE (operands[1], QImode);
10715   operands[2] = gen_lowpart (QImode, operands[0]);
10718 (define_insn "*setcc_qi"
10719   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10720         (match_operator:QI 1 "ix86_comparison_operator"
10721           [(reg FLAGS_REG) (const_int 0)]))]
10722   ""
10723   "set%C1\t%0"
10724   [(set_attr "type" "setcc")
10725    (set_attr "mode" "QI")])
10727 (define_insn "*setcc_qi_slp"
10728   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10729         (match_operator:QI 1 "ix86_comparison_operator"
10730           [(reg FLAGS_REG) (const_int 0)]))]
10731   ""
10732   "set%C1\t%0"
10733   [(set_attr "type" "setcc")
10734    (set_attr "mode" "QI")])
10736 ;; In general it is not safe to assume too much about CCmode registers,
10737 ;; so simplify-rtx stops when it sees a second one.  Under certain
10738 ;; conditions this is safe on x86, so help combine not create
10740 ;;      seta    %al
10741 ;;      testb   %al, %al
10742 ;;      sete    %al
10744 (define_split
10745   [(set (match_operand:QI 0 "nonimmediate_operand")
10746         (ne:QI (match_operator 1 "ix86_comparison_operator"
10747                  [(reg FLAGS_REG) (const_int 0)])
10748             (const_int 0)))]
10749   ""
10750   [(set (match_dup 0) (match_dup 1))]
10751   "PUT_MODE (operands[1], QImode);")
10753 (define_split
10754   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10755         (ne:QI (match_operator 1 "ix86_comparison_operator"
10756                  [(reg FLAGS_REG) (const_int 0)])
10757             (const_int 0)))]
10758   ""
10759   [(set (match_dup 0) (match_dup 1))]
10760   "PUT_MODE (operands[1], QImode);")
10762 (define_split
10763   [(set (match_operand:QI 0 "nonimmediate_operand")
10764         (eq:QI (match_operator 1 "ix86_comparison_operator"
10765                  [(reg FLAGS_REG) (const_int 0)])
10766             (const_int 0)))]
10767   ""
10768   [(set (match_dup 0) (match_dup 1))]
10770   rtx new_op1 = copy_rtx (operands[1]);
10771   operands[1] = new_op1;
10772   PUT_MODE (new_op1, QImode);
10773   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10774                                              GET_MODE (XEXP (new_op1, 0))));
10776   /* Make sure that (a) the CCmode we have for the flags is strong
10777      enough for the reversed compare or (b) we have a valid FP compare.  */
10778   if (! ix86_comparison_operator (new_op1, VOIDmode))
10779     FAIL;
10782 (define_split
10783   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10784         (eq:QI (match_operator 1 "ix86_comparison_operator"
10785                  [(reg FLAGS_REG) (const_int 0)])
10786             (const_int 0)))]
10787   ""
10788   [(set (match_dup 0) (match_dup 1))]
10790   rtx new_op1 = copy_rtx (operands[1]);
10791   operands[1] = new_op1;
10792   PUT_MODE (new_op1, QImode);
10793   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10794                                              GET_MODE (XEXP (new_op1, 0))));
10796   /* Make sure that (a) the CCmode we have for the flags is strong
10797      enough for the reversed compare or (b) we have a valid FP compare.  */
10798   if (! ix86_comparison_operator (new_op1, VOIDmode))
10799     FAIL;
10802 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10803 ;; subsequent logical operations are used to imitate conditional moves.
10804 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10805 ;; it directly.
10807 (define_insn "setcc_<mode>_sse"
10808   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10809         (match_operator:MODEF 3 "sse_comparison_operator"
10810           [(match_operand:MODEF 1 "register_operand" "0,x")
10811            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10812   "SSE_FLOAT_MODE_P (<MODE>mode)"
10813   "@
10814    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10815    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10816   [(set_attr "isa" "noavx,avx")
10817    (set_attr "type" "ssecmp")
10818    (set_attr "length_immediate" "1")
10819    (set_attr "prefix" "orig,vex")
10820    (set_attr "mode" "<MODE>")])
10822 ;; Basic conditional jump instructions.
10823 ;; We ignore the overflow flag for signed branch instructions.
10825 (define_insn "*jcc_1"
10826   [(set (pc)
10827         (if_then_else (match_operator 1 "ix86_comparison_operator"
10828                                       [(reg FLAGS_REG) (const_int 0)])
10829                       (label_ref (match_operand 0))
10830                       (pc)))]
10831   ""
10832   "%+j%C1\t%l0"
10833   [(set_attr "type" "ibr")
10834    (set_attr "modrm" "0")
10835    (set (attr "length")
10836            (if_then_else (and (ge (minus (match_dup 0) (pc))
10837                                   (const_int -126))
10838                               (lt (minus (match_dup 0) (pc))
10839                                   (const_int 128)))
10840              (const_int 2)
10841              (const_int 6)))])
10843 (define_insn "*jcc_2"
10844   [(set (pc)
10845         (if_then_else (match_operator 1 "ix86_comparison_operator"
10846                                       [(reg FLAGS_REG) (const_int 0)])
10847                       (pc)
10848                       (label_ref (match_operand 0))))]
10849   ""
10850   "%+j%c1\t%l0"
10851   [(set_attr "type" "ibr")
10852    (set_attr "modrm" "0")
10853    (set (attr "length")
10854            (if_then_else (and (ge (minus (match_dup 0) (pc))
10855                                   (const_int -126))
10856                               (lt (minus (match_dup 0) (pc))
10857                                   (const_int 128)))
10858              (const_int 2)
10859              (const_int 6)))])
10861 ;; In general it is not safe to assume too much about CCmode registers,
10862 ;; so simplify-rtx stops when it sees a second one.  Under certain
10863 ;; conditions this is safe on x86, so help combine not create
10865 ;;      seta    %al
10866 ;;      testb   %al, %al
10867 ;;      je      Lfoo
10869 (define_split
10870   [(set (pc)
10871         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10872                                       [(reg FLAGS_REG) (const_int 0)])
10873                           (const_int 0))
10874                       (label_ref (match_operand 1))
10875                       (pc)))]
10876   ""
10877   [(set (pc)
10878         (if_then_else (match_dup 0)
10879                       (label_ref (match_dup 1))
10880                       (pc)))]
10881   "PUT_MODE (operands[0], VOIDmode);")
10883 (define_split
10884   [(set (pc)
10885         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10886                                       [(reg FLAGS_REG) (const_int 0)])
10887                           (const_int 0))
10888                       (label_ref (match_operand 1))
10889                       (pc)))]
10890   ""
10891   [(set (pc)
10892         (if_then_else (match_dup 0)
10893                       (label_ref (match_dup 1))
10894                       (pc)))]
10896   rtx new_op0 = copy_rtx (operands[0]);
10897   operands[0] = new_op0;
10898   PUT_MODE (new_op0, VOIDmode);
10899   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10900                                              GET_MODE (XEXP (new_op0, 0))));
10902   /* Make sure that (a) the CCmode we have for the flags is strong
10903      enough for the reversed compare or (b) we have a valid FP compare.  */
10904   if (! ix86_comparison_operator (new_op0, VOIDmode))
10905     FAIL;
10908 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10909 ;; pass generates from shift insn with QImode operand.  Actually, the mode
10910 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10911 ;; appropriate modulo of the bit offset value.
10913 (define_insn_and_split "*jcc_bt<mode>"
10914   [(set (pc)
10915         (if_then_else (match_operator 0 "bt_comparison_operator"
10916                         [(zero_extract:SWI48
10917                            (match_operand:SWI48 1 "register_operand" "r")
10918                            (const_int 1)
10919                            (zero_extend:SI
10920                              (match_operand:QI 2 "register_operand" "r")))
10921                          (const_int 0)])
10922                       (label_ref (match_operand 3))
10923                       (pc)))
10924    (clobber (reg:CC FLAGS_REG))]
10925   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10926   "#"
10927   "&& 1"
10928   [(set (reg:CCC FLAGS_REG)
10929         (compare:CCC
10930           (zero_extract:SWI48
10931             (match_dup 1)
10932             (const_int 1)
10933             (match_dup 2))
10934           (const_int 0)))
10935    (set (pc)
10936         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10937                       (label_ref (match_dup 3))
10938                       (pc)))]
10940   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10942   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10945 ;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode
10946 ;; zero extended to SImode.
10947 (define_insn_and_split "*jcc_bt<mode>_1"
10948   [(set (pc)
10949         (if_then_else (match_operator 0 "bt_comparison_operator"
10950                         [(zero_extract:SWI48
10951                            (match_operand:SWI48 1 "register_operand" "r")
10952                            (const_int 1)
10953                            (match_operand:SI 2 "register_operand" "r"))
10954                          (const_int 0)])
10955                       (label_ref (match_operand 3))
10956                       (pc)))
10957    (clobber (reg:CC FLAGS_REG))]
10958   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10959   "#"
10960   "&& 1"
10961   [(set (reg:CCC FLAGS_REG)
10962         (compare:CCC
10963           (zero_extract:SWI48
10964             (match_dup 1)
10965             (const_int 1)
10966             (match_dup 2))
10967           (const_int 0)))
10968    (set (pc)
10969         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10970                       (label_ref (match_dup 3))
10971                       (pc)))]
10973   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10975   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10978 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10979 ;; also for DImode, this is what combine produces.
10980 (define_insn_and_split "*jcc_bt<mode>_mask"
10981   [(set (pc)
10982         (if_then_else (match_operator 0 "bt_comparison_operator"
10983                         [(zero_extract:SWI48
10984                            (match_operand:SWI48 1 "register_operand" "r")
10985                            (const_int 1)
10986                            (and:SI
10987                              (match_operand:SI 2 "register_operand" "r")
10988                              (match_operand:SI 3 "const_int_operand" "n")))])
10989                       (label_ref (match_operand 4))
10990                       (pc)))
10991    (clobber (reg:CC FLAGS_REG))]
10992   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10993    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10994       == GET_MODE_BITSIZE (<MODE>mode)-1"
10995   "#"
10996   "&& 1"
10997   [(set (reg:CCC FLAGS_REG)
10998         (compare:CCC
10999           (zero_extract:SWI48
11000             (match_dup 1)
11001             (const_int 1)
11002             (match_dup 2))
11003           (const_int 0)))
11004    (set (pc)
11005         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11006                       (label_ref (match_dup 4))
11007                       (pc)))]
11009   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11011   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11014 (define_insn_and_split "*jcc_btsi_1"
11015   [(set (pc)
11016         (if_then_else (match_operator 0 "bt_comparison_operator"
11017                         [(and:SI
11018                            (lshiftrt:SI
11019                              (match_operand:SI 1 "register_operand" "r")
11020                              (match_operand:QI 2 "register_operand" "r"))
11021                            (const_int 1))
11022                          (const_int 0)])
11023                       (label_ref (match_operand 3))
11024                       (pc)))
11025    (clobber (reg:CC FLAGS_REG))]
11026   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11027   "#"
11028   "&& 1"
11029   [(set (reg:CCC FLAGS_REG)
11030         (compare:CCC
11031           (zero_extract:SI
11032             (match_dup 1)
11033             (const_int 1)
11034             (match_dup 2))
11035           (const_int 0)))
11036    (set (pc)
11037         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11038                       (label_ref (match_dup 3))
11039                       (pc)))]
11041   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11043   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11046 ;; avoid useless masking of bit offset operand
11047 (define_insn_and_split "*jcc_btsi_mask_1"
11048   [(set (pc)
11049         (if_then_else
11050           (match_operator 0 "bt_comparison_operator"
11051             [(and:SI
11052                (lshiftrt:SI
11053                  (match_operand:SI 1 "register_operand" "r")
11054                  (subreg:QI
11055                    (and:SI
11056                      (match_operand:SI 2 "register_operand" "r")
11057                      (match_operand:SI 3 "const_int_operand" "n")) 0))
11058                (const_int 1))
11059              (const_int 0)])
11060           (label_ref (match_operand 4))
11061           (pc)))
11062    (clobber (reg:CC FLAGS_REG))]
11063   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11064    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11065   "#"
11066   "&& 1"
11067   [(set (reg:CCC FLAGS_REG)
11068         (compare:CCC
11069           (zero_extract:SI
11070             (match_dup 1)
11071             (const_int 1)
11072             (match_dup 2))
11073           (const_int 0)))
11074    (set (pc)
11075         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11076                       (label_ref (match_dup 4))
11077                       (pc)))]
11078   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11080 ;; Define combination compare-and-branch fp compare instructions to help
11081 ;; combine.
11083 (define_insn "*jcc<mode>_0_i387"
11084   [(set (pc)
11085         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11086                         [(match_operand:X87MODEF 1 "register_operand" "f")
11087                          (match_operand:X87MODEF 2 "const0_operand")])
11088           (label_ref (match_operand 3))
11089           (pc)))
11090    (clobber (reg:CCFP FPSR_REG))
11091    (clobber (reg:CCFP FLAGS_REG))
11092    (clobber (match_scratch:HI 4 "=a"))]
11093   "TARGET_80387 && !TARGET_CMOVE"
11094   "#")
11096 (define_insn "*jcc<mode>_0_r_i387"
11097   [(set (pc)
11098         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11099                         [(match_operand:X87MODEF 1 "register_operand" "f")
11100                          (match_operand:X87MODEF 2 "const0_operand")])
11101           (pc)
11102           (label_ref (match_operand 3))))
11103    (clobber (reg:CCFP FPSR_REG))
11104    (clobber (reg:CCFP FLAGS_REG))
11105    (clobber (match_scratch:HI 4 "=a"))]
11106   "TARGET_80387 && !TARGET_CMOVE"
11107   "#")
11109 (define_insn "*jccxf_i387"
11110   [(set (pc)
11111         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11112                         [(match_operand:XF 1 "register_operand" "f")
11113                          (match_operand:XF 2 "register_operand" "f")])
11114           (label_ref (match_operand 3))
11115           (pc)))
11116    (clobber (reg:CCFP FPSR_REG))
11117    (clobber (reg:CCFP FLAGS_REG))
11118    (clobber (match_scratch:HI 4 "=a"))]
11119   "TARGET_80387 && !TARGET_CMOVE"
11120   "#")
11122 (define_insn "*jccxf_r_i387"
11123   [(set (pc)
11124         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11125                         [(match_operand:XF 1 "register_operand" "f")
11126                          (match_operand:XF 2 "register_operand" "f")])
11127           (pc)
11128           (label_ref (match_operand 3))))
11129    (clobber (reg:CCFP FPSR_REG))
11130    (clobber (reg:CCFP FLAGS_REG))
11131    (clobber (match_scratch:HI 4 "=a"))]
11132   "TARGET_80387 && !TARGET_CMOVE"
11133   "#")
11135 (define_insn "*jcc<mode>_i387"
11136   [(set (pc)
11137         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11138                         [(match_operand:MODEF 1 "register_operand" "f")
11139                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11140           (label_ref (match_operand 3))
11141           (pc)))
11142    (clobber (reg:CCFP FPSR_REG))
11143    (clobber (reg:CCFP FLAGS_REG))
11144    (clobber (match_scratch:HI 4 "=a"))]
11145   "TARGET_80387 && !TARGET_CMOVE"
11146   "#")
11148 (define_insn "*jcc<mode>_r_i387"
11149   [(set (pc)
11150         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11151                         [(match_operand:MODEF 1 "register_operand" "f")
11152                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11153           (pc)
11154           (label_ref (match_operand 3))))
11155    (clobber (reg:CCFP FPSR_REG))
11156    (clobber (reg:CCFP FLAGS_REG))
11157    (clobber (match_scratch:HI 4 "=a"))]
11158   "TARGET_80387 && !TARGET_CMOVE"
11159   "#")
11161 (define_insn "*jccu<mode>_i387"
11162   [(set (pc)
11163         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11164                         [(match_operand:X87MODEF 1 "register_operand" "f")
11165                          (match_operand:X87MODEF 2 "register_operand" "f")])
11166           (label_ref (match_operand 3))
11167           (pc)))
11168    (clobber (reg:CCFP FPSR_REG))
11169    (clobber (reg:CCFP FLAGS_REG))
11170    (clobber (match_scratch:HI 4 "=a"))]
11171   "TARGET_80387 && !TARGET_CMOVE"
11172   "#")
11174 (define_insn "*jccu<mode>_r_i387"
11175   [(set (pc)
11176         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11177                         [(match_operand:X87MODEF 1 "register_operand" "f")
11178                          (match_operand:X87MODEF 2 "register_operand" "f")])
11179           (pc)
11180           (label_ref (match_operand 3))))
11181    (clobber (reg:CCFP FPSR_REG))
11182    (clobber (reg:CCFP FLAGS_REG))
11183    (clobber (match_scratch:HI 4 "=a"))]
11184   "TARGET_80387 && !TARGET_CMOVE"
11185   "#")
11187 (define_split
11188   [(set (pc)
11189         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11190                         [(match_operand:X87MODEF 1 "register_operand")
11191                          (match_operand:X87MODEF 2 "nonimmediate_operand")])
11192           (match_operand 3)
11193           (match_operand 4)))
11194    (clobber (reg:CCFP FPSR_REG))
11195    (clobber (reg:CCFP FLAGS_REG))]
11196   "TARGET_80387 && !TARGET_CMOVE
11197    && reload_completed"
11198   [(const_int 0)]
11200   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11201                         operands[3], operands[4], NULL_RTX);
11202   DONE;
11205 (define_split
11206   [(set (pc)
11207         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11208                         [(match_operand:X87MODEF 1 "register_operand")
11209                          (match_operand:X87MODEF 2 "general_operand")])
11210           (match_operand 3)
11211           (match_operand 4)))
11212    (clobber (reg:CCFP FPSR_REG))
11213    (clobber (reg:CCFP FLAGS_REG))
11214    (clobber (match_scratch:HI 5))]
11215   "TARGET_80387 && !TARGET_CMOVE
11216    && reload_completed"
11217   [(const_int 0)]
11219   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11220                         operands[3], operands[4], operands[5]);
11221   DONE;
11224 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11225 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11226 ;; with a precedence over other operators and is always put in the first
11227 ;; place. Swap condition and operands to match ficom instruction.
11229 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11230   [(set (pc)
11231         (if_then_else
11232           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11233             [(match_operator:X87MODEF 1 "float_operator"
11234               [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11235              (match_operand:X87MODEF 3 "register_operand" "f")])
11236           (label_ref (match_operand 4))
11237           (pc)))
11238    (clobber (reg:CCFP FPSR_REG))
11239    (clobber (reg:CCFP FLAGS_REG))
11240    (clobber (match_scratch:HI 5 "=a"))]
11241   "TARGET_80387 && !TARGET_CMOVE
11242    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11243        || optimize_function_for_size_p (cfun))"
11244   "#")
11246 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11247   [(set (pc)
11248         (if_then_else
11249           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11250             [(match_operator:X87MODEF 1 "float_operator"
11251               [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11252              (match_operand:X87MODEF 3 "register_operand" "f")])
11253           (pc)
11254           (label_ref (match_operand 4))))
11255    (clobber (reg:CCFP FPSR_REG))
11256    (clobber (reg:CCFP FLAGS_REG))
11257    (clobber (match_scratch:HI 5 "=a"))]
11258   "TARGET_80387 && !TARGET_CMOVE
11259    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11260        || optimize_function_for_size_p (cfun))"
11261   "#")
11263 (define_split
11264   [(set (pc)
11265         (if_then_else
11266           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11267             [(match_operator:X87MODEF 1 "float_operator"
11268               [(match_operand:SWI24 2 "memory_operand")])
11269              (match_operand:X87MODEF 3 "register_operand")])
11270           (match_operand 4)
11271           (match_operand 5)))
11272    (clobber (reg:CCFP FPSR_REG))
11273    (clobber (reg:CCFP FLAGS_REG))
11274    (clobber (match_scratch:HI 6))]
11275   "TARGET_80387 && !TARGET_CMOVE
11276    && reload_completed"
11277   [(const_int 0)]
11279   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11280                         gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11281                         operands[4], operands[5], operands[6]);
11282   DONE;
11285 ;; Unconditional and other jump instructions
11287 (define_insn "jump"
11288   [(set (pc)
11289         (label_ref (match_operand 0)))]
11290   ""
11291   "jmp\t%l0"
11292   [(set_attr "type" "ibr")
11293    (set (attr "length")
11294            (if_then_else (and (ge (minus (match_dup 0) (pc))
11295                                   (const_int -126))
11296                               (lt (minus (match_dup 0) (pc))
11297                                   (const_int 128)))
11298              (const_int 2)
11299              (const_int 5)))
11300    (set_attr "modrm" "0")])
11302 (define_expand "indirect_jump"
11303   [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11304   ""
11306   if (TARGET_X32)
11307     operands[0] = convert_memory_address (word_mode, operands[0]);
11310 (define_insn "*indirect_jump"
11311   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11312   ""
11313   "jmp\t%A0"
11314   [(set_attr "type" "ibr")
11315    (set_attr "length_immediate" "0")])
11317 (define_expand "tablejump"
11318   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11319               (use (label_ref (match_operand 1)))])]
11320   ""
11322   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11323      relative.  Convert the relative address to an absolute address.  */
11324   if (flag_pic)
11325     {
11326       rtx op0, op1;
11327       enum rtx_code code;
11329       /* We can't use @GOTOFF for text labels on VxWorks;
11330          see gotoff_operand.  */
11331       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11332         {
11333           code = PLUS;
11334           op0 = operands[0];
11335           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11336         }
11337       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11338         {
11339           code = PLUS;
11340           op0 = operands[0];
11341           op1 = pic_offset_table_rtx;
11342         }
11343       else
11344         {
11345           code = MINUS;
11346           op0 = pic_offset_table_rtx;
11347           op1 = operands[0];
11348         }
11350       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11351                                          OPTAB_DIRECT);
11352     }
11354   if (TARGET_X32)
11355     operands[0] = convert_memory_address (word_mode, operands[0]);
11358 (define_insn "*tablejump_1"
11359   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11360    (use (label_ref (match_operand 1)))]
11361   ""
11362   "jmp\t%A0"
11363   [(set_attr "type" "ibr")
11364    (set_attr "length_immediate" "0")])
11366 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11368 (define_peephole2
11369   [(set (reg FLAGS_REG) (match_operand 0))
11370    (set (match_operand:QI 1 "register_operand")
11371         (match_operator:QI 2 "ix86_comparison_operator"
11372           [(reg FLAGS_REG) (const_int 0)]))
11373    (set (match_operand 3 "q_regs_operand")
11374         (zero_extend (match_dup 1)))]
11375   "(peep2_reg_dead_p (3, operands[1])
11376     || operands_match_p (operands[1], operands[3]))
11377    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11378   [(set (match_dup 4) (match_dup 0))
11379    (set (strict_low_part (match_dup 5))
11380         (match_dup 2))]
11382   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11383   operands[5] = gen_lowpart (QImode, operands[3]);
11384   ix86_expand_clear (operands[3]);
11387 (define_peephole2
11388   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11389               (match_operand 4)])
11390    (set (match_operand:QI 1 "register_operand")
11391         (match_operator:QI 2 "ix86_comparison_operator"
11392           [(reg FLAGS_REG) (const_int 0)]))
11393    (set (match_operand 3 "q_regs_operand")
11394         (zero_extend (match_dup 1)))]
11395   "(peep2_reg_dead_p (3, operands[1])
11396     || operands_match_p (operands[1], operands[3]))
11397    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11398   [(parallel [(set (match_dup 5) (match_dup 0))
11399               (match_dup 4)])
11400    (set (strict_low_part (match_dup 6))
11401         (match_dup 2))]
11403   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11404   operands[6] = gen_lowpart (QImode, operands[3]);
11405   ix86_expand_clear (operands[3]);
11408 ;; Similar, but match zero extend with andsi3.
11410 (define_peephole2
11411   [(set (reg FLAGS_REG) (match_operand 0))
11412    (set (match_operand:QI 1 "register_operand")
11413         (match_operator:QI 2 "ix86_comparison_operator"
11414           [(reg FLAGS_REG) (const_int 0)]))
11415    (parallel [(set (match_operand:SI 3 "q_regs_operand")
11416                    (and:SI (match_dup 3) (const_int 255)))
11417               (clobber (reg:CC FLAGS_REG))])]
11418   "REGNO (operands[1]) == REGNO (operands[3])
11419    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11420   [(set (match_dup 4) (match_dup 0))
11421    (set (strict_low_part (match_dup 5))
11422         (match_dup 2))]
11424   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11425   operands[5] = gen_lowpart (QImode, operands[3]);
11426   ix86_expand_clear (operands[3]);
11429 (define_peephole2
11430   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11431               (match_operand 4)])
11432    (set (match_operand:QI 1 "register_operand")
11433         (match_operator:QI 2 "ix86_comparison_operator"
11434           [(reg FLAGS_REG) (const_int 0)]))
11435    (parallel [(set (match_operand 3 "q_regs_operand")
11436                    (zero_extend (match_dup 1)))
11437               (clobber (reg:CC FLAGS_REG))])]
11438   "(peep2_reg_dead_p (3, operands[1])
11439     || operands_match_p (operands[1], operands[3]))
11440    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11441   [(parallel [(set (match_dup 5) (match_dup 0))
11442               (match_dup 4)])
11443    (set (strict_low_part (match_dup 6))
11444         (match_dup 2))]
11446   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11447   operands[6] = gen_lowpart (QImode, operands[3]);
11448   ix86_expand_clear (operands[3]);
11451 ;; Call instructions.
11453 ;; The predicates normally associated with named expanders are not properly
11454 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11455 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11457 ;; P6 processors will jump to the address after the decrement when %esp
11458 ;; is used as a call operand, so they will execute return address as a code.
11459 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11461 ;; Register constraint for call instruction.
11462 (define_mode_attr c [(SI "l") (DI "r")])
11464 ;; Call subroutine returning no value.
11466 (define_expand "call"
11467   [(call (match_operand:QI 0)
11468          (match_operand 1))
11469    (use (match_operand 2))]
11470   ""
11472   ix86_expand_call (NULL, operands[0], operands[1],
11473                     operands[2], NULL, false);
11474   DONE;
11477 (define_expand "sibcall"
11478   [(call (match_operand:QI 0)
11479          (match_operand 1))
11480    (use (match_operand 2))]
11481   ""
11483   ix86_expand_call (NULL, operands[0], operands[1],
11484                     operands[2], NULL, true);
11485   DONE;
11488 (define_insn "*call"
11489   [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
11490          (match_operand 1))]
11491   "!SIBLING_CALL_P (insn)"
11492   "* return ix86_output_call_insn (insn, operands[0]);"
11493   [(set_attr "type" "call")])
11495 (define_insn "*call_rex64_ms_sysv"
11496   [(match_parallel 2 "call_rex64_ms_sysv_operation"
11497     [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rBwBz"))
11498            (match_operand 1))
11499      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11500   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11501   "* return ix86_output_call_insn (insn, operands[0]);"
11502   [(set_attr "type" "call")])
11504 (define_insn "*sibcall"
11505   [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
11506          (match_operand 1))]
11507   "SIBLING_CALL_P (insn)"
11508   "* return ix86_output_call_insn (insn, operands[0]);"
11509   [(set_attr "type" "call")])
11511 (define_insn "*sibcall_memory"
11512   [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
11513          (match_operand 1))
11514    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11515   "!TARGET_X32"
11516   "* return ix86_output_call_insn (insn, operands[0]);"
11517   [(set_attr "type" "call")])
11519 (define_peephole2
11520   [(set (match_operand:W 0 "register_operand")
11521         (match_operand:W 1 "memory_operand"))
11522    (call (mem:QI (match_dup 0))
11523          (match_operand 3))]
11524   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11525    && peep2_reg_dead_p (2, operands[0])"
11526   [(parallel [(call (mem:QI (match_dup 1))
11527                     (match_dup 3))
11528               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11530 (define_peephole2
11531   [(set (match_operand:W 0 "register_operand")
11532         (match_operand:W 1 "memory_operand"))
11533    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11534    (call (mem:QI (match_dup 0))
11535          (match_operand 3))]
11536   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11537    && peep2_reg_dead_p (3, operands[0])"
11538   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11539    (parallel [(call (mem:QI (match_dup 1))
11540                     (match_dup 3))
11541               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11543 (define_expand "call_pop"
11544   [(parallel [(call (match_operand:QI 0)
11545                     (match_operand:SI 1))
11546               (set (reg:SI SP_REG)
11547                    (plus:SI (reg:SI SP_REG)
11548                             (match_operand:SI 3)))])]
11549   "!TARGET_64BIT"
11551   ix86_expand_call (NULL, operands[0], operands[1],
11552                     operands[2], operands[3], false);
11553   DONE;
11556 (define_insn "*call_pop"
11557   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
11558          (match_operand 1))
11559    (set (reg:SI SP_REG)
11560         (plus:SI (reg:SI SP_REG)
11561                  (match_operand:SI 2 "immediate_operand" "i")))]
11562   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11563   "* return ix86_output_call_insn (insn, operands[0]);"
11564   [(set_attr "type" "call")])
11566 (define_insn "*sibcall_pop"
11567   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
11568          (match_operand 1))
11569    (set (reg:SI SP_REG)
11570         (plus:SI (reg:SI SP_REG)
11571                  (match_operand:SI 2 "immediate_operand" "i")))]
11572   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11573   "* return ix86_output_call_insn (insn, operands[0]);"
11574   [(set_attr "type" "call")])
11576 (define_insn "*sibcall_pop_memory"
11577   [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
11578          (match_operand 1))
11579    (set (reg:SI SP_REG)
11580         (plus:SI (reg:SI SP_REG)
11581                  (match_operand:SI 2 "immediate_operand" "i")))
11582    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11583   "!TARGET_64BIT"
11584   "* return ix86_output_call_insn (insn, operands[0]);"
11585   [(set_attr "type" "call")])
11587 (define_peephole2
11588   [(set (match_operand:SI 0 "register_operand")
11589         (match_operand:SI 1 "memory_operand"))
11590    (parallel [(call (mem:QI (match_dup 0))
11591                     (match_operand 3))
11592               (set (reg:SI SP_REG)
11593                    (plus:SI (reg:SI SP_REG)
11594                             (match_operand:SI 4 "immediate_operand")))])]
11595   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11596    && peep2_reg_dead_p (2, operands[0])"
11597   [(parallel [(call (mem:QI (match_dup 1))
11598                     (match_dup 3))
11599               (set (reg:SI SP_REG)
11600                    (plus:SI (reg:SI SP_REG)
11601                             (match_dup 4)))
11602               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11604 (define_peephole2
11605   [(set (match_operand:SI 0 "register_operand")
11606         (match_operand:SI 1 "memory_operand"))
11607    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11608    (parallel [(call (mem:QI (match_dup 0))
11609                     (match_operand 3))
11610               (set (reg:SI SP_REG)
11611                    (plus:SI (reg:SI SP_REG)
11612                             (match_operand:SI 4 "immediate_operand")))])]
11613   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11614    && peep2_reg_dead_p (3, operands[0])"
11615   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11616    (parallel [(call (mem:QI (match_dup 1))
11617                     (match_dup 3))
11618               (set (reg:SI SP_REG)
11619                    (plus:SI (reg:SI SP_REG)
11620                             (match_dup 4)))
11621               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11623 ;; Combining simple memory jump instruction
11625 (define_peephole2
11626   [(set (match_operand:W 0 "register_operand")
11627         (match_operand:W 1 "memory_operand"))
11628    (set (pc) (match_dup 0))]
11629   "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
11630   [(set (pc) (match_dup 1))])
11632 ;; Call subroutine, returning value in operand 0
11634 (define_expand "call_value"
11635   [(set (match_operand 0)
11636         (call (match_operand:QI 1)
11637               (match_operand 2)))
11638    (use (match_operand 3))]
11639   ""
11641   ix86_expand_call (operands[0], operands[1], operands[2],
11642                     operands[3], NULL, false);
11643   DONE;
11646 (define_expand "sibcall_value"
11647   [(set (match_operand 0)
11648         (call (match_operand:QI 1)
11649               (match_operand 2)))
11650    (use (match_operand 3))]
11651   ""
11653   ix86_expand_call (operands[0], operands[1], operands[2],
11654                     operands[3], NULL, true);
11655   DONE;
11658 (define_insn "*call_value"
11659   [(set (match_operand 0)
11660         (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
11661               (match_operand 2)))]
11662   "!SIBLING_CALL_P (insn)"
11663   "* return ix86_output_call_insn (insn, operands[1]);"
11664   [(set_attr "type" "callv")])
11666 (define_insn "*sibcall_value"
11667   [(set (match_operand 0)
11668         (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
11669               (match_operand 2)))]
11670   "SIBLING_CALL_P (insn)"
11671   "* return ix86_output_call_insn (insn, operands[1]);"
11672   [(set_attr "type" "callv")])
11674 (define_insn "*sibcall_value_memory"
11675   [(set (match_operand 0)
11676         (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
11677               (match_operand 2)))
11678    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11679   "!TARGET_X32"
11680   "* return ix86_output_call_insn (insn, operands[1]);"
11681   [(set_attr "type" "callv")])
11683 (define_peephole2
11684   [(set (match_operand:W 0 "register_operand")
11685         (match_operand:W 1 "memory_operand"))
11686    (set (match_operand 2)
11687    (call (mem:QI (match_dup 0))
11688                  (match_operand 3)))]
11689   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11690    && peep2_reg_dead_p (2, operands[0])"
11691   [(parallel [(set (match_dup 2)
11692                    (call (mem:QI (match_dup 1))
11693                          (match_dup 3)))
11694               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11696 (define_peephole2
11697   [(set (match_operand:W 0 "register_operand")
11698         (match_operand:W 1 "memory_operand"))
11699    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11700    (set (match_operand 2)
11701         (call (mem:QI (match_dup 0))
11702               (match_operand 3)))]
11703   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11704    && peep2_reg_dead_p (3, operands[0])"
11705   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11706    (parallel [(set (match_dup 2)
11707                    (call (mem:QI (match_dup 1))
11708                          (match_dup 3)))
11709               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11711 (define_insn "*call_value_rex64_ms_sysv"
11712   [(match_parallel 3 "call_rex64_ms_sysv_operation"
11713     [(set (match_operand 0)
11714           (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rBwBz"))
11715                 (match_operand 2)))
11716      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11717  "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11718   "* return ix86_output_call_insn (insn, operands[1]);"
11719   [(set_attr "type" "callv")])
11721 (define_expand "call_value_pop"
11722   [(parallel [(set (match_operand 0)
11723                    (call (match_operand:QI 1)
11724                          (match_operand:SI 2)))
11725               (set (reg:SI SP_REG)
11726                    (plus:SI (reg:SI SP_REG)
11727                             (match_operand:SI 4)))])]
11728   "!TARGET_64BIT"
11730   ix86_expand_call (operands[0], operands[1], operands[2],
11731                     operands[3], operands[4], false);
11732   DONE;
11735 (define_insn "*call_value_pop"
11736   [(set (match_operand 0)
11737         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
11738               (match_operand 2)))
11739    (set (reg:SI SP_REG)
11740         (plus:SI (reg:SI SP_REG)
11741                  (match_operand:SI 3 "immediate_operand" "i")))]
11742   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11743   "* return ix86_output_call_insn (insn, operands[1]);"
11744   [(set_attr "type" "callv")])
11746 (define_insn "*sibcall_value_pop"
11747   [(set (match_operand 0)
11748         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
11749               (match_operand 2)))
11750    (set (reg:SI SP_REG)
11751         (plus:SI (reg:SI SP_REG)
11752                  (match_operand:SI 3 "immediate_operand" "i")))]
11753   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11754   "* return ix86_output_call_insn (insn, operands[1]);"
11755   [(set_attr "type" "callv")])
11757 (define_insn "*sibcall_value_pop_memory"
11758   [(set (match_operand 0)
11759         (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
11760               (match_operand 2)))
11761    (set (reg:SI SP_REG)
11762         (plus:SI (reg:SI SP_REG)
11763                  (match_operand:SI 3 "immediate_operand" "i")))
11764    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11765   "!TARGET_64BIT"
11766   "* return ix86_output_call_insn (insn, operands[1]);"
11767   [(set_attr "type" "callv")])
11769 (define_peephole2
11770   [(set (match_operand:SI 0 "register_operand")
11771         (match_operand:SI 1 "memory_operand"))
11772    (parallel [(set (match_operand 2)
11773                    (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 [(set (match_dup 2)
11781                    (call (mem:QI (match_dup 1))
11782                          (match_dup 3)))
11783               (set (reg:SI SP_REG)
11784                    (plus:SI (reg:SI SP_REG)
11785                             (match_dup 4)))
11786               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11788 (define_peephole2
11789   [(set (match_operand:SI 0 "register_operand")
11790         (match_operand:SI 1 "memory_operand"))
11791    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11792    (parallel [(set (match_operand 2)
11793                    (call (mem:QI (match_dup 0))
11794                          (match_operand 3)))
11795               (set (reg:SI SP_REG)
11796                    (plus:SI (reg:SI SP_REG)
11797                             (match_operand:SI 4 "immediate_operand")))])]
11798   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11799    && peep2_reg_dead_p (3, operands[0])"
11800   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11801    (parallel [(set (match_dup 2)
11802                    (call (mem:QI (match_dup 1))
11803                          (match_dup 3)))
11804               (set (reg:SI SP_REG)
11805                    (plus:SI (reg:SI SP_REG)
11806                             (match_dup 4)))
11807               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11809 ;; Call subroutine returning any type.
11811 (define_expand "untyped_call"
11812   [(parallel [(call (match_operand 0)
11813                     (const_int 0))
11814               (match_operand 1)
11815               (match_operand 2)])]
11816   ""
11818   int i;
11820   /* In order to give reg-stack an easier job in validating two
11821      coprocessor registers as containing a possible return value,
11822      simply pretend the untyped call returns a complex long double
11823      value. 
11825      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11826      and should have the default ABI.  */
11828   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11829                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11830                     operands[0], const0_rtx,
11831                     GEN_INT ((TARGET_64BIT
11832                               ? (ix86_abi == SYSV_ABI
11833                                  ? X86_64_SSE_REGPARM_MAX
11834                                  : X86_64_MS_SSE_REGPARM_MAX)
11835                               : X86_32_SSE_REGPARM_MAX)
11836                              - 1),
11837                     NULL, false);
11839   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11840     {
11841       rtx set = XVECEXP (operands[2], 0, i);
11842       emit_move_insn (SET_DEST (set), SET_SRC (set));
11843     }
11845   /* The optimizer does not know that the call sets the function value
11846      registers we stored in the result block.  We avoid problems by
11847      claiming that all hard registers are used and clobbered at this
11848      point.  */
11849   emit_insn (gen_blockage ());
11851   DONE;
11854 ;; Prologue and epilogue instructions
11856 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11857 ;; all of memory.  This blocks insns from being moved across this point.
11859 (define_insn "blockage"
11860   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11861   ""
11862   ""
11863   [(set_attr "length" "0")])
11865 ;; Do not schedule instructions accessing memory across this point.
11867 (define_expand "memory_blockage"
11868   [(set (match_dup 0)
11869         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11870   ""
11872   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11873   MEM_VOLATILE_P (operands[0]) = 1;
11876 (define_insn "*memory_blockage"
11877   [(set (match_operand:BLK 0)
11878         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11879   ""
11880   ""
11881   [(set_attr "length" "0")])
11883 ;; As USE insns aren't meaningful after reload, this is used instead
11884 ;; to prevent deleting instructions setting registers for PIC code
11885 (define_insn "prologue_use"
11886   [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11887   ""
11888   ""
11889   [(set_attr "length" "0")])
11891 ;; Insn emitted into the body of a function to return from a function.
11892 ;; This is only done if the function's epilogue is known to be simple.
11893 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11895 (define_expand "return"
11896   [(simple_return)]
11897   "ix86_can_use_return_insn_p ()"
11899   if (crtl->args.pops_args)
11900     {
11901       rtx popc = GEN_INT (crtl->args.pops_args);
11902       emit_jump_insn (gen_simple_return_pop_internal (popc));
11903       DONE;
11904     }
11907 ;; We need to disable this for TARGET_SEH, as otherwise
11908 ;; shrink-wrapped prologue gets enabled too.  This might exceed
11909 ;; the maximum size of prologue in unwind information.
11911 (define_expand "simple_return"
11912   [(simple_return)]
11913   "!TARGET_SEH"
11915   if (crtl->args.pops_args)
11916     {
11917       rtx popc = GEN_INT (crtl->args.pops_args);
11918       emit_jump_insn (gen_simple_return_pop_internal (popc));
11919       DONE;
11920     }
11923 (define_insn "simple_return_internal"
11924   [(simple_return)]
11925   "reload_completed"
11926   "ret"
11927   [(set_attr "length" "1")
11928    (set_attr "atom_unit" "jeu")
11929    (set_attr "length_immediate" "0")
11930    (set_attr "modrm" "0")])
11932 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11933 ;; instruction Athlon and K8 have.
11935 (define_insn "simple_return_internal_long"
11936   [(simple_return)
11937    (unspec [(const_int 0)] UNSPEC_REP)]
11938   "reload_completed"
11939   "rep%; ret"
11940   [(set_attr "length" "2")
11941    (set_attr "atom_unit" "jeu")
11942    (set_attr "length_immediate" "0")
11943    (set_attr "prefix_rep" "1")
11944    (set_attr "modrm" "0")])
11946 (define_insn "simple_return_pop_internal"
11947   [(simple_return)
11948    (use (match_operand:SI 0 "const_int_operand"))]
11949   "reload_completed"
11950   "ret\t%0"
11951   [(set_attr "length" "3")
11952    (set_attr "atom_unit" "jeu")
11953    (set_attr "length_immediate" "2")
11954    (set_attr "modrm" "0")])
11956 (define_insn "simple_return_indirect_internal"
11957   [(simple_return)
11958    (use (match_operand:SI 0 "register_operand" "r"))]
11959   "reload_completed"
11960   "jmp\t%A0"
11961   [(set_attr "type" "ibr")
11962    (set_attr "length_immediate" "0")])
11964 (define_insn "nop"
11965   [(const_int 0)]
11966   ""
11967   "nop"
11968   [(set_attr "length" "1")
11969    (set_attr "length_immediate" "0")
11970    (set_attr "modrm" "0")])
11972 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
11973 (define_insn "nops"
11974   [(unspec_volatile [(match_operand 0 "const_int_operand")]
11975                     UNSPECV_NOPS)]
11976   "reload_completed"
11978   int num = INTVAL (operands[0]);
11980   gcc_assert (IN_RANGE (num, 1, 8));
11982   while (num--)
11983     fputs ("\tnop\n", asm_out_file);
11985   return "";
11987   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11988    (set_attr "length_immediate" "0")
11989    (set_attr "modrm" "0")])
11991 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11992 ;; branch prediction penalty for the third jump in a 16-byte
11993 ;; block on K8.
11995 (define_insn "pad"
11996   [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11997   ""
11999 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12000   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12001 #else
12002   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12003      The align insn is used to avoid 3 jump instructions in the row to improve
12004      branch prediction and the benefits hardly outweigh the cost of extra 8
12005      nops on the average inserted by full alignment pseudo operation.  */
12006 #endif
12007   return "";
12009   [(set_attr "length" "16")])
12011 (define_expand "prologue"
12012   [(const_int 0)]
12013   ""
12014   "ix86_expand_prologue (); DONE;")
12016 (define_insn "set_got"
12017   [(set (match_operand:SI 0 "register_operand" "=r")
12018         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12019    (clobber (reg:CC FLAGS_REG))]
12020   "!TARGET_64BIT"
12021   "* return output_set_got (operands[0], NULL_RTX);"
12022   [(set_attr "type" "multi")
12023    (set_attr "length" "12")])
12025 (define_insn "set_got_labelled"
12026   [(set (match_operand:SI 0 "register_operand" "=r")
12027         (unspec:SI [(label_ref (match_operand 1))]
12028          UNSPEC_SET_GOT))
12029    (clobber (reg:CC FLAGS_REG))]
12030   "!TARGET_64BIT"
12031   "* return output_set_got (operands[0], operands[1]);"
12032   [(set_attr "type" "multi")
12033    (set_attr "length" "12")])
12035 (define_insn "set_got_rex64"
12036   [(set (match_operand:DI 0 "register_operand" "=r")
12037         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12038   "TARGET_64BIT"
12039   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12040   [(set_attr "type" "lea")
12041    (set_attr "length_address" "4")
12042    (set_attr "mode" "DI")])
12044 (define_insn "set_rip_rex64"
12045   [(set (match_operand:DI 0 "register_operand" "=r")
12046         (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12047   "TARGET_64BIT"
12048   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12049   [(set_attr "type" "lea")
12050    (set_attr "length_address" "4")
12051    (set_attr "mode" "DI")])
12053 (define_insn "set_got_offset_rex64"
12054   [(set (match_operand:DI 0 "register_operand" "=r")
12055         (unspec:DI
12056           [(label_ref (match_operand 1))]
12057           UNSPEC_SET_GOT_OFFSET))]
12058   "TARGET_LP64"
12059   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12060   [(set_attr "type" "imov")
12061    (set_attr "length_immediate" "0")
12062    (set_attr "length_address" "8")
12063    (set_attr "mode" "DI")])
12065 (define_expand "epilogue"
12066   [(const_int 0)]
12067   ""
12068   "ix86_expand_epilogue (1); DONE;")
12070 (define_expand "sibcall_epilogue"
12071   [(const_int 0)]
12072   ""
12073   "ix86_expand_epilogue (0); DONE;")
12075 (define_expand "eh_return"
12076   [(use (match_operand 0 "register_operand"))]
12077   ""
12079   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12081   /* Tricky bit: we write the address of the handler to which we will
12082      be returning into someone else's stack frame, one word below the
12083      stack address we wish to restore.  */
12084   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12085   tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12086   tmp = gen_rtx_MEM (Pmode, tmp);
12087   emit_move_insn (tmp, ra);
12089   emit_jump_insn (gen_eh_return_internal ());
12090   emit_barrier ();
12091   DONE;
12094 (define_insn_and_split "eh_return_internal"
12095   [(eh_return)]
12096   ""
12097   "#"
12098   "epilogue_completed"
12099   [(const_int 0)]
12100   "ix86_expand_epilogue (2); DONE;")
12102 (define_insn "leave"
12103   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12104    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12105    (clobber (mem:BLK (scratch)))]
12106   "!TARGET_64BIT"
12107   "leave"
12108   [(set_attr "type" "leave")])
12110 (define_insn "leave_rex64"
12111   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12112    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12113    (clobber (mem:BLK (scratch)))]
12114   "TARGET_64BIT"
12115   "leave"
12116   [(set_attr "type" "leave")])
12118 ;; Handle -fsplit-stack.
12120 (define_expand "split_stack_prologue"
12121   [(const_int 0)]
12122   ""
12124   ix86_expand_split_stack_prologue ();
12125   DONE;
12128 ;; In order to support the call/return predictor, we use a return
12129 ;; instruction which the middle-end doesn't see.
12130 (define_insn "split_stack_return"
12131   [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12132                      UNSPECV_SPLIT_STACK_RETURN)]
12133   ""
12135   if (operands[0] == const0_rtx)
12136     return "ret";
12137   else
12138     return "ret\t%0";
12140   [(set_attr "atom_unit" "jeu")
12141    (set_attr "modrm" "0")
12142    (set (attr "length")
12143         (if_then_else (match_operand:SI 0 "const0_operand")
12144                       (const_int 1)
12145                       (const_int 3)))
12146    (set (attr "length_immediate")
12147         (if_then_else (match_operand:SI 0 "const0_operand")
12148                       (const_int 0)
12149                       (const_int 2)))])
12151 ;; If there are operand 0 bytes available on the stack, jump to
12152 ;; operand 1.
12154 (define_expand "split_stack_space_check"
12155   [(set (pc) (if_then_else
12156               (ltu (minus (reg SP_REG)
12157                           (match_operand 0 "register_operand"))
12158                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12159               (label_ref (match_operand 1))
12160               (pc)))]
12161   ""
12163   rtx reg, size, limit;
12165   reg = gen_reg_rtx (Pmode);
12166   size = force_reg (Pmode, operands[0]);
12167   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12168   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12169                           UNSPEC_STACK_CHECK);
12170   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12171   ix86_expand_branch (GEU, reg, limit, operands[1]);
12173   DONE;
12176 ;; Bit manipulation instructions.
12178 (define_expand "ffs<mode>2"
12179   [(set (match_dup 2) (const_int -1))
12180    (parallel [(set (match_dup 3) (match_dup 4))
12181               (set (match_operand:SWI48 0 "register_operand")
12182                    (ctz:SWI48
12183                      (match_operand:SWI48 1 "nonimmediate_operand")))])
12184    (set (match_dup 0) (if_then_else:SWI48
12185                         (eq (match_dup 3) (const_int 0))
12186                         (match_dup 2)
12187                         (match_dup 0)))
12188    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12189               (clobber (reg:CC FLAGS_REG))])]
12190   ""
12192   enum machine_mode flags_mode;
12194   if (<MODE>mode == SImode && !TARGET_CMOVE)
12195     {
12196       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12197       DONE;
12198     }
12200   flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12202   operands[2] = gen_reg_rtx (<MODE>mode);
12203   operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12204   operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12207 (define_insn_and_split "ffssi2_no_cmove"
12208   [(set (match_operand:SI 0 "register_operand" "=r")
12209         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12210    (clobber (match_scratch:SI 2 "=&q"))
12211    (clobber (reg:CC FLAGS_REG))]
12212   "!TARGET_CMOVE"
12213   "#"
12214   "&& reload_completed"
12215   [(parallel [(set (match_dup 4) (match_dup 5))
12216               (set (match_dup 0) (ctz:SI (match_dup 1)))])
12217    (set (strict_low_part (match_dup 3))
12218         (eq:QI (match_dup 4) (const_int 0)))
12219    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12220               (clobber (reg:CC FLAGS_REG))])
12221    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12222               (clobber (reg:CC FLAGS_REG))])
12223    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12224               (clobber (reg:CC FLAGS_REG))])]
12226   enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12228   operands[3] = gen_lowpart (QImode, operands[2]);
12229   operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12230   operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12232   ix86_expand_clear (operands[2]);
12235 (define_insn "*tzcnt<mode>_1"
12236   [(set (reg:CCC FLAGS_REG)
12237         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12238                      (const_int 0)))
12239    (set (match_operand:SWI48 0 "register_operand" "=r")
12240         (ctz:SWI48 (match_dup 1)))]
12241   "TARGET_BMI"
12242   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12243   [(set_attr "type" "alu1")
12244    (set_attr "prefix_0f" "1")
12245    (set_attr "prefix_rep" "1")
12246    (set_attr "btver2_decode" "double")
12247    (set_attr "mode" "<MODE>")])
12249 (define_insn "*bsf<mode>_1"
12250   [(set (reg:CCZ FLAGS_REG)
12251         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12252                      (const_int 0)))
12253    (set (match_operand:SWI48 0 "register_operand" "=r")
12254         (ctz:SWI48 (match_dup 1)))]
12255   ""
12256   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12257   [(set_attr "type" "alu1")
12258    (set_attr "prefix_0f" "1")
12259    (set_attr "btver2_decode" "double")
12260    (set_attr "mode" "<MODE>")])
12262 (define_insn "ctz<mode>2"
12263   [(set (match_operand:SWI248 0 "register_operand" "=r")
12264         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12265    (clobber (reg:CC FLAGS_REG))]
12266   ""
12268   if (TARGET_BMI)
12269     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12270   else if (optimize_function_for_size_p (cfun))
12271     ;
12272   else if (TARGET_GENERIC)
12273     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
12274     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12276   return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12278   [(set_attr "type" "alu1")
12279    (set_attr "prefix_0f" "1")
12280    (set (attr "prefix_rep")
12281      (if_then_else
12282        (ior (match_test "TARGET_BMI")
12283             (and (not (match_test "optimize_function_for_size_p (cfun)"))
12284                  (match_test "TARGET_GENERIC")))
12285        (const_string "1")
12286        (const_string "0")))
12287    (set_attr "mode" "<MODE>")])
12289 (define_expand "clz<mode>2"
12290   [(parallel
12291      [(set (match_operand:SWI248 0 "register_operand")
12292            (minus:SWI248
12293              (match_dup 2)
12294              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12295       (clobber (reg:CC FLAGS_REG))])
12296    (parallel
12297      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12298       (clobber (reg:CC FLAGS_REG))])]
12299   ""
12301   if (TARGET_LZCNT)
12302     {
12303       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12304       DONE;
12305     }
12306   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12309 (define_insn "clz<mode>2_lzcnt"
12310   [(set (match_operand:SWI248 0 "register_operand" "=r")
12311         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12312    (clobber (reg:CC FLAGS_REG))]
12313   "TARGET_LZCNT"
12314   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12315   [(set_attr "prefix_rep" "1")
12316    (set_attr "type" "bitmanip")
12317    (set_attr "mode" "<MODE>")])
12319 ;; BMI instructions.
12320 (define_insn "*bmi_andn_<mode>"
12321   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12322         (and:SWI48
12323           (not:SWI48
12324             (match_operand:SWI48 1 "register_operand" "r,r"))
12325             (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12326    (clobber (reg:CC FLAGS_REG))]
12327   "TARGET_BMI"
12328   "andn\t{%2, %1, %0|%0, %1, %2}"
12329   [(set_attr "type" "bitmanip")
12330    (set_attr "btver2_decode" "direct, double")
12331    (set_attr "mode" "<MODE>")])
12333 (define_insn "bmi_bextr_<mode>"
12334   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12335         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12336                        (match_operand:SWI48 2 "register_operand" "r,r")]
12337                        UNSPEC_BEXTR))
12338    (clobber (reg:CC FLAGS_REG))]
12339   "TARGET_BMI"
12340   "bextr\t{%2, %1, %0|%0, %1, %2}"
12341   [(set_attr "type" "bitmanip")
12342    (set_attr "btver2_decode" "direct, double")
12343    (set_attr "mode" "<MODE>")])
12345 (define_insn "*bmi_blsi_<mode>"
12346   [(set (match_operand:SWI48 0 "register_operand" "=r")
12347         (and:SWI48
12348           (neg:SWI48
12349             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12350           (match_dup 1)))
12351    (clobber (reg:CC FLAGS_REG))]
12352   "TARGET_BMI"
12353   "blsi\t{%1, %0|%0, %1}"
12354   [(set_attr "type" "bitmanip")
12355    (set_attr "btver2_decode" "double")
12356    (set_attr "mode" "<MODE>")])
12358 (define_insn "*bmi_blsmsk_<mode>"
12359   [(set (match_operand:SWI48 0 "register_operand" "=r")
12360         (xor:SWI48
12361           (plus:SWI48
12362             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12363             (const_int -1))
12364           (match_dup 1)))
12365    (clobber (reg:CC FLAGS_REG))]
12366   "TARGET_BMI"
12367   "blsmsk\t{%1, %0|%0, %1}"
12368   [(set_attr "type" "bitmanip")
12369    (set_attr "btver2_decode" "double")
12370    (set_attr "mode" "<MODE>")])
12372 (define_insn "*bmi_blsr_<mode>"
12373   [(set (match_operand:SWI48 0 "register_operand" "=r")
12374         (and:SWI48
12375           (plus:SWI48
12376             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12377             (const_int -1))
12378           (match_dup 1)))
12379    (clobber (reg:CC FLAGS_REG))]
12380    "TARGET_BMI"
12381    "blsr\t{%1, %0|%0, %1}"
12382   [(set_attr "type" "bitmanip")
12383    (set_attr "btver2_decode" "double")
12384    (set_attr "mode" "<MODE>")])
12386 ;; BMI2 instructions.
12387 (define_insn "bmi2_bzhi_<mode>3"
12388   [(set (match_operand:SWI48 0 "register_operand" "=r")
12389         (and:SWI48 (lshiftrt:SWI48 (const_int -1)
12390                                    (match_operand:SWI48 2 "register_operand" "r"))
12391                    (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12392    (clobber (reg:CC FLAGS_REG))]
12393   "TARGET_BMI2"
12394   "bzhi\t{%2, %1, %0|%0, %1, %2}"
12395   [(set_attr "type" "bitmanip")
12396    (set_attr "prefix" "vex")
12397    (set_attr "mode" "<MODE>")])
12399 (define_insn "bmi2_pdep_<mode>3"
12400   [(set (match_operand:SWI48 0 "register_operand" "=r")
12401         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12402                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12403                        UNSPEC_PDEP))]
12404   "TARGET_BMI2"
12405   "pdep\t{%2, %1, %0|%0, %1, %2}"
12406   [(set_attr "type" "bitmanip")
12407    (set_attr "prefix" "vex")
12408    (set_attr "mode" "<MODE>")])
12410 (define_insn "bmi2_pext_<mode>3"
12411   [(set (match_operand:SWI48 0 "register_operand" "=r")
12412         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12413                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12414                        UNSPEC_PEXT))]
12415   "TARGET_BMI2"
12416   "pext\t{%2, %1, %0|%0, %1, %2}"
12417   [(set_attr "type" "bitmanip")
12418    (set_attr "prefix" "vex")
12419    (set_attr "mode" "<MODE>")])
12421 ;; TBM instructions.
12422 (define_insn "tbm_bextri_<mode>"
12423   [(set (match_operand:SWI48 0 "register_operand" "=r")
12424         (zero_extract:SWI48
12425           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12426           (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12427           (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12428    (clobber (reg:CC FLAGS_REG))]
12429    "TARGET_TBM"
12431   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12432   return "bextr\t{%2, %1, %0|%0, %1, %2}";
12434   [(set_attr "type" "bitmanip")
12435    (set_attr "mode" "<MODE>")])
12437 (define_insn "*tbm_blcfill_<mode>"
12438   [(set (match_operand:SWI48 0 "register_operand" "=r")
12439         (and:SWI48
12440           (plus:SWI48
12441             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12442             (const_int 1))
12443           (match_dup 1)))
12444    (clobber (reg:CC FLAGS_REG))]
12445    "TARGET_TBM"
12446    "blcfill\t{%1, %0|%0, %1}"
12447   [(set_attr "type" "bitmanip")
12448    (set_attr "mode" "<MODE>")])
12450 (define_insn "*tbm_blci_<mode>"
12451   [(set (match_operand:SWI48 0 "register_operand" "=r")
12452         (ior:SWI48
12453           (not:SWI48
12454             (plus:SWI48
12455               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12456               (const_int 1)))
12457           (match_dup 1)))
12458    (clobber (reg:CC FLAGS_REG))]
12459    "TARGET_TBM"
12460    "blci\t{%1, %0|%0, %1}"
12461   [(set_attr "type" "bitmanip")
12462    (set_attr "mode" "<MODE>")])
12464 (define_insn "*tbm_blcic_<mode>"
12465   [(set (match_operand:SWI48 0 "register_operand" "=r")
12466         (and:SWI48
12467           (plus:SWI48
12468             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12469             (const_int 1))
12470           (not:SWI48
12471             (match_dup 1))))
12472    (clobber (reg:CC FLAGS_REG))]
12473    "TARGET_TBM"
12474    "blcic\t{%1, %0|%0, %1}"
12475   [(set_attr "type" "bitmanip")
12476    (set_attr "mode" "<MODE>")])
12478 (define_insn "*tbm_blcmsk_<mode>"
12479   [(set (match_operand:SWI48 0 "register_operand" "=r")
12480         (xor:SWI48
12481           (plus:SWI48
12482             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12483             (const_int 1))
12484           (match_dup 1)))
12485    (clobber (reg:CC FLAGS_REG))]
12486    "TARGET_TBM"
12487    "blcmsk\t{%1, %0|%0, %1}"
12488   [(set_attr "type" "bitmanip")
12489    (set_attr "mode" "<MODE>")])
12491 (define_insn "*tbm_blcs_<mode>"
12492   [(set (match_operand:SWI48 0 "register_operand" "=r")
12493         (ior:SWI48
12494           (plus:SWI48
12495             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12496             (const_int 1))
12497           (match_dup 1)))
12498    (clobber (reg:CC FLAGS_REG))]
12499    "TARGET_TBM"
12500    "blcs\t{%1, %0|%0, %1}"
12501   [(set_attr "type" "bitmanip")
12502    (set_attr "mode" "<MODE>")])
12504 (define_insn "*tbm_blsfill_<mode>"
12505   [(set (match_operand:SWI48 0 "register_operand" "=r")
12506         (ior:SWI48
12507           (plus:SWI48
12508             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12509             (const_int -1))
12510           (match_dup 1)))
12511    (clobber (reg:CC FLAGS_REG))]
12512    "TARGET_TBM"
12513    "blsfill\t{%1, %0|%0, %1}"
12514   [(set_attr "type" "bitmanip")
12515    (set_attr "mode" "<MODE>")])
12517 (define_insn "*tbm_blsic_<mode>"
12518   [(set (match_operand:SWI48 0 "register_operand" "=r")
12519         (ior:SWI48
12520           (plus:SWI48
12521             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12522             (const_int -1))
12523           (not:SWI48
12524             (match_dup 1))))
12525    (clobber (reg:CC FLAGS_REG))]
12526    "TARGET_TBM"
12527    "blsic\t{%1, %0|%0, %1}"
12528   [(set_attr "type" "bitmanip")
12529    (set_attr "mode" "<MODE>")])
12531 (define_insn "*tbm_t1mskc_<mode>"
12532   [(set (match_operand:SWI48 0 "register_operand" "=r")
12533         (ior:SWI48
12534           (plus:SWI48
12535             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12536             (const_int 1))
12537           (not:SWI48
12538             (match_dup 1))))
12539    (clobber (reg:CC FLAGS_REG))]
12540    "TARGET_TBM"
12541    "t1mskc\t{%1, %0|%0, %1}"
12542   [(set_attr "type" "bitmanip")
12543    (set_attr "mode" "<MODE>")])
12545 (define_insn "*tbm_tzmsk_<mode>"
12546   [(set (match_operand:SWI48 0 "register_operand" "=r")
12547         (and:SWI48
12548           (plus:SWI48
12549             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12550             (const_int -1))
12551           (not:SWI48
12552             (match_dup 1))))
12553    (clobber (reg:CC FLAGS_REG))]
12554    "TARGET_TBM"
12555    "tzmsk\t{%1, %0|%0, %1}"
12556   [(set_attr "type" "bitmanip")
12557    (set_attr "mode" "<MODE>")])
12559 (define_insn "bsr_rex64"
12560   [(set (match_operand:DI 0 "register_operand" "=r")
12561         (minus:DI (const_int 63)
12562                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12563    (clobber (reg:CC FLAGS_REG))]
12564   "TARGET_64BIT"
12565   "bsr{q}\t{%1, %0|%0, %1}"
12566   [(set_attr "type" "alu1")
12567    (set_attr "prefix_0f" "1")
12568    (set_attr "mode" "DI")])
12570 (define_insn "bsr"
12571   [(set (match_operand:SI 0 "register_operand" "=r")
12572         (minus:SI (const_int 31)
12573                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12574    (clobber (reg:CC FLAGS_REG))]
12575   ""
12576   "bsr{l}\t{%1, %0|%0, %1}"
12577   [(set_attr "type" "alu1")
12578    (set_attr "prefix_0f" "1")
12579    (set_attr "mode" "SI")])
12581 (define_insn "*bsrhi"
12582   [(set (match_operand:HI 0 "register_operand" "=r")
12583         (minus:HI (const_int 15)
12584                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12585    (clobber (reg:CC FLAGS_REG))]
12586   ""
12587   "bsr{w}\t{%1, %0|%0, %1}"
12588   [(set_attr "type" "alu1")
12589    (set_attr "prefix_0f" "1")
12590    (set_attr "mode" "HI")])
12592 (define_insn "popcount<mode>2"
12593   [(set (match_operand:SWI248 0 "register_operand" "=r")
12594         (popcount:SWI248
12595           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12596    (clobber (reg:CC FLAGS_REG))]
12597   "TARGET_POPCNT"
12599 #if TARGET_MACHO
12600   return "popcnt\t{%1, %0|%0, %1}";
12601 #else
12602   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12603 #endif
12605   [(set_attr "prefix_rep" "1")
12606    (set_attr "type" "bitmanip")
12607    (set_attr "mode" "<MODE>")])
12609 (define_insn "*popcount<mode>2_cmp"
12610   [(set (reg FLAGS_REG)
12611         (compare
12612           (popcount:SWI248
12613             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12614           (const_int 0)))
12615    (set (match_operand:SWI248 0 "register_operand" "=r")
12616         (popcount:SWI248 (match_dup 1)))]
12617   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12619 #if TARGET_MACHO
12620   return "popcnt\t{%1, %0|%0, %1}";
12621 #else
12622   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12623 #endif
12625   [(set_attr "prefix_rep" "1")
12626    (set_attr "type" "bitmanip")
12627    (set_attr "mode" "<MODE>")])
12629 (define_insn "*popcountsi2_cmp_zext"
12630   [(set (reg FLAGS_REG)
12631         (compare
12632           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12633           (const_int 0)))
12634    (set (match_operand:DI 0 "register_operand" "=r")
12635         (zero_extend:DI(popcount:SI (match_dup 1))))]
12636   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12638 #if TARGET_MACHO
12639   return "popcnt\t{%1, %0|%0, %1}";
12640 #else
12641   return "popcnt{l}\t{%1, %0|%0, %1}";
12642 #endif
12644   [(set_attr "prefix_rep" "1")
12645    (set_attr "type" "bitmanip")
12646    (set_attr "mode" "SI")])
12648 (define_expand "bswapdi2"
12649   [(set (match_operand:DI 0 "register_operand")
12650         (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12651   "TARGET_64BIT"
12653   if (!TARGET_MOVBE)
12654     operands[1] = force_reg (DImode, operands[1]);
12657 (define_expand "bswapsi2"
12658   [(set (match_operand:SI 0 "register_operand")
12659         (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12660   ""
12662   if (TARGET_MOVBE)
12663     ;
12664   else if (TARGET_BSWAP)
12665     operands[1] = force_reg (SImode, operands[1]);
12666   else
12667     {
12668       rtx x = operands[0];
12670       emit_move_insn (x, operands[1]);
12671       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12672       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12673       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12674       DONE;
12675     }
12678 (define_insn "*bswap<mode>2_movbe"
12679   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12680         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12681   "TARGET_MOVBE
12682    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12683   "@
12684     bswap\t%0
12685     movbe\t{%1, %0|%0, %1}
12686     movbe\t{%1, %0|%0, %1}"
12687   [(set_attr "type" "bitmanip,imov,imov")
12688    (set_attr "modrm" "0,1,1")
12689    (set_attr "prefix_0f" "*,1,1")
12690    (set_attr "prefix_extra" "*,1,1")
12691    (set_attr "mode" "<MODE>")])
12693 (define_insn "*bswap<mode>2"
12694   [(set (match_operand:SWI48 0 "register_operand" "=r")
12695         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12696   "TARGET_BSWAP"
12697   "bswap\t%0"
12698   [(set_attr "type" "bitmanip")
12699    (set_attr "modrm" "0")
12700    (set_attr "mode" "<MODE>")])
12702 (define_insn "*bswaphi_lowpart_1"
12703   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12704         (bswap:HI (match_dup 0)))
12705    (clobber (reg:CC FLAGS_REG))]
12706   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12707   "@
12708     xchg{b}\t{%h0, %b0|%b0, %h0}
12709     rol{w}\t{$8, %0|%0, 8}"
12710   [(set_attr "length" "2,4")
12711    (set_attr "mode" "QI,HI")])
12713 (define_insn "bswaphi_lowpart"
12714   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12715         (bswap:HI (match_dup 0)))
12716    (clobber (reg:CC FLAGS_REG))]
12717   ""
12718   "rol{w}\t{$8, %0|%0, 8}"
12719   [(set_attr "length" "4")
12720    (set_attr "mode" "HI")])
12722 (define_expand "paritydi2"
12723   [(set (match_operand:DI 0 "register_operand")
12724         (parity:DI (match_operand:DI 1 "register_operand")))]
12725   "! TARGET_POPCNT"
12727   rtx scratch = gen_reg_rtx (QImode);
12728   rtx cond;
12730   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12731                                 NULL_RTX, operands[1]));
12733   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12734                          gen_rtx_REG (CCmode, FLAGS_REG),
12735                          const0_rtx);
12736   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12738   if (TARGET_64BIT)
12739     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12740   else
12741     {
12742       rtx tmp = gen_reg_rtx (SImode);
12744       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12745       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12746     }
12747   DONE;
12750 (define_expand "paritysi2"
12751   [(set (match_operand:SI 0 "register_operand")
12752         (parity:SI (match_operand:SI 1 "register_operand")))]
12753   "! TARGET_POPCNT"
12755   rtx scratch = gen_reg_rtx (QImode);
12756   rtx cond;
12758   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12760   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12761                          gen_rtx_REG (CCmode, FLAGS_REG),
12762                          const0_rtx);
12763   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12765   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12766   DONE;
12769 (define_insn_and_split "paritydi2_cmp"
12770   [(set (reg:CC FLAGS_REG)
12771         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12772                    UNSPEC_PARITY))
12773    (clobber (match_scratch:DI 0 "=r"))
12774    (clobber (match_scratch:SI 1 "=&r"))
12775    (clobber (match_scratch:HI 2 "=Q"))]
12776   "! TARGET_POPCNT"
12777   "#"
12778   "&& reload_completed"
12779   [(parallel
12780      [(set (match_dup 1)
12781            (xor:SI (match_dup 1) (match_dup 4)))
12782       (clobber (reg:CC FLAGS_REG))])
12783    (parallel
12784      [(set (reg:CC FLAGS_REG)
12785            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12786       (clobber (match_dup 1))
12787       (clobber (match_dup 2))])]
12789   operands[4] = gen_lowpart (SImode, operands[3]);
12791   if (TARGET_64BIT)
12792     {
12793       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12794       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12795     }
12796   else
12797     operands[1] = gen_highpart (SImode, operands[3]);
12800 (define_insn_and_split "paritysi2_cmp"
12801   [(set (reg:CC FLAGS_REG)
12802         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12803                    UNSPEC_PARITY))
12804    (clobber (match_scratch:SI 0 "=r"))
12805    (clobber (match_scratch:HI 1 "=&Q"))]
12806   "! TARGET_POPCNT"
12807   "#"
12808   "&& reload_completed"
12809   [(parallel
12810      [(set (match_dup 1)
12811            (xor:HI (match_dup 1) (match_dup 3)))
12812       (clobber (reg:CC FLAGS_REG))])
12813    (parallel
12814      [(set (reg:CC FLAGS_REG)
12815            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12816       (clobber (match_dup 1))])]
12818   operands[3] = gen_lowpart (HImode, operands[2]);
12820   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12821   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12824 (define_insn "*parityhi2_cmp"
12825   [(set (reg:CC FLAGS_REG)
12826         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12827                    UNSPEC_PARITY))
12828    (clobber (match_scratch:HI 0 "=Q"))]
12829   "! TARGET_POPCNT"
12830   "xor{b}\t{%h0, %b0|%b0, %h0}"
12831   [(set_attr "length" "2")
12832    (set_attr "mode" "HI")])
12835 ;; Thread-local storage patterns for ELF.
12837 ;; Note that these code sequences must appear exactly as shown
12838 ;; in order to allow linker relaxation.
12840 (define_insn "*tls_global_dynamic_32_gnu"
12841   [(set (match_operand:SI 0 "register_operand" "=a")
12842         (unspec:SI
12843          [(match_operand:SI 1 "register_operand" "b")
12844           (match_operand 2 "tls_symbolic_operand")
12845           (match_operand 3 "constant_call_address_operand" "Bz")
12846           (reg:SI SP_REG)]
12847          UNSPEC_TLS_GD))
12848    (clobber (match_scratch:SI 4 "=d"))
12849    (clobber (match_scratch:SI 5 "=c"))
12850    (clobber (reg:CC FLAGS_REG))]
12851   "!TARGET_64BIT && TARGET_GNU_TLS"
12853   output_asm_insn
12854     ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12855   if (TARGET_SUN_TLS)
12856 #ifdef HAVE_AS_IX86_TLSGDPLT
12857     return "call\t%a2@tlsgdplt";
12858 #else
12859     return "call\t%p3@plt";
12860 #endif
12861   return "call\t%P3";
12863   [(set_attr "type" "multi")
12864    (set_attr "length" "12")])
12866 (define_expand "tls_global_dynamic_32"
12867   [(parallel
12868     [(set (match_operand:SI 0 "register_operand")
12869           (unspec:SI [(match_operand:SI 2 "register_operand")
12870                       (match_operand 1 "tls_symbolic_operand")
12871                       (match_operand 3 "constant_call_address_operand")
12872                       (reg:SI SP_REG)]
12873                      UNSPEC_TLS_GD))
12874      (clobber (match_scratch:SI 4))
12875      (clobber (match_scratch:SI 5))
12876      (clobber (reg:CC FLAGS_REG))])]
12877   ""
12878   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
12880 (define_insn "*tls_global_dynamic_64_<mode>"
12881   [(set (match_operand:P 0 "register_operand" "=a")
12882         (call:P
12883          (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
12884          (match_operand 3)))
12885    (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12886              UNSPEC_TLS_GD)]
12887   "TARGET_64BIT"
12889   if (!TARGET_X32)
12890     fputs (ASM_BYTE "0x66\n", asm_out_file);
12891   output_asm_insn
12892     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12893   fputs (ASM_SHORT "0x6666\n", asm_out_file);
12894   fputs ("\trex64\n", asm_out_file);
12895   if (TARGET_SUN_TLS)
12896     return "call\t%p2@plt";
12897   return "call\t%P2";
12899   [(set_attr "type" "multi")
12900    (set (attr "length")
12901         (symbol_ref "TARGET_X32 ? 15 : 16"))])
12903 (define_insn "*tls_global_dynamic_64_largepic"
12904   [(set (match_operand:DI 0 "register_operand" "=a")
12905         (call:DI
12906          (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
12907                           (match_operand:DI 3 "immediate_operand" "i")))
12908          (match_operand 4)))
12909    (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12910              UNSPEC_TLS_GD)]
12911   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
12912    && GET_CODE (operands[3]) == CONST
12913    && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
12914    && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
12916   output_asm_insn
12917     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12918   output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
12919   output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
12920   return "call\t{*%%rax|rax}";
12922   [(set_attr "type" "multi")
12923    (set_attr "length" "22")])
12925 (define_expand "tls_global_dynamic_64_<mode>"
12926   [(parallel
12927     [(set (match_operand:P 0 "register_operand")
12928           (call:P
12929            (mem:QI (match_operand 2))
12930            (const_int 0)))
12931      (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12932                UNSPEC_TLS_GD)])]
12933   "TARGET_64BIT"
12934   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
12936 (define_insn "*tls_local_dynamic_base_32_gnu"
12937   [(set (match_operand:SI 0 "register_operand" "=a")
12938         (unspec:SI
12939          [(match_operand:SI 1 "register_operand" "b")
12940           (match_operand 2 "constant_call_address_operand" "Bz")
12941           (reg:SI SP_REG)]
12942          UNSPEC_TLS_LD_BASE))
12943    (clobber (match_scratch:SI 3 "=d"))
12944    (clobber (match_scratch:SI 4 "=c"))
12945    (clobber (reg:CC FLAGS_REG))]
12946   "!TARGET_64BIT && TARGET_GNU_TLS"
12948   output_asm_insn
12949     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12950   if (TARGET_SUN_TLS)
12951     {
12952       if (HAVE_AS_IX86_TLSLDMPLT)
12953         return "call\t%&@tlsldmplt";
12954       else
12955         return "call\t%p2@plt";
12956     }
12957   return "call\t%P2";
12959   [(set_attr "type" "multi")
12960    (set_attr "length" "11")])
12962 (define_expand "tls_local_dynamic_base_32"
12963   [(parallel
12964      [(set (match_operand:SI 0 "register_operand")
12965            (unspec:SI
12966             [(match_operand:SI 1 "register_operand")
12967              (match_operand 2 "constant_call_address_operand")
12968              (reg:SI SP_REG)]
12969             UNSPEC_TLS_LD_BASE))
12970       (clobber (match_scratch:SI 3))
12971       (clobber (match_scratch:SI 4))
12972       (clobber (reg:CC FLAGS_REG))])]
12973   ""
12974   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
12976 (define_insn "*tls_local_dynamic_base_64_<mode>"
12977   [(set (match_operand:P 0 "register_operand" "=a")
12978         (call:P
12979          (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
12980          (match_operand 2)))
12981    (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12982   "TARGET_64BIT"
12984   output_asm_insn
12985     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12986   if (TARGET_SUN_TLS)
12987     return "call\t%p1@plt";
12988   return "call\t%P1";
12990   [(set_attr "type" "multi")
12991    (set_attr "length" "12")])
12993 (define_insn "*tls_local_dynamic_base_64_largepic"
12994   [(set (match_operand:DI 0 "register_operand" "=a")
12995         (call:DI
12996          (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
12997                           (match_operand:DI 2 "immediate_operand" "i")))
12998          (match_operand 3)))
12999    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13000   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13001    && GET_CODE (operands[2]) == CONST
13002    && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13003    && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13005   output_asm_insn
13006     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13007   output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13008   output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13009   return "call\t{*%%rax|rax}";
13011   [(set_attr "type" "multi")
13012    (set_attr "length" "22")])
13014 (define_expand "tls_local_dynamic_base_64_<mode>"
13015   [(parallel
13016      [(set (match_operand:P 0 "register_operand")
13017            (call:P
13018             (mem:QI (match_operand 1))
13019             (const_int 0)))
13020       (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13021   "TARGET_64BIT"
13022   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13024 ;; Local dynamic of a single variable is a lose.  Show combine how
13025 ;; to convert that back to global dynamic.
13027 (define_insn_and_split "*tls_local_dynamic_32_once"
13028   [(set (match_operand:SI 0 "register_operand" "=a")
13029         (plus:SI
13030          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13031                      (match_operand 2 "constant_call_address_operand" "Bz")
13032                      (reg:SI SP_REG)]
13033                     UNSPEC_TLS_LD_BASE)
13034          (const:SI (unspec:SI
13035                     [(match_operand 3 "tls_symbolic_operand")]
13036                     UNSPEC_DTPOFF))))
13037    (clobber (match_scratch:SI 4 "=d"))
13038    (clobber (match_scratch:SI 5 "=c"))
13039    (clobber (reg:CC FLAGS_REG))]
13040   ""
13041   "#"
13042   ""
13043   [(parallel
13044      [(set (match_dup 0)
13045            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13046                        (reg:SI SP_REG)]
13047                       UNSPEC_TLS_GD))
13048       (clobber (match_dup 4))
13049       (clobber (match_dup 5))
13050       (clobber (reg:CC FLAGS_REG))])])
13052 ;; Segment register for the thread base ptr load
13053 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13055 ;; Load and add the thread base pointer from %<tp_seg>:0.
13056 (define_insn "*load_tp_x32"
13057   [(set (match_operand:SI 0 "register_operand" "=r")
13058         (unspec:SI [(const_int 0)] UNSPEC_TP))]
13059   "TARGET_X32"
13060   "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13061   [(set_attr "type" "imov")
13062    (set_attr "modrm" "0")
13063    (set_attr "length" "7")
13064    (set_attr "memory" "load")
13065    (set_attr "imm_disp" "false")])
13067 (define_insn "*load_tp_x32_zext"
13068   [(set (match_operand:DI 0 "register_operand" "=r")
13069         (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13070   "TARGET_X32"
13071   "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13072   [(set_attr "type" "imov")
13073    (set_attr "modrm" "0")
13074    (set_attr "length" "7")
13075    (set_attr "memory" "load")
13076    (set_attr "imm_disp" "false")])
13078 (define_insn "*load_tp_<mode>"
13079   [(set (match_operand:P 0 "register_operand" "=r")
13080         (unspec:P [(const_int 0)] UNSPEC_TP))]
13081   "!TARGET_X32"
13082   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13083   [(set_attr "type" "imov")
13084    (set_attr "modrm" "0")
13085    (set_attr "length" "7")
13086    (set_attr "memory" "load")
13087    (set_attr "imm_disp" "false")])
13089 (define_insn "*add_tp_x32"
13090   [(set (match_operand:SI 0 "register_operand" "=r")
13091         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13092                  (match_operand:SI 1 "register_operand" "0")))
13093    (clobber (reg:CC FLAGS_REG))]
13094   "TARGET_X32"
13095   "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13096   [(set_attr "type" "alu")
13097    (set_attr "modrm" "0")
13098    (set_attr "length" "7")
13099    (set_attr "memory" "load")
13100    (set_attr "imm_disp" "false")])
13102 (define_insn "*add_tp_x32_zext"
13103   [(set (match_operand:DI 0 "register_operand" "=r")
13104         (zero_extend:DI
13105           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13106                    (match_operand:SI 1 "register_operand" "0"))))
13107    (clobber (reg:CC FLAGS_REG))]
13108   "TARGET_X32"
13109   "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13110   [(set_attr "type" "alu")
13111    (set_attr "modrm" "0")
13112    (set_attr "length" "7")
13113    (set_attr "memory" "load")
13114    (set_attr "imm_disp" "false")])
13116 (define_insn "*add_tp_<mode>"
13117   [(set (match_operand:P 0 "register_operand" "=r")
13118         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13119                 (match_operand:P 1 "register_operand" "0")))
13120    (clobber (reg:CC FLAGS_REG))]
13121   "!TARGET_X32"
13122   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13123   [(set_attr "type" "alu")
13124    (set_attr "modrm" "0")
13125    (set_attr "length" "7")
13126    (set_attr "memory" "load")
13127    (set_attr "imm_disp" "false")])
13129 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13130 ;; %rax as destination of the initial executable code sequence.
13131 (define_insn "tls_initial_exec_64_sun"
13132   [(set (match_operand:DI 0 "register_operand" "=a")
13133         (unspec:DI
13134          [(match_operand 1 "tls_symbolic_operand")]
13135          UNSPEC_TLS_IE_SUN))
13136    (clobber (reg:CC FLAGS_REG))]
13137   "TARGET_64BIT && TARGET_SUN_TLS"
13139   output_asm_insn
13140     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13141   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13143   [(set_attr "type" "multi")])
13145 ;; GNU2 TLS patterns can be split.
13147 (define_expand "tls_dynamic_gnu2_32"
13148   [(set (match_dup 3)
13149         (plus:SI (match_operand:SI 2 "register_operand")
13150                  (const:SI
13151                   (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13152                              UNSPEC_TLSDESC))))
13153    (parallel
13154     [(set (match_operand:SI 0 "register_operand")
13155           (unspec:SI [(match_dup 1) (match_dup 3)
13156                       (match_dup 2) (reg:SI SP_REG)]
13157                       UNSPEC_TLSDESC))
13158      (clobber (reg:CC FLAGS_REG))])]
13159   "!TARGET_64BIT && TARGET_GNU2_TLS"
13161   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13162   ix86_tls_descriptor_calls_expanded_in_cfun = true;
13165 (define_insn "*tls_dynamic_gnu2_lea_32"
13166   [(set (match_operand:SI 0 "register_operand" "=r")
13167         (plus:SI (match_operand:SI 1 "register_operand" "b")
13168                  (const:SI
13169                   (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13170                               UNSPEC_TLSDESC))))]
13171   "!TARGET_64BIT && TARGET_GNU2_TLS"
13172   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13173   [(set_attr "type" "lea")
13174    (set_attr "mode" "SI")
13175    (set_attr "length" "6")
13176    (set_attr "length_address" "4")])
13178 (define_insn "*tls_dynamic_gnu2_call_32"
13179   [(set (match_operand:SI 0 "register_operand" "=a")
13180         (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13181                     (match_operand:SI 2 "register_operand" "0")
13182                     ;; we have to make sure %ebx still points to the GOT
13183                     (match_operand:SI 3 "register_operand" "b")
13184                     (reg:SI SP_REG)]
13185                    UNSPEC_TLSDESC))
13186    (clobber (reg:CC FLAGS_REG))]
13187   "!TARGET_64BIT && TARGET_GNU2_TLS"
13188   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13189   [(set_attr "type" "call")
13190    (set_attr "length" "2")
13191    (set_attr "length_address" "0")])
13193 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13194   [(set (match_operand:SI 0 "register_operand" "=&a")
13195         (plus:SI
13196          (unspec:SI [(match_operand 3 "tls_modbase_operand")
13197                      (match_operand:SI 4)
13198                      (match_operand:SI 2 "register_operand" "b")
13199                      (reg:SI SP_REG)]
13200                     UNSPEC_TLSDESC)
13201          (const:SI (unspec:SI
13202                     [(match_operand 1 "tls_symbolic_operand")]
13203                     UNSPEC_DTPOFF))))
13204    (clobber (reg:CC FLAGS_REG))]
13205   "!TARGET_64BIT && TARGET_GNU2_TLS"
13206   "#"
13207   ""
13208   [(set (match_dup 0) (match_dup 5))]
13210   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13211   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13214 (define_expand "tls_dynamic_gnu2_64"
13215   [(set (match_dup 2)
13216         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13217                    UNSPEC_TLSDESC))
13218    (parallel
13219     [(set (match_operand:DI 0 "register_operand")
13220           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13221                      UNSPEC_TLSDESC))
13222      (clobber (reg:CC FLAGS_REG))])]
13223   "TARGET_64BIT && TARGET_GNU2_TLS"
13225   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13226   ix86_tls_descriptor_calls_expanded_in_cfun = true;
13229 (define_insn "*tls_dynamic_gnu2_lea_64"
13230   [(set (match_operand:DI 0 "register_operand" "=r")
13231         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13232                    UNSPEC_TLSDESC))]
13233   "TARGET_64BIT && TARGET_GNU2_TLS"
13234   "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13235   [(set_attr "type" "lea")
13236    (set_attr "mode" "DI")
13237    (set_attr "length" "7")
13238    (set_attr "length_address" "4")])
13240 (define_insn "*tls_dynamic_gnu2_call_64"
13241   [(set (match_operand:DI 0 "register_operand" "=a")
13242         (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13243                     (match_operand:DI 2 "register_operand" "0")
13244                     (reg:DI SP_REG)]
13245                    UNSPEC_TLSDESC))
13246    (clobber (reg:CC FLAGS_REG))]
13247   "TARGET_64BIT && TARGET_GNU2_TLS"
13248   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13249   [(set_attr "type" "call")
13250    (set_attr "length" "2")
13251    (set_attr "length_address" "0")])
13253 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13254   [(set (match_operand:DI 0 "register_operand" "=&a")
13255         (plus:DI
13256          (unspec:DI [(match_operand 2 "tls_modbase_operand")
13257                      (match_operand:DI 3)
13258                      (reg:DI SP_REG)]
13259                     UNSPEC_TLSDESC)
13260          (const:DI (unspec:DI
13261                     [(match_operand 1 "tls_symbolic_operand")]
13262                     UNSPEC_DTPOFF))))
13263    (clobber (reg:CC FLAGS_REG))]
13264   "TARGET_64BIT && TARGET_GNU2_TLS"
13265   "#"
13266   ""
13267   [(set (match_dup 0) (match_dup 4))]
13269   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13270   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13273 ;; These patterns match the binary 387 instructions for addM3, subM3,
13274 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
13275 ;; SFmode.  The first is the normal insn, the second the same insn but
13276 ;; with one operand a conversion, and the third the same insn but with
13277 ;; the other operand a conversion.  The conversion may be SFmode or
13278 ;; SImode if the target mode DFmode, but only SImode if the target mode
13279 ;; is SFmode.
13281 ;; Gcc is slightly more smart about handling normal two address instructions
13282 ;; so use special patterns for add and mull.
13284 (define_insn "*fop_<mode>_comm_mixed"
13285   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13286         (match_operator:MODEF 3 "binary_fp_operator"
13287           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13288            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13289   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13290    && COMMUTATIVE_ARITH_P (operands[3])
13291    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13292   "* return output_387_binary_op (insn, operands);"
13293   [(set (attr "type")
13294         (if_then_else (eq_attr "alternative" "1,2")
13295            (if_then_else (match_operand:MODEF 3 "mult_operator")
13296               (const_string "ssemul")
13297               (const_string "sseadd"))
13298            (if_then_else (match_operand:MODEF 3 "mult_operator")
13299               (const_string "fmul")
13300               (const_string "fop"))))
13301    (set_attr "isa" "*,noavx,avx")
13302    (set_attr "prefix" "orig,orig,vex")
13303    (set_attr "mode" "<MODE>")])
13305 (define_insn "*fop_<mode>_comm_sse"
13306   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
13307         (match_operator:MODEF 3 "binary_fp_operator"
13308           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
13309            (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]))]
13310   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13311    && COMMUTATIVE_ARITH_P (operands[3])
13312    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13313   "* return output_387_binary_op (insn, operands);"
13314   [(set (attr "type")
13315         (if_then_else (match_operand:MODEF 3 "mult_operator")
13316            (const_string "ssemul")
13317            (const_string "sseadd")))
13318    (set_attr "isa" "noavx,avx")
13319    (set_attr "prefix" "orig,vex")
13320    (set_attr "mode" "<MODE>")])
13322 (define_insn "*fop_<mode>_comm_i387"
13323   [(set (match_operand:MODEF 0 "register_operand" "=f")
13324         (match_operator:MODEF 3 "binary_fp_operator"
13325           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13326            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13327   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13328    && COMMUTATIVE_ARITH_P (operands[3])
13329    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13330   "* return output_387_binary_op (insn, operands);"
13331   [(set (attr "type")
13332         (if_then_else (match_operand:MODEF 3 "mult_operator")
13333            (const_string "fmul")
13334            (const_string "fop")))
13335    (set_attr "mode" "<MODE>")])
13337 (define_insn "*fop_<mode>_1_mixed"
13338   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13339         (match_operator:MODEF 3 "binary_fp_operator"
13340           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13341            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13342   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13343    && !COMMUTATIVE_ARITH_P (operands[3])
13344    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13345   "* return output_387_binary_op (insn, operands);"
13346   [(set (attr "type")
13347         (cond [(and (eq_attr "alternative" "2,3")
13348                     (match_operand:MODEF 3 "mult_operator"))
13349                  (const_string "ssemul")
13350                (and (eq_attr "alternative" "2,3")
13351                     (match_operand:MODEF 3 "div_operator"))
13352                  (const_string "ssediv")
13353                (eq_attr "alternative" "2,3")
13354                  (const_string "sseadd")
13355                (match_operand:MODEF 3 "mult_operator")
13356                  (const_string "fmul")
13357                (match_operand:MODEF 3 "div_operator")
13358                  (const_string "fdiv")
13359               ]
13360               (const_string "fop")))
13361    (set_attr "isa" "*,*,noavx,avx")
13362    (set_attr "prefix" "orig,orig,orig,vex")
13363    (set_attr "mode" "<MODE>")])
13365 (define_insn "*rcpsf2_sse"
13366   [(set (match_operand:SF 0 "register_operand" "=x")
13367         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13368                    UNSPEC_RCP))]
13369   "TARGET_SSE_MATH"
13370   "%vrcpss\t{%1, %d0|%d0, %1}"
13371   [(set_attr "type" "sse")
13372    (set_attr "atom_sse_attr" "rcp")
13373    (set_attr "btver2_sse_attr" "rcp")
13374    (set_attr "prefix" "maybe_vex")
13375    (set_attr "mode" "SF")])
13377 (define_insn "*fop_<mode>_1_sse"
13378   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13379         (match_operator:MODEF 3 "binary_fp_operator"
13380           [(match_operand:MODEF 1 "register_operand" "0,x")
13381            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13382   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13383    && !COMMUTATIVE_ARITH_P (operands[3])"
13384   "* return output_387_binary_op (insn, operands);"
13385   [(set (attr "type")
13386         (cond [(match_operand:MODEF 3 "mult_operator")
13387                  (const_string "ssemul")
13388                (match_operand:MODEF 3 "div_operator")
13389                  (const_string "ssediv")
13390               ]
13391               (const_string "sseadd")))
13392    (set_attr "isa" "noavx,avx")
13393    (set_attr "prefix" "orig,vex")
13394    (set_attr "mode" "<MODE>")])
13396 ;; This pattern is not fully shadowed by the pattern above.
13397 (define_insn "*fop_<mode>_1_i387"
13398   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13399         (match_operator:MODEF 3 "binary_fp_operator"
13400           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13401            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13402   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13403    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13404    && !COMMUTATIVE_ARITH_P (operands[3])
13405    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13406   "* return output_387_binary_op (insn, operands);"
13407   [(set (attr "type")
13408         (cond [(match_operand:MODEF 3 "mult_operator")
13409                  (const_string "fmul")
13410                (match_operand:MODEF 3 "div_operator")
13411                  (const_string "fdiv")
13412               ]
13413               (const_string "fop")))
13414    (set_attr "mode" "<MODE>")])
13416 ;; ??? Add SSE splitters for these!
13417 (define_insn "*fop_<MODEF:mode>_2_i387"
13418   [(set (match_operand:MODEF 0 "register_operand" "=f")
13419         (match_operator:MODEF 3 "binary_fp_operator"
13420           [(float:MODEF
13421              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13422            (match_operand:MODEF 2 "register_operand" "0")]))]
13423   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13424    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13425    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13426        || optimize_function_for_size_p (cfun))"
13427   { return output_387_binary_op (insn, operands); }
13428   [(set (attr "type")
13429         (cond [(match_operand:MODEF 3 "mult_operator")
13430                  (const_string "fmul")
13431                (match_operand:MODEF 3 "div_operator")
13432                  (const_string "fdiv")
13433               ]
13434               (const_string "fop")))
13435    (set_attr "fp_int_src" "true")
13436    (set_attr "mode" "<SWI24:MODE>")])
13438 (define_insn "*fop_<MODEF:mode>_3_i387"
13439   [(set (match_operand:MODEF 0 "register_operand" "=f")
13440         (match_operator:MODEF 3 "binary_fp_operator"
13441           [(match_operand:MODEF 1 "register_operand" "0")
13442            (float:MODEF
13443              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13444   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13445    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13446    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13447        || optimize_function_for_size_p (cfun))"
13448   { return output_387_binary_op (insn, operands); }
13449   [(set (attr "type")
13450         (cond [(match_operand:MODEF 3 "mult_operator")
13451                  (const_string "fmul")
13452                (match_operand:MODEF 3 "div_operator")
13453                  (const_string "fdiv")
13454               ]
13455               (const_string "fop")))
13456    (set_attr "fp_int_src" "true")
13457    (set_attr "mode" "<MODE>")])
13459 (define_insn "*fop_df_4_i387"
13460   [(set (match_operand:DF 0 "register_operand" "=f,f")
13461         (match_operator:DF 3 "binary_fp_operator"
13462            [(float_extend:DF
13463              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13464             (match_operand:DF 2 "register_operand" "0,f")]))]
13465   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13466    && !(TARGET_SSE2 && TARGET_SSE_MATH)
13467    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13468   "* return output_387_binary_op (insn, operands);"
13469   [(set (attr "type")
13470         (cond [(match_operand:DF 3 "mult_operator")
13471                  (const_string "fmul")
13472                (match_operand:DF 3 "div_operator")
13473                  (const_string "fdiv")
13474               ]
13475               (const_string "fop")))
13476    (set_attr "mode" "SF")])
13478 (define_insn "*fop_df_5_i387"
13479   [(set (match_operand:DF 0 "register_operand" "=f,f")
13480         (match_operator:DF 3 "binary_fp_operator"
13481           [(match_operand:DF 1 "register_operand" "0,f")
13482            (float_extend:DF
13483             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13484   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13485    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13486   "* return output_387_binary_op (insn, operands);"
13487   [(set (attr "type")
13488         (cond [(match_operand:DF 3 "mult_operator")
13489                  (const_string "fmul")
13490                (match_operand:DF 3 "div_operator")
13491                  (const_string "fdiv")
13492               ]
13493               (const_string "fop")))
13494    (set_attr "mode" "SF")])
13496 (define_insn "*fop_df_6_i387"
13497   [(set (match_operand:DF 0 "register_operand" "=f,f")
13498         (match_operator:DF 3 "binary_fp_operator"
13499           [(float_extend:DF
13500             (match_operand:SF 1 "register_operand" "0,f"))
13501            (float_extend:DF
13502             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13503   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13504    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13505   "* return output_387_binary_op (insn, operands);"
13506   [(set (attr "type")
13507         (cond [(match_operand:DF 3 "mult_operator")
13508                  (const_string "fmul")
13509                (match_operand:DF 3 "div_operator")
13510                  (const_string "fdiv")
13511               ]
13512               (const_string "fop")))
13513    (set_attr "mode" "SF")])
13515 (define_insn "*fop_xf_comm_i387"
13516   [(set (match_operand:XF 0 "register_operand" "=f")
13517         (match_operator:XF 3 "binary_fp_operator"
13518                         [(match_operand:XF 1 "register_operand" "%0")
13519                          (match_operand:XF 2 "register_operand" "f")]))]
13520   "TARGET_80387
13521    && COMMUTATIVE_ARITH_P (operands[3])"
13522   "* return output_387_binary_op (insn, operands);"
13523   [(set (attr "type")
13524         (if_then_else (match_operand:XF 3 "mult_operator")
13525            (const_string "fmul")
13526            (const_string "fop")))
13527    (set_attr "mode" "XF")])
13529 (define_insn "*fop_xf_1_i387"
13530   [(set (match_operand:XF 0 "register_operand" "=f,f")
13531         (match_operator:XF 3 "binary_fp_operator"
13532                         [(match_operand:XF 1 "register_operand" "0,f")
13533                          (match_operand:XF 2 "register_operand" "f,0")]))]
13534   "TARGET_80387
13535    && !COMMUTATIVE_ARITH_P (operands[3])"
13536   "* return output_387_binary_op (insn, operands);"
13537   [(set (attr "type")
13538         (cond [(match_operand:XF 3 "mult_operator")
13539                  (const_string "fmul")
13540                (match_operand:XF 3 "div_operator")
13541                  (const_string "fdiv")
13542               ]
13543               (const_string "fop")))
13544    (set_attr "mode" "XF")])
13546 (define_insn "*fop_xf_2_i387"
13547   [(set (match_operand:XF 0 "register_operand" "=f")
13548         (match_operator:XF 3 "binary_fp_operator"
13549           [(float:XF
13550              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13551            (match_operand:XF 2 "register_operand" "0")]))]
13552   "TARGET_80387
13553    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13554   { return output_387_binary_op (insn, operands); }
13555   [(set (attr "type")
13556         (cond [(match_operand:XF 3 "mult_operator")
13557                  (const_string "fmul")
13558                (match_operand:XF 3 "div_operator")
13559                  (const_string "fdiv")
13560               ]
13561               (const_string "fop")))
13562    (set_attr "fp_int_src" "true")
13563    (set_attr "mode" "<MODE>")])
13565 (define_insn "*fop_xf_3_i387"
13566   [(set (match_operand:XF 0 "register_operand" "=f")
13567         (match_operator:XF 3 "binary_fp_operator"
13568           [(match_operand:XF 1 "register_operand" "0")
13569            (float:XF
13570              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13571   "TARGET_80387
13572    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13573   { return output_387_binary_op (insn, operands); }
13574   [(set (attr "type")
13575         (cond [(match_operand:XF 3 "mult_operator")
13576                  (const_string "fmul")
13577                (match_operand:XF 3 "div_operator")
13578                  (const_string "fdiv")
13579               ]
13580               (const_string "fop")))
13581    (set_attr "fp_int_src" "true")
13582    (set_attr "mode" "<MODE>")])
13584 (define_insn "*fop_xf_4_i387"
13585   [(set (match_operand:XF 0 "register_operand" "=f,f")
13586         (match_operator:XF 3 "binary_fp_operator"
13587            [(float_extend:XF
13588               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13589             (match_operand:XF 2 "register_operand" "0,f")]))]
13590   "TARGET_80387"
13591   "* return output_387_binary_op (insn, operands);"
13592   [(set (attr "type")
13593         (cond [(match_operand:XF 3 "mult_operator")
13594                  (const_string "fmul")
13595                (match_operand:XF 3 "div_operator")
13596                  (const_string "fdiv")
13597               ]
13598               (const_string "fop")))
13599    (set_attr "mode" "<MODE>")])
13601 (define_insn "*fop_xf_5_i387"
13602   [(set (match_operand:XF 0 "register_operand" "=f,f")
13603         (match_operator:XF 3 "binary_fp_operator"
13604           [(match_operand:XF 1 "register_operand" "0,f")
13605            (float_extend:XF
13606              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13607   "TARGET_80387"
13608   "* return output_387_binary_op (insn, operands);"
13609   [(set (attr "type")
13610         (cond [(match_operand:XF 3 "mult_operator")
13611                  (const_string "fmul")
13612                (match_operand:XF 3 "div_operator")
13613                  (const_string "fdiv")
13614               ]
13615               (const_string "fop")))
13616    (set_attr "mode" "<MODE>")])
13618 (define_insn "*fop_xf_6_i387"
13619   [(set (match_operand:XF 0 "register_operand" "=f,f")
13620         (match_operator:XF 3 "binary_fp_operator"
13621           [(float_extend:XF
13622              (match_operand:MODEF 1 "register_operand" "0,f"))
13623            (float_extend:XF
13624              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13625   "TARGET_80387"
13626   "* return output_387_binary_op (insn, operands);"
13627   [(set (attr "type")
13628         (cond [(match_operand:XF 3 "mult_operator")
13629                  (const_string "fmul")
13630                (match_operand:XF 3 "div_operator")
13631                  (const_string "fdiv")
13632               ]
13633               (const_string "fop")))
13634    (set_attr "mode" "<MODE>")])
13636 ;; FPU special functions.
13638 ;; This pattern implements a no-op XFmode truncation for
13639 ;; all fancy i386 XFmode math functions.
13641 (define_insn "truncxf<mode>2_i387_noop_unspec"
13642   [(set (match_operand:MODEF 0 "register_operand" "=f")
13643         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13644         UNSPEC_TRUNC_NOOP))]
13645   "TARGET_USE_FANCY_MATH_387"
13646   "* return output_387_reg_move (insn, operands);"
13647   [(set_attr "type" "fmov")
13648    (set_attr "mode" "<MODE>")])
13650 (define_insn "sqrtxf2"
13651   [(set (match_operand:XF 0 "register_operand" "=f")
13652         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13653   "TARGET_USE_FANCY_MATH_387"
13654   "fsqrt"
13655   [(set_attr "type" "fpspc")
13656    (set_attr "mode" "XF")
13657    (set_attr "athlon_decode" "direct")
13658    (set_attr "amdfam10_decode" "direct")
13659    (set_attr "bdver1_decode" "direct")])
13661 (define_insn "sqrt_extend<mode>xf2_i387"
13662   [(set (match_operand:XF 0 "register_operand" "=f")
13663         (sqrt:XF
13664           (float_extend:XF
13665             (match_operand:MODEF 1 "register_operand" "0"))))]
13666   "TARGET_USE_FANCY_MATH_387"
13667   "fsqrt"
13668   [(set_attr "type" "fpspc")
13669    (set_attr "mode" "XF")
13670    (set_attr "athlon_decode" "direct")
13671    (set_attr "amdfam10_decode" "direct")
13672    (set_attr "bdver1_decode" "direct")])
13674 (define_insn "*rsqrtsf2_sse"
13675   [(set (match_operand:SF 0 "register_operand" "=x")
13676         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13677                    UNSPEC_RSQRT))]
13678   "TARGET_SSE_MATH"
13679   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13680   [(set_attr "type" "sse")
13681    (set_attr "atom_sse_attr" "rcp")
13682    (set_attr "btver2_sse_attr" "rcp")
13683    (set_attr "prefix" "maybe_vex")
13684    (set_attr "mode" "SF")])
13686 (define_expand "rsqrtsf2"
13687   [(set (match_operand:SF 0 "register_operand")
13688         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13689                    UNSPEC_RSQRT))]
13690   "TARGET_SSE_MATH"
13692   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13693   DONE;
13696 (define_insn "*sqrt<mode>2_sse"
13697   [(set (match_operand:MODEF 0 "register_operand" "=x")
13698         (sqrt:MODEF
13699           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13700   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13701   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13702   [(set_attr "type" "sse")
13703    (set_attr "atom_sse_attr" "sqrt")
13704    (set_attr "btver2_sse_attr" "sqrt")
13705    (set_attr "prefix" "maybe_vex")
13706    (set_attr "mode" "<MODE>")
13707    (set_attr "athlon_decode" "*")
13708    (set_attr "amdfam10_decode" "*")
13709    (set_attr "bdver1_decode" "*")])
13711 (define_expand "sqrt<mode>2"
13712   [(set (match_operand:MODEF 0 "register_operand")
13713         (sqrt:MODEF
13714           (match_operand:MODEF 1 "nonimmediate_operand")))]
13715   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13716    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13718   if (<MODE>mode == SFmode
13719       && TARGET_SSE_MATH
13720       && TARGET_RECIP_SQRT
13721       && !optimize_function_for_size_p (cfun)
13722       && flag_finite_math_only && !flag_trapping_math
13723       && flag_unsafe_math_optimizations)
13724     {
13725       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13726       DONE;
13727     }
13729   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13730     {
13731       rtx op0 = gen_reg_rtx (XFmode);
13732       rtx op1 = force_reg (<MODE>mode, operands[1]);
13734       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13735       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13736       DONE;
13737    }
13740 (define_insn "fpremxf4_i387"
13741   [(set (match_operand:XF 0 "register_operand" "=f")
13742         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13743                     (match_operand:XF 3 "register_operand" "1")]
13744                    UNSPEC_FPREM_F))
13745    (set (match_operand:XF 1 "register_operand" "=u")
13746         (unspec:XF [(match_dup 2) (match_dup 3)]
13747                    UNSPEC_FPREM_U))
13748    (set (reg:CCFP FPSR_REG)
13749         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13750                      UNSPEC_C2_FLAG))]
13751   "TARGET_USE_FANCY_MATH_387"
13752   "fprem"
13753   [(set_attr "type" "fpspc")
13754    (set_attr "mode" "XF")])
13756 (define_expand "fmodxf3"
13757   [(use (match_operand:XF 0 "register_operand"))
13758    (use (match_operand:XF 1 "general_operand"))
13759    (use (match_operand:XF 2 "general_operand"))]
13760   "TARGET_USE_FANCY_MATH_387"
13762   rtx label = gen_label_rtx ();
13764   rtx op1 = gen_reg_rtx (XFmode);
13765   rtx op2 = gen_reg_rtx (XFmode);
13767   emit_move_insn (op2, operands[2]);
13768   emit_move_insn (op1, operands[1]);
13770   emit_label (label);
13771   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13772   ix86_emit_fp_unordered_jump (label);
13773   LABEL_NUSES (label) = 1;
13775   emit_move_insn (operands[0], op1);
13776   DONE;
13779 (define_expand "fmod<mode>3"
13780   [(use (match_operand:MODEF 0 "register_operand"))
13781    (use (match_operand:MODEF 1 "general_operand"))
13782    (use (match_operand:MODEF 2 "general_operand"))]
13783   "TARGET_USE_FANCY_MATH_387"
13785   rtx (*gen_truncxf) (rtx, rtx);
13787   rtx label = gen_label_rtx ();
13789   rtx op1 = gen_reg_rtx (XFmode);
13790   rtx op2 = gen_reg_rtx (XFmode);
13792   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13793   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13795   emit_label (label);
13796   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13797   ix86_emit_fp_unordered_jump (label);
13798   LABEL_NUSES (label) = 1;
13800   /* Truncate the result properly for strict SSE math.  */
13801   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13802       && !TARGET_MIX_SSE_I387)
13803     gen_truncxf = gen_truncxf<mode>2;
13804   else
13805     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13807   emit_insn (gen_truncxf (operands[0], op1));
13808   DONE;
13811 (define_insn "fprem1xf4_i387"
13812   [(set (match_operand:XF 0 "register_operand" "=f")
13813         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13814                     (match_operand:XF 3 "register_operand" "1")]
13815                    UNSPEC_FPREM1_F))
13816    (set (match_operand:XF 1 "register_operand" "=u")
13817         (unspec:XF [(match_dup 2) (match_dup 3)]
13818                    UNSPEC_FPREM1_U))
13819    (set (reg:CCFP FPSR_REG)
13820         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13821                      UNSPEC_C2_FLAG))]
13822   "TARGET_USE_FANCY_MATH_387"
13823   "fprem1"
13824   [(set_attr "type" "fpspc")
13825    (set_attr "mode" "XF")])
13827 (define_expand "remainderxf3"
13828   [(use (match_operand:XF 0 "register_operand"))
13829    (use (match_operand:XF 1 "general_operand"))
13830    (use (match_operand:XF 2 "general_operand"))]
13831   "TARGET_USE_FANCY_MATH_387"
13833   rtx label = gen_label_rtx ();
13835   rtx op1 = gen_reg_rtx (XFmode);
13836   rtx op2 = gen_reg_rtx (XFmode);
13838   emit_move_insn (op2, operands[2]);
13839   emit_move_insn (op1, operands[1]);
13841   emit_label (label);
13842   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13843   ix86_emit_fp_unordered_jump (label);
13844   LABEL_NUSES (label) = 1;
13846   emit_move_insn (operands[0], op1);
13847   DONE;
13850 (define_expand "remainder<mode>3"
13851   [(use (match_operand:MODEF 0 "register_operand"))
13852    (use (match_operand:MODEF 1 "general_operand"))
13853    (use (match_operand:MODEF 2 "general_operand"))]
13854   "TARGET_USE_FANCY_MATH_387"
13856   rtx (*gen_truncxf) (rtx, rtx);
13858   rtx label = gen_label_rtx ();
13860   rtx op1 = gen_reg_rtx (XFmode);
13861   rtx op2 = gen_reg_rtx (XFmode);
13863   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13864   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13866   emit_label (label);
13868   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13869   ix86_emit_fp_unordered_jump (label);
13870   LABEL_NUSES (label) = 1;
13872   /* Truncate the result properly for strict SSE math.  */
13873   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13874       && !TARGET_MIX_SSE_I387)
13875     gen_truncxf = gen_truncxf<mode>2;
13876   else
13877     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13879   emit_insn (gen_truncxf (operands[0], op1));
13880   DONE;
13883 (define_int_iterator SINCOS
13884         [UNSPEC_SIN
13885          UNSPEC_COS])
13887 (define_int_attr sincos
13888         [(UNSPEC_SIN "sin")
13889          (UNSPEC_COS "cos")])
13891 (define_insn "*<sincos>xf2_i387"
13892   [(set (match_operand:XF 0 "register_operand" "=f")
13893         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13894                    SINCOS))]
13895   "TARGET_USE_FANCY_MATH_387
13896    && flag_unsafe_math_optimizations"
13897   "f<sincos>"
13898   [(set_attr "type" "fpspc")
13899    (set_attr "mode" "XF")])
13901 (define_insn "*<sincos>_extend<mode>xf2_i387"
13902   [(set (match_operand:XF 0 "register_operand" "=f")
13903         (unspec:XF [(float_extend:XF
13904                       (match_operand:MODEF 1 "register_operand" "0"))]
13905                    SINCOS))]
13906   "TARGET_USE_FANCY_MATH_387
13907    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13908        || TARGET_MIX_SSE_I387)
13909    && flag_unsafe_math_optimizations"
13910   "f<sincos>"
13911   [(set_attr "type" "fpspc")
13912    (set_attr "mode" "XF")])
13914 ;; When sincos pattern is defined, sin and cos builtin functions will be
13915 ;; expanded to sincos pattern with one of its outputs left unused.
13916 ;; CSE pass will figure out if two sincos patterns can be combined,
13917 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13918 ;; depending on the unused output.
13920 (define_insn "sincosxf3"
13921   [(set (match_operand:XF 0 "register_operand" "=f")
13922         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13923                    UNSPEC_SINCOS_COS))
13924    (set (match_operand:XF 1 "register_operand" "=u")
13925         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13926   "TARGET_USE_FANCY_MATH_387
13927    && flag_unsafe_math_optimizations"
13928   "fsincos"
13929   [(set_attr "type" "fpspc")
13930    (set_attr "mode" "XF")])
13932 (define_split
13933   [(set (match_operand:XF 0 "register_operand")
13934         (unspec:XF [(match_operand:XF 2 "register_operand")]
13935                    UNSPEC_SINCOS_COS))
13936    (set (match_operand:XF 1 "register_operand")
13937         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13938   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13939    && can_create_pseudo_p ()"
13940   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13942 (define_split
13943   [(set (match_operand:XF 0 "register_operand")
13944         (unspec:XF [(match_operand:XF 2 "register_operand")]
13945                    UNSPEC_SINCOS_COS))
13946    (set (match_operand:XF 1 "register_operand")
13947         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13948   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13949    && can_create_pseudo_p ()"
13950   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13952 (define_insn "sincos_extend<mode>xf3_i387"
13953   [(set (match_operand:XF 0 "register_operand" "=f")
13954         (unspec:XF [(float_extend:XF
13955                       (match_operand:MODEF 2 "register_operand" "0"))]
13956                    UNSPEC_SINCOS_COS))
13957    (set (match_operand:XF 1 "register_operand" "=u")
13958         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13959   "TARGET_USE_FANCY_MATH_387
13960    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13961        || TARGET_MIX_SSE_I387)
13962    && flag_unsafe_math_optimizations"
13963   "fsincos"
13964   [(set_attr "type" "fpspc")
13965    (set_attr "mode" "XF")])
13967 (define_split
13968   [(set (match_operand:XF 0 "register_operand")
13969         (unspec:XF [(float_extend:XF
13970                       (match_operand:MODEF 2 "register_operand"))]
13971                    UNSPEC_SINCOS_COS))
13972    (set (match_operand:XF 1 "register_operand")
13973         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13974   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13975    && can_create_pseudo_p ()"
13976   [(set (match_dup 1)
13977         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13979 (define_split
13980   [(set (match_operand:XF 0 "register_operand")
13981         (unspec:XF [(float_extend:XF
13982                       (match_operand:MODEF 2 "register_operand"))]
13983                    UNSPEC_SINCOS_COS))
13984    (set (match_operand:XF 1 "register_operand")
13985         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13986   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13987    && can_create_pseudo_p ()"
13988   [(set (match_dup 0)
13989         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13991 (define_expand "sincos<mode>3"
13992   [(use (match_operand:MODEF 0 "register_operand"))
13993    (use (match_operand:MODEF 1 "register_operand"))
13994    (use (match_operand:MODEF 2 "register_operand"))]
13995   "TARGET_USE_FANCY_MATH_387
13996    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13997        || TARGET_MIX_SSE_I387)
13998    && flag_unsafe_math_optimizations"
14000   rtx op0 = gen_reg_rtx (XFmode);
14001   rtx op1 = gen_reg_rtx (XFmode);
14003   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14004   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14005   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14006   DONE;
14009 (define_insn "fptanxf4_i387"
14010   [(set (match_operand:XF 0 "register_operand" "=f")
14011         (match_operand:XF 3 "const_double_operand" "F"))
14012    (set (match_operand:XF 1 "register_operand" "=u")
14013         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14014                    UNSPEC_TAN))]
14015   "TARGET_USE_FANCY_MATH_387
14016    && flag_unsafe_math_optimizations
14017    && standard_80387_constant_p (operands[3]) == 2"
14018   "fptan"
14019   [(set_attr "type" "fpspc")
14020    (set_attr "mode" "XF")])
14022 (define_insn "fptan_extend<mode>xf4_i387"
14023   [(set (match_operand:MODEF 0 "register_operand" "=f")
14024         (match_operand:MODEF 3 "const_double_operand" "F"))
14025    (set (match_operand:XF 1 "register_operand" "=u")
14026         (unspec:XF [(float_extend:XF
14027                       (match_operand:MODEF 2 "register_operand" "0"))]
14028                    UNSPEC_TAN))]
14029   "TARGET_USE_FANCY_MATH_387
14030    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14031        || TARGET_MIX_SSE_I387)
14032    && flag_unsafe_math_optimizations
14033    && standard_80387_constant_p (operands[3]) == 2"
14034   "fptan"
14035   [(set_attr "type" "fpspc")
14036    (set_attr "mode" "XF")])
14038 (define_expand "tanxf2"
14039   [(use (match_operand:XF 0 "register_operand"))
14040    (use (match_operand:XF 1 "register_operand"))]
14041   "TARGET_USE_FANCY_MATH_387
14042    && flag_unsafe_math_optimizations"
14044   rtx one = gen_reg_rtx (XFmode);
14045   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14047   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14048   DONE;
14051 (define_expand "tan<mode>2"
14052   [(use (match_operand:MODEF 0 "register_operand"))
14053    (use (match_operand:MODEF 1 "register_operand"))]
14054   "TARGET_USE_FANCY_MATH_387
14055    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14056        || TARGET_MIX_SSE_I387)
14057    && flag_unsafe_math_optimizations"
14059   rtx op0 = gen_reg_rtx (XFmode);
14061   rtx one = gen_reg_rtx (<MODE>mode);
14062   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14064   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14065                                              operands[1], op2));
14066   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14067   DONE;
14070 (define_insn "*fpatanxf3_i387"
14071   [(set (match_operand:XF 0 "register_operand" "=f")
14072         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14073                     (match_operand:XF 2 "register_operand" "u")]
14074                    UNSPEC_FPATAN))
14075    (clobber (match_scratch:XF 3 "=2"))]
14076   "TARGET_USE_FANCY_MATH_387
14077    && flag_unsafe_math_optimizations"
14078   "fpatan"
14079   [(set_attr "type" "fpspc")
14080    (set_attr "mode" "XF")])
14082 (define_insn "fpatan_extend<mode>xf3_i387"
14083   [(set (match_operand:XF 0 "register_operand" "=f")
14084         (unspec:XF [(float_extend:XF
14085                       (match_operand:MODEF 1 "register_operand" "0"))
14086                     (float_extend:XF
14087                       (match_operand:MODEF 2 "register_operand" "u"))]
14088                    UNSPEC_FPATAN))
14089    (clobber (match_scratch:XF 3 "=2"))]
14090   "TARGET_USE_FANCY_MATH_387
14091    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14092        || TARGET_MIX_SSE_I387)
14093    && flag_unsafe_math_optimizations"
14094   "fpatan"
14095   [(set_attr "type" "fpspc")
14096    (set_attr "mode" "XF")])
14098 (define_expand "atan2xf3"
14099   [(parallel [(set (match_operand:XF 0 "register_operand")
14100                    (unspec:XF [(match_operand:XF 2 "register_operand")
14101                                (match_operand:XF 1 "register_operand")]
14102                               UNSPEC_FPATAN))
14103               (clobber (match_scratch:XF 3))])]
14104   "TARGET_USE_FANCY_MATH_387
14105    && flag_unsafe_math_optimizations")
14107 (define_expand "atan2<mode>3"
14108   [(use (match_operand:MODEF 0 "register_operand"))
14109    (use (match_operand:MODEF 1 "register_operand"))
14110    (use (match_operand:MODEF 2 "register_operand"))]
14111   "TARGET_USE_FANCY_MATH_387
14112    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14113        || TARGET_MIX_SSE_I387)
14114    && flag_unsafe_math_optimizations"
14116   rtx op0 = gen_reg_rtx (XFmode);
14118   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14119   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14120   DONE;
14123 (define_expand "atanxf2"
14124   [(parallel [(set (match_operand:XF 0 "register_operand")
14125                    (unspec:XF [(match_dup 2)
14126                                (match_operand:XF 1 "register_operand")]
14127                               UNSPEC_FPATAN))
14128               (clobber (match_scratch:XF 3))])]
14129   "TARGET_USE_FANCY_MATH_387
14130    && flag_unsafe_math_optimizations"
14132   operands[2] = gen_reg_rtx (XFmode);
14133   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
14136 (define_expand "atan<mode>2"
14137   [(use (match_operand:MODEF 0 "register_operand"))
14138    (use (match_operand:MODEF 1 "register_operand"))]
14139   "TARGET_USE_FANCY_MATH_387
14140    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14141        || TARGET_MIX_SSE_I387)
14142    && flag_unsafe_math_optimizations"
14144   rtx op0 = gen_reg_rtx (XFmode);
14146   rtx op2 = gen_reg_rtx (<MODE>mode);
14147   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
14149   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14150   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14151   DONE;
14154 (define_expand "asinxf2"
14155   [(set (match_dup 2)
14156         (mult:XF (match_operand:XF 1 "register_operand")
14157                  (match_dup 1)))
14158    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14159    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14160    (parallel [(set (match_operand:XF 0 "register_operand")
14161                    (unspec:XF [(match_dup 5) (match_dup 1)]
14162                               UNSPEC_FPATAN))
14163               (clobber (match_scratch:XF 6))])]
14164   "TARGET_USE_FANCY_MATH_387
14165    && flag_unsafe_math_optimizations"
14167   int i;
14169   if (optimize_insn_for_size_p ())
14170     FAIL;
14172   for (i = 2; i < 6; i++)
14173     operands[i] = gen_reg_rtx (XFmode);
14175   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14178 (define_expand "asin<mode>2"
14179   [(use (match_operand:MODEF 0 "register_operand"))
14180    (use (match_operand:MODEF 1 "general_operand"))]
14181  "TARGET_USE_FANCY_MATH_387
14182    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14183        || TARGET_MIX_SSE_I387)
14184    && flag_unsafe_math_optimizations"
14186   rtx op0 = gen_reg_rtx (XFmode);
14187   rtx op1 = gen_reg_rtx (XFmode);
14189   if (optimize_insn_for_size_p ())
14190     FAIL;
14192   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14193   emit_insn (gen_asinxf2 (op0, op1));
14194   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14195   DONE;
14198 (define_expand "acosxf2"
14199   [(set (match_dup 2)
14200         (mult:XF (match_operand:XF 1 "register_operand")
14201                  (match_dup 1)))
14202    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14203    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14204    (parallel [(set (match_operand:XF 0 "register_operand")
14205                    (unspec:XF [(match_dup 1) (match_dup 5)]
14206                               UNSPEC_FPATAN))
14207               (clobber (match_scratch:XF 6))])]
14208   "TARGET_USE_FANCY_MATH_387
14209    && flag_unsafe_math_optimizations"
14211   int i;
14213   if (optimize_insn_for_size_p ())
14214     FAIL;
14216   for (i = 2; i < 6; i++)
14217     operands[i] = gen_reg_rtx (XFmode);
14219   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14222 (define_expand "acos<mode>2"
14223   [(use (match_operand:MODEF 0 "register_operand"))
14224    (use (match_operand:MODEF 1 "general_operand"))]
14225  "TARGET_USE_FANCY_MATH_387
14226    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14227        || TARGET_MIX_SSE_I387)
14228    && flag_unsafe_math_optimizations"
14230   rtx op0 = gen_reg_rtx (XFmode);
14231   rtx op1 = gen_reg_rtx (XFmode);
14233   if (optimize_insn_for_size_p ())
14234     FAIL;
14236   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14237   emit_insn (gen_acosxf2 (op0, op1));
14238   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14239   DONE;
14242 (define_insn "fyl2xxf3_i387"
14243   [(set (match_operand:XF 0 "register_operand" "=f")
14244         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14245                     (match_operand:XF 2 "register_operand" "u")]
14246                    UNSPEC_FYL2X))
14247    (clobber (match_scratch:XF 3 "=2"))]
14248   "TARGET_USE_FANCY_MATH_387
14249    && flag_unsafe_math_optimizations"
14250   "fyl2x"
14251   [(set_attr "type" "fpspc")
14252    (set_attr "mode" "XF")])
14254 (define_insn "fyl2x_extend<mode>xf3_i387"
14255   [(set (match_operand:XF 0 "register_operand" "=f")
14256         (unspec:XF [(float_extend:XF
14257                       (match_operand:MODEF 1 "register_operand" "0"))
14258                     (match_operand:XF 2 "register_operand" "u")]
14259                    UNSPEC_FYL2X))
14260    (clobber (match_scratch:XF 3 "=2"))]
14261   "TARGET_USE_FANCY_MATH_387
14262    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14263        || TARGET_MIX_SSE_I387)
14264    && flag_unsafe_math_optimizations"
14265   "fyl2x"
14266   [(set_attr "type" "fpspc")
14267    (set_attr "mode" "XF")])
14269 (define_expand "logxf2"
14270   [(parallel [(set (match_operand:XF 0 "register_operand")
14271                    (unspec:XF [(match_operand:XF 1 "register_operand")
14272                                (match_dup 2)] UNSPEC_FYL2X))
14273               (clobber (match_scratch:XF 3))])]
14274   "TARGET_USE_FANCY_MATH_387
14275    && flag_unsafe_math_optimizations"
14277   operands[2] = gen_reg_rtx (XFmode);
14278   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14281 (define_expand "log<mode>2"
14282   [(use (match_operand:MODEF 0 "register_operand"))
14283    (use (match_operand:MODEF 1 "register_operand"))]
14284   "TARGET_USE_FANCY_MATH_387
14285    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14286        || TARGET_MIX_SSE_I387)
14287    && flag_unsafe_math_optimizations"
14289   rtx op0 = gen_reg_rtx (XFmode);
14291   rtx op2 = gen_reg_rtx (XFmode);
14292   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14294   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14295   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14296   DONE;
14299 (define_expand "log10xf2"
14300   [(parallel [(set (match_operand:XF 0 "register_operand")
14301                    (unspec:XF [(match_operand:XF 1 "register_operand")
14302                                (match_dup 2)] UNSPEC_FYL2X))
14303               (clobber (match_scratch:XF 3))])]
14304   "TARGET_USE_FANCY_MATH_387
14305    && flag_unsafe_math_optimizations"
14307   operands[2] = gen_reg_rtx (XFmode);
14308   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14311 (define_expand "log10<mode>2"
14312   [(use (match_operand:MODEF 0 "register_operand"))
14313    (use (match_operand:MODEF 1 "register_operand"))]
14314   "TARGET_USE_FANCY_MATH_387
14315    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14316        || TARGET_MIX_SSE_I387)
14317    && flag_unsafe_math_optimizations"
14319   rtx op0 = gen_reg_rtx (XFmode);
14321   rtx op2 = gen_reg_rtx (XFmode);
14322   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14324   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14325   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14326   DONE;
14329 (define_expand "log2xf2"
14330   [(parallel [(set (match_operand:XF 0 "register_operand")
14331                    (unspec:XF [(match_operand:XF 1 "register_operand")
14332                                (match_dup 2)] UNSPEC_FYL2X))
14333               (clobber (match_scratch:XF 3))])]
14334   "TARGET_USE_FANCY_MATH_387
14335    && flag_unsafe_math_optimizations"
14337   operands[2] = gen_reg_rtx (XFmode);
14338   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14341 (define_expand "log2<mode>2"
14342   [(use (match_operand:MODEF 0 "register_operand"))
14343    (use (match_operand:MODEF 1 "register_operand"))]
14344   "TARGET_USE_FANCY_MATH_387
14345    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14346        || TARGET_MIX_SSE_I387)
14347    && flag_unsafe_math_optimizations"
14349   rtx op0 = gen_reg_rtx (XFmode);
14351   rtx op2 = gen_reg_rtx (XFmode);
14352   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14354   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14355   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14356   DONE;
14359 (define_insn "fyl2xp1xf3_i387"
14360   [(set (match_operand:XF 0 "register_operand" "=f")
14361         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14362                     (match_operand:XF 2 "register_operand" "u")]
14363                    UNSPEC_FYL2XP1))
14364    (clobber (match_scratch:XF 3 "=2"))]
14365   "TARGET_USE_FANCY_MATH_387
14366    && flag_unsafe_math_optimizations"
14367   "fyl2xp1"
14368   [(set_attr "type" "fpspc")
14369    (set_attr "mode" "XF")])
14371 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14372   [(set (match_operand:XF 0 "register_operand" "=f")
14373         (unspec:XF [(float_extend:XF
14374                       (match_operand:MODEF 1 "register_operand" "0"))
14375                     (match_operand:XF 2 "register_operand" "u")]
14376                    UNSPEC_FYL2XP1))
14377    (clobber (match_scratch:XF 3 "=2"))]
14378   "TARGET_USE_FANCY_MATH_387
14379    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14380        || TARGET_MIX_SSE_I387)
14381    && flag_unsafe_math_optimizations"
14382   "fyl2xp1"
14383   [(set_attr "type" "fpspc")
14384    (set_attr "mode" "XF")])
14386 (define_expand "log1pxf2"
14387   [(use (match_operand:XF 0 "register_operand"))
14388    (use (match_operand:XF 1 "register_operand"))]
14389   "TARGET_USE_FANCY_MATH_387
14390    && flag_unsafe_math_optimizations"
14392   if (optimize_insn_for_size_p ())
14393     FAIL;
14395   ix86_emit_i387_log1p (operands[0], operands[1]);
14396   DONE;
14399 (define_expand "log1p<mode>2"
14400   [(use (match_operand:MODEF 0 "register_operand"))
14401    (use (match_operand:MODEF 1 "register_operand"))]
14402   "TARGET_USE_FANCY_MATH_387
14403    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14404        || TARGET_MIX_SSE_I387)
14405    && flag_unsafe_math_optimizations"
14407   rtx op0;
14409   if (optimize_insn_for_size_p ())
14410     FAIL;
14412   op0 = gen_reg_rtx (XFmode);
14414   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14416   ix86_emit_i387_log1p (op0, operands[1]);
14417   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14418   DONE;
14421 (define_insn "fxtractxf3_i387"
14422   [(set (match_operand:XF 0 "register_operand" "=f")
14423         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14424                    UNSPEC_XTRACT_FRACT))
14425    (set (match_operand:XF 1 "register_operand" "=u")
14426         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14427   "TARGET_USE_FANCY_MATH_387
14428    && flag_unsafe_math_optimizations"
14429   "fxtract"
14430   [(set_attr "type" "fpspc")
14431    (set_attr "mode" "XF")])
14433 (define_insn "fxtract_extend<mode>xf3_i387"
14434   [(set (match_operand:XF 0 "register_operand" "=f")
14435         (unspec:XF [(float_extend:XF
14436                       (match_operand:MODEF 2 "register_operand" "0"))]
14437                    UNSPEC_XTRACT_FRACT))
14438    (set (match_operand:XF 1 "register_operand" "=u")
14439         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14440   "TARGET_USE_FANCY_MATH_387
14441    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14442        || TARGET_MIX_SSE_I387)
14443    && flag_unsafe_math_optimizations"
14444   "fxtract"
14445   [(set_attr "type" "fpspc")
14446    (set_attr "mode" "XF")])
14448 (define_expand "logbxf2"
14449   [(parallel [(set (match_dup 2)
14450                    (unspec:XF [(match_operand:XF 1 "register_operand")]
14451                               UNSPEC_XTRACT_FRACT))
14452               (set (match_operand:XF 0 "register_operand")
14453                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14454   "TARGET_USE_FANCY_MATH_387
14455    && flag_unsafe_math_optimizations"
14456   "operands[2] = gen_reg_rtx (XFmode);")
14458 (define_expand "logb<mode>2"
14459   [(use (match_operand:MODEF 0 "register_operand"))
14460    (use (match_operand:MODEF 1 "register_operand"))]
14461   "TARGET_USE_FANCY_MATH_387
14462    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14463        || TARGET_MIX_SSE_I387)
14464    && flag_unsafe_math_optimizations"
14466   rtx op0 = gen_reg_rtx (XFmode);
14467   rtx op1 = gen_reg_rtx (XFmode);
14469   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14470   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14471   DONE;
14474 (define_expand "ilogbxf2"
14475   [(use (match_operand:SI 0 "register_operand"))
14476    (use (match_operand:XF 1 "register_operand"))]
14477   "TARGET_USE_FANCY_MATH_387
14478    && flag_unsafe_math_optimizations"
14480   rtx op0, op1;
14482   if (optimize_insn_for_size_p ())
14483     FAIL;
14485   op0 = gen_reg_rtx (XFmode);
14486   op1 = gen_reg_rtx (XFmode);
14488   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14489   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14490   DONE;
14493 (define_expand "ilogb<mode>2"
14494   [(use (match_operand:SI 0 "register_operand"))
14495    (use (match_operand:MODEF 1 "register_operand"))]
14496   "TARGET_USE_FANCY_MATH_387
14497    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14498        || TARGET_MIX_SSE_I387)
14499    && flag_unsafe_math_optimizations"
14501   rtx op0, op1;
14503   if (optimize_insn_for_size_p ())
14504     FAIL;
14506   op0 = gen_reg_rtx (XFmode);
14507   op1 = gen_reg_rtx (XFmode);
14509   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14510   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14511   DONE;
14514 (define_insn "*f2xm1xf2_i387"
14515   [(set (match_operand:XF 0 "register_operand" "=f")
14516         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14517                    UNSPEC_F2XM1))]
14518   "TARGET_USE_FANCY_MATH_387
14519    && flag_unsafe_math_optimizations"
14520   "f2xm1"
14521   [(set_attr "type" "fpspc")
14522    (set_attr "mode" "XF")])
14524 (define_insn "fscalexf4_i387"
14525   [(set (match_operand:XF 0 "register_operand" "=f")
14526         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14527                     (match_operand:XF 3 "register_operand" "1")]
14528                    UNSPEC_FSCALE_FRACT))
14529    (set (match_operand:XF 1 "register_operand" "=u")
14530         (unspec:XF [(match_dup 2) (match_dup 3)]
14531                    UNSPEC_FSCALE_EXP))]
14532   "TARGET_USE_FANCY_MATH_387
14533    && flag_unsafe_math_optimizations"
14534   "fscale"
14535   [(set_attr "type" "fpspc")
14536    (set_attr "mode" "XF")])
14538 (define_expand "expNcorexf3"
14539   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14540                                (match_operand:XF 2 "register_operand")))
14541    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14542    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14543    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14544    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14545    (parallel [(set (match_operand:XF 0 "register_operand")
14546                    (unspec:XF [(match_dup 8) (match_dup 4)]
14547                               UNSPEC_FSCALE_FRACT))
14548               (set (match_dup 9)
14549                    (unspec:XF [(match_dup 8) (match_dup 4)]
14550                               UNSPEC_FSCALE_EXP))])]
14551   "TARGET_USE_FANCY_MATH_387
14552    && flag_unsafe_math_optimizations"
14554   int i;
14556   if (optimize_insn_for_size_p ())
14557     FAIL;
14559   for (i = 3; i < 10; i++)
14560     operands[i] = gen_reg_rtx (XFmode);
14562   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14565 (define_expand "expxf2"
14566   [(use (match_operand:XF 0 "register_operand"))
14567    (use (match_operand:XF 1 "register_operand"))]
14568   "TARGET_USE_FANCY_MATH_387
14569    && flag_unsafe_math_optimizations"
14571   rtx op2;
14573   if (optimize_insn_for_size_p ())
14574     FAIL;
14576   op2 = gen_reg_rtx (XFmode);
14577   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14579   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14580   DONE;
14583 (define_expand "exp<mode>2"
14584   [(use (match_operand:MODEF 0 "register_operand"))
14585    (use (match_operand:MODEF 1 "general_operand"))]
14586  "TARGET_USE_FANCY_MATH_387
14587    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14588        || TARGET_MIX_SSE_I387)
14589    && flag_unsafe_math_optimizations"
14591   rtx op0, op1;
14593   if (optimize_insn_for_size_p ())
14594     FAIL;
14596   op0 = gen_reg_rtx (XFmode);
14597   op1 = gen_reg_rtx (XFmode);
14599   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14600   emit_insn (gen_expxf2 (op0, op1));
14601   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14602   DONE;
14605 (define_expand "exp10xf2"
14606   [(use (match_operand:XF 0 "register_operand"))
14607    (use (match_operand:XF 1 "register_operand"))]
14608   "TARGET_USE_FANCY_MATH_387
14609    && flag_unsafe_math_optimizations"
14611   rtx op2;
14613   if (optimize_insn_for_size_p ())
14614     FAIL;
14616   op2 = gen_reg_rtx (XFmode);
14617   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14619   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14620   DONE;
14623 (define_expand "exp10<mode>2"
14624   [(use (match_operand:MODEF 0 "register_operand"))
14625    (use (match_operand:MODEF 1 "general_operand"))]
14626  "TARGET_USE_FANCY_MATH_387
14627    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14628        || TARGET_MIX_SSE_I387)
14629    && flag_unsafe_math_optimizations"
14631   rtx op0, op1;
14633   if (optimize_insn_for_size_p ())
14634     FAIL;
14636   op0 = gen_reg_rtx (XFmode);
14637   op1 = gen_reg_rtx (XFmode);
14639   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14640   emit_insn (gen_exp10xf2 (op0, op1));
14641   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14642   DONE;
14645 (define_expand "exp2xf2"
14646   [(use (match_operand:XF 0 "register_operand"))
14647    (use (match_operand:XF 1 "register_operand"))]
14648   "TARGET_USE_FANCY_MATH_387
14649    && flag_unsafe_math_optimizations"
14651   rtx op2;
14653   if (optimize_insn_for_size_p ())
14654     FAIL;
14656   op2 = gen_reg_rtx (XFmode);
14657   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14659   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14660   DONE;
14663 (define_expand "exp2<mode>2"
14664   [(use (match_operand:MODEF 0 "register_operand"))
14665    (use (match_operand:MODEF 1 "general_operand"))]
14666  "TARGET_USE_FANCY_MATH_387
14667    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14668        || TARGET_MIX_SSE_I387)
14669    && flag_unsafe_math_optimizations"
14671   rtx op0, op1;
14673   if (optimize_insn_for_size_p ())
14674     FAIL;
14676   op0 = gen_reg_rtx (XFmode);
14677   op1 = gen_reg_rtx (XFmode);
14679   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14680   emit_insn (gen_exp2xf2 (op0, op1));
14681   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14682   DONE;
14685 (define_expand "expm1xf2"
14686   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14687                                (match_dup 2)))
14688    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14689    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14690    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14691    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14692    (parallel [(set (match_dup 7)
14693                    (unspec:XF [(match_dup 6) (match_dup 4)]
14694                               UNSPEC_FSCALE_FRACT))
14695               (set (match_dup 8)
14696                    (unspec:XF [(match_dup 6) (match_dup 4)]
14697                               UNSPEC_FSCALE_EXP))])
14698    (parallel [(set (match_dup 10)
14699                    (unspec:XF [(match_dup 9) (match_dup 8)]
14700                               UNSPEC_FSCALE_FRACT))
14701               (set (match_dup 11)
14702                    (unspec:XF [(match_dup 9) (match_dup 8)]
14703                               UNSPEC_FSCALE_EXP))])
14704    (set (match_dup 12) (minus:XF (match_dup 10)
14705                                  (float_extend:XF (match_dup 13))))
14706    (set (match_operand:XF 0 "register_operand")
14707         (plus:XF (match_dup 12) (match_dup 7)))]
14708   "TARGET_USE_FANCY_MATH_387
14709    && flag_unsafe_math_optimizations"
14711   int i;
14713   if (optimize_insn_for_size_p ())
14714     FAIL;
14716   for (i = 2; i < 13; i++)
14717     operands[i] = gen_reg_rtx (XFmode);
14719   operands[13]
14720     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14722   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14725 (define_expand "expm1<mode>2"
14726   [(use (match_operand:MODEF 0 "register_operand"))
14727    (use (match_operand:MODEF 1 "general_operand"))]
14728  "TARGET_USE_FANCY_MATH_387
14729    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14730        || TARGET_MIX_SSE_I387)
14731    && flag_unsafe_math_optimizations"
14733   rtx op0, op1;
14735   if (optimize_insn_for_size_p ())
14736     FAIL;
14738   op0 = gen_reg_rtx (XFmode);
14739   op1 = gen_reg_rtx (XFmode);
14741   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14742   emit_insn (gen_expm1xf2 (op0, op1));
14743   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14744   DONE;
14747 (define_expand "ldexpxf3"
14748   [(match_operand:XF 0 "register_operand")
14749    (match_operand:XF 1 "register_operand")
14750    (match_operand:SI 2 "register_operand")]
14751   "TARGET_USE_FANCY_MATH_387
14752    && flag_unsafe_math_optimizations"
14754   rtx tmp1, tmp2;
14755   if (optimize_insn_for_size_p ())
14756     FAIL;
14758   tmp1 = gen_reg_rtx (XFmode);
14759   tmp2 = gen_reg_rtx (XFmode);
14761   emit_insn (gen_floatsixf2 (tmp1, operands[2]));
14762   emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
14763                                  operands[1], tmp1));
14764   DONE;
14767 (define_expand "ldexp<mode>3"
14768   [(use (match_operand:MODEF 0 "register_operand"))
14769    (use (match_operand:MODEF 1 "general_operand"))
14770    (use (match_operand:SI 2 "register_operand"))]
14771  "TARGET_USE_FANCY_MATH_387
14772    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14773        || TARGET_MIX_SSE_I387)
14774    && flag_unsafe_math_optimizations"
14776   rtx op0, op1;
14778   if (optimize_insn_for_size_p ())
14779     FAIL;
14781   op0 = gen_reg_rtx (XFmode);
14782   op1 = gen_reg_rtx (XFmode);
14784   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14785   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14786   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14787   DONE;
14790 (define_expand "scalbxf3"
14791   [(parallel [(set (match_operand:XF 0 " register_operand")
14792                    (unspec:XF [(match_operand:XF 1 "register_operand")
14793                                (match_operand:XF 2 "register_operand")]
14794                               UNSPEC_FSCALE_FRACT))
14795               (set (match_dup 3)
14796                    (unspec:XF [(match_dup 1) (match_dup 2)]
14797                               UNSPEC_FSCALE_EXP))])]
14798   "TARGET_USE_FANCY_MATH_387
14799    && flag_unsafe_math_optimizations"
14801   if (optimize_insn_for_size_p ())
14802     FAIL;
14804   operands[3] = gen_reg_rtx (XFmode);
14807 (define_expand "scalb<mode>3"
14808   [(use (match_operand:MODEF 0 "register_operand"))
14809    (use (match_operand:MODEF 1 "general_operand"))
14810    (use (match_operand:MODEF 2 "general_operand"))]
14811  "TARGET_USE_FANCY_MATH_387
14812    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14813        || TARGET_MIX_SSE_I387)
14814    && flag_unsafe_math_optimizations"
14816   rtx op0, op1, op2;
14818   if (optimize_insn_for_size_p ())
14819     FAIL;
14821   op0 = gen_reg_rtx (XFmode);
14822   op1 = gen_reg_rtx (XFmode);
14823   op2 = gen_reg_rtx (XFmode);
14825   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14826   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14827   emit_insn (gen_scalbxf3 (op0, op1, op2));
14828   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14829   DONE;
14832 (define_expand "significandxf2"
14833   [(parallel [(set (match_operand:XF 0 "register_operand")
14834                    (unspec:XF [(match_operand:XF 1 "register_operand")]
14835                               UNSPEC_XTRACT_FRACT))
14836               (set (match_dup 2)
14837                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14838   "TARGET_USE_FANCY_MATH_387
14839    && flag_unsafe_math_optimizations"
14840   "operands[2] = gen_reg_rtx (XFmode);")
14842 (define_expand "significand<mode>2"
14843   [(use (match_operand:MODEF 0 "register_operand"))
14844    (use (match_operand:MODEF 1 "register_operand"))]
14845   "TARGET_USE_FANCY_MATH_387
14846    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14847        || TARGET_MIX_SSE_I387)
14848    && flag_unsafe_math_optimizations"
14850   rtx op0 = gen_reg_rtx (XFmode);
14851   rtx op1 = gen_reg_rtx (XFmode);
14853   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14854   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14855   DONE;
14859 (define_insn "sse4_1_round<mode>2"
14860   [(set (match_operand:MODEF 0 "register_operand" "=x")
14861         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14862                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14863                       UNSPEC_ROUND))]
14864   "TARGET_ROUND"
14865   "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14866   [(set_attr "type" "ssecvt")
14867    (set_attr "prefix_extra" "1")
14868    (set_attr "prefix" "maybe_vex")
14869    (set_attr "mode" "<MODE>")])
14871 (define_insn "rintxf2"
14872   [(set (match_operand:XF 0 "register_operand" "=f")
14873         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14874                    UNSPEC_FRNDINT))]
14875   "TARGET_USE_FANCY_MATH_387
14876    && flag_unsafe_math_optimizations"
14877   "frndint"
14878   [(set_attr "type" "fpspc")
14879    (set_attr "mode" "XF")])
14881 (define_expand "rint<mode>2"
14882   [(use (match_operand:MODEF 0 "register_operand"))
14883    (use (match_operand:MODEF 1 "register_operand"))]
14884   "(TARGET_USE_FANCY_MATH_387
14885     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14886         || TARGET_MIX_SSE_I387)
14887     && flag_unsafe_math_optimizations)
14888    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14889        && !flag_trapping_math)"
14891   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14892       && !flag_trapping_math)
14893     {
14894       if (TARGET_ROUND)
14895         emit_insn (gen_sse4_1_round<mode>2
14896                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14897       else if (optimize_insn_for_size_p ())
14898         FAIL;
14899       else
14900         ix86_expand_rint (operands[0], operands[1]);
14901     }
14902   else
14903     {
14904       rtx op0 = gen_reg_rtx (XFmode);
14905       rtx op1 = gen_reg_rtx (XFmode);
14907       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14908       emit_insn (gen_rintxf2 (op0, op1));
14910       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14911     }
14912   DONE;
14915 (define_expand "round<mode>2"
14916   [(match_operand:X87MODEF 0 "register_operand")
14917    (match_operand:X87MODEF 1 "nonimmediate_operand")]
14918   "(TARGET_USE_FANCY_MATH_387
14919     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14920         || TARGET_MIX_SSE_I387)
14921     && flag_unsafe_math_optimizations)
14922    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14923        && !flag_trapping_math && !flag_rounding_math)"
14925   if (optimize_insn_for_size_p ())
14926     FAIL;
14928   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14929       && !flag_trapping_math && !flag_rounding_math)
14930     {
14931       if (TARGET_ROUND)
14932         {
14933           operands[1] = force_reg (<MODE>mode, operands[1]);
14934           ix86_expand_round_sse4 (operands[0], operands[1]);
14935         }
14936       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14937         ix86_expand_round (operands[0], operands[1]);
14938       else
14939         ix86_expand_rounddf_32 (operands[0], operands[1]);
14940     }
14941   else
14942     {
14943       operands[1] = force_reg (<MODE>mode, operands[1]);
14944       ix86_emit_i387_round (operands[0], operands[1]);
14945     }
14946   DONE;
14949 (define_insn_and_split "*fistdi2_1"
14950   [(set (match_operand:DI 0 "nonimmediate_operand")
14951         (unspec:DI [(match_operand:XF 1 "register_operand")]
14952                    UNSPEC_FIST))]
14953   "TARGET_USE_FANCY_MATH_387
14954    && can_create_pseudo_p ()"
14955   "#"
14956   "&& 1"
14957   [(const_int 0)]
14959   if (memory_operand (operands[0], VOIDmode))
14960     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14961   else
14962     {
14963       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14964       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14965                                          operands[2]));
14966     }
14967   DONE;
14969   [(set_attr "type" "fpspc")
14970    (set_attr "mode" "DI")])
14972 (define_insn "fistdi2"
14973   [(set (match_operand:DI 0 "memory_operand" "=m")
14974         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14975                    UNSPEC_FIST))
14976    (clobber (match_scratch:XF 2 "=&1f"))]
14977   "TARGET_USE_FANCY_MATH_387"
14978   "* return output_fix_trunc (insn, operands, false);"
14979   [(set_attr "type" "fpspc")
14980    (set_attr "mode" "DI")])
14982 (define_insn "fistdi2_with_temp"
14983   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14984         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14985                    UNSPEC_FIST))
14986    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14987    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14988   "TARGET_USE_FANCY_MATH_387"
14989   "#"
14990   [(set_attr "type" "fpspc")
14991    (set_attr "mode" "DI")])
14993 (define_split
14994   [(set (match_operand:DI 0 "register_operand")
14995         (unspec:DI [(match_operand:XF 1 "register_operand")]
14996                    UNSPEC_FIST))
14997    (clobber (match_operand:DI 2 "memory_operand"))
14998    (clobber (match_scratch 3))]
14999   "reload_completed"
15000   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15001               (clobber (match_dup 3))])
15002    (set (match_dup 0) (match_dup 2))])
15004 (define_split
15005   [(set (match_operand:DI 0 "memory_operand")
15006         (unspec:DI [(match_operand:XF 1 "register_operand")]
15007                    UNSPEC_FIST))
15008    (clobber (match_operand:DI 2 "memory_operand"))
15009    (clobber (match_scratch 3))]
15010   "reload_completed"
15011   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15012               (clobber (match_dup 3))])])
15014 (define_insn_and_split "*fist<mode>2_1"
15015   [(set (match_operand:SWI24 0 "register_operand")
15016         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15017                       UNSPEC_FIST))]
15018   "TARGET_USE_FANCY_MATH_387
15019    && can_create_pseudo_p ()"
15020   "#"
15021   "&& 1"
15022   [(const_int 0)]
15024   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15025   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15026                                         operands[2]));
15027   DONE;
15029   [(set_attr "type" "fpspc")
15030    (set_attr "mode" "<MODE>")])
15032 (define_insn "fist<mode>2"
15033   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15034         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15035                       UNSPEC_FIST))]
15036   "TARGET_USE_FANCY_MATH_387"
15037   "* return output_fix_trunc (insn, operands, false);"
15038   [(set_attr "type" "fpspc")
15039    (set_attr "mode" "<MODE>")])
15041 (define_insn "fist<mode>2_with_temp"
15042   [(set (match_operand:SWI24 0 "register_operand" "=r")
15043         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15044                       UNSPEC_FIST))
15045    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15046   "TARGET_USE_FANCY_MATH_387"
15047   "#"
15048   [(set_attr "type" "fpspc")
15049    (set_attr "mode" "<MODE>")])
15051 (define_split
15052   [(set (match_operand:SWI24 0 "register_operand")
15053         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15054                       UNSPEC_FIST))
15055    (clobber (match_operand:SWI24 2 "memory_operand"))]
15056   "reload_completed"
15057   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15058    (set (match_dup 0) (match_dup 2))])
15060 (define_split
15061   [(set (match_operand:SWI24 0 "memory_operand")
15062         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15063                       UNSPEC_FIST))
15064    (clobber (match_operand:SWI24 2 "memory_operand"))]
15065   "reload_completed"
15066   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15068 (define_expand "lrintxf<mode>2"
15069   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15070      (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15071                      UNSPEC_FIST))]
15072   "TARGET_USE_FANCY_MATH_387")
15074 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15075   [(set (match_operand:SWI48 0 "nonimmediate_operand")
15076      (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15077                    UNSPEC_FIX_NOTRUNC))]
15078   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15080 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15081   [(match_operand:SWI248x 0 "nonimmediate_operand")
15082    (match_operand:X87MODEF 1 "register_operand")]
15083   "(TARGET_USE_FANCY_MATH_387
15084     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15085         || TARGET_MIX_SSE_I387)
15086     && flag_unsafe_math_optimizations)
15087    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15088        && <SWI248x:MODE>mode != HImode 
15089        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15090        && !flag_trapping_math && !flag_rounding_math)"
15092   if (optimize_insn_for_size_p ())
15093     FAIL;
15095   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15096       && <SWI248x:MODE>mode != HImode
15097       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15098       && !flag_trapping_math && !flag_rounding_math)
15099     ix86_expand_lround (operands[0], operands[1]);
15100   else
15101     ix86_emit_i387_round (operands[0], operands[1]);
15102   DONE;
15105 (define_int_iterator FRNDINT_ROUNDING
15106         [UNSPEC_FRNDINT_FLOOR
15107          UNSPEC_FRNDINT_CEIL
15108          UNSPEC_FRNDINT_TRUNC])
15110 (define_int_iterator FIST_ROUNDING
15111         [UNSPEC_FIST_FLOOR
15112          UNSPEC_FIST_CEIL])
15114 ;; Base name for define_insn
15115 (define_int_attr rounding_insn
15116         [(UNSPEC_FRNDINT_FLOOR "floor")
15117          (UNSPEC_FRNDINT_CEIL "ceil")
15118          (UNSPEC_FRNDINT_TRUNC "btrunc")
15119          (UNSPEC_FIST_FLOOR "floor")
15120          (UNSPEC_FIST_CEIL "ceil")])
15122 (define_int_attr rounding
15123         [(UNSPEC_FRNDINT_FLOOR "floor")
15124          (UNSPEC_FRNDINT_CEIL "ceil")
15125          (UNSPEC_FRNDINT_TRUNC "trunc")
15126          (UNSPEC_FIST_FLOOR "floor")
15127          (UNSPEC_FIST_CEIL "ceil")])
15129 (define_int_attr ROUNDING
15130         [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15131          (UNSPEC_FRNDINT_CEIL "CEIL")
15132          (UNSPEC_FRNDINT_TRUNC "TRUNC")
15133          (UNSPEC_FIST_FLOOR "FLOOR")
15134          (UNSPEC_FIST_CEIL "CEIL")])
15136 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15137 (define_insn_and_split "frndintxf2_<rounding>"
15138   [(set (match_operand:XF 0 "register_operand")
15139         (unspec:XF [(match_operand:XF 1 "register_operand")]
15140                    FRNDINT_ROUNDING))
15141    (clobber (reg:CC FLAGS_REG))]
15142   "TARGET_USE_FANCY_MATH_387
15143    && flag_unsafe_math_optimizations
15144    && can_create_pseudo_p ()"
15145   "#"
15146   "&& 1"
15147   [(const_int 0)]
15149   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15151   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15152   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15154   emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15155                                              operands[2], operands[3]));
15156   DONE;
15158   [(set_attr "type" "frndint")
15159    (set_attr "i387_cw" "<rounding>")
15160    (set_attr "mode" "XF")])
15162 (define_insn "frndintxf2_<rounding>_i387"
15163   [(set (match_operand:XF 0 "register_operand" "=f")
15164         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15165                    FRNDINT_ROUNDING))
15166    (use (match_operand:HI 2 "memory_operand" "m"))
15167    (use (match_operand:HI 3 "memory_operand" "m"))]
15168   "TARGET_USE_FANCY_MATH_387
15169    && flag_unsafe_math_optimizations"
15170   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15171   [(set_attr "type" "frndint")
15172    (set_attr "i387_cw" "<rounding>")
15173    (set_attr "mode" "XF")])
15175 (define_expand "<rounding_insn>xf2"
15176   [(parallel [(set (match_operand:XF 0 "register_operand")
15177                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15178                               FRNDINT_ROUNDING))
15179               (clobber (reg:CC FLAGS_REG))])]
15180   "TARGET_USE_FANCY_MATH_387
15181    && flag_unsafe_math_optimizations
15182    && !optimize_insn_for_size_p ()")
15184 (define_expand "<rounding_insn><mode>2"
15185   [(parallel [(set (match_operand:MODEF 0 "register_operand")
15186                    (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15187                                  FRNDINT_ROUNDING))
15188               (clobber (reg:CC FLAGS_REG))])]
15189   "(TARGET_USE_FANCY_MATH_387
15190     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15191         || TARGET_MIX_SSE_I387)
15192     && flag_unsafe_math_optimizations)
15193    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15194        && !flag_trapping_math)"
15196   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15197       && !flag_trapping_math)
15198     {
15199       if (TARGET_ROUND)
15200         emit_insn (gen_sse4_1_round<mode>2
15201                    (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15202       else if (optimize_insn_for_size_p ())
15203         FAIL;
15204       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15205         {
15206           if (ROUND_<ROUNDING> == ROUND_FLOOR)
15207             ix86_expand_floorceil (operands[0], operands[1], true);
15208           else if (ROUND_<ROUNDING> == ROUND_CEIL)
15209             ix86_expand_floorceil (operands[0], operands[1], false);
15210           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15211             ix86_expand_trunc (operands[0], operands[1]);
15212           else
15213             gcc_unreachable ();
15214         }
15215       else
15216         {
15217           if (ROUND_<ROUNDING> == ROUND_FLOOR)
15218             ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15219           else if (ROUND_<ROUNDING> == ROUND_CEIL)
15220             ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15221           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15222             ix86_expand_truncdf_32 (operands[0], operands[1]);
15223           else
15224             gcc_unreachable ();
15225         }
15226     }
15227   else
15228     {
15229       rtx op0, op1;
15231       if (optimize_insn_for_size_p ())
15232         FAIL;
15234       op0 = gen_reg_rtx (XFmode);
15235       op1 = gen_reg_rtx (XFmode);
15236       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15237       emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15239       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15240     }
15241   DONE;
15244 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15245 (define_insn_and_split "frndintxf2_mask_pm"
15246   [(set (match_operand:XF 0 "register_operand")
15247         (unspec:XF [(match_operand:XF 1 "register_operand")]
15248                    UNSPEC_FRNDINT_MASK_PM))
15249    (clobber (reg:CC FLAGS_REG))]
15250   "TARGET_USE_FANCY_MATH_387
15251    && flag_unsafe_math_optimizations
15252    && can_create_pseudo_p ()"
15253   "#"
15254   "&& 1"
15255   [(const_int 0)]
15257   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15259   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15260   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15262   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15263                                           operands[2], operands[3]));
15264   DONE;
15266   [(set_attr "type" "frndint")
15267    (set_attr "i387_cw" "mask_pm")
15268    (set_attr "mode" "XF")])
15270 (define_insn "frndintxf2_mask_pm_i387"
15271   [(set (match_operand:XF 0 "register_operand" "=f")
15272         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15273                    UNSPEC_FRNDINT_MASK_PM))
15274    (use (match_operand:HI 2 "memory_operand" "m"))
15275    (use (match_operand:HI 3 "memory_operand" "m"))]
15276   "TARGET_USE_FANCY_MATH_387
15277    && flag_unsafe_math_optimizations"
15278   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15279   [(set_attr "type" "frndint")
15280    (set_attr "i387_cw" "mask_pm")
15281    (set_attr "mode" "XF")])
15283 (define_expand "nearbyintxf2"
15284   [(parallel [(set (match_operand:XF 0 "register_operand")
15285                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15286                               UNSPEC_FRNDINT_MASK_PM))
15287               (clobber (reg:CC FLAGS_REG))])]
15288   "TARGET_USE_FANCY_MATH_387
15289    && flag_unsafe_math_optimizations")
15291 (define_expand "nearbyint<mode>2"
15292   [(use (match_operand:MODEF 0 "register_operand"))
15293    (use (match_operand:MODEF 1 "register_operand"))]
15294   "TARGET_USE_FANCY_MATH_387
15295    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15296        || TARGET_MIX_SSE_I387)
15297    && flag_unsafe_math_optimizations"
15299   rtx op0 = gen_reg_rtx (XFmode);
15300   rtx op1 = gen_reg_rtx (XFmode);
15302   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15303   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15305   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15306   DONE;
15309 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15310 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15311   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15312         (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15313                         FIST_ROUNDING))
15314    (clobber (reg:CC FLAGS_REG))]
15315   "TARGET_USE_FANCY_MATH_387
15316    && flag_unsafe_math_optimizations
15317    && can_create_pseudo_p ()"
15318   "#"
15319   "&& 1"
15320   [(const_int 0)]
15322   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15324   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15325   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15326   if (memory_operand (operands[0], VOIDmode))
15327     emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15328                                            operands[2], operands[3]));
15329   else
15330     {
15331       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15332       emit_insn (gen_fist<mode>2_<rounding>_with_temp
15333                   (operands[0], operands[1], operands[2],
15334                    operands[3], operands[4]));
15335     }
15336   DONE;
15338   [(set_attr "type" "fistp")
15339    (set_attr "i387_cw" "<rounding>")
15340    (set_attr "mode" "<MODE>")])
15342 (define_insn "fistdi2_<rounding>"
15343   [(set (match_operand:DI 0 "memory_operand" "=m")
15344         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15345                    FIST_ROUNDING))
15346    (use (match_operand:HI 2 "memory_operand" "m"))
15347    (use (match_operand:HI 3 "memory_operand" "m"))
15348    (clobber (match_scratch:XF 4 "=&1f"))]
15349   "TARGET_USE_FANCY_MATH_387
15350    && flag_unsafe_math_optimizations"
15351   "* return output_fix_trunc (insn, operands, false);"
15352   [(set_attr "type" "fistp")
15353    (set_attr "i387_cw" "<rounding>")
15354    (set_attr "mode" "DI")])
15356 (define_insn "fistdi2_<rounding>_with_temp"
15357   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15358         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15359                    FIST_ROUNDING))
15360    (use (match_operand:HI 2 "memory_operand" "m,m"))
15361    (use (match_operand:HI 3 "memory_operand" "m,m"))
15362    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15363    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15364   "TARGET_USE_FANCY_MATH_387
15365    && flag_unsafe_math_optimizations"
15366   "#"
15367   [(set_attr "type" "fistp")
15368    (set_attr "i387_cw" "<rounding>")
15369    (set_attr "mode" "DI")])
15371 (define_split
15372   [(set (match_operand:DI 0 "register_operand")
15373         (unspec:DI [(match_operand:XF 1 "register_operand")]
15374                    FIST_ROUNDING))
15375    (use (match_operand:HI 2 "memory_operand"))
15376    (use (match_operand:HI 3 "memory_operand"))
15377    (clobber (match_operand:DI 4 "memory_operand"))
15378    (clobber (match_scratch 5))]
15379   "reload_completed"
15380   [(parallel [(set (match_dup 4)
15381                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15382               (use (match_dup 2))
15383               (use (match_dup 3))
15384               (clobber (match_dup 5))])
15385    (set (match_dup 0) (match_dup 4))])
15387 (define_split
15388   [(set (match_operand:DI 0 "memory_operand")
15389         (unspec:DI [(match_operand:XF 1 "register_operand")]
15390                    FIST_ROUNDING))
15391    (use (match_operand:HI 2 "memory_operand"))
15392    (use (match_operand:HI 3 "memory_operand"))
15393    (clobber (match_operand:DI 4 "memory_operand"))
15394    (clobber (match_scratch 5))]
15395   "reload_completed"
15396   [(parallel [(set (match_dup 0)
15397                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15398               (use (match_dup 2))
15399               (use (match_dup 3))
15400               (clobber (match_dup 5))])])
15402 (define_insn "fist<mode>2_<rounding>"
15403   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15404         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15405                       FIST_ROUNDING))
15406    (use (match_operand:HI 2 "memory_operand" "m"))
15407    (use (match_operand:HI 3 "memory_operand" "m"))]
15408   "TARGET_USE_FANCY_MATH_387
15409    && flag_unsafe_math_optimizations"
15410   "* return output_fix_trunc (insn, operands, false);"
15411   [(set_attr "type" "fistp")
15412    (set_attr "i387_cw" "<rounding>")
15413    (set_attr "mode" "<MODE>")])
15415 (define_insn "fist<mode>2_<rounding>_with_temp"
15416   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15417         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15418                       FIST_ROUNDING))
15419    (use (match_operand:HI 2 "memory_operand" "m,m"))
15420    (use (match_operand:HI 3 "memory_operand" "m,m"))
15421    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15422   "TARGET_USE_FANCY_MATH_387
15423    && flag_unsafe_math_optimizations"
15424   "#"
15425   [(set_attr "type" "fistp")
15426    (set_attr "i387_cw" "<rounding>")
15427    (set_attr "mode" "<MODE>")])
15429 (define_split
15430   [(set (match_operand:SWI24 0 "register_operand")
15431         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15432                       FIST_ROUNDING))
15433    (use (match_operand:HI 2 "memory_operand"))
15434    (use (match_operand:HI 3 "memory_operand"))
15435    (clobber (match_operand:SWI24 4 "memory_operand"))]
15436   "reload_completed"
15437   [(parallel [(set (match_dup 4)
15438                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15439               (use (match_dup 2))
15440               (use (match_dup 3))])
15441    (set (match_dup 0) (match_dup 4))])
15443 (define_split
15444   [(set (match_operand:SWI24 0 "memory_operand")
15445         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15446                       FIST_ROUNDING))
15447    (use (match_operand:HI 2 "memory_operand"))
15448    (use (match_operand:HI 3 "memory_operand"))
15449    (clobber (match_operand:SWI24 4 "memory_operand"))]
15450   "reload_completed"
15451   [(parallel [(set (match_dup 0)
15452                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15453               (use (match_dup 2))
15454               (use (match_dup 3))])])
15456 (define_expand "l<rounding_insn>xf<mode>2"
15457   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15458                    (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15459                                    FIST_ROUNDING))
15460               (clobber (reg:CC FLAGS_REG))])]
15461   "TARGET_USE_FANCY_MATH_387
15462    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15463    && flag_unsafe_math_optimizations")
15465 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15466   [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15467                    (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15468                                  FIST_ROUNDING))
15469               (clobber (reg:CC FLAGS_REG))])]
15470   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15471    && !flag_trapping_math"
15473   if (TARGET_64BIT && optimize_insn_for_size_p ())
15474     FAIL;
15476   if (ROUND_<ROUNDING> == ROUND_FLOOR)
15477     ix86_expand_lfloorceil (operands[0], operands[1], true);
15478   else if (ROUND_<ROUNDING> == ROUND_CEIL)
15479     ix86_expand_lfloorceil (operands[0], operands[1], false);
15480   else
15481     gcc_unreachable ();
15483   DONE;
15486 (define_insn "fxam<mode>2_i387"
15487   [(set (match_operand:HI 0 "register_operand" "=a")
15488         (unspec:HI
15489           [(match_operand:X87MODEF 1 "register_operand" "f")]
15490           UNSPEC_FXAM))]
15491   "TARGET_USE_FANCY_MATH_387"
15492   "fxam\n\tfnstsw\t%0"
15493   [(set_attr "type" "multi")
15494    (set_attr "length" "4")
15495    (set_attr "unit" "i387")
15496    (set_attr "mode" "<MODE>")])
15498 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15499   [(set (match_operand:HI 0 "register_operand")
15500         (unspec:HI
15501           [(match_operand:MODEF 1 "memory_operand")]
15502           UNSPEC_FXAM_MEM))]
15503   "TARGET_USE_FANCY_MATH_387
15504    && can_create_pseudo_p ()"
15505   "#"
15506   "&& 1"
15507   [(set (match_dup 2)(match_dup 1))
15508    (set (match_dup 0)
15509         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15511   operands[2] = gen_reg_rtx (<MODE>mode);
15513   MEM_VOLATILE_P (operands[1]) = 1;
15515   [(set_attr "type" "multi")
15516    (set_attr "unit" "i387")
15517    (set_attr "mode" "<MODE>")])
15519 (define_expand "isinfxf2"
15520   [(use (match_operand:SI 0 "register_operand"))
15521    (use (match_operand:XF 1 "register_operand"))]
15522   "TARGET_USE_FANCY_MATH_387
15523    && ix86_libc_has_function (function_c99_misc)"
15525   rtx mask = GEN_INT (0x45);
15526   rtx val = GEN_INT (0x05);
15528   rtx cond;
15530   rtx scratch = gen_reg_rtx (HImode);
15531   rtx res = gen_reg_rtx (QImode);
15533   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15535   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15536   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15537   cond = gen_rtx_fmt_ee (EQ, QImode,
15538                          gen_rtx_REG (CCmode, FLAGS_REG),
15539                          const0_rtx);
15540   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15541   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15542   DONE;
15545 (define_expand "isinf<mode>2"
15546   [(use (match_operand:SI 0 "register_operand"))
15547    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15548   "TARGET_USE_FANCY_MATH_387
15549    && ix86_libc_has_function (function_c99_misc)
15550    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15552   rtx mask = GEN_INT (0x45);
15553   rtx val = GEN_INT (0x05);
15555   rtx cond;
15557   rtx scratch = gen_reg_rtx (HImode);
15558   rtx res = gen_reg_rtx (QImode);
15560   /* Remove excess precision by forcing value through memory. */
15561   if (memory_operand (operands[1], VOIDmode))
15562     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15563   else
15564     {
15565       rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15567       emit_move_insn (temp, operands[1]);
15568       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15569     }
15571   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15572   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15573   cond = gen_rtx_fmt_ee (EQ, QImode,
15574                          gen_rtx_REG (CCmode, FLAGS_REG),
15575                          const0_rtx);
15576   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15577   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15578   DONE;
15581 (define_expand "signbitxf2"
15582   [(use (match_operand:SI 0 "register_operand"))
15583    (use (match_operand:XF 1 "register_operand"))]
15584   "TARGET_USE_FANCY_MATH_387"
15586   rtx scratch = gen_reg_rtx (HImode);
15588   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15589   emit_insn (gen_andsi3 (operands[0],
15590              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15591   DONE;
15594 (define_insn "movmsk_df"
15595   [(set (match_operand:SI 0 "register_operand" "=r")
15596         (unspec:SI
15597           [(match_operand:DF 1 "register_operand" "x")]
15598           UNSPEC_MOVMSK))]
15599   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15600   "%vmovmskpd\t{%1, %0|%0, %1}"
15601   [(set_attr "type" "ssemov")
15602    (set_attr "prefix" "maybe_vex")
15603    (set_attr "mode" "DF")])
15605 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15606 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15607 (define_expand "signbitdf2"
15608   [(use (match_operand:SI 0 "register_operand"))
15609    (use (match_operand:DF 1 "register_operand"))]
15610   "TARGET_USE_FANCY_MATH_387
15611    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15613   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15614     {
15615       emit_insn (gen_movmsk_df (operands[0], operands[1]));
15616       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15617     }
15618   else
15619     {
15620       rtx scratch = gen_reg_rtx (HImode);
15622       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15623       emit_insn (gen_andsi3 (operands[0],
15624                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15625     }
15626   DONE;
15629 (define_expand "signbitsf2"
15630   [(use (match_operand:SI 0 "register_operand"))
15631    (use (match_operand:SF 1 "register_operand"))]
15632   "TARGET_USE_FANCY_MATH_387
15633    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15635   rtx scratch = gen_reg_rtx (HImode);
15637   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15638   emit_insn (gen_andsi3 (operands[0],
15639              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15640   DONE;
15643 ;; Block operation instructions
15645 (define_insn "cld"
15646   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15647   ""
15648   "cld"
15649   [(set_attr "length" "1")
15650    (set_attr "length_immediate" "0")
15651    (set_attr "modrm" "0")])
15653 (define_expand "movmem<mode>"
15654   [(use (match_operand:BLK 0 "memory_operand"))
15655    (use (match_operand:BLK 1 "memory_operand"))
15656    (use (match_operand:SWI48 2 "nonmemory_operand"))
15657    (use (match_operand:SWI48 3 "const_int_operand"))
15658    (use (match_operand:SI 4 "const_int_operand"))
15659    (use (match_operand:SI 5 "const_int_operand"))
15660    (use (match_operand:SI 6 ""))
15661    (use (match_operand:SI 7 ""))
15662    (use (match_operand:SI 8 ""))]
15663   ""
15665  if (ix86_expand_set_or_movmem (operands[0], operands[1],
15666                                 operands[2], NULL, operands[3],
15667                                 operands[4], operands[5],
15668                                 operands[6], operands[7],
15669                                 operands[8], false))
15670    DONE;
15671  else
15672    FAIL;
15675 ;; Most CPUs don't like single string operations
15676 ;; Handle this case here to simplify previous expander.
15678 (define_expand "strmov"
15679   [(set (match_dup 4) (match_operand 3 "memory_operand"))
15680    (set (match_operand 1 "memory_operand") (match_dup 4))
15681    (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15682               (clobber (reg:CC FLAGS_REG))])
15683    (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15684               (clobber (reg:CC FLAGS_REG))])]
15685   ""
15687   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15689   /* If .md ever supports :P for Pmode, these can be directly
15690      in the pattern above.  */
15691   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15692   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15694   /* Can't use this if the user has appropriated esi or edi.  */
15695   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15696       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15697     {
15698       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15699                                       operands[2], operands[3],
15700                                       operands[5], operands[6]));
15701       DONE;
15702     }
15704   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15707 (define_expand "strmov_singleop"
15708   [(parallel [(set (match_operand 1 "memory_operand")
15709                    (match_operand 3 "memory_operand"))
15710               (set (match_operand 0 "register_operand")
15711                    (match_operand 4))
15712               (set (match_operand 2 "register_operand")
15713                    (match_operand 5))])]
15714   ""
15715   "ix86_current_function_needs_cld = 1;")
15717 (define_insn "*strmovdi_rex_1"
15718   [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15719         (mem:DI (match_operand:P 3 "register_operand" "1")))
15720    (set (match_operand:P 0 "register_operand" "=D")
15721         (plus:P (match_dup 2)
15722                 (const_int 8)))
15723    (set (match_operand:P 1 "register_operand" "=S")
15724         (plus:P (match_dup 3)
15725                 (const_int 8)))]
15726   "TARGET_64BIT
15727    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15728   "%^movsq"
15729   [(set_attr "type" "str")
15730    (set_attr "memory" "both")
15731    (set_attr "mode" "DI")])
15733 (define_insn "*strmovsi_1"
15734   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15735         (mem:SI (match_operand:P 3 "register_operand" "1")))
15736    (set (match_operand:P 0 "register_operand" "=D")
15737         (plus:P (match_dup 2)
15738                 (const_int 4)))
15739    (set (match_operand:P 1 "register_operand" "=S")
15740         (plus:P (match_dup 3)
15741                 (const_int 4)))]
15742   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15743   "%^movs{l|d}"
15744   [(set_attr "type" "str")
15745    (set_attr "memory" "both")
15746    (set_attr "mode" "SI")])
15748 (define_insn "*strmovhi_1"
15749   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15750         (mem:HI (match_operand:P 3 "register_operand" "1")))
15751    (set (match_operand:P 0 "register_operand" "=D")
15752         (plus:P (match_dup 2)
15753                 (const_int 2)))
15754    (set (match_operand:P 1 "register_operand" "=S")
15755         (plus:P (match_dup 3)
15756                 (const_int 2)))]
15757   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15758   "%^movsw"
15759   [(set_attr "type" "str")
15760    (set_attr "memory" "both")
15761    (set_attr "mode" "HI")])
15763 (define_insn "*strmovqi_1"
15764   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15765         (mem:QI (match_operand:P 3 "register_operand" "1")))
15766    (set (match_operand:P 0 "register_operand" "=D")
15767         (plus:P (match_dup 2)
15768                 (const_int 1)))
15769    (set (match_operand:P 1 "register_operand" "=S")
15770         (plus:P (match_dup 3)
15771                 (const_int 1)))]
15772   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15773   "%^movsb"
15774   [(set_attr "type" "str")
15775    (set_attr "memory" "both")
15776    (set (attr "prefix_rex")
15777         (if_then_else
15778           (match_test "<P:MODE>mode == DImode")
15779           (const_string "0")
15780           (const_string "*")))
15781    (set_attr "mode" "QI")])
15783 (define_expand "rep_mov"
15784   [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15785               (set (match_operand 0 "register_operand")
15786                    (match_operand 5))
15787               (set (match_operand 2 "register_operand")
15788                    (match_operand 6))
15789               (set (match_operand 1 "memory_operand")
15790                    (match_operand 3 "memory_operand"))
15791               (use (match_dup 4))])]
15792   ""
15793   "ix86_current_function_needs_cld = 1;")
15795 (define_insn "*rep_movdi_rex64"
15796   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15797    (set (match_operand:P 0 "register_operand" "=D")
15798         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15799                           (const_int 3))
15800                 (match_operand:P 3 "register_operand" "0")))
15801    (set (match_operand:P 1 "register_operand" "=S")
15802         (plus:P (ashift:P (match_dup 5) (const_int 3))
15803                 (match_operand:P 4 "register_operand" "1")))
15804    (set (mem:BLK (match_dup 3))
15805         (mem:BLK (match_dup 4)))
15806    (use (match_dup 5))]
15807   "TARGET_64BIT
15808    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15809   "%^rep{%;} movsq"
15810   [(set_attr "type" "str")
15811    (set_attr "prefix_rep" "1")
15812    (set_attr "memory" "both")
15813    (set_attr "mode" "DI")])
15815 (define_insn "*rep_movsi"
15816   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15817    (set (match_operand:P 0 "register_operand" "=D")
15818         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15819                           (const_int 2))
15820                  (match_operand:P 3 "register_operand" "0")))
15821    (set (match_operand:P 1 "register_operand" "=S")
15822         (plus:P (ashift:P (match_dup 5) (const_int 2))
15823                 (match_operand:P 4 "register_operand" "1")))
15824    (set (mem:BLK (match_dup 3))
15825         (mem:BLK (match_dup 4)))
15826    (use (match_dup 5))]
15827   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15828   "%^rep{%;} movs{l|d}"
15829   [(set_attr "type" "str")
15830    (set_attr "prefix_rep" "1")
15831    (set_attr "memory" "both")
15832    (set_attr "mode" "SI")])
15834 (define_insn "*rep_movqi"
15835   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15836    (set (match_operand:P 0 "register_operand" "=D")
15837         (plus:P (match_operand:P 3 "register_operand" "0")
15838                 (match_operand:P 5 "register_operand" "2")))
15839    (set (match_operand:P 1 "register_operand" "=S")
15840         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15841    (set (mem:BLK (match_dup 3))
15842         (mem:BLK (match_dup 4)))
15843    (use (match_dup 5))]
15844   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15845   "%^rep{%;} movsb"
15846   [(set_attr "type" "str")
15847    (set_attr "prefix_rep" "1")
15848    (set_attr "memory" "both")
15849    (set_attr "mode" "QI")])
15851 (define_expand "setmem<mode>"
15852    [(use (match_operand:BLK 0 "memory_operand"))
15853     (use (match_operand:SWI48 1 "nonmemory_operand"))
15854     (use (match_operand:QI 2 "nonmemory_operand"))
15855     (use (match_operand 3 "const_int_operand"))
15856     (use (match_operand:SI 4 "const_int_operand"))
15857     (use (match_operand:SI 5 "const_int_operand"))
15858     (use (match_operand:SI 6 ""))
15859     (use (match_operand:SI 7 ""))
15860     (use (match_operand:SI 8 ""))]
15861   ""
15863  if (ix86_expand_set_or_movmem (operands[0], NULL,
15864                                 operands[1], operands[2],
15865                                 operands[3], operands[4],
15866                                 operands[5], operands[6],
15867                                 operands[7], operands[8], true))
15868    DONE;
15869  else
15870    FAIL;
15873 ;; Most CPUs don't like single string operations
15874 ;; Handle this case here to simplify previous expander.
15876 (define_expand "strset"
15877   [(set (match_operand 1 "memory_operand")
15878         (match_operand 2 "register_operand"))
15879    (parallel [(set (match_operand 0 "register_operand")
15880                    (match_dup 3))
15881               (clobber (reg:CC FLAGS_REG))])]
15882   ""
15884   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15885     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15887   /* If .md ever supports :P for Pmode, this can be directly
15888      in the pattern above.  */
15889   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15890                               GEN_INT (GET_MODE_SIZE (GET_MODE
15891                                                       (operands[2]))));
15892   /* Can't use this if the user has appropriated eax or edi.  */
15893   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15894       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15895     {
15896       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15897                                       operands[3]));
15898       DONE;
15899     }
15902 (define_expand "strset_singleop"
15903   [(parallel [(set (match_operand 1 "memory_operand")
15904                    (match_operand 2 "register_operand"))
15905               (set (match_operand 0 "register_operand")
15906                    (match_operand 3))
15907               (unspec [(const_int 0)] UNSPEC_STOS)])]
15908   ""
15909   "ix86_current_function_needs_cld = 1;")
15911 (define_insn "*strsetdi_rex_1"
15912   [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15913         (match_operand:DI 2 "register_operand" "a"))
15914    (set (match_operand:P 0 "register_operand" "=D")
15915         (plus:P (match_dup 1)
15916                 (const_int 8)))
15917    (unspec [(const_int 0)] UNSPEC_STOS)]
15918   "TARGET_64BIT
15919    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15920   "%^stosq"
15921   [(set_attr "type" "str")
15922    (set_attr "memory" "store")
15923    (set_attr "mode" "DI")])
15925 (define_insn "*strsetsi_1"
15926   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15927         (match_operand:SI 2 "register_operand" "a"))
15928    (set (match_operand:P 0 "register_operand" "=D")
15929         (plus:P (match_dup 1)
15930                 (const_int 4)))
15931    (unspec [(const_int 0)] UNSPEC_STOS)]
15932   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15933   "%^stos{l|d}"
15934   [(set_attr "type" "str")
15935    (set_attr "memory" "store")
15936    (set_attr "mode" "SI")])
15938 (define_insn "*strsethi_1"
15939   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15940         (match_operand:HI 2 "register_operand" "a"))
15941    (set (match_operand:P 0 "register_operand" "=D")
15942         (plus:P (match_dup 1)
15943                 (const_int 2)))
15944    (unspec [(const_int 0)] UNSPEC_STOS)]
15945   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15946   "%^stosw"
15947   [(set_attr "type" "str")
15948    (set_attr "memory" "store")
15949    (set_attr "mode" "HI")])
15951 (define_insn "*strsetqi_1"
15952   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15953         (match_operand:QI 2 "register_operand" "a"))
15954    (set (match_operand:P 0 "register_operand" "=D")
15955         (plus:P (match_dup 1)
15956                 (const_int 1)))
15957    (unspec [(const_int 0)] UNSPEC_STOS)]
15958   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15959   "%^stosb"
15960   [(set_attr "type" "str")
15961    (set_attr "memory" "store")
15962    (set (attr "prefix_rex")
15963         (if_then_else
15964           (match_test "<P:MODE>mode == DImode")
15965           (const_string "0")
15966           (const_string "*")))
15967    (set_attr "mode" "QI")])
15969 (define_expand "rep_stos"
15970   [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
15971               (set (match_operand 0 "register_operand")
15972                    (match_operand 4))
15973               (set (match_operand 2 "memory_operand") (const_int 0))
15974               (use (match_operand 3 "register_operand"))
15975               (use (match_dup 1))])]
15976   ""
15977   "ix86_current_function_needs_cld = 1;")
15979 (define_insn "*rep_stosdi_rex64"
15980   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15981    (set (match_operand:P 0 "register_operand" "=D")
15982         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15983                           (const_int 3))
15984                  (match_operand:P 3 "register_operand" "0")))
15985    (set (mem:BLK (match_dup 3))
15986         (const_int 0))
15987    (use (match_operand:DI 2 "register_operand" "a"))
15988    (use (match_dup 4))]
15989   "TARGET_64BIT
15990    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15991   "%^rep{%;} stosq"
15992   [(set_attr "type" "str")
15993    (set_attr "prefix_rep" "1")
15994    (set_attr "memory" "store")
15995    (set_attr "mode" "DI")])
15997 (define_insn "*rep_stossi"
15998   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15999    (set (match_operand:P 0 "register_operand" "=D")
16000         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16001                           (const_int 2))
16002                  (match_operand:P 3 "register_operand" "0")))
16003    (set (mem:BLK (match_dup 3))
16004         (const_int 0))
16005    (use (match_operand:SI 2 "register_operand" "a"))
16006    (use (match_dup 4))]
16007   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16008   "%^rep{%;} stos{l|d}"
16009   [(set_attr "type" "str")
16010    (set_attr "prefix_rep" "1")
16011    (set_attr "memory" "store")
16012    (set_attr "mode" "SI")])
16014 (define_insn "*rep_stosqi"
16015   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16016    (set (match_operand:P 0 "register_operand" "=D")
16017         (plus:P (match_operand:P 3 "register_operand" "0")
16018                 (match_operand:P 4 "register_operand" "1")))
16019    (set (mem:BLK (match_dup 3))
16020         (const_int 0))
16021    (use (match_operand:QI 2 "register_operand" "a"))
16022    (use (match_dup 4))]
16023   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16024   "%^rep{%;} stosb"
16025   [(set_attr "type" "str")
16026    (set_attr "prefix_rep" "1")
16027    (set_attr "memory" "store")
16028    (set (attr "prefix_rex")
16029         (if_then_else
16030           (match_test "<P:MODE>mode == DImode")
16031           (const_string "0")
16032           (const_string "*")))
16033    (set_attr "mode" "QI")])
16035 (define_expand "cmpstrnsi"
16036   [(set (match_operand:SI 0 "register_operand")
16037         (compare:SI (match_operand:BLK 1 "general_operand")
16038                     (match_operand:BLK 2 "general_operand")))
16039    (use (match_operand 3 "general_operand"))
16040    (use (match_operand 4 "immediate_operand"))]
16041   ""
16043   rtx addr1, addr2, out, outlow, count, countreg, align;
16045   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16046     FAIL;
16048   /* Can't use this if the user has appropriated ecx, esi or edi.  */
16049   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16050     FAIL;
16052   out = operands[0];
16053   if (!REG_P (out))
16054     out = gen_reg_rtx (SImode);
16056   addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16057   addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16058   if (addr1 != XEXP (operands[1], 0))
16059     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16060   if (addr2 != XEXP (operands[2], 0))
16061     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16063   count = operands[3];
16064   countreg = ix86_zero_extend_to_Pmode (count);
16066   /* %%% Iff we are testing strict equality, we can use known alignment
16067      to good advantage.  This may be possible with combine, particularly
16068      once cc0 is dead.  */
16069   align = operands[4];
16071   if (CONST_INT_P (count))
16072     {
16073       if (INTVAL (count) == 0)
16074         {
16075           emit_move_insn (operands[0], const0_rtx);
16076           DONE;
16077         }
16078       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16079                                      operands[1], operands[2]));
16080     }
16081   else
16082     {
16083       rtx (*gen_cmp) (rtx, rtx);
16085       gen_cmp = (TARGET_64BIT
16086                  ? gen_cmpdi_1 : gen_cmpsi_1);
16088       emit_insn (gen_cmp (countreg, countreg));
16089       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16090                                   operands[1], operands[2]));
16091     }
16093   outlow = gen_lowpart (QImode, out);
16094   emit_insn (gen_cmpintqi (outlow));
16095   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16097   if (operands[0] != out)
16098     emit_move_insn (operands[0], out);
16100   DONE;
16103 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16105 (define_expand "cmpintqi"
16106   [(set (match_dup 1)
16107         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16108    (set (match_dup 2)
16109         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16110    (parallel [(set (match_operand:QI 0 "register_operand")
16111                    (minus:QI (match_dup 1)
16112                              (match_dup 2)))
16113               (clobber (reg:CC FLAGS_REG))])]
16114   ""
16116   operands[1] = gen_reg_rtx (QImode);
16117   operands[2] = gen_reg_rtx (QImode);
16120 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16121 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16123 (define_expand "cmpstrnqi_nz_1"
16124   [(parallel [(set (reg:CC FLAGS_REG)
16125                    (compare:CC (match_operand 4 "memory_operand")
16126                                (match_operand 5 "memory_operand")))
16127               (use (match_operand 2 "register_operand"))
16128               (use (match_operand:SI 3 "immediate_operand"))
16129               (clobber (match_operand 0 "register_operand"))
16130               (clobber (match_operand 1 "register_operand"))
16131               (clobber (match_dup 2))])]
16132   ""
16133   "ix86_current_function_needs_cld = 1;")
16135 (define_insn "*cmpstrnqi_nz_1"
16136   [(set (reg:CC FLAGS_REG)
16137         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16138                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16139    (use (match_operand:P 6 "register_operand" "2"))
16140    (use (match_operand:SI 3 "immediate_operand" "i"))
16141    (clobber (match_operand:P 0 "register_operand" "=S"))
16142    (clobber (match_operand:P 1 "register_operand" "=D"))
16143    (clobber (match_operand:P 2 "register_operand" "=c"))]
16144   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16145   "%^repz{%;} cmpsb"
16146   [(set_attr "type" "str")
16147    (set_attr "mode" "QI")
16148    (set (attr "prefix_rex")
16149         (if_then_else
16150           (match_test "<P:MODE>mode == DImode")
16151           (const_string "0")
16152           (const_string "*")))
16153    (set_attr "prefix_rep" "1")])
16155 ;; The same, but the count is not known to not be zero.
16157 (define_expand "cmpstrnqi_1"
16158   [(parallel [(set (reg:CC FLAGS_REG)
16159                 (if_then_else:CC (ne (match_operand 2 "register_operand")
16160                                      (const_int 0))
16161                   (compare:CC (match_operand 4 "memory_operand")
16162                               (match_operand 5 "memory_operand"))
16163                   (const_int 0)))
16164               (use (match_operand:SI 3 "immediate_operand"))
16165               (use (reg:CC FLAGS_REG))
16166               (clobber (match_operand 0 "register_operand"))
16167               (clobber (match_operand 1 "register_operand"))
16168               (clobber (match_dup 2))])]
16169   ""
16170   "ix86_current_function_needs_cld = 1;")
16172 (define_insn "*cmpstrnqi_1"
16173   [(set (reg:CC FLAGS_REG)
16174         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16175                              (const_int 0))
16176           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16177                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
16178           (const_int 0)))
16179    (use (match_operand:SI 3 "immediate_operand" "i"))
16180    (use (reg:CC FLAGS_REG))
16181    (clobber (match_operand:P 0 "register_operand" "=S"))
16182    (clobber (match_operand:P 1 "register_operand" "=D"))
16183    (clobber (match_operand:P 2 "register_operand" "=c"))]
16184   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16185   "%^repz{%;} cmpsb"
16186   [(set_attr "type" "str")
16187    (set_attr "mode" "QI")
16188    (set (attr "prefix_rex")
16189         (if_then_else
16190           (match_test "<P:MODE>mode == DImode")
16191           (const_string "0")
16192           (const_string "*")))
16193    (set_attr "prefix_rep" "1")])
16195 (define_expand "strlen<mode>"
16196   [(set (match_operand:P 0 "register_operand")
16197         (unspec:P [(match_operand:BLK 1 "general_operand")
16198                    (match_operand:QI 2 "immediate_operand")
16199                    (match_operand 3 "immediate_operand")]
16200                   UNSPEC_SCAS))]
16201   ""
16203  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16204    DONE;
16205  else
16206    FAIL;
16209 (define_expand "strlenqi_1"
16210   [(parallel [(set (match_operand 0 "register_operand")
16211                    (match_operand 2))
16212               (clobber (match_operand 1 "register_operand"))
16213               (clobber (reg:CC FLAGS_REG))])]
16214   ""
16215   "ix86_current_function_needs_cld = 1;")
16217 (define_insn "*strlenqi_1"
16218   [(set (match_operand:P 0 "register_operand" "=&c")
16219         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16220                    (match_operand:QI 2 "register_operand" "a")
16221                    (match_operand:P 3 "immediate_operand" "i")
16222                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16223    (clobber (match_operand:P 1 "register_operand" "=D"))
16224    (clobber (reg:CC FLAGS_REG))]
16225   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16226   "%^repnz{%;} scasb"
16227   [(set_attr "type" "str")
16228    (set_attr "mode" "QI")
16229    (set (attr "prefix_rex")
16230         (if_then_else
16231           (match_test "<P:MODE>mode == DImode")
16232           (const_string "0")
16233           (const_string "*")))
16234    (set_attr "prefix_rep" "1")])
16236 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
16237 ;; handled in combine, but it is not currently up to the task.
16238 ;; When used for their truth value, the cmpstrn* expanders generate
16239 ;; code like this:
16241 ;;   repz cmpsb
16242 ;;   seta       %al
16243 ;;   setb       %dl
16244 ;;   cmpb       %al, %dl
16245 ;;   jcc        label
16247 ;; The intermediate three instructions are unnecessary.
16249 ;; This one handles cmpstrn*_nz_1...
16250 (define_peephole2
16251   [(parallel[
16252      (set (reg:CC FLAGS_REG)
16253           (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16254                       (mem:BLK (match_operand 5 "register_operand"))))
16255      (use (match_operand 6 "register_operand"))
16256      (use (match_operand:SI 3 "immediate_operand"))
16257      (clobber (match_operand 0 "register_operand"))
16258      (clobber (match_operand 1 "register_operand"))
16259      (clobber (match_operand 2 "register_operand"))])
16260    (set (match_operand:QI 7 "register_operand")
16261         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16262    (set (match_operand:QI 8 "register_operand")
16263         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16264    (set (reg FLAGS_REG)
16265         (compare (match_dup 7) (match_dup 8)))
16266   ]
16267   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16268   [(parallel[
16269      (set (reg:CC FLAGS_REG)
16270           (compare:CC (mem:BLK (match_dup 4))
16271                       (mem:BLK (match_dup 5))))
16272      (use (match_dup 6))
16273      (use (match_dup 3))
16274      (clobber (match_dup 0))
16275      (clobber (match_dup 1))
16276      (clobber (match_dup 2))])])
16278 ;; ...and this one handles cmpstrn*_1.
16279 (define_peephole2
16280   [(parallel[
16281      (set (reg:CC FLAGS_REG)
16282           (if_then_else:CC (ne (match_operand 6 "register_operand")
16283                                (const_int 0))
16284             (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16285                         (mem:BLK (match_operand 5 "register_operand")))
16286             (const_int 0)))
16287      (use (match_operand:SI 3 "immediate_operand"))
16288      (use (reg:CC FLAGS_REG))
16289      (clobber (match_operand 0 "register_operand"))
16290      (clobber (match_operand 1 "register_operand"))
16291      (clobber (match_operand 2 "register_operand"))])
16292    (set (match_operand:QI 7 "register_operand")
16293         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16294    (set (match_operand:QI 8 "register_operand")
16295         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16296    (set (reg FLAGS_REG)
16297         (compare (match_dup 7) (match_dup 8)))
16298   ]
16299   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16300   [(parallel[
16301      (set (reg:CC FLAGS_REG)
16302           (if_then_else:CC (ne (match_dup 6)
16303                                (const_int 0))
16304             (compare:CC (mem:BLK (match_dup 4))
16305                         (mem:BLK (match_dup 5)))
16306             (const_int 0)))
16307      (use (match_dup 3))
16308      (use (reg:CC FLAGS_REG))
16309      (clobber (match_dup 0))
16310      (clobber (match_dup 1))
16311      (clobber (match_dup 2))])])
16313 ;; Conditional move instructions.
16315 (define_expand "mov<mode>cc"
16316   [(set (match_operand:SWIM 0 "register_operand")
16317         (if_then_else:SWIM (match_operand 1 "comparison_operator")
16318                            (match_operand:SWIM 2 "<general_operand>")
16319                            (match_operand:SWIM 3 "<general_operand>")))]
16320   ""
16321   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16323 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16324 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16325 ;; So just document what we're doing explicitly.
16327 (define_expand "x86_mov<mode>cc_0_m1"
16328   [(parallel
16329     [(set (match_operand:SWI48 0 "register_operand")
16330           (if_then_else:SWI48
16331             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16332              [(match_operand 1 "flags_reg_operand")
16333               (const_int 0)])
16334             (const_int -1)
16335             (const_int 0)))
16336      (clobber (reg:CC FLAGS_REG))])])
16338 (define_insn "*x86_mov<mode>cc_0_m1"
16339   [(set (match_operand:SWI48 0 "register_operand" "=r")
16340         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16341                              [(reg FLAGS_REG) (const_int 0)])
16342           (const_int -1)
16343           (const_int 0)))
16344    (clobber (reg:CC FLAGS_REG))]
16345   ""
16346   "sbb{<imodesuffix>}\t%0, %0"
16347   ; Since we don't have the proper number of operands for an alu insn,
16348   ; fill in all the blanks.
16349   [(set_attr "type" "alu")
16350    (set_attr "use_carry" "1")
16351    (set_attr "pent_pair" "pu")
16352    (set_attr "memory" "none")
16353    (set_attr "imm_disp" "false")
16354    (set_attr "mode" "<MODE>")
16355    (set_attr "length_immediate" "0")])
16357 (define_insn "*x86_mov<mode>cc_0_m1_se"
16358   [(set (match_operand:SWI48 0 "register_operand" "=r")
16359         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16360                              [(reg FLAGS_REG) (const_int 0)])
16361                             (const_int 1)
16362                             (const_int 0)))
16363    (clobber (reg:CC FLAGS_REG))]
16364   ""
16365   "sbb{<imodesuffix>}\t%0, %0"
16366   [(set_attr "type" "alu")
16367    (set_attr "use_carry" "1")
16368    (set_attr "pent_pair" "pu")
16369    (set_attr "memory" "none")
16370    (set_attr "imm_disp" "false")
16371    (set_attr "mode" "<MODE>")
16372    (set_attr "length_immediate" "0")])
16374 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16375   [(set (match_operand:SWI48 0 "register_operand" "=r")
16376         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16377                     [(reg FLAGS_REG) (const_int 0)])))
16378    (clobber (reg:CC FLAGS_REG))]
16379   ""
16380   "sbb{<imodesuffix>}\t%0, %0"
16381   [(set_attr "type" "alu")
16382    (set_attr "use_carry" "1")
16383    (set_attr "pent_pair" "pu")
16384    (set_attr "memory" "none")
16385    (set_attr "imm_disp" "false")
16386    (set_attr "mode" "<MODE>")
16387    (set_attr "length_immediate" "0")])
16389 (define_insn "*mov<mode>cc_noc"
16390   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16391         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16392                                [(reg FLAGS_REG) (const_int 0)])
16393           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16394           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16395   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16396   "@
16397    cmov%O2%C1\t{%2, %0|%0, %2}
16398    cmov%O2%c1\t{%3, %0|%0, %3}"
16399   [(set_attr "type" "icmov")
16400    (set_attr "mode" "<MODE>")])
16402 ;; Don't do conditional moves with memory inputs.  This splitter helps
16403 ;; register starved x86_32 by forcing inputs into registers before reload.
16404 (define_split
16405   [(set (match_operand:SWI248 0 "register_operand")
16406         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16407                                [(reg FLAGS_REG) (const_int 0)])
16408           (match_operand:SWI248 2 "nonimmediate_operand")
16409           (match_operand:SWI248 3 "nonimmediate_operand")))]
16410   "!TARGET_64BIT && TARGET_CMOVE
16411    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16412    && (MEM_P (operands[2]) || MEM_P (operands[3]))
16413    && can_create_pseudo_p ()
16414    && optimize_insn_for_speed_p ()"
16415   [(set (match_dup 0)
16416         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16418   if (MEM_P (operands[2]))
16419     operands[2] = force_reg (<MODE>mode, operands[2]);
16420   if (MEM_P (operands[3]))
16421     operands[3] = force_reg (<MODE>mode, operands[3]);
16424 (define_insn "*movqicc_noc"
16425   [(set (match_operand:QI 0 "register_operand" "=r,r")
16426         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16427                            [(reg FLAGS_REG) (const_int 0)])
16428                       (match_operand:QI 2 "register_operand" "r,0")
16429                       (match_operand:QI 3 "register_operand" "0,r")))]
16430   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16431   "#"
16432   [(set_attr "type" "icmov")
16433    (set_attr "mode" "QI")])
16435 (define_split
16436   [(set (match_operand:SWI12 0 "register_operand")
16437         (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16438                               [(reg FLAGS_REG) (const_int 0)])
16439                       (match_operand:SWI12 2 "register_operand")
16440                       (match_operand:SWI12 3 "register_operand")))]
16441   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16442    && reload_completed"
16443   [(set (match_dup 0)
16444         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16446   operands[0] = gen_lowpart (SImode, operands[0]);
16447   operands[2] = gen_lowpart (SImode, operands[2]);
16448   operands[3] = gen_lowpart (SImode, operands[3]);
16451 ;; Don't do conditional moves with memory inputs
16452 (define_peephole2
16453   [(match_scratch:SWI248 2 "r")
16454    (set (match_operand:SWI248 0 "register_operand")
16455         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16456                                [(reg FLAGS_REG) (const_int 0)])
16457           (match_dup 0)
16458           (match_operand:SWI248 3 "memory_operand")))]
16459   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16460    && optimize_insn_for_speed_p ()"
16461   [(set (match_dup 2) (match_dup 3))
16462    (set (match_dup 0)
16463         (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
16465 (define_peephole2
16466   [(match_scratch:SWI248 2 "r")
16467    (set (match_operand:SWI248 0 "register_operand")
16468         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16469                                [(reg FLAGS_REG) (const_int 0)])
16470           (match_operand:SWI248 3 "memory_operand")
16471           (match_dup 0)))]
16472   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16473    && optimize_insn_for_speed_p ()"
16474   [(set (match_dup 2) (match_dup 3))
16475    (set (match_dup 0)
16476         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
16478 (define_expand "mov<mode>cc"
16479   [(set (match_operand:X87MODEF 0 "register_operand")
16480         (if_then_else:X87MODEF
16481           (match_operand 1 "comparison_operator")
16482           (match_operand:X87MODEF 2 "register_operand")
16483           (match_operand:X87MODEF 3 "register_operand")))]
16484   "(TARGET_80387 && TARGET_CMOVE)
16485    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16486   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16488 (define_insn "*movxfcc_1"
16489   [(set (match_operand:XF 0 "register_operand" "=f,f")
16490         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16491                                 [(reg FLAGS_REG) (const_int 0)])
16492                       (match_operand:XF 2 "register_operand" "f,0")
16493                       (match_operand:XF 3 "register_operand" "0,f")))]
16494   "TARGET_80387 && TARGET_CMOVE"
16495   "@
16496    fcmov%F1\t{%2, %0|%0, %2}
16497    fcmov%f1\t{%3, %0|%0, %3}"
16498   [(set_attr "type" "fcmov")
16499    (set_attr "mode" "XF")])
16501 (define_insn "*movdfcc_1"
16502   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16503         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16504                                 [(reg FLAGS_REG) (const_int 0)])
16505                       (match_operand:DF 2 "nonimmediate_operand"
16506                                                "f ,0,rm,0 ,rm,0")
16507                       (match_operand:DF 3 "nonimmediate_operand"
16508                                                "0 ,f,0 ,rm,0, rm")))]
16509   "TARGET_80387 && TARGET_CMOVE
16510    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16511   "@
16512    fcmov%F1\t{%2, %0|%0, %2}
16513    fcmov%f1\t{%3, %0|%0, %3}
16514    #
16515    #
16516    cmov%O2%C1\t{%2, %0|%0, %2}
16517    cmov%O2%c1\t{%3, %0|%0, %3}"
16518   [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16519    (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16520    (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16522 (define_split
16523   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16524         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16525                                 [(reg FLAGS_REG) (const_int 0)])
16526                       (match_operand:DF 2 "nonimmediate_operand")
16527                       (match_operand:DF 3 "nonimmediate_operand")))]
16528   "!TARGET_64BIT && reload_completed"
16529   [(set (match_dup 2)
16530         (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16531    (set (match_dup 3)
16532         (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16534   split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16535   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16538 (define_insn "*movsfcc_1_387"
16539   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16540         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16541                                 [(reg FLAGS_REG) (const_int 0)])
16542                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16543                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16544   "TARGET_80387 && TARGET_CMOVE
16545    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16546   "@
16547    fcmov%F1\t{%2, %0|%0, %2}
16548    fcmov%f1\t{%3, %0|%0, %3}
16549    cmov%O2%C1\t{%2, %0|%0, %2}
16550    cmov%O2%c1\t{%3, %0|%0, %3}"
16551   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16552    (set_attr "mode" "SF,SF,SI,SI")])
16554 ;; Don't do conditional moves with memory inputs.  This splitter helps
16555 ;; register starved x86_32 by forcing inputs into registers before reload.
16556 (define_split
16557   [(set (match_operand:MODEF 0 "register_operand")
16558         (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16559                               [(reg FLAGS_REG) (const_int 0)])
16560           (match_operand:MODEF 2 "nonimmediate_operand")
16561           (match_operand:MODEF 3 "nonimmediate_operand")))]
16562   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16563    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16564    && (MEM_P (operands[2]) || MEM_P (operands[3]))
16565    && can_create_pseudo_p ()
16566    && optimize_insn_for_speed_p ()"
16567   [(set (match_dup 0)
16568         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16570   if (MEM_P (operands[2]))
16571     operands[2] = force_reg (<MODE>mode, operands[2]);
16572   if (MEM_P (operands[3]))
16573     operands[3] = force_reg (<MODE>mode, operands[3]);
16576 ;; Don't do conditional moves with memory inputs
16577 (define_peephole2
16578   [(match_scratch:MODEF 2 "r")
16579    (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16580         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16581                               [(reg FLAGS_REG) (const_int 0)])
16582           (match_dup 0)
16583           (match_operand:MODEF 3 "memory_operand")))]
16584   "(<MODE>mode != DFmode || TARGET_64BIT)
16585    && TARGET_80387 && TARGET_CMOVE
16586    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16587    && optimize_insn_for_speed_p ()"
16588   [(set (match_dup 2) (match_dup 3))
16589    (set (match_dup 0)
16590         (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16592 (define_peephole2
16593   [(match_scratch:MODEF 2 "r")
16594    (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16595         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16596                               [(reg FLAGS_REG) (const_int 0)])
16597           (match_operand:MODEF 3 "memory_operand")
16598           (match_dup 0)))]
16599   "(<MODE>mode != DFmode || TARGET_64BIT)
16600    && TARGET_80387 && TARGET_CMOVE
16601    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16602    && optimize_insn_for_speed_p ()"
16603   [(set (match_dup 2) (match_dup 3))
16604    (set (match_dup 0)
16605         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16607 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16608 ;; the scalar versions to have only XMM registers as operands.
16610 ;; XOP conditional move
16611 (define_insn "*xop_pcmov_<mode>"
16612   [(set (match_operand:MODEF 0 "register_operand" "=x")
16613         (if_then_else:MODEF
16614           (match_operand:MODEF 1 "register_operand" "x")
16615           (match_operand:MODEF 2 "register_operand" "x")
16616           (match_operand:MODEF 3 "register_operand" "x")))]
16617   "TARGET_XOP"
16618   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16619   [(set_attr "type" "sse4arg")])
16621 ;; These versions of the min/max patterns are intentionally ignorant of
16622 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16623 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16624 ;; are undefined in this condition, we're certain this is correct.
16626 (define_insn "<code><mode>3"
16627   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16628         (smaxmin:MODEF
16629           (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
16630           (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
16631   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16632   "@
16633    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16634    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16635   [(set_attr "isa" "noavx,avx")
16636    (set_attr "prefix" "orig,vex")
16637    (set_attr "type" "sseadd")
16638    (set_attr "mode" "<MODE>")])
16640 ;; These versions of the min/max patterns implement exactly the operations
16641 ;;   min = (op1 < op2 ? op1 : op2)
16642 ;;   max = (!(op1 < op2) ? op1 : op2)
16643 ;; Their operands are not commutative, and thus they may be used in the
16644 ;; presence of -0.0 and NaN.
16646 (define_int_iterator IEEE_MAXMIN
16647         [UNSPEC_IEEE_MAX
16648          UNSPEC_IEEE_MIN])
16650 (define_int_attr ieee_maxmin
16651         [(UNSPEC_IEEE_MAX "max")
16652          (UNSPEC_IEEE_MIN "min")])
16654 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16655   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16656         (unspec:MODEF
16657           [(match_operand:MODEF 1 "register_operand" "0,x")
16658            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16659           IEEE_MAXMIN))]
16660   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16661   "@
16662    <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16663    v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16664   [(set_attr "isa" "noavx,avx")
16665    (set_attr "prefix" "orig,vex")
16666    (set_attr "type" "sseadd")
16667    (set_attr "mode" "<MODE>")])
16669 ;; Make two stack loads independent:
16670 ;;   fld aa              fld aa
16671 ;;   fld %st(0)     ->   fld bb
16672 ;;   fmul bb             fmul %st(1), %st
16674 ;; Actually we only match the last two instructions for simplicity.
16675 (define_peephole2
16676   [(set (match_operand 0 "fp_register_operand")
16677         (match_operand 1 "fp_register_operand"))
16678    (set (match_dup 0)
16679         (match_operator 2 "binary_fp_operator"
16680            [(match_dup 0)
16681             (match_operand 3 "memory_operand")]))]
16682   "REGNO (operands[0]) != REGNO (operands[1])"
16683   [(set (match_dup 0) (match_dup 3))
16684    (set (match_dup 0) (match_dup 4))]
16686   ;; The % modifier is not operational anymore in peephole2's, so we have to
16687   ;; swap the operands manually in the case of addition and multiplication.
16689   rtx op0, op1;
16691   if (COMMUTATIVE_ARITH_P (operands[2]))
16692     op0 = operands[0], op1 = operands[1];
16693   else
16694     op0 = operands[1], op1 = operands[0];
16696   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16697                                 GET_MODE (operands[2]),
16698                                 op0, op1);
16701 ;; Conditional addition patterns
16702 (define_expand "add<mode>cc"
16703   [(match_operand:SWI 0 "register_operand")
16704    (match_operand 1 "ordered_comparison_operator")
16705    (match_operand:SWI 2 "register_operand")
16706    (match_operand:SWI 3 "const_int_operand")]
16707   ""
16708   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16710 ;; Misc patterns (?)
16712 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16713 ;; Otherwise there will be nothing to keep
16715 ;; [(set (reg ebp) (reg esp))]
16716 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16717 ;;  (clobber (eflags)]
16718 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16720 ;; in proper program order.
16722 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16723   [(set (match_operand:P 0 "register_operand" "=r,r")
16724         (plus:P (match_operand:P 1 "register_operand" "0,r")
16725                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16726    (clobber (reg:CC FLAGS_REG))
16727    (clobber (mem:BLK (scratch)))]
16728   ""
16730   switch (get_attr_type (insn))
16731     {
16732     case TYPE_IMOV:
16733       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16735     case TYPE_ALU:
16736       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16737       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16738         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16740       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16742     default:
16743       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16744       return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16745     }
16747   [(set (attr "type")
16748         (cond [(and (eq_attr "alternative" "0")
16749                     (not (match_test "TARGET_OPT_AGU")))
16750                  (const_string "alu")
16751                (match_operand:<MODE> 2 "const0_operand")
16752                  (const_string "imov")
16753               ]
16754               (const_string "lea")))
16755    (set (attr "length_immediate")
16756         (cond [(eq_attr "type" "imov")
16757                  (const_string "0")
16758                (and (eq_attr "type" "alu")
16759                     (match_operand 2 "const128_operand"))
16760                  (const_string "1")
16761               ]
16762               (const_string "*")))
16763    (set_attr "mode" "<MODE>")])
16765 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16766   [(set (match_operand:P 0 "register_operand" "=r")
16767         (minus:P (match_operand:P 1 "register_operand" "0")
16768                  (match_operand:P 2 "register_operand" "r")))
16769    (clobber (reg:CC FLAGS_REG))
16770    (clobber (mem:BLK (scratch)))]
16771   ""
16772   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16773   [(set_attr "type" "alu")
16774    (set_attr "mode" "<MODE>")])
16776 (define_insn "allocate_stack_worker_probe_<mode>"
16777   [(set (match_operand:P 0 "register_operand" "=a")
16778         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16779                             UNSPECV_STACK_PROBE))
16780    (clobber (reg:CC FLAGS_REG))]
16781   "ix86_target_stack_probe ()"
16782   "call\t___chkstk_ms"
16783   [(set_attr "type" "multi")
16784    (set_attr "length" "5")])
16786 (define_expand "allocate_stack"
16787   [(match_operand 0 "register_operand")
16788    (match_operand 1 "general_operand")]
16789   "ix86_target_stack_probe ()"
16791   rtx x;
16793 #ifndef CHECK_STACK_LIMIT
16794 #define CHECK_STACK_LIMIT 0
16795 #endif
16797   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16798       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16799     x = operands[1];
16800   else
16801     {
16802       rtx (*insn) (rtx, rtx);
16804       x = copy_to_mode_reg (Pmode, operands[1]);
16806       insn = (TARGET_64BIT
16807               ? gen_allocate_stack_worker_probe_di
16808               : gen_allocate_stack_worker_probe_si);
16810       emit_insn (insn (x, x));
16811     }
16813   x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16814                            stack_pointer_rtx, 0, OPTAB_DIRECT);
16816   if (x != stack_pointer_rtx)
16817     emit_move_insn (stack_pointer_rtx, x);
16819   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16820   DONE;
16823 ;; Use IOR for stack probes, this is shorter.
16824 (define_expand "probe_stack"
16825   [(match_operand 0 "memory_operand")]
16826   ""
16828   rtx (*gen_ior3) (rtx, rtx, rtx);
16830   gen_ior3 = (GET_MODE (operands[0]) == DImode
16831               ? gen_iordi3 : gen_iorsi3);
16833   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16834   DONE;
16837 (define_insn "adjust_stack_and_probe<mode>"
16838   [(set (match_operand:P 0 "register_operand" "=r")
16839         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16840                             UNSPECV_PROBE_STACK_RANGE))
16841    (set (reg:P SP_REG)
16842         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16843    (clobber (reg:CC FLAGS_REG))
16844    (clobber (mem:BLK (scratch)))]
16845   ""
16846   "* return output_adjust_stack_and_probe (operands[0]);"
16847   [(set_attr "type" "multi")])
16849 (define_insn "probe_stack_range<mode>"
16850   [(set (match_operand:P 0 "register_operand" "=r")
16851         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16852                             (match_operand:P 2 "const_int_operand" "n")]
16853                             UNSPECV_PROBE_STACK_RANGE))
16854    (clobber (reg:CC FLAGS_REG))]
16855   ""
16856   "* return output_probe_stack_range (operands[0], operands[2]);"
16857   [(set_attr "type" "multi")])
16859 (define_expand "builtin_setjmp_receiver"
16860   [(label_ref (match_operand 0))]
16861   "!TARGET_64BIT && flag_pic"
16863 #if TARGET_MACHO
16864   if (TARGET_MACHO)
16865     {
16866       rtx xops[3];
16867       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16868       rtx label_rtx = gen_label_rtx ();
16869       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16870       xops[0] = xops[1] = picreg;
16871       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16872       ix86_expand_binary_operator (MINUS, SImode, xops);
16873     }
16874   else
16875 #endif
16876     emit_insn (gen_set_got (pic_offset_table_rtx));
16877   DONE;
16880 (define_insn_and_split "nonlocal_goto_receiver"
16881   [(unspec_volatile [(const_int 0)] UNSPECV_NLGR)]
16882   "TARGET_MACHO && !TARGET_64BIT && flag_pic"
16883   "#"
16884   "&& reload_completed"
16885   [(const_int 0)]
16887   if (crtl->uses_pic_offset_table)
16888     {
16889       rtx xops[3];
16890       rtx label_rtx = gen_label_rtx ();
16891       rtx tmp;
16893       /* Get a new pic base.  */
16894       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16895       /* Correct this with the offset from the new to the old.  */
16896       xops[0] = xops[1] = pic_offset_table_rtx;
16897       label_rtx = gen_rtx_LABEL_REF (SImode, label_rtx);
16898       tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, label_rtx),
16899                             UNSPEC_MACHOPIC_OFFSET);
16900       xops[2] = gen_rtx_CONST (Pmode, tmp);
16901       ix86_expand_binary_operator (MINUS, SImode, xops);
16902     }
16903   else
16904     /* No pic reg restore needed.  */
16905     emit_note (NOTE_INSN_DELETED);
16907   DONE;
16910 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16911 ;; Do not split instructions with mask registers.
16912 (define_split
16913   [(set (match_operand 0 "general_reg_operand")
16914         (match_operator 3 "promotable_binary_operator"
16915            [(match_operand 1 "general_reg_operand")
16916             (match_operand 2 "aligned_operand")]))
16917    (clobber (reg:CC FLAGS_REG))]
16918   "! TARGET_PARTIAL_REG_STALL && reload_completed
16919    && ((GET_MODE (operands[0]) == HImode
16920         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16921             /* ??? next two lines just !satisfies_constraint_K (...) */
16922             || !CONST_INT_P (operands[2])
16923             || satisfies_constraint_K (operands[2])))
16924        || (GET_MODE (operands[0]) == QImode
16925            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16926   [(parallel [(set (match_dup 0)
16927                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16928               (clobber (reg:CC FLAGS_REG))])]
16930   operands[0] = gen_lowpart (SImode, operands[0]);
16931   operands[1] = gen_lowpart (SImode, operands[1]);
16932   if (GET_CODE (operands[3]) != ASHIFT)
16933     operands[2] = gen_lowpart (SImode, operands[2]);
16934   PUT_MODE (operands[3], SImode);
16937 ; Promote the QImode tests, as i386 has encoding of the AND
16938 ; instruction with 32-bit sign-extended immediate and thus the
16939 ; instruction size is unchanged, except in the %eax case for
16940 ; which it is increased by one byte, hence the ! optimize_size.
16941 (define_split
16942   [(set (match_operand 0 "flags_reg_operand")
16943         (match_operator 2 "compare_operator"
16944           [(and (match_operand 3 "aligned_operand")
16945                 (match_operand 4 "const_int_operand"))
16946            (const_int 0)]))
16947    (set (match_operand 1 "register_operand")
16948         (and (match_dup 3) (match_dup 4)))]
16949   "! TARGET_PARTIAL_REG_STALL && reload_completed
16950    && optimize_insn_for_speed_p ()
16951    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16952        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16953    /* Ensure that the operand will remain sign-extended immediate.  */
16954    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16955   [(parallel [(set (match_dup 0)
16956                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16957                                     (const_int 0)]))
16958               (set (match_dup 1)
16959                    (and:SI (match_dup 3) (match_dup 4)))])]
16961   operands[4]
16962     = gen_int_mode (INTVAL (operands[4])
16963                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16964   operands[1] = gen_lowpart (SImode, operands[1]);
16965   operands[3] = gen_lowpart (SImode, operands[3]);
16968 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16969 ; the TEST instruction with 32-bit sign-extended immediate and thus
16970 ; the instruction size would at least double, which is not what we
16971 ; want even with ! optimize_size.
16972 (define_split
16973   [(set (match_operand 0 "flags_reg_operand")
16974         (match_operator 1 "compare_operator"
16975           [(and (match_operand:HI 2 "aligned_operand")
16976                 (match_operand:HI 3 "const_int_operand"))
16977            (const_int 0)]))]
16978   "! TARGET_PARTIAL_REG_STALL && reload_completed
16979    && ! TARGET_FAST_PREFIX
16980    && optimize_insn_for_speed_p ()
16981    /* Ensure that the operand will remain sign-extended immediate.  */
16982    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16983   [(set (match_dup 0)
16984         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16985                          (const_int 0)]))]
16987   operands[3]
16988     = gen_int_mode (INTVAL (operands[3])
16989                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16990   operands[2] = gen_lowpart (SImode, operands[2]);
16993 (define_split
16994   [(set (match_operand 0 "register_operand")
16995         (neg (match_operand 1 "register_operand")))
16996    (clobber (reg:CC FLAGS_REG))]
16997   "! TARGET_PARTIAL_REG_STALL && reload_completed
16998    && (GET_MODE (operands[0]) == HImode
16999        || (GET_MODE (operands[0]) == QImode
17000            && (TARGET_PROMOTE_QImode
17001                || optimize_insn_for_size_p ())))"
17002   [(parallel [(set (match_dup 0)
17003                    (neg:SI (match_dup 1)))
17004               (clobber (reg:CC FLAGS_REG))])]
17006   operands[0] = gen_lowpart (SImode, operands[0]);
17007   operands[1] = gen_lowpart (SImode, operands[1]);
17010 ;; Do not split instructions with mask regs.
17011 (define_split
17012   [(set (match_operand 0 "general_reg_operand")
17013         (not (match_operand 1 "general_reg_operand")))]
17014   "! TARGET_PARTIAL_REG_STALL && reload_completed
17015    && (GET_MODE (operands[0]) == HImode
17016        || (GET_MODE (operands[0]) == QImode
17017            && (TARGET_PROMOTE_QImode
17018                || optimize_insn_for_size_p ())))"
17019   [(set (match_dup 0)
17020         (not:SI (match_dup 1)))]
17022   operands[0] = gen_lowpart (SImode, operands[0]);
17023   operands[1] = gen_lowpart (SImode, operands[1]);
17026 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
17027 ;; transform a complex memory operation into two memory to register operations.
17029 ;; Don't push memory operands
17030 (define_peephole2
17031   [(set (match_operand:SWI 0 "push_operand")
17032         (match_operand:SWI 1 "memory_operand"))
17033    (match_scratch:SWI 2 "<r>")]
17034   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17035    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17036   [(set (match_dup 2) (match_dup 1))
17037    (set (match_dup 0) (match_dup 2))])
17039 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17040 ;; SImode pushes.
17041 (define_peephole2
17042   [(set (match_operand:SF 0 "push_operand")
17043         (match_operand:SF 1 "memory_operand"))
17044    (match_scratch:SF 2 "r")]
17045   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17046    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17047   [(set (match_dup 2) (match_dup 1))
17048    (set (match_dup 0) (match_dup 2))])
17050 ;; Don't move an immediate directly to memory when the instruction
17051 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17052 (define_peephole2
17053   [(match_scratch:SWI124 1 "<r>")
17054    (set (match_operand:SWI124 0 "memory_operand")
17055         (const_int 0))]
17056   "optimize_insn_for_speed_p ()
17057    && ((<MODE>mode == HImode
17058        && TARGET_LCP_STALL)
17059        || (!TARGET_USE_MOV0
17060           && TARGET_SPLIT_LONG_MOVES
17061           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17062    && peep2_regno_dead_p (0, FLAGS_REG)"
17063   [(parallel [(set (match_dup 2) (const_int 0))
17064               (clobber (reg:CC FLAGS_REG))])
17065    (set (match_dup 0) (match_dup 1))]
17066   "operands[2] = gen_lowpart (SImode, operands[1]);")
17068 (define_peephole2
17069   [(match_scratch:SWI124 2 "<r>")
17070    (set (match_operand:SWI124 0 "memory_operand")
17071         (match_operand:SWI124 1 "immediate_operand"))]
17072   "optimize_insn_for_speed_p ()
17073    && ((<MODE>mode == HImode
17074        && TARGET_LCP_STALL)
17075        || (TARGET_SPLIT_LONG_MOVES
17076           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17077   [(set (match_dup 2) (match_dup 1))
17078    (set (match_dup 0) (match_dup 2))])
17080 ;; Don't compare memory with zero, load and use a test instead.
17081 (define_peephole2
17082   [(set (match_operand 0 "flags_reg_operand")
17083         (match_operator 1 "compare_operator"
17084           [(match_operand:SI 2 "memory_operand")
17085            (const_int 0)]))
17086    (match_scratch:SI 3 "r")]
17087   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17088   [(set (match_dup 3) (match_dup 2))
17089    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17091 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17092 ;; Don't split NOTs with a displacement operand, because resulting XOR
17093 ;; will not be pairable anyway.
17095 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17096 ;; represented using a modRM byte.  The XOR replacement is long decoded,
17097 ;; so this split helps here as well.
17099 ;; Note: Can't do this as a regular split because we can't get proper
17100 ;; lifetime information then.
17102 (define_peephole2
17103   [(set (match_operand:SWI124 0 "nonimmediate_operand")
17104         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
17105   "optimize_insn_for_speed_p ()
17106    && ((TARGET_NOT_UNPAIRABLE
17107         && (!MEM_P (operands[0])
17108             || !memory_displacement_operand (operands[0], <MODE>mode)))
17109        || (TARGET_NOT_VECTORMODE
17110            && long_memory_operand (operands[0], <MODE>mode)))
17111    && peep2_regno_dead_p (0, FLAGS_REG)"
17112   [(parallel [(set (match_dup 0)
17113                    (xor:SWI124 (match_dup 1) (const_int -1)))
17114               (clobber (reg:CC FLAGS_REG))])])
17116 ;; Non pairable "test imm, reg" instructions can be translated to
17117 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17118 ;; byte opcode instead of two, have a short form for byte operands),
17119 ;; so do it for other CPUs as well.  Given that the value was dead,
17120 ;; this should not create any new dependencies.  Pass on the sub-word
17121 ;; versions if we're concerned about partial register stalls.
17123 (define_peephole2
17124   [(set (match_operand 0 "flags_reg_operand")
17125         (match_operator 1 "compare_operator"
17126           [(and:SI (match_operand:SI 2 "register_operand")
17127                    (match_operand:SI 3 "immediate_operand"))
17128            (const_int 0)]))]
17129   "ix86_match_ccmode (insn, CCNOmode)
17130    && (true_regnum (operands[2]) != AX_REG
17131        || satisfies_constraint_K (operands[3]))
17132    && peep2_reg_dead_p (1, operands[2])"
17133   [(parallel
17134      [(set (match_dup 0)
17135            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17136                             (const_int 0)]))
17137       (set (match_dup 2)
17138            (and:SI (match_dup 2) (match_dup 3)))])])
17140 ;; We don't need to handle HImode case, because it will be promoted to SImode
17141 ;; on ! TARGET_PARTIAL_REG_STALL
17143 (define_peephole2
17144   [(set (match_operand 0 "flags_reg_operand")
17145         (match_operator 1 "compare_operator"
17146           [(and:QI (match_operand:QI 2 "register_operand")
17147                    (match_operand:QI 3 "immediate_operand"))
17148            (const_int 0)]))]
17149   "! TARGET_PARTIAL_REG_STALL
17150    && ix86_match_ccmode (insn, CCNOmode)
17151    && true_regnum (operands[2]) != AX_REG
17152    && peep2_reg_dead_p (1, operands[2])"
17153   [(parallel
17154      [(set (match_dup 0)
17155            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17156                             (const_int 0)]))
17157       (set (match_dup 2)
17158            (and:QI (match_dup 2) (match_dup 3)))])])
17160 (define_peephole2
17161   [(set (match_operand 0 "flags_reg_operand")
17162         (match_operator 1 "compare_operator"
17163           [(and:SI
17164              (zero_extract:SI
17165                (match_operand 2 "ext_register_operand")
17166                (const_int 8)
17167                (const_int 8))
17168              (match_operand 3 "const_int_operand"))
17169            (const_int 0)]))]
17170   "! TARGET_PARTIAL_REG_STALL
17171    && ix86_match_ccmode (insn, CCNOmode)
17172    && true_regnum (operands[2]) != AX_REG
17173    && peep2_reg_dead_p (1, operands[2])"
17174   [(parallel [(set (match_dup 0)
17175                    (match_op_dup 1
17176                      [(and:SI
17177                         (zero_extract:SI
17178                           (match_dup 2)
17179                           (const_int 8)
17180                           (const_int 8))
17181                         (match_dup 3))
17182                       (const_int 0)]))
17183               (set (zero_extract:SI (match_dup 2)
17184                                     (const_int 8)
17185                                     (const_int 8))
17186                    (and:SI
17187                      (zero_extract:SI
17188                        (match_dup 2)
17189                        (const_int 8)
17190                        (const_int 8))
17191                      (match_dup 3)))])])
17193 ;; Don't do logical operations with memory inputs.
17194 (define_peephole2
17195   [(match_scratch:SI 2 "r")
17196    (parallel [(set (match_operand:SI 0 "register_operand")
17197                    (match_operator:SI 3 "arith_or_logical_operator"
17198                      [(match_dup 0)
17199                       (match_operand:SI 1 "memory_operand")]))
17200               (clobber (reg:CC FLAGS_REG))])]
17201   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17202   [(set (match_dup 2) (match_dup 1))
17203    (parallel [(set (match_dup 0)
17204                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17205               (clobber (reg:CC FLAGS_REG))])])
17207 (define_peephole2
17208   [(match_scratch:SI 2 "r")
17209    (parallel [(set (match_operand:SI 0 "register_operand")
17210                    (match_operator:SI 3 "arith_or_logical_operator"
17211                      [(match_operand:SI 1 "memory_operand")
17212                       (match_dup 0)]))
17213               (clobber (reg:CC FLAGS_REG))])]
17214   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17215   [(set (match_dup 2) (match_dup 1))
17216    (parallel [(set (match_dup 0)
17217                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17218               (clobber (reg:CC FLAGS_REG))])])
17220 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17221 ;; refers to the destination of the load!
17223 (define_peephole2
17224   [(set (match_operand:SI 0 "register_operand")
17225         (match_operand:SI 1 "register_operand"))
17226    (parallel [(set (match_dup 0)
17227                    (match_operator:SI 3 "commutative_operator"
17228                      [(match_dup 0)
17229                       (match_operand:SI 2 "memory_operand")]))
17230               (clobber (reg:CC FLAGS_REG))])]
17231   "REGNO (operands[0]) != REGNO (operands[1])
17232    && GENERAL_REGNO_P (REGNO (operands[0]))
17233    && GENERAL_REGNO_P (REGNO (operands[1]))"
17234   [(set (match_dup 0) (match_dup 4))
17235    (parallel [(set (match_dup 0)
17236                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17237               (clobber (reg:CC FLAGS_REG))])]
17238   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17240 (define_peephole2
17241   [(set (match_operand 0 "register_operand")
17242         (match_operand 1 "register_operand"))
17243    (set (match_dup 0)
17244                    (match_operator 3 "commutative_operator"
17245                      [(match_dup 0)
17246                       (match_operand 2 "memory_operand")]))]
17247   "REGNO (operands[0]) != REGNO (operands[1])
17248    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
17249        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17250   [(set (match_dup 0) (match_dup 2))
17251    (set (match_dup 0)
17252         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17254 ; Don't do logical operations with memory outputs
17256 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17257 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17258 ; the same decoder scheduling characteristics as the original.
17260 (define_peephole2
17261   [(match_scratch:SI 2 "r")
17262    (parallel [(set (match_operand:SI 0 "memory_operand")
17263                    (match_operator:SI 3 "arith_or_logical_operator"
17264                      [(match_dup 0)
17265                       (match_operand:SI 1 "nonmemory_operand")]))
17266               (clobber (reg:CC FLAGS_REG))])]
17267   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17268    /* Do not split stack checking probes.  */
17269    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17270   [(set (match_dup 2) (match_dup 0))
17271    (parallel [(set (match_dup 2)
17272                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17273               (clobber (reg:CC FLAGS_REG))])
17274    (set (match_dup 0) (match_dup 2))])
17276 (define_peephole2
17277   [(match_scratch:SI 2 "r")
17278    (parallel [(set (match_operand:SI 0 "memory_operand")
17279                    (match_operator:SI 3 "arith_or_logical_operator"
17280                      [(match_operand:SI 1 "nonmemory_operand")
17281                       (match_dup 0)]))
17282               (clobber (reg:CC FLAGS_REG))])]
17283   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17284    /* Do not split stack checking probes.  */
17285    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17286   [(set (match_dup 2) (match_dup 0))
17287    (parallel [(set (match_dup 2)
17288                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17289               (clobber (reg:CC FLAGS_REG))])
17290    (set (match_dup 0) (match_dup 2))])
17292 ;; Attempt to use arith or logical operations with memory outputs with
17293 ;; setting of flags.
17294 (define_peephole2
17295   [(set (match_operand:SWI 0 "register_operand")
17296         (match_operand:SWI 1 "memory_operand"))
17297    (parallel [(set (match_dup 0)
17298                    (match_operator:SWI 3 "plusminuslogic_operator"
17299                      [(match_dup 0)
17300                       (match_operand:SWI 2 "<nonmemory_operand>")]))
17301               (clobber (reg:CC FLAGS_REG))])
17302    (set (match_dup 1) (match_dup 0))
17303    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17304   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17305    && peep2_reg_dead_p (4, operands[0])
17306    && !reg_overlap_mentioned_p (operands[0], operands[1])
17307    && !reg_overlap_mentioned_p (operands[0], operands[2])
17308    && (<MODE>mode != QImode
17309        || immediate_operand (operands[2], QImode)
17310        || q_regs_operand (operands[2], QImode))
17311    && ix86_match_ccmode (peep2_next_insn (3),
17312                          (GET_CODE (operands[3]) == PLUS
17313                           || GET_CODE (operands[3]) == MINUS)
17314                          ? CCGOCmode : CCNOmode)"
17315   [(parallel [(set (match_dup 4) (match_dup 5))
17316               (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17317                                                   (match_dup 2)]))])]
17319   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17320   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17321                                 copy_rtx (operands[1]),
17322                                 copy_rtx (operands[2]));
17323   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17324                                  operands[5], const0_rtx);
17327 (define_peephole2
17328   [(parallel [(set (match_operand:SWI 0 "register_operand")
17329                    (match_operator:SWI 2 "plusminuslogic_operator"
17330                      [(match_dup 0)
17331                       (match_operand:SWI 1 "memory_operand")]))
17332               (clobber (reg:CC FLAGS_REG))])
17333    (set (match_dup 1) (match_dup 0))
17334    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17335   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17336    && GET_CODE (operands[2]) != MINUS
17337    && peep2_reg_dead_p (3, operands[0])
17338    && !reg_overlap_mentioned_p (operands[0], operands[1])
17339    && ix86_match_ccmode (peep2_next_insn (2),
17340                          GET_CODE (operands[2]) == PLUS
17341                          ? CCGOCmode : CCNOmode)"
17342   [(parallel [(set (match_dup 3) (match_dup 4))
17343               (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17344                                                   (match_dup 0)]))])]
17346   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17347   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17348                                 copy_rtx (operands[1]),
17349                                 copy_rtx (operands[0]));
17350   operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17351                                  operands[4], const0_rtx);
17354 (define_peephole2
17355   [(set (match_operand:SWI12 0 "register_operand")
17356         (match_operand:SWI12 1 "memory_operand"))
17357    (parallel [(set (match_operand:SI 4 "register_operand")
17358                    (match_operator:SI 3 "plusminuslogic_operator"
17359                      [(match_dup 4)
17360                       (match_operand:SI 2 "nonmemory_operand")]))
17361               (clobber (reg:CC FLAGS_REG))])
17362    (set (match_dup 1) (match_dup 0))
17363    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17364   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17365    && REG_P (operands[0]) && REG_P (operands[4])
17366    && REGNO (operands[0]) == REGNO (operands[4])
17367    && peep2_reg_dead_p (4, operands[0])
17368    && (<MODE>mode != QImode
17369        || immediate_operand (operands[2], SImode)
17370        || q_regs_operand (operands[2], SImode))
17371    && !reg_overlap_mentioned_p (operands[0], operands[1])
17372    && !reg_overlap_mentioned_p (operands[0], operands[2])
17373    && ix86_match_ccmode (peep2_next_insn (3),
17374                          (GET_CODE (operands[3]) == PLUS
17375                           || GET_CODE (operands[3]) == MINUS)
17376                          ? CCGOCmode : CCNOmode)"
17377   [(parallel [(set (match_dup 4) (match_dup 5))
17378               (set (match_dup 1) (match_dup 6))])]
17380   operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17381   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17382   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17383                                 copy_rtx (operands[1]), operands[2]);
17384   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17385                                  operands[5], const0_rtx);
17386   operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17387                                 copy_rtx (operands[1]),
17388                                 copy_rtx (operands[2]));
17391 ;; Attempt to always use XOR for zeroing registers.
17392 (define_peephole2
17393   [(set (match_operand 0 "register_operand")
17394         (match_operand 1 "const0_operand"))]
17395   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17396    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17397    && GENERAL_REG_P (operands[0])
17398    && peep2_regno_dead_p (0, FLAGS_REG)"
17399   [(parallel [(set (match_dup 0) (const_int 0))
17400               (clobber (reg:CC FLAGS_REG))])]
17401   "operands[0] = gen_lowpart (word_mode, operands[0]);")
17403 (define_peephole2
17404   [(set (strict_low_part (match_operand 0 "register_operand"))
17405         (const_int 0))]
17406   "(GET_MODE (operands[0]) == QImode
17407     || GET_MODE (operands[0]) == HImode)
17408    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17409    && peep2_regno_dead_p (0, FLAGS_REG)"
17410   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17411               (clobber (reg:CC FLAGS_REG))])])
17413 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17414 (define_peephole2
17415   [(set (match_operand:SWI248 0 "register_operand")
17416         (const_int -1))]
17417   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17418    && peep2_regno_dead_p (0, FLAGS_REG)"
17419   [(parallel [(set (match_dup 0) (const_int -1))
17420               (clobber (reg:CC FLAGS_REG))])]
17422   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
17423     operands[0] = gen_lowpart (SImode, operands[0]);
17426 ;; Attempt to convert simple lea to add/shift.
17427 ;; These can be created by move expanders.
17428 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17429 ;; relevant lea instructions were already split.
17431 (define_peephole2
17432   [(set (match_operand:SWI48 0 "register_operand")
17433         (plus:SWI48 (match_dup 0)
17434                     (match_operand:SWI48 1 "<nonmemory_operand>")))]
17435   "!TARGET_OPT_AGU
17436    && peep2_regno_dead_p (0, FLAGS_REG)"
17437   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17438               (clobber (reg:CC FLAGS_REG))])])
17440 (define_peephole2
17441   [(set (match_operand:SWI48 0 "register_operand")
17442         (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17443                     (match_dup 0)))]
17444   "!TARGET_OPT_AGU
17445    && peep2_regno_dead_p (0, FLAGS_REG)"
17446   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17447               (clobber (reg:CC FLAGS_REG))])])
17449 (define_peephole2
17450   [(set (match_operand:DI 0 "register_operand")
17451         (zero_extend:DI
17452           (plus:SI (match_operand:SI 1 "register_operand")
17453                    (match_operand:SI 2 "nonmemory_operand"))))]
17454   "TARGET_64BIT && !TARGET_OPT_AGU
17455    && REGNO (operands[0]) == REGNO (operands[1])
17456    && peep2_regno_dead_p (0, FLAGS_REG)"
17457   [(parallel [(set (match_dup 0)
17458                    (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17459               (clobber (reg:CC FLAGS_REG))])])
17461 (define_peephole2
17462   [(set (match_operand:DI 0 "register_operand")
17463         (zero_extend:DI
17464           (plus:SI (match_operand:SI 1 "nonmemory_operand")
17465                    (match_operand:SI 2 "register_operand"))))]
17466   "TARGET_64BIT && !TARGET_OPT_AGU
17467    && REGNO (operands[0]) == REGNO (operands[2])
17468    && peep2_regno_dead_p (0, FLAGS_REG)"
17469   [(parallel [(set (match_dup 0)
17470                    (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17471               (clobber (reg:CC FLAGS_REG))])])
17473 (define_peephole2
17474   [(set (match_operand:SWI48 0 "register_operand")
17475         (mult:SWI48 (match_dup 0)
17476                     (match_operand:SWI48 1 "const_int_operand")))]
17477   "exact_log2 (INTVAL (operands[1])) >= 0
17478    && peep2_regno_dead_p (0, FLAGS_REG)"
17479   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17480               (clobber (reg:CC FLAGS_REG))])]
17481   "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17483 (define_peephole2
17484   [(set (match_operand:DI 0 "register_operand")
17485         (zero_extend:DI
17486           (mult:SI (match_operand:SI 1 "register_operand")
17487                    (match_operand:SI 2 "const_int_operand"))))]
17488   "TARGET_64BIT
17489    && exact_log2 (INTVAL (operands[2])) >= 0
17490    && REGNO (operands[0]) == REGNO (operands[1])
17491    && peep2_regno_dead_p (0, FLAGS_REG)"
17492   [(parallel [(set (match_dup 0)
17493                    (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
17494               (clobber (reg:CC FLAGS_REG))])]
17495   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17497 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17498 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17499 ;; On many CPUs it is also faster, since special hardware to avoid esp
17500 ;; dependencies is present.
17502 ;; While some of these conversions may be done using splitters, we use
17503 ;; peepholes in order to allow combine_stack_adjustments pass to see
17504 ;; nonobfuscated RTL.
17506 ;; Convert prologue esp subtractions to push.
17507 ;; We need register to push.  In order to keep verify_flow_info happy we have
17508 ;; two choices
17509 ;; - use scratch and clobber it in order to avoid dependencies
17510 ;; - use already live register
17511 ;; We can't use the second way right now, since there is no reliable way how to
17512 ;; verify that given register is live.  First choice will also most likely in
17513 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17514 ;; call clobbered registers are dead.  We may want to use base pointer as an
17515 ;; alternative when no register is available later.
17517 (define_peephole2
17518   [(match_scratch:W 1 "r")
17519    (parallel [(set (reg:P SP_REG)
17520                    (plus:P (reg:P SP_REG)
17521                            (match_operand:P 0 "const_int_operand")))
17522               (clobber (reg:CC FLAGS_REG))
17523               (clobber (mem:BLK (scratch)))])]
17524   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17525    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17526   [(clobber (match_dup 1))
17527    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17528               (clobber (mem:BLK (scratch)))])])
17530 (define_peephole2
17531   [(match_scratch:W 1 "r")
17532    (parallel [(set (reg:P SP_REG)
17533                    (plus:P (reg:P SP_REG)
17534                            (match_operand:P 0 "const_int_operand")))
17535               (clobber (reg:CC FLAGS_REG))
17536               (clobber (mem:BLK (scratch)))])]
17537   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17538    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17539   [(clobber (match_dup 1))
17540    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17541    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17542               (clobber (mem:BLK (scratch)))])])
17544 ;; Convert esp subtractions to push.
17545 (define_peephole2
17546   [(match_scratch:W 1 "r")
17547    (parallel [(set (reg:P SP_REG)
17548                    (plus:P (reg:P SP_REG)
17549                            (match_operand:P 0 "const_int_operand")))
17550               (clobber (reg:CC FLAGS_REG))])]
17551   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17552    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17553   [(clobber (match_dup 1))
17554    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17556 (define_peephole2
17557   [(match_scratch:W 1 "r")
17558    (parallel [(set (reg:P SP_REG)
17559                    (plus:P (reg:P SP_REG)
17560                            (match_operand:P 0 "const_int_operand")))
17561               (clobber (reg:CC FLAGS_REG))])]
17562   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17563    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17564   [(clobber (match_dup 1))
17565    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17566    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17568 ;; Convert epilogue deallocator to pop.
17569 (define_peephole2
17570   [(match_scratch:W 1 "r")
17571    (parallel [(set (reg:P SP_REG)
17572                    (plus:P (reg:P SP_REG)
17573                            (match_operand:P 0 "const_int_operand")))
17574               (clobber (reg:CC FLAGS_REG))
17575               (clobber (mem:BLK (scratch)))])]
17576   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17577    && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17578   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17579               (clobber (mem:BLK (scratch)))])])
17581 ;; Two pops case is tricky, since pop causes dependency
17582 ;; on destination register.  We use two registers if available.
17583 (define_peephole2
17584   [(match_scratch:W 1 "r")
17585    (match_scratch:W 2 "r")
17586    (parallel [(set (reg:P SP_REG)
17587                    (plus:P (reg:P SP_REG)
17588                            (match_operand:P 0 "const_int_operand")))
17589               (clobber (reg:CC FLAGS_REG))
17590               (clobber (mem:BLK (scratch)))])]
17591   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17592    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17593   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17594               (clobber (mem:BLK (scratch)))])
17595    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17597 (define_peephole2
17598   [(match_scratch:W 1 "r")
17599    (parallel [(set (reg:P SP_REG)
17600                    (plus:P (reg:P SP_REG)
17601                            (match_operand:P 0 "const_int_operand")))
17602               (clobber (reg:CC FLAGS_REG))
17603               (clobber (mem:BLK (scratch)))])]
17604   "optimize_insn_for_size_p ()
17605    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17606   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17607               (clobber (mem:BLK (scratch)))])
17608    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17610 ;; Convert esp additions to pop.
17611 (define_peephole2
17612   [(match_scratch:W 1 "r")
17613    (parallel [(set (reg:P SP_REG)
17614                    (plus:P (reg:P SP_REG)
17615                            (match_operand:P 0 "const_int_operand")))
17616               (clobber (reg:CC FLAGS_REG))])]
17617   "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17618   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17620 ;; Two pops case is tricky, since pop causes dependency
17621 ;; on destination register.  We use two registers if available.
17622 (define_peephole2
17623   [(match_scratch:W 1 "r")
17624    (match_scratch:W 2 "r")
17625    (parallel [(set (reg:P SP_REG)
17626                    (plus:P (reg:P SP_REG)
17627                            (match_operand:P 0 "const_int_operand")))
17628               (clobber (reg:CC FLAGS_REG))])]
17629   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17630   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17631    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17633 (define_peephole2
17634   [(match_scratch:W 1 "r")
17635    (parallel [(set (reg:P SP_REG)
17636                    (plus:P (reg:P SP_REG)
17637                            (match_operand:P 0 "const_int_operand")))
17638               (clobber (reg:CC FLAGS_REG))])]
17639   "optimize_insn_for_size_p ()
17640    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17641   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17642    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17644 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17645 ;; required and register dies.  Similarly for 128 to -128.
17646 (define_peephole2
17647   [(set (match_operand 0 "flags_reg_operand")
17648         (match_operator 1 "compare_operator"
17649           [(match_operand 2 "register_operand")
17650            (match_operand 3 "const_int_operand")]))]
17651   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17652      && incdec_operand (operands[3], GET_MODE (operands[3])))
17653     || (!TARGET_FUSE_CMP_AND_BRANCH
17654         && INTVAL (operands[3]) == 128))
17655    && ix86_match_ccmode (insn, CCGCmode)
17656    && peep2_reg_dead_p (1, operands[2])"
17657   [(parallel [(set (match_dup 0)
17658                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17659               (clobber (match_dup 2))])])
17661 ;; Convert imul by three, five and nine into lea
17662 (define_peephole2
17663   [(parallel
17664     [(set (match_operand:SWI48 0 "register_operand")
17665           (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17666                       (match_operand:SWI48 2 "const359_operand")))
17667      (clobber (reg:CC FLAGS_REG))])]
17668   "!TARGET_PARTIAL_REG_STALL
17669    || <MODE>mode == SImode
17670    || optimize_function_for_size_p (cfun)"
17671   [(set (match_dup 0)
17672         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17673                     (match_dup 1)))]
17674   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17676 (define_peephole2
17677   [(parallel
17678     [(set (match_operand:SWI48 0 "register_operand")
17679           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17680                       (match_operand:SWI48 2 "const359_operand")))
17681      (clobber (reg:CC FLAGS_REG))])]
17682   "optimize_insn_for_speed_p ()
17683    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17684   [(set (match_dup 0) (match_dup 1))
17685    (set (match_dup 0)
17686         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17687                     (match_dup 0)))]
17688   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17690 ;; imul $32bit_imm, mem, reg is vector decoded, while
17691 ;; imul $32bit_imm, reg, reg is direct decoded.
17692 (define_peephole2
17693   [(match_scratch:SWI48 3 "r")
17694    (parallel [(set (match_operand:SWI48 0 "register_operand")
17695                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17696                                (match_operand:SWI48 2 "immediate_operand")))
17697               (clobber (reg:CC FLAGS_REG))])]
17698   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17699    && !satisfies_constraint_K (operands[2])"
17700   [(set (match_dup 3) (match_dup 1))
17701    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17702               (clobber (reg:CC FLAGS_REG))])])
17704 (define_peephole2
17705   [(match_scratch:SI 3 "r")
17706    (parallel [(set (match_operand:DI 0 "register_operand")
17707                    (zero_extend:DI
17708                      (mult:SI (match_operand:SI 1 "memory_operand")
17709                               (match_operand:SI 2 "immediate_operand"))))
17710               (clobber (reg:CC FLAGS_REG))])]
17711   "TARGET_64BIT
17712    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17713    && !satisfies_constraint_K (operands[2])"
17714   [(set (match_dup 3) (match_dup 1))
17715    (parallel [(set (match_dup 0)
17716                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17717               (clobber (reg:CC FLAGS_REG))])])
17719 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17720 ;; Convert it into imul reg, reg
17721 ;; It would be better to force assembler to encode instruction using long
17722 ;; immediate, but there is apparently no way to do so.
17723 (define_peephole2
17724   [(parallel [(set (match_operand:SWI248 0 "register_operand")
17725                    (mult:SWI248
17726                     (match_operand:SWI248 1 "nonimmediate_operand")
17727                     (match_operand:SWI248 2 "const_int_operand")))
17728               (clobber (reg:CC FLAGS_REG))])
17729    (match_scratch:SWI248 3 "r")]
17730   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17731    && satisfies_constraint_K (operands[2])"
17732   [(set (match_dup 3) (match_dup 2))
17733    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17734               (clobber (reg:CC FLAGS_REG))])]
17736   if (!rtx_equal_p (operands[0], operands[1]))
17737     emit_move_insn (operands[0], operands[1]);
17740 ;; After splitting up read-modify operations, array accesses with memory
17741 ;; operands might end up in form:
17742 ;;  sall    $2, %eax
17743 ;;  movl    4(%esp), %edx
17744 ;;  addl    %edx, %eax
17745 ;; instead of pre-splitting:
17746 ;;  sall    $2, %eax
17747 ;;  addl    4(%esp), %eax
17748 ;; Turn it into:
17749 ;;  movl    4(%esp), %edx
17750 ;;  leal    (%edx,%eax,4), %eax
17752 (define_peephole2
17753   [(match_scratch:W 5 "r")
17754    (parallel [(set (match_operand 0 "register_operand")
17755                    (ashift (match_operand 1 "register_operand")
17756                            (match_operand 2 "const_int_operand")))
17757                (clobber (reg:CC FLAGS_REG))])
17758    (parallel [(set (match_operand 3 "register_operand")
17759                    (plus (match_dup 0)
17760                          (match_operand 4 "x86_64_general_operand")))
17761                    (clobber (reg:CC FLAGS_REG))])]
17762   "IN_RANGE (INTVAL (operands[2]), 1, 3)
17763    /* Validate MODE for lea.  */
17764    && ((!TARGET_PARTIAL_REG_STALL
17765         && (GET_MODE (operands[0]) == QImode
17766             || GET_MODE (operands[0]) == HImode))
17767        || GET_MODE (operands[0]) == SImode
17768        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17769    && (rtx_equal_p (operands[0], operands[3])
17770        || peep2_reg_dead_p (2, operands[0]))
17771    /* We reorder load and the shift.  */
17772    && !reg_overlap_mentioned_p (operands[0], operands[4])"
17773   [(set (match_dup 5) (match_dup 4))
17774    (set (match_dup 0) (match_dup 1))]
17776   enum machine_mode op1mode = GET_MODE (operands[1]);
17777   enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17778   int scale = 1 << INTVAL (operands[2]);
17779   rtx index = gen_lowpart (word_mode, operands[1]);
17780   rtx base = gen_lowpart (word_mode, operands[5]);
17781   rtx dest = gen_lowpart (mode, operands[3]);
17783   operands[1] = gen_rtx_PLUS (word_mode, base,
17784                               gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17785   operands[5] = base;
17786   if (mode != word_mode)
17787     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17788   if (op1mode != word_mode)
17789     operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17790   operands[0] = dest;
17793 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17794 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17795 ;; caught for use by garbage collectors and the like.  Using an insn that
17796 ;; maps to SIGILL makes it more likely the program will rightfully die.
17797 ;; Keeping with tradition, "6" is in honor of #UD.
17798 (define_insn "trap"
17799   [(trap_if (const_int 1) (const_int 6))]
17800   ""
17802 #ifdef HAVE_AS_IX86_UD2
17803   return "ud2";
17804 #else
17805   return ASM_SHORT "0x0b0f";
17806 #endif
17808   [(set_attr "length" "2")])
17810 (define_expand "prefetch"
17811   [(prefetch (match_operand 0 "address_operand")
17812              (match_operand:SI 1 "const_int_operand")
17813              (match_operand:SI 2 "const_int_operand"))]
17814   "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
17816   bool write = INTVAL (operands[1]) != 0;
17817   int locality = INTVAL (operands[2]);
17819   gcc_assert (IN_RANGE (locality, 0, 3));
17821   /* Use 3dNOW prefetch in case we are asking for write prefetch not
17822      supported by SSE counterpart or the SSE prefetch is not available
17823      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17824      of locality.  */
17825   if (TARGET_PREFETCHWT1 && write && locality <= 2)
17826     operands[2] = const2_rtx;
17827   else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
17828     operands[2] = GEN_INT (3);
17829   else
17830     operands[1] = const0_rtx;
17833 (define_insn "*prefetch_sse"
17834   [(prefetch (match_operand 0 "address_operand" "p")
17835              (const_int 0)
17836              (match_operand:SI 1 "const_int_operand"))]
17837   "TARGET_PREFETCH_SSE"
17839   static const char * const patterns[4] = {
17840    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17841   };
17843   int locality = INTVAL (operands[1]);
17844   gcc_assert (IN_RANGE (locality, 0, 3));
17846   return patterns[locality];
17848   [(set_attr "type" "sse")
17849    (set_attr "atom_sse_attr" "prefetch")
17850    (set (attr "length_address")
17851         (symbol_ref "memory_address_length (operands[0], false)"))
17852    (set_attr "memory" "none")])
17854 (define_insn "*prefetch_3dnow"
17855   [(prefetch (match_operand 0 "address_operand" "p")
17856              (match_operand:SI 1 "const_int_operand" "n")
17857              (const_int 3))]
17858   "TARGET_PRFCHW"
17860   if (INTVAL (operands[1]) == 0)
17861     return "prefetch\t%a0";
17862   else
17863     return "prefetchw\t%a0";
17865   [(set_attr "type" "mmx")
17866    (set (attr "length_address")
17867         (symbol_ref "memory_address_length (operands[0], false)"))
17868    (set_attr "memory" "none")])
17870 (define_insn "*prefetch_prefetchwt1_<mode>"
17871   [(prefetch (match_operand:P 0 "address_operand" "p")
17872              (const_int 1)
17873              (const_int 2))]
17874   "TARGET_PREFETCHWT1"
17875   "prefetchwt1\t%a0";
17876   [(set_attr "type" "sse")
17877    (set (attr "length_address")
17878         (symbol_ref "memory_address_length (operands[0], false)"))
17879    (set_attr "memory" "none")])
17881 (define_expand "stack_protect_set"
17882   [(match_operand 0 "memory_operand")
17883    (match_operand 1 "memory_operand")]
17884   "TARGET_SSP_TLS_GUARD"
17886   rtx (*insn)(rtx, rtx);
17888 #ifdef TARGET_THREAD_SSP_OFFSET
17889   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17890   insn = (TARGET_LP64
17891           ? gen_stack_tls_protect_set_di
17892           : gen_stack_tls_protect_set_si);
17893 #else
17894   insn = (TARGET_LP64
17895           ? gen_stack_protect_set_di
17896           : gen_stack_protect_set_si);
17897 #endif
17899   emit_insn (insn (operands[0], operands[1]));
17900   DONE;
17903 (define_insn "stack_protect_set_<mode>"
17904   [(set (match_operand:PTR 0 "memory_operand" "=m")
17905         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17906                     UNSPEC_SP_SET))
17907    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17908    (clobber (reg:CC FLAGS_REG))]
17909   "TARGET_SSP_TLS_GUARD"
17910   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17911   [(set_attr "type" "multi")])
17913 (define_insn "stack_tls_protect_set_<mode>"
17914   [(set (match_operand:PTR 0 "memory_operand" "=m")
17915         (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17916                     UNSPEC_SP_TLS_SET))
17917    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17918    (clobber (reg:CC FLAGS_REG))]
17919   ""
17920   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17921   [(set_attr "type" "multi")])
17923 (define_expand "stack_protect_test"
17924   [(match_operand 0 "memory_operand")
17925    (match_operand 1 "memory_operand")
17926    (match_operand 2)]
17927   "TARGET_SSP_TLS_GUARD"
17929   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17931   rtx (*insn)(rtx, rtx, rtx);
17933 #ifdef TARGET_THREAD_SSP_OFFSET
17934   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17935   insn = (TARGET_LP64
17936           ? gen_stack_tls_protect_test_di
17937           : gen_stack_tls_protect_test_si);
17938 #else
17939   insn = (TARGET_LP64
17940           ? gen_stack_protect_test_di
17941           : gen_stack_protect_test_si);
17942 #endif
17944   emit_insn (insn (flags, operands[0], operands[1]));
17946   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17947                                   flags, const0_rtx, operands[2]));
17948   DONE;
17951 (define_insn "stack_protect_test_<mode>"
17952   [(set (match_operand:CCZ 0 "flags_reg_operand")
17953         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17954                      (match_operand:PTR 2 "memory_operand" "m")]
17955                     UNSPEC_SP_TEST))
17956    (clobber (match_scratch:PTR 3 "=&r"))]
17957   "TARGET_SSP_TLS_GUARD"
17958   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17959   [(set_attr "type" "multi")])
17961 (define_insn "stack_tls_protect_test_<mode>"
17962   [(set (match_operand:CCZ 0 "flags_reg_operand")
17963         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17964                      (match_operand:PTR 2 "const_int_operand" "i")]
17965                     UNSPEC_SP_TLS_TEST))
17966    (clobber (match_scratch:PTR 3 "=r"))]
17967   ""
17968   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17969   [(set_attr "type" "multi")])
17971 (define_insn "sse4_2_crc32<mode>"
17972   [(set (match_operand:SI 0 "register_operand" "=r")
17973         (unspec:SI
17974           [(match_operand:SI 1 "register_operand" "0")
17975            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17976           UNSPEC_CRC32))]
17977   "TARGET_SSE4_2 || TARGET_CRC32"
17978   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17979   [(set_attr "type" "sselog1")
17980    (set_attr "prefix_rep" "1")
17981    (set_attr "prefix_extra" "1")
17982    (set (attr "prefix_data16")
17983      (if_then_else (match_operand:HI 2)
17984        (const_string "1")
17985        (const_string "*")))
17986    (set (attr "prefix_rex")
17987      (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17988        (const_string "1")
17989        (const_string "*")))
17990    (set_attr "mode" "SI")])
17992 (define_insn "sse4_2_crc32di"
17993   [(set (match_operand:DI 0 "register_operand" "=r")
17994         (unspec:DI
17995           [(match_operand:DI 1 "register_operand" "0")
17996            (match_operand:DI 2 "nonimmediate_operand" "rm")]
17997           UNSPEC_CRC32))]
17998   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17999   "crc32{q}\t{%2, %0|%0, %2}"
18000   [(set_attr "type" "sselog1")
18001    (set_attr "prefix_rep" "1")
18002    (set_attr "prefix_extra" "1")
18003    (set_attr "mode" "DI")])
18005 (define_insn "rdpmc"
18006   [(set (match_operand:DI 0 "register_operand" "=A")
18007         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18008                             UNSPECV_RDPMC))]
18009   "!TARGET_64BIT"
18010   "rdpmc"
18011   [(set_attr "type" "other")
18012    (set_attr "length" "2")])
18014 (define_insn "rdpmc_rex64"
18015   [(set (match_operand:DI 0 "register_operand" "=a")
18016         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18017                             UNSPECV_RDPMC))
18018    (set (match_operand:DI 1 "register_operand" "=d")
18019         (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18020   "TARGET_64BIT"
18021   "rdpmc"
18022   [(set_attr "type" "other")
18023    (set_attr "length" "2")])
18025 (define_insn "rdtsc"
18026   [(set (match_operand:DI 0 "register_operand" "=A")
18027         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18028   "!TARGET_64BIT"
18029   "rdtsc"
18030   [(set_attr "type" "other")
18031    (set_attr "length" "2")])
18033 (define_insn "rdtsc_rex64"
18034   [(set (match_operand:DI 0 "register_operand" "=a")
18035         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18036    (set (match_operand:DI 1 "register_operand" "=d")
18037         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18038   "TARGET_64BIT"
18039   "rdtsc"
18040   [(set_attr "type" "other")
18041    (set_attr "length" "2")])
18043 (define_insn "rdtscp"
18044   [(set (match_operand:DI 0 "register_operand" "=A")
18045         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18046    (set (match_operand:SI 1 "register_operand" "=c")
18047         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18048   "!TARGET_64BIT"
18049   "rdtscp"
18050   [(set_attr "type" "other")
18051    (set_attr "length" "3")])
18053 (define_insn "rdtscp_rex64"
18054   [(set (match_operand:DI 0 "register_operand" "=a")
18055         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18056    (set (match_operand:DI 1 "register_operand" "=d")
18057         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18058    (set (match_operand:SI 2 "register_operand" "=c")
18059         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18060   "TARGET_64BIT"
18061   "rdtscp"
18062   [(set_attr "type" "other")
18063    (set_attr "length" "3")])
18065 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18067 ;; FXSR, XSAVE and XSAVEOPT instructions
18069 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18071 (define_insn "fxsave"
18072   [(set (match_operand:BLK 0 "memory_operand" "=m")
18073         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18074   "TARGET_FXSR"
18075   "fxsave\t%0"
18076   [(set_attr "type" "other")
18077    (set_attr "memory" "store")
18078    (set (attr "length")
18079         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18081 (define_insn "fxsave64"
18082   [(set (match_operand:BLK 0 "memory_operand" "=m")
18083         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18084   "TARGET_64BIT && TARGET_FXSR"
18085   "fxsave64\t%0"
18086   [(set_attr "type" "other")
18087    (set_attr "memory" "store")
18088    (set (attr "length")
18089         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18091 (define_insn "fxrstor"
18092   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18093                     UNSPECV_FXRSTOR)]
18094   "TARGET_FXSR"
18095   "fxrstor\t%0"
18096   [(set_attr "type" "other")
18097    (set_attr "memory" "load")
18098    (set (attr "length")
18099         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18101 (define_insn "fxrstor64"
18102   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18103                     UNSPECV_FXRSTOR64)]
18104   "TARGET_64BIT && TARGET_FXSR"
18105   "fxrstor64\t%0"
18106   [(set_attr "type" "other")
18107    (set_attr "memory" "load")
18108    (set (attr "length")
18109         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18111 (define_int_iterator ANY_XSAVE
18112         [UNSPECV_XSAVE
18113          (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
18114          (UNSPECV_XSAVEC "TARGET_XSAVEC")
18115          (UNSPECV_XSAVES "TARGET_XSAVES")])
18117 (define_int_iterator ANY_XSAVE64
18118         [UNSPECV_XSAVE64
18119          (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
18120          (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
18121          (UNSPECV_XSAVES64 "TARGET_XSAVES")])
18123 (define_int_attr xsave
18124         [(UNSPECV_XSAVE "xsave")
18125          (UNSPECV_XSAVE64 "xsave64")
18126          (UNSPECV_XSAVEOPT "xsaveopt")
18127          (UNSPECV_XSAVEOPT64 "xsaveopt64")
18128          (UNSPECV_XSAVEC "xsavec")
18129          (UNSPECV_XSAVEC64 "xsavec64")
18130          (UNSPECV_XSAVES "xsaves")
18131          (UNSPECV_XSAVES64 "xsaves64")])
18133 (define_int_iterator ANY_XRSTOR
18134         [UNSPECV_XRSTOR
18135          (UNSPECV_XRSTORS "TARGET_XSAVES")])
18137 (define_int_iterator ANY_XRSTOR64
18138         [UNSPECV_XRSTOR64
18139          (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
18141 (define_int_attr xrstor
18142         [(UNSPECV_XRSTOR "xrstor")
18143          (UNSPECV_XRSTOR64 "xrstor")
18144          (UNSPECV_XRSTORS "xrstors")
18145          (UNSPECV_XRSTORS64 "xrstors")])
18147 (define_insn "<xsave>"
18148   [(set (match_operand:BLK 0 "memory_operand" "=m")
18149         (unspec_volatile:BLK
18150          [(match_operand:DI 1 "register_operand" "A")]
18151          ANY_XSAVE))]
18152   "!TARGET_64BIT && TARGET_XSAVE"
18153   "<xsave>\t%0"
18154   [(set_attr "type" "other")
18155    (set_attr "memory" "store")
18156    (set (attr "length")
18157         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18159 (define_insn "<xsave>_rex64"
18160   [(set (match_operand:BLK 0 "memory_operand" "=m")
18161         (unspec_volatile:BLK
18162          [(match_operand:SI 1 "register_operand" "a")
18163           (match_operand:SI 2 "register_operand" "d")]
18164          ANY_XSAVE))]
18165   "TARGET_64BIT && TARGET_XSAVE"
18166   "<xsave>\t%0"
18167   [(set_attr "type" "other")
18168    (set_attr "memory" "store")
18169    (set (attr "length")
18170         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18172 (define_insn "<xsave>"
18173   [(set (match_operand:BLK 0 "memory_operand" "=m")
18174         (unspec_volatile:BLK
18175          [(match_operand:SI 1 "register_operand" "a")
18176           (match_operand:SI 2 "register_operand" "d")]
18177          ANY_XSAVE64))]
18178   "TARGET_64BIT && TARGET_XSAVE"
18179   "<xsave>\t%0"
18180   [(set_attr "type" "other")
18181    (set_attr "memory" "store")
18182    (set (attr "length")
18183         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18185 (define_insn "<xrstor>"
18186    [(unspec_volatile:BLK
18187      [(match_operand:BLK 0 "memory_operand" "m")
18188       (match_operand:DI 1 "register_operand" "A")]
18189      ANY_XRSTOR)]
18190   "!TARGET_64BIT && TARGET_XSAVE"
18191   "<xrstor>\t%0"
18192   [(set_attr "type" "other")
18193    (set_attr "memory" "load")
18194    (set (attr "length")
18195         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18197 (define_insn "<xrstor>_rex64"
18198    [(unspec_volatile:BLK
18199      [(match_operand:BLK 0 "memory_operand" "m")
18200       (match_operand:SI 1 "register_operand" "a")
18201       (match_operand:SI 2 "register_operand" "d")]
18202      ANY_XRSTOR)]
18203   "TARGET_64BIT && TARGET_XSAVE"
18204   "<xrstor>\t%0"
18205   [(set_attr "type" "other")
18206    (set_attr "memory" "load")
18207    (set (attr "length")
18208         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18210 (define_insn "<xrstor>64"
18211    [(unspec_volatile:BLK
18212      [(match_operand:BLK 0 "memory_operand" "m")
18213       (match_operand:SI 1 "register_operand" "a")
18214       (match_operand:SI 2 "register_operand" "d")]
18215      ANY_XRSTOR64)]
18216   "TARGET_64BIT && TARGET_XSAVE"
18217   "<xrstor>64\t%0"
18218   [(set_attr "type" "other")
18219    (set_attr "memory" "load")
18220    (set (attr "length")
18221         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18223 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18225 ;; Floating-point instructions for atomic compound assignments
18227 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18229 ; Clobber all floating-point registers on environment save and restore
18230 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18231 (define_insn "fnstenv"
18232   [(set (match_operand:BLK 0 "memory_operand" "=m")
18233         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18234    (clobber (reg:HI FPCR_REG))
18235    (clobber (reg:XF ST0_REG))
18236    (clobber (reg:XF ST1_REG))
18237    (clobber (reg:XF ST2_REG))
18238    (clobber (reg:XF ST3_REG))
18239    (clobber (reg:XF ST4_REG))
18240    (clobber (reg:XF ST5_REG))
18241    (clobber (reg:XF ST6_REG))
18242    (clobber (reg:XF ST7_REG))]
18243   "TARGET_80387"
18244   "fnstenv\t%0"
18245   [(set_attr "type" "other")
18246    (set_attr "memory" "store")
18247    (set (attr "length")
18248         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18250 (define_insn "fldenv"
18251   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18252                     UNSPECV_FLDENV)
18253    (clobber (reg:CCFP FPSR_REG))
18254    (clobber (reg:HI FPCR_REG))
18255    (clobber (reg:XF ST0_REG))
18256    (clobber (reg:XF ST1_REG))
18257    (clobber (reg:XF ST2_REG))
18258    (clobber (reg:XF ST3_REG))
18259    (clobber (reg:XF ST4_REG))
18260    (clobber (reg:XF ST5_REG))
18261    (clobber (reg:XF ST6_REG))
18262    (clobber (reg:XF ST7_REG))]
18263   "TARGET_80387"
18264   "fldenv\t%0"
18265   [(set_attr "type" "other")
18266    (set_attr "memory" "load")
18267    (set (attr "length")
18268         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18270 (define_insn "fnstsw"
18271   [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
18272         (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18273   "TARGET_80387"
18274   "fnstsw\t%0"
18275   [(set_attr "type" "other,other")
18276    (set_attr "memory" "none,store")
18277    (set (attr "length")
18278         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18280 (define_insn "fnclex"
18281   [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
18282   "TARGET_80387"
18283   "fnclex"
18284   [(set_attr "type" "other")
18285    (set_attr "memory" "none")
18286    (set_attr "length" "2")])
18288 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18290 ;; LWP instructions
18292 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18294 (define_expand "lwp_llwpcb"
18295   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18296                     UNSPECV_LLWP_INTRINSIC)]
18297   "TARGET_LWP")
18299 (define_insn "*lwp_llwpcb<mode>1"
18300   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18301                     UNSPECV_LLWP_INTRINSIC)]
18302   "TARGET_LWP"
18303   "llwpcb\t%0"
18304   [(set_attr "type" "lwp")
18305    (set_attr "mode" "<MODE>")
18306    (set_attr "length" "5")])
18308 (define_expand "lwp_slwpcb"
18309   [(set (match_operand 0 "register_operand" "=r")
18310         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18311   "TARGET_LWP"
18313   rtx (*insn)(rtx);
18315   insn = (Pmode == DImode
18316           ? gen_lwp_slwpcbdi
18317           : gen_lwp_slwpcbsi);
18319   emit_insn (insn (operands[0]));
18320   DONE;
18323 (define_insn "lwp_slwpcb<mode>"
18324   [(set (match_operand:P 0 "register_operand" "=r")
18325         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18326   "TARGET_LWP"
18327   "slwpcb\t%0"
18328   [(set_attr "type" "lwp")
18329    (set_attr "mode" "<MODE>")
18330    (set_attr "length" "5")])
18332 (define_expand "lwp_lwpval<mode>3"
18333   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18334                      (match_operand:SI 2 "nonimmediate_operand" "rm")
18335                      (match_operand:SI 3 "const_int_operand" "i")]
18336                     UNSPECV_LWPVAL_INTRINSIC)]
18337   "TARGET_LWP"
18338   ;; Avoid unused variable warning.
18339   "(void) operands[0];")
18341 (define_insn "*lwp_lwpval<mode>3_1"
18342   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18343                      (match_operand:SI 1 "nonimmediate_operand" "rm")
18344                      (match_operand:SI 2 "const_int_operand" "i")]
18345                     UNSPECV_LWPVAL_INTRINSIC)]
18346   "TARGET_LWP"
18347   "lwpval\t{%2, %1, %0|%0, %1, %2}"
18348   [(set_attr "type" "lwp")
18349    (set_attr "mode" "<MODE>")
18350    (set (attr "length")
18351         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18353 (define_expand "lwp_lwpins<mode>3"
18354   [(set (reg:CCC FLAGS_REG)
18355         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18356                               (match_operand:SI 2 "nonimmediate_operand" "rm")
18357                               (match_operand:SI 3 "const_int_operand" "i")]
18358                              UNSPECV_LWPINS_INTRINSIC))
18359    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18360         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18361   "TARGET_LWP")
18363 (define_insn "*lwp_lwpins<mode>3_1"
18364   [(set (reg:CCC FLAGS_REG)
18365         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18366                               (match_operand:SI 1 "nonimmediate_operand" "rm")
18367                               (match_operand:SI 2 "const_int_operand" "i")]
18368                              UNSPECV_LWPINS_INTRINSIC))]
18369   "TARGET_LWP"
18370   "lwpins\t{%2, %1, %0|%0, %1, %2}"
18371   [(set_attr "type" "lwp")
18372    (set_attr "mode" "<MODE>")
18373    (set (attr "length")
18374         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18376 (define_int_iterator RDFSGSBASE
18377         [UNSPECV_RDFSBASE
18378          UNSPECV_RDGSBASE])
18380 (define_int_iterator WRFSGSBASE
18381         [UNSPECV_WRFSBASE
18382          UNSPECV_WRGSBASE])
18384 (define_int_attr fsgs
18385         [(UNSPECV_RDFSBASE "fs")
18386          (UNSPECV_RDGSBASE "gs")
18387          (UNSPECV_WRFSBASE "fs")
18388          (UNSPECV_WRGSBASE "gs")])
18390 (define_insn "rd<fsgs>base<mode>"
18391   [(set (match_operand:SWI48 0 "register_operand" "=r")
18392         (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18393   "TARGET_64BIT && TARGET_FSGSBASE"
18394   "rd<fsgs>base\t%0"
18395   [(set_attr "type" "other")
18396    (set_attr "prefix_extra" "2")])
18398 (define_insn "wr<fsgs>base<mode>"
18399   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18400                     WRFSGSBASE)]
18401   "TARGET_64BIT && TARGET_FSGSBASE"
18402   "wr<fsgs>base\t%0"
18403   [(set_attr "type" "other")
18404    (set_attr "prefix_extra" "2")])
18406 (define_insn "rdrand<mode>_1"
18407   [(set (match_operand:SWI248 0 "register_operand" "=r")
18408         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18409    (set (reg:CCC FLAGS_REG)
18410         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18411   "TARGET_RDRND"
18412   "rdrand\t%0"
18413   [(set_attr "type" "other")
18414    (set_attr "prefix_extra" "1")])
18416 (define_insn "rdseed<mode>_1"
18417   [(set (match_operand:SWI248 0 "register_operand" "=r")
18418         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18419    (set (reg:CCC FLAGS_REG)
18420         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18421   "TARGET_RDSEED"
18422   "rdseed\t%0"
18423   [(set_attr "type" "other")
18424    (set_attr "prefix_extra" "1")])
18426 (define_expand "pause"
18427   [(set (match_dup 0)
18428         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18429   ""
18431   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18432   MEM_VOLATILE_P (operands[0]) = 1;
18435 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18436 ;; They have the same encoding.
18437 (define_insn "*pause"
18438   [(set (match_operand:BLK 0)
18439         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18440   ""
18441   "rep%; nop"
18442   [(set_attr "length" "2")
18443    (set_attr "memory" "unknown")])
18445 (define_expand "xbegin"
18446   [(set (match_operand:SI 0 "register_operand")
18447         (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18448   "TARGET_RTM"
18450   rtx label = gen_label_rtx ();
18452   /* xbegin is emitted as jump_insn, so reload won't be able
18453      to reload its operand.  Force the value into AX hard register.  */
18454   rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18455   emit_move_insn (ax_reg, constm1_rtx);
18457   emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18459   emit_label (label);
18460   LABEL_NUSES (label) = 1;
18462   emit_move_insn (operands[0], ax_reg);
18464   DONE;
18467 (define_insn "xbegin_1"
18468   [(set (pc)
18469         (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18470                           (const_int 0))
18471                       (label_ref (match_operand 1))
18472                       (pc)))
18473    (set (match_operand:SI 0 "register_operand" "+a")
18474         (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18475   "TARGET_RTM"
18476   "xbegin\t%l1"
18477   [(set_attr "type" "other")
18478    (set_attr "length" "6")])
18480 (define_insn "xend"
18481   [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18482   "TARGET_RTM"
18483   "xend"
18484   [(set_attr "type" "other")
18485    (set_attr "length" "3")])
18487 (define_insn "xabort"
18488   [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18489                     UNSPECV_XABORT)]
18490   "TARGET_RTM"
18491   "xabort\t%0"
18492   [(set_attr "type" "other")
18493    (set_attr "length" "3")])
18495 (define_expand "xtest"
18496   [(set (match_operand:QI 0 "register_operand")
18497         (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18498   "TARGET_RTM"
18500   emit_insn (gen_xtest_1 ());
18502   ix86_expand_setcc (operands[0], NE,
18503                      gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18504   DONE;
18507 (define_insn "xtest_1"
18508   [(set (reg:CCZ FLAGS_REG)
18509         (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18510   "TARGET_RTM"
18511   "xtest"
18512   [(set_attr "type" "other")
18513    (set_attr "length" "3")])
18515 (define_insn "clflushopt"
18516   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18517                    UNSPECV_CLFLUSHOPT)]
18518   "TARGET_CLFLUSHOPT"
18519   "clflushopt\t%a0"
18520   [(set_attr "type" "sse")
18521    (set_attr "atom_sse_attr" "fence")
18522    (set_attr "memory" "unknown")])
18524 (include "mmx.md")
18525 (include "sse.md")
18526 (include "sync.md")