PR target/63620
[official-gcc.git] / gcc / config / i386 / i386.md
blob7e4f328aa7f93bb617efb668af52c88012c6cfad
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_PAUSE
110   UNSPEC_LEA_ADDR
111   UNSPEC_XBEGIN_ABORT
112   UNSPEC_STOS
113   UNSPEC_PEEPSIB
114   UNSPEC_INSN_FALSE_DEP
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 (define_attr "preferred_for_speed" "" (const_int 1))
784 ;; Describe a user's asm statement.
785 (define_asm_attributes
786   [(set_attr "length" "128")
787    (set_attr "type" "multi")])
789 (define_code_iterator plusminus [plus minus])
791 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
793 (define_code_iterator multdiv [mult div])
795 ;; Base name for define_insn
796 (define_code_attr plusminus_insn
797   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
798    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
800 ;; Base name for insn mnemonic.
801 (define_code_attr plusminus_mnemonic
802   [(plus "add") (ss_plus "adds") (us_plus "addus")
803    (minus "sub") (ss_minus "subs") (us_minus "subus")])
804 (define_code_attr plusminus_carry_mnemonic
805   [(plus "adc") (minus "sbb")])
806 (define_code_attr multdiv_mnemonic
807   [(mult "mul") (div "div")])
809 ;; Mark commutative operators as such in constraints.
810 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
811                         (minus "") (ss_minus "") (us_minus "")])
813 ;; Mapping of max and min
814 (define_code_iterator maxmin [smax smin umax umin])
816 ;; Mapping of signed max and min
817 (define_code_iterator smaxmin [smax smin])
819 ;; Mapping of unsigned max and min
820 (define_code_iterator umaxmin [umax umin])
822 ;; Base name for integer and FP insn mnemonic
823 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
824                               (umax "maxu") (umin "minu")])
825 (define_code_attr maxmin_float [(smax "max") (smin "min")])
827 ;; Mapping of logic operators
828 (define_code_iterator any_logic [and ior xor])
829 (define_code_iterator any_or [ior xor])
830 (define_code_iterator fpint_logic [and xor])
832 ;; Base name for insn mnemonic.
833 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
835 ;; Mapping of logic-shift operators
836 (define_code_iterator any_lshift [ashift lshiftrt])
838 ;; Mapping of shift-right operators
839 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
841 ;; Mapping of all shift operators
842 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
844 ;; Base name for define_insn
845 (define_code_attr shift_insn
846   [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
848 ;; Base name for insn mnemonic.
849 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
850 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
852 ;; Mapping of rotate operators
853 (define_code_iterator any_rotate [rotate rotatert])
855 ;; Base name for define_insn
856 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
858 ;; Base name for insn mnemonic.
859 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
861 ;; Mapping of abs neg operators
862 (define_code_iterator absneg [abs neg])
864 ;; Base name for x87 insn mnemonic.
865 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
867 ;; Used in signed and unsigned widening multiplications.
868 (define_code_iterator any_extend [sign_extend zero_extend])
870 ;; Prefix for insn menmonic.
871 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
873 ;; Prefix for define_insn
874 (define_code_attr u [(sign_extend "") (zero_extend "u")])
875 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
876 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
878 ;; Used in signed and unsigned truncations.
879 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
880 ;; Instruction suffix for truncations.
881 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
883 ;; Used in signed and unsigned fix.
884 (define_code_iterator any_fix [fix unsigned_fix])
885 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
887 ;; Used in signed and unsigned float.
888 (define_code_iterator any_float [float unsigned_float])
889 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
891 ;; All integer modes.
892 (define_mode_iterator SWI1248x [QI HI SI DI])
894 ;; All integer modes with AVX512BW.
895 (define_mode_iterator SWI1248_AVX512BW
896   [QI HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
898 ;; All integer modes without QImode.
899 (define_mode_iterator SWI248x [HI SI DI])
901 ;; All integer modes without QImode and HImode.
902 (define_mode_iterator SWI48x [SI DI])
904 ;; All integer modes without SImode and DImode.
905 (define_mode_iterator SWI12 [QI HI])
907 ;; All integer modes without DImode.
908 (define_mode_iterator SWI124 [QI HI SI])
910 ;; All integer modes without QImode and DImode.
911 (define_mode_iterator SWI24 [HI SI])
913 ;; Single word integer modes.
914 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
916 ;; Single word integer modes without QImode.
917 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
919 ;; Single word integer modes without QImode and HImode.
920 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
922 ;; All math-dependant single and double word integer modes.
923 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
924                              (HI "TARGET_HIMODE_MATH")
925                              SI DI (TI "TARGET_64BIT")])
927 ;; Math-dependant single word integer modes.
928 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
929                             (HI "TARGET_HIMODE_MATH")
930                             SI (DI "TARGET_64BIT")])
932 ;; Math-dependant integer modes without DImode.
933 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
934                                (HI "TARGET_HIMODE_MATH")
935                                SI])
937 ;; Math-dependant single word integer modes without QImode.
938 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
939                                SI (DI "TARGET_64BIT")])
941 ;; Double word integer modes.
942 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
943                            (TI "TARGET_64BIT")])
945 ;; GET_MODE_SIZE for selected modes.  As GET_MODE_SIZE is not
946 ;; compile time constant, it is faster to use <MODE_SIZE> than
947 ;; GET_MODE_SIZE (<MODE>mode).  For XFmode which depends on
948 ;; command line options just use GET_MODE_SIZE macro.
949 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
950                              (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
951                              (V16QI "16") (V32QI "32") (V64QI "64")
952                              (V8HI "16") (V16HI "32") (V32HI "64")
953                              (V4SI "16") (V8SI "32") (V16SI "64")
954                              (V2DI "16") (V4DI "32") (V8DI "64")
955                              (V1TI "16") (V2TI "32") (V4TI "64")
956                              (V2DF "16") (V4DF "32") (V8DF "64")
957                              (V4SF "16") (V8SF "32") (V16SF "64")])
959 ;; Double word integer modes as mode attribute.
960 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
961 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
963 ;; Half mode for double word integer modes.
964 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
965                             (DI "TARGET_64BIT")])
967 ;; Instruction suffix for integer modes.
968 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
970 ;; Instruction suffix for masks.
971 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
973 ;; Pointer size prefix for integer modes (Intel asm dialect)
974 (define_mode_attr iptrsize [(QI "BYTE")
975                             (HI "WORD")
976                             (SI "DWORD")
977                             (DI "QWORD")])
979 ;; Register class for integer modes.
980 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
982 ;; Immediate operand constraint for integer modes.
983 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
985 ;; General operand constraint for word modes.
986 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
988 ;; Immediate operand constraint for double integer modes.
989 (define_mode_attr di [(SI "nF") (DI "e")])
991 ;; Immediate operand constraint for shifts.
992 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
994 ;; General operand predicate for integer modes.
995 (define_mode_attr general_operand
996         [(QI "general_operand")
997          (HI "general_operand")
998          (SI "x86_64_general_operand")
999          (DI "x86_64_general_operand")
1000          (TI "x86_64_general_operand")])
1002 ;; General sign extend operand predicate for integer modes,
1003 ;; which disallows VOIDmode operands and thus it is suitable
1004 ;; for use inside sign_extend.
1005 (define_mode_attr general_sext_operand
1006         [(QI "sext_operand")
1007          (HI "sext_operand")
1008          (SI "x86_64_sext_operand")
1009          (DI "x86_64_sext_operand")])
1011 ;; General sign/zero extend operand predicate for integer modes.
1012 (define_mode_attr general_szext_operand
1013         [(QI "general_operand")
1014          (HI "general_operand")
1015          (SI "x86_64_szext_general_operand")
1016          (DI "x86_64_szext_general_operand")])
1018 ;; Immediate operand predicate for integer modes.
1019 (define_mode_attr immediate_operand
1020         [(QI "immediate_operand")
1021          (HI "immediate_operand")
1022          (SI "x86_64_immediate_operand")
1023          (DI "x86_64_immediate_operand")])
1025 ;; Nonmemory operand predicate for integer modes.
1026 (define_mode_attr nonmemory_operand
1027         [(QI "nonmemory_operand")
1028          (HI "nonmemory_operand")
1029          (SI "x86_64_nonmemory_operand")
1030          (DI "x86_64_nonmemory_operand")])
1032 ;; Operand predicate for shifts.
1033 (define_mode_attr shift_operand
1034         [(QI "nonimmediate_operand")
1035          (HI "nonimmediate_operand")
1036          (SI "nonimmediate_operand")
1037          (DI "shiftdi_operand")
1038          (TI "register_operand")])
1040 ;; Operand predicate for shift argument.
1041 (define_mode_attr shift_immediate_operand
1042         [(QI "const_1_to_31_operand")
1043          (HI "const_1_to_31_operand")
1044          (SI "const_1_to_31_operand")
1045          (DI "const_1_to_63_operand")])
1047 ;; Input operand predicate for arithmetic left shifts.
1048 (define_mode_attr ashl_input_operand
1049         [(QI "nonimmediate_operand")
1050          (HI "nonimmediate_operand")
1051          (SI "nonimmediate_operand")
1052          (DI "ashldi_input_operand")
1053          (TI "reg_or_pm1_operand")])
1055 ;; SSE and x87 SFmode and DFmode floating point modes
1056 (define_mode_iterator MODEF [SF DF])
1058 ;; All x87 floating point modes
1059 (define_mode_iterator X87MODEF [SF DF XF])
1061 ;; SSE instruction suffix for various modes
1062 (define_mode_attr ssemodesuffix
1063   [(SF "ss") (DF "sd")
1064    (V16SF "ps") (V8DF "pd")
1065    (V8SF "ps") (V4DF "pd")
1066    (V4SF "ps") (V2DF "pd")
1067    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1068    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1069    (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1071 ;; SSE vector suffix for floating point modes
1072 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1074 ;; SSE vector mode corresponding to a scalar mode
1075 (define_mode_attr ssevecmode
1076   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1077 (define_mode_attr ssevecmodelower
1078   [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1080 ;; Instruction suffix for REX 64bit operators.
1081 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1083 ;; This mode iterator allows :P to be used for patterns that operate on
1084 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
1085 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1087 ;; This mode iterator allows :W to be used for patterns that operate on
1088 ;; word_mode sized quantities.
1089 (define_mode_iterator W
1090   [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1092 ;; This mode iterator allows :PTR to be used for patterns that operate on
1093 ;; ptr_mode sized quantities.
1094 (define_mode_iterator PTR
1095   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1097 ;; Scheduling descriptions
1099 (include "pentium.md")
1100 (include "ppro.md")
1101 (include "k6.md")
1102 (include "athlon.md")
1103 (include "bdver1.md")
1104 (include "bdver3.md")
1105 (include "btver2.md")
1106 (include "geode.md")
1107 (include "atom.md")
1108 (include "slm.md")
1109 (include "core2.md")
1112 ;; Operand and operator predicates and constraints
1114 (include "predicates.md")
1115 (include "constraints.md")
1118 ;; Compare and branch/compare and store instructions.
1120 (define_expand "cbranch<mode>4"
1121   [(set (reg:CC FLAGS_REG)
1122         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1123                     (match_operand:SDWIM 2 "<general_operand>")))
1124    (set (pc) (if_then_else
1125                (match_operator 0 "ordered_comparison_operator"
1126                 [(reg:CC FLAGS_REG) (const_int 0)])
1127                (label_ref (match_operand 3))
1128                (pc)))]
1129   ""
1131   if (MEM_P (operands[1]) && MEM_P (operands[2]))
1132     operands[1] = force_reg (<MODE>mode, operands[1]);
1133   ix86_expand_branch (GET_CODE (operands[0]),
1134                       operands[1], operands[2], operands[3]);
1135   DONE;
1138 (define_expand "cstore<mode>4"
1139   [(set (reg:CC FLAGS_REG)
1140         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1141                     (match_operand:SWIM 3 "<general_operand>")))
1142    (set (match_operand:QI 0 "register_operand")
1143         (match_operator 1 "ordered_comparison_operator"
1144           [(reg:CC FLAGS_REG) (const_int 0)]))]
1145   ""
1147   if (MEM_P (operands[2]) && MEM_P (operands[3]))
1148     operands[2] = force_reg (<MODE>mode, operands[2]);
1149   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1150                      operands[2], operands[3]);
1151   DONE;
1154 (define_expand "cmp<mode>_1"
1155   [(set (reg:CC FLAGS_REG)
1156         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1157                     (match_operand:SWI48 1 "<general_operand>")))])
1159 (define_insn "*cmp<mode>_ccno_1"
1160   [(set (reg FLAGS_REG)
1161         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1162                  (match_operand:SWI 1 "const0_operand")))]
1163   "ix86_match_ccmode (insn, CCNOmode)"
1164   "@
1165    test{<imodesuffix>}\t%0, %0
1166    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1167   [(set_attr "type" "test,icmp")
1168    (set_attr "length_immediate" "0,1")
1169    (set_attr "mode" "<MODE>")])
1171 (define_insn "*cmp<mode>_1"
1172   [(set (reg FLAGS_REG)
1173         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1174                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1175   "ix86_match_ccmode (insn, CCmode)"
1176   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1177   [(set_attr "type" "icmp")
1178    (set_attr "mode" "<MODE>")])
1180 (define_insn "*cmp<mode>_minus_1"
1181   [(set (reg FLAGS_REG)
1182         (compare
1183           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1184                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1185           (const_int 0)))]
1186   "ix86_match_ccmode (insn, CCGOCmode)"
1187   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1188   [(set_attr "type" "icmp")
1189    (set_attr "mode" "<MODE>")])
1191 (define_insn "*cmpqi_ext_1"
1192   [(set (reg FLAGS_REG)
1193         (compare
1194           (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1195           (subreg:QI
1196             (zero_extract:SI
1197               (match_operand 1 "ext_register_operand" "Q,Q")
1198               (const_int 8)
1199               (const_int 8)) 0)))]
1200   "ix86_match_ccmode (insn, CCmode)"
1201   "cmp{b}\t{%h1, %0|%0, %h1}"
1202   [(set_attr "isa" "*,nox64")
1203    (set_attr "type" "icmp")
1204    (set_attr "mode" "QI")])
1206 (define_insn "*cmpqi_ext_2"
1207   [(set (reg FLAGS_REG)
1208         (compare
1209           (subreg:QI
1210             (zero_extract:SI
1211               (match_operand 0 "ext_register_operand" "Q")
1212               (const_int 8)
1213               (const_int 8)) 0)
1214           (match_operand:QI 1 "const0_operand")))]
1215   "ix86_match_ccmode (insn, CCNOmode)"
1216   "test{b}\t%h0, %h0"
1217   [(set_attr "type" "test")
1218    (set_attr "length_immediate" "0")
1219    (set_attr "mode" "QI")])
1221 (define_expand "cmpqi_ext_3"
1222   [(set (reg:CC FLAGS_REG)
1223         (compare:CC
1224           (subreg:QI
1225             (zero_extract:SI
1226               (match_operand 0 "ext_register_operand")
1227               (const_int 8)
1228               (const_int 8)) 0)
1229           (match_operand:QI 1 "const_int_operand")))])
1231 (define_insn "*cmpqi_ext_3"
1232   [(set (reg FLAGS_REG)
1233         (compare
1234           (subreg:QI
1235             (zero_extract:SI
1236               (match_operand 0 "ext_register_operand" "Q,Q")
1237               (const_int 8)
1238               (const_int 8)) 0)
1239           (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1240   "ix86_match_ccmode (insn, CCmode)"
1241   "cmp{b}\t{%1, %h0|%h0, %1}"
1242   [(set_attr "isa" "*,nox64")
1243    (set_attr "type" "icmp")
1244    (set_attr "modrm" "1")
1245    (set_attr "mode" "QI")])
1247 (define_insn "*cmpqi_ext_4"
1248   [(set (reg FLAGS_REG)
1249         (compare
1250           (subreg:QI
1251             (zero_extract:SI
1252               (match_operand 0 "ext_register_operand" "Q")
1253               (const_int 8)
1254               (const_int 8)) 0)
1255           (subreg:QI
1256             (zero_extract:SI
1257               (match_operand 1 "ext_register_operand" "Q")
1258               (const_int 8)
1259               (const_int 8)) 0)))]
1260   "ix86_match_ccmode (insn, CCmode)"
1261   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1262   [(set_attr "type" "icmp")
1263    (set_attr "mode" "QI")])
1265 ;; These implement float point compares.
1266 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1267 ;; which would allow mix and match FP modes on the compares.  Which is what
1268 ;; the old patterns did, but with many more of them.
1270 (define_expand "cbranchxf4"
1271   [(set (reg:CC FLAGS_REG)
1272         (compare:CC (match_operand:XF 1 "nonmemory_operand")
1273                     (match_operand:XF 2 "nonmemory_operand")))
1274    (set (pc) (if_then_else
1275               (match_operator 0 "ix86_fp_comparison_operator"
1276                [(reg:CC FLAGS_REG)
1277                 (const_int 0)])
1278               (label_ref (match_operand 3))
1279               (pc)))]
1280   "TARGET_80387"
1282   ix86_expand_branch (GET_CODE (operands[0]),
1283                       operands[1], operands[2], operands[3]);
1284   DONE;
1287 (define_expand "cstorexf4"
1288   [(set (reg:CC FLAGS_REG)
1289         (compare:CC (match_operand:XF 2 "nonmemory_operand")
1290                     (match_operand:XF 3 "nonmemory_operand")))
1291    (set (match_operand:QI 0 "register_operand")
1292               (match_operator 1 "ix86_fp_comparison_operator"
1293                [(reg:CC FLAGS_REG)
1294                 (const_int 0)]))]
1295   "TARGET_80387"
1297   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1298                      operands[2], operands[3]);
1299   DONE;
1302 (define_expand "cbranch<mode>4"
1303   [(set (reg:CC FLAGS_REG)
1304         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1305                     (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1306    (set (pc) (if_then_else
1307               (match_operator 0 "ix86_fp_comparison_operator"
1308                [(reg:CC FLAGS_REG)
1309                 (const_int 0)])
1310               (label_ref (match_operand 3))
1311               (pc)))]
1312   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1314   ix86_expand_branch (GET_CODE (operands[0]),
1315                       operands[1], operands[2], operands[3]);
1316   DONE;
1319 (define_expand "cstore<mode>4"
1320   [(set (reg:CC FLAGS_REG)
1321         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1322                     (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1323    (set (match_operand:QI 0 "register_operand")
1324               (match_operator 1 "ix86_fp_comparison_operator"
1325                [(reg:CC FLAGS_REG)
1326                 (const_int 0)]))]
1327   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1329   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1330                      operands[2], operands[3]);
1331   DONE;
1334 (define_expand "cbranchcc4"
1335   [(set (pc) (if_then_else
1336               (match_operator 0 "comparison_operator"
1337                [(match_operand 1 "flags_reg_operand")
1338                 (match_operand 2 "const0_operand")])
1339               (label_ref (match_operand 3))
1340               (pc)))]
1341   ""
1343   ix86_expand_branch (GET_CODE (operands[0]),
1344                       operands[1], operands[2], operands[3]);
1345   DONE;
1348 (define_expand "cstorecc4"
1349   [(set (match_operand:QI 0 "register_operand")
1350               (match_operator 1 "comparison_operator"
1351                [(match_operand 2 "flags_reg_operand")
1352                 (match_operand 3 "const0_operand")]))]
1353   ""
1355   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1356                      operands[2], operands[3]);
1357   DONE;
1361 ;; FP compares, step 1:
1362 ;; Set the FP condition codes.
1364 ;; CCFPmode     compare with exceptions
1365 ;; CCFPUmode    compare with no exceptions
1367 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1368 ;; used to manage the reg stack popping would not be preserved.
1370 (define_insn "*cmp<mode>_0_i387"
1371   [(set (match_operand:HI 0 "register_operand" "=a")
1372         (unspec:HI
1373           [(compare:CCFP
1374              (match_operand:X87MODEF 1 "register_operand" "f")
1375              (match_operand:X87MODEF 2 "const0_operand"))]
1376         UNSPEC_FNSTSW))]
1377   "TARGET_80387"
1378   "* return output_fp_compare (insn, operands, false, false);"
1379   [(set_attr "type" "multi")
1380    (set_attr "unit" "i387")
1381    (set_attr "mode" "<MODE>")])
1383 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1384   [(set (reg:CCFP FLAGS_REG)
1385         (compare:CCFP
1386           (match_operand:X87MODEF 1 "register_operand" "f")
1387           (match_operand:X87MODEF 2 "const0_operand")))
1388    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1389   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1390   "#"
1391   "&& reload_completed"
1392   [(set (match_dup 0)
1393         (unspec:HI
1394           [(compare:CCFP (match_dup 1)(match_dup 2))]
1395         UNSPEC_FNSTSW))
1396    (set (reg:CC FLAGS_REG)
1397         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1398   ""
1399   [(set_attr "type" "multi")
1400    (set_attr "unit" "i387")
1401    (set_attr "mode" "<MODE>")])
1403 (define_insn "*cmpxf_i387"
1404   [(set (match_operand:HI 0 "register_operand" "=a")
1405         (unspec:HI
1406           [(compare:CCFP
1407              (match_operand:XF 1 "register_operand" "f")
1408              (match_operand:XF 2 "register_operand" "f"))]
1409           UNSPEC_FNSTSW))]
1410   "TARGET_80387"
1411   "* return output_fp_compare (insn, operands, false, false);"
1412   [(set_attr "type" "multi")
1413    (set_attr "unit" "i387")
1414    (set_attr "mode" "XF")])
1416 (define_insn_and_split "*cmpxf_cc_i387"
1417   [(set (reg:CCFP FLAGS_REG)
1418         (compare:CCFP
1419           (match_operand:XF 1 "register_operand" "f")
1420           (match_operand:XF 2 "register_operand" "f")))
1421    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1422   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1423   "#"
1424   "&& reload_completed"
1425   [(set (match_dup 0)
1426         (unspec:HI
1427           [(compare:CCFP (match_dup 1)(match_dup 2))]
1428         UNSPEC_FNSTSW))
1429    (set (reg:CC FLAGS_REG)
1430         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1431   ""
1432   [(set_attr "type" "multi")
1433    (set_attr "unit" "i387")
1434    (set_attr "mode" "XF")])
1436 (define_insn "*cmp<mode>_i387"
1437   [(set (match_operand:HI 0 "register_operand" "=a")
1438         (unspec:HI
1439           [(compare:CCFP
1440              (match_operand:MODEF 1 "register_operand" "f")
1441              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1442           UNSPEC_FNSTSW))]
1443   "TARGET_80387"
1444   "* return output_fp_compare (insn, operands, false, false);"
1445   [(set_attr "type" "multi")
1446    (set_attr "unit" "i387")
1447    (set_attr "mode" "<MODE>")])
1449 (define_insn_and_split "*cmp<mode>_cc_i387"
1450   [(set (reg:CCFP FLAGS_REG)
1451         (compare:CCFP
1452           (match_operand:MODEF 1 "register_operand" "f")
1453           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1454    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1455   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1456   "#"
1457   "&& reload_completed"
1458   [(set (match_dup 0)
1459         (unspec:HI
1460           [(compare:CCFP (match_dup 1)(match_dup 2))]
1461         UNSPEC_FNSTSW))
1462    (set (reg:CC FLAGS_REG)
1463         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1464   ""
1465   [(set_attr "type" "multi")
1466    (set_attr "unit" "i387")
1467    (set_attr "mode" "<MODE>")])
1469 (define_insn "*cmpu<mode>_i387"
1470   [(set (match_operand:HI 0 "register_operand" "=a")
1471         (unspec:HI
1472           [(compare:CCFPU
1473              (match_operand:X87MODEF 1 "register_operand" "f")
1474              (match_operand:X87MODEF 2 "register_operand" "f"))]
1475           UNSPEC_FNSTSW))]
1476   "TARGET_80387"
1477   "* return output_fp_compare (insn, operands, false, true);"
1478   [(set_attr "type" "multi")
1479    (set_attr "unit" "i387")
1480    (set_attr "mode" "<MODE>")])
1482 (define_insn_and_split "*cmpu<mode>_cc_i387"
1483   [(set (reg:CCFPU FLAGS_REG)
1484         (compare:CCFPU
1485           (match_operand:X87MODEF 1 "register_operand" "f")
1486           (match_operand:X87MODEF 2 "register_operand" "f")))
1487    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1488   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1489   "#"
1490   "&& reload_completed"
1491   [(set (match_dup 0)
1492         (unspec:HI
1493           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1494         UNSPEC_FNSTSW))
1495    (set (reg:CC FLAGS_REG)
1496         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1497   ""
1498   [(set_attr "type" "multi")
1499    (set_attr "unit" "i387")
1500    (set_attr "mode" "<MODE>")])
1502 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1503   [(set (match_operand:HI 0 "register_operand" "=a")
1504         (unspec:HI
1505           [(compare:CCFP
1506              (match_operand:X87MODEF 1 "register_operand" "f")
1507              (match_operator:X87MODEF 3 "float_operator"
1508                [(match_operand:SWI24 2 "memory_operand" "m")]))]
1509           UNSPEC_FNSTSW))]
1510   "TARGET_80387
1511    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1512        || optimize_function_for_size_p (cfun))"
1513   "* return output_fp_compare (insn, operands, false, false);"
1514   [(set_attr "type" "multi")
1515    (set_attr "unit" "i387")
1516    (set_attr "fp_int_src" "true")
1517    (set_attr "mode" "<SWI24:MODE>")])
1519 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1520   [(set (reg:CCFP FLAGS_REG)
1521         (compare:CCFP
1522           (match_operand:X87MODEF 1 "register_operand" "f")
1523           (match_operator:X87MODEF 3 "float_operator"
1524             [(match_operand:SWI24 2 "memory_operand" "m")])))
1525    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1526   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1527    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1528        || optimize_function_for_size_p (cfun))"
1529   "#"
1530   "&& reload_completed"
1531   [(set (match_dup 0)
1532         (unspec:HI
1533           [(compare:CCFP
1534              (match_dup 1)
1535              (match_op_dup 3 [(match_dup 2)]))]
1536         UNSPEC_FNSTSW))
1537    (set (reg:CC FLAGS_REG)
1538         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1539   ""
1540   [(set_attr "type" "multi")
1541    (set_attr "unit" "i387")
1542    (set_attr "fp_int_src" "true")
1543    (set_attr "mode" "<SWI24:MODE>")])
1545 ;; FP compares, step 2
1546 ;; Move the fpsw to ax.
1548 (define_insn "x86_fnstsw_1"
1549   [(set (match_operand:HI 0 "register_operand" "=a")
1550         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1551   "TARGET_80387"
1552   "fnstsw\t%0"
1553   [(set_attr "length" "2")
1554    (set_attr "mode" "SI")
1555    (set_attr "unit" "i387")])
1557 ;; FP compares, step 3
1558 ;; Get ax into flags, general case.
1560 (define_insn "x86_sahf_1"
1561   [(set (reg:CC FLAGS_REG)
1562         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1563                    UNSPEC_SAHF))]
1564   "TARGET_SAHF"
1566 #ifndef HAVE_AS_IX86_SAHF
1567   if (TARGET_64BIT)
1568     return ASM_BYTE "0x9e";
1569   else
1570 #endif
1571   return "sahf";
1573   [(set_attr "length" "1")
1574    (set_attr "athlon_decode" "vector")
1575    (set_attr "amdfam10_decode" "direct")
1576    (set_attr "bdver1_decode" "direct")
1577    (set_attr "mode" "SI")])
1579 ;; Pentium Pro can do steps 1 through 3 in one go.
1580 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1581 ;; (these i387 instructions set flags directly)
1583 (define_mode_iterator FPCMP [CCFP CCFPU])
1584 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1586 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1587   [(set (reg:FPCMP FLAGS_REG)
1588         (compare:FPCMP
1589           (match_operand:MODEF 0 "register_operand" "f,x")
1590           (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1591   "TARGET_MIX_SSE_I387
1592    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1593   "* return output_fp_compare (insn, operands, true,
1594                                <FPCMP:MODE>mode == CCFPUmode);"
1595   [(set_attr "type" "fcmp,ssecomi")
1596    (set_attr "prefix" "orig,maybe_vex")
1597    (set_attr "mode" "<MODEF:MODE>")
1598    (set (attr "prefix_rep")
1599         (if_then_else (eq_attr "type" "ssecomi")
1600                       (const_string "0")
1601                       (const_string "*")))
1602    (set (attr "prefix_data16")
1603         (cond [(eq_attr "type" "fcmp")
1604                  (const_string "*")
1605                (eq_attr "mode" "DF")
1606                  (const_string "1")
1607               ]
1608               (const_string "0")))
1609    (set_attr "athlon_decode" "vector")
1610    (set_attr "amdfam10_decode" "direct")
1611    (set_attr "bdver1_decode" "double")])
1613 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1614   [(set (reg:FPCMP FLAGS_REG)
1615         (compare:FPCMP
1616           (match_operand:MODEF 0 "register_operand" "x")
1617           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1618   "TARGET_SSE_MATH
1619    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1620   "* return output_fp_compare (insn, operands, true,
1621                                <FPCMP:MODE>mode == CCFPUmode);"
1622   [(set_attr "type" "ssecomi")
1623    (set_attr "prefix" "maybe_vex")
1624    (set_attr "mode" "<MODEF:MODE>")
1625    (set_attr "prefix_rep" "0")
1626    (set (attr "prefix_data16")
1627         (if_then_else (eq_attr "mode" "DF")
1628                       (const_string "1")
1629                       (const_string "0")))
1630    (set_attr "athlon_decode" "vector")
1631    (set_attr "amdfam10_decode" "direct")
1632    (set_attr "bdver1_decode" "double")])
1634 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1635   [(set (reg:FPCMP FLAGS_REG)
1636         (compare:FPCMP
1637           (match_operand:X87MODEF 0 "register_operand" "f")
1638           (match_operand:X87MODEF 1 "register_operand" "f")))]
1639   "TARGET_80387 && TARGET_CMOVE
1640    && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1641   "* return output_fp_compare (insn, operands, true,
1642                                <FPCMP:MODE>mode == CCFPUmode);"
1643   [(set_attr "type" "fcmp")
1644    (set_attr "mode" "<X87MODEF:MODE>")
1645    (set_attr "athlon_decode" "vector")
1646    (set_attr "amdfam10_decode" "direct")
1647    (set_attr "bdver1_decode" "double")])
1649 ;; Push/pop instructions.
1651 (define_insn "*push<mode>2"
1652   [(set (match_operand:DWI 0 "push_operand" "=<")
1653         (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1654   ""
1655   "#"
1656   [(set_attr "type" "multi")
1657    (set_attr "mode" "<MODE>")])
1659 (define_split
1660   [(set (match_operand:TI 0 "push_operand")
1661         (match_operand:TI 1 "general_operand"))]
1662   "TARGET_64BIT && reload_completed
1663    && !SSE_REG_P (operands[1])"
1664   [(const_int 0)]
1665   "ix86_split_long_move (operands); DONE;")
1667 (define_insn "*pushdi2_rex64"
1668   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1669         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1670   "TARGET_64BIT"
1671   "@
1672    push{q}\t%1
1673    #"
1674   [(set_attr "type" "push,multi")
1675    (set_attr "mode" "DI")])
1677 ;; Convert impossible pushes of immediate to existing instructions.
1678 ;; First try to get scratch register and go through it.  In case this
1679 ;; fails, push sign extended lower part first and then overwrite
1680 ;; upper part by 32bit move.
1681 (define_peephole2
1682   [(match_scratch:DI 2 "r")
1683    (set (match_operand:DI 0 "push_operand")
1684         (match_operand:DI 1 "immediate_operand"))]
1685   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1686    && !x86_64_immediate_operand (operands[1], DImode)"
1687   [(set (match_dup 2) (match_dup 1))
1688    (set (match_dup 0) (match_dup 2))])
1690 ;; We need to define this as both peepholer and splitter for case
1691 ;; peephole2 pass is not run.
1692 ;; "&& 1" is needed to keep it from matching the previous pattern.
1693 (define_peephole2
1694   [(set (match_operand:DI 0 "push_operand")
1695         (match_operand:DI 1 "immediate_operand"))]
1696   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1697    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1698   [(set (match_dup 0) (match_dup 1))
1699    (set (match_dup 2) (match_dup 3))]
1701   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1703   operands[1] = gen_lowpart (DImode, operands[2]);
1704   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1705                                                    GEN_INT (4)));
1708 (define_split
1709   [(set (match_operand:DI 0 "push_operand")
1710         (match_operand:DI 1 "immediate_operand"))]
1711   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1712                     ? epilogue_completed : reload_completed)
1713    && !symbolic_operand (operands[1], DImode)
1714    && !x86_64_immediate_operand (operands[1], DImode)"
1715   [(set (match_dup 0) (match_dup 1))
1716    (set (match_dup 2) (match_dup 3))]
1718   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1720   operands[1] = gen_lowpart (DImode, operands[2]);
1721   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1722                                                    GEN_INT (4)));
1725 (define_split
1726   [(set (match_operand:DI 0 "push_operand")
1727         (match_operand:DI 1 "general_operand"))]
1728   "!TARGET_64BIT && reload_completed
1729    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1730   [(const_int 0)]
1731   "ix86_split_long_move (operands); DONE;")
1733 (define_insn "*pushsi2"
1734   [(set (match_operand:SI 0 "push_operand" "=<")
1735         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1736   "!TARGET_64BIT"
1737   "push{l}\t%1"
1738   [(set_attr "type" "push")
1739    (set_attr "mode" "SI")])
1741 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1742 ;; "push a byte/word".  But actually we use pushl, which has the effect
1743 ;; of rounding the amount pushed up to a word.
1745 ;; For TARGET_64BIT we always round up to 8 bytes.
1746 (define_insn "*push<mode>2_rex64"
1747   [(set (match_operand:SWI124 0 "push_operand" "=X")
1748         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1749   "TARGET_64BIT"
1750   "push{q}\t%q1"
1751   [(set_attr "type" "push")
1752    (set_attr "mode" "DI")])
1754 (define_insn "*push<mode>2"
1755   [(set (match_operand:SWI12 0 "push_operand" "=X")
1756         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1757   "!TARGET_64BIT"
1758   "push{l}\t%k1"
1759   [(set_attr "type" "push")
1760    (set_attr "mode" "SI")])
1762 (define_insn "*push<mode>2_prologue"
1763   [(set (match_operand:W 0 "push_operand" "=<")
1764         (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1765    (clobber (mem:BLK (scratch)))]
1766   ""
1767   "push{<imodesuffix>}\t%1"
1768   [(set_attr "type" "push")
1769    (set_attr "mode" "<MODE>")])
1771 (define_insn "*pop<mode>1"
1772   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1773         (match_operand:W 1 "pop_operand" ">"))]
1774   ""
1775   "pop{<imodesuffix>}\t%0"
1776   [(set_attr "type" "pop")
1777    (set_attr "mode" "<MODE>")])
1779 (define_insn "*pop<mode>1_epilogue"
1780   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1781         (match_operand:W 1 "pop_operand" ">"))
1782    (clobber (mem:BLK (scratch)))]
1783   ""
1784   "pop{<imodesuffix>}\t%0"
1785   [(set_attr "type" "pop")
1786    (set_attr "mode" "<MODE>")])
1788 (define_insn "*pushfl<mode>2"
1789   [(set (match_operand:W 0 "push_operand" "=<")
1790         (match_operand:W 1 "flags_reg_operand"))]
1791   ""
1792   "pushf{<imodesuffix>}"
1793   [(set_attr "type" "push")
1794    (set_attr "mode" "<MODE>")])
1796 (define_insn "*popfl<mode>1"
1797   [(set (match_operand:W 0 "flags_reg_operand")
1798         (match_operand:W 1 "pop_operand" ">"))]
1799   ""
1800   "popf{<imodesuffix>}"
1801   [(set_attr "type" "pop")
1802    (set_attr "mode" "<MODE>")])
1805 ;; Move instructions.
1807 (define_expand "movxi"
1808   [(set (match_operand:XI 0 "nonimmediate_operand")
1809         (match_operand:XI 1 "general_operand"))]
1810   "TARGET_AVX512F"
1811   "ix86_expand_move (XImode, operands); DONE;")
1813 ;; Reload patterns to support multi-word load/store
1814 ;; with non-offsetable address.
1815 (define_expand "reload_noff_store"
1816   [(parallel [(match_operand 0 "memory_operand" "=m")
1817               (match_operand 1 "register_operand" "r")
1818               (match_operand:DI 2 "register_operand" "=&r")])]
1819   "TARGET_64BIT"
1821   rtx mem = operands[0];
1822   rtx addr = XEXP (mem, 0);
1824   emit_move_insn (operands[2], addr);
1825   mem = replace_equiv_address_nv (mem, operands[2]);
1827   emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
1828   DONE;
1831 (define_expand "reload_noff_load"
1832   [(parallel [(match_operand 0 "register_operand" "=r")
1833               (match_operand 1 "memory_operand" "m")
1834               (match_operand:DI 2 "register_operand" "=r")])]
1835   "TARGET_64BIT"
1837   rtx mem = operands[1];
1838   rtx addr = XEXP (mem, 0);
1840   emit_move_insn (operands[2], addr);
1841   mem = replace_equiv_address_nv (mem, operands[2]);
1843   emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
1844   DONE;
1847 (define_expand "movoi"
1848   [(set (match_operand:OI 0 "nonimmediate_operand")
1849         (match_operand:OI 1 "general_operand"))]
1850   "TARGET_AVX"
1851   "ix86_expand_move (OImode, operands); DONE;")
1853 (define_expand "movti"
1854   [(set (match_operand:TI 0 "nonimmediate_operand")
1855         (match_operand:TI 1 "nonimmediate_operand"))]
1856   "TARGET_64BIT || TARGET_SSE"
1858   if (TARGET_64BIT)
1859     ix86_expand_move (TImode, operands);
1860   else
1861     ix86_expand_vector_move (TImode, operands);
1862   DONE;
1865 ;; This expands to what emit_move_complex would generate if we didn't
1866 ;; have a movti pattern.  Having this avoids problems with reload on
1867 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1868 ;; to have around all the time.
1869 (define_expand "movcdi"
1870   [(set (match_operand:CDI 0 "nonimmediate_operand")
1871         (match_operand:CDI 1 "general_operand"))]
1872   ""
1874   if (push_operand (operands[0], CDImode))
1875     emit_move_complex_push (CDImode, operands[0], operands[1]);
1876   else
1877     emit_move_complex_parts (operands[0], operands[1]);
1878   DONE;
1881 (define_expand "mov<mode>"
1882   [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1883         (match_operand:SWI1248x 1 "general_operand"))]
1884   ""
1885   "ix86_expand_move (<MODE>mode, operands); DONE;")
1887 (define_insn "*mov<mode>_xor"
1888   [(set (match_operand:SWI48 0 "register_operand" "=r")
1889         (match_operand:SWI48 1 "const0_operand"))
1890    (clobber (reg:CC FLAGS_REG))]
1891   "reload_completed"
1892   "xor{l}\t%k0, %k0"
1893   [(set_attr "type" "alu1")
1894    (set_attr "mode" "SI")
1895    (set_attr "length_immediate" "0")])
1897 (define_insn "*mov<mode>_or"
1898   [(set (match_operand:SWI48 0 "register_operand" "=r")
1899         (match_operand:SWI48 1 "const_int_operand"))
1900    (clobber (reg:CC FLAGS_REG))]
1901   "reload_completed
1902    && operands[1] == constm1_rtx"
1903   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1904   [(set_attr "type" "alu1")
1905    (set_attr "mode" "<MODE>")
1906    (set_attr "length_immediate" "1")])
1908 (define_insn "*movxi_internal_avx512f"
1909   [(set (match_operand:XI 0 "nonimmediate_operand" "=x,x ,m")
1910         (match_operand:XI 1 "vector_move_operand"  "C ,xm,x"))]
1911   "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1913   switch (which_alternative)
1914     {
1915     case 0:
1916       return standard_sse_constant_opcode (insn, operands[1]);
1917     case 1:
1918     case 2:
1919       if (misaligned_operand (operands[0], XImode)
1920           || misaligned_operand (operands[1], XImode))
1921         return "vmovdqu32\t{%1, %0|%0, %1}";
1922       else
1923         return "vmovdqa32\t{%1, %0|%0, %1}";
1924     default:
1925       gcc_unreachable ();
1926     }
1928   [(set_attr "type" "sselog1,ssemov,ssemov")
1929    (set_attr "prefix" "evex")
1930    (set_attr "mode" "XI")])
1932 (define_insn "*movoi_internal_avx"
1933   [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,m")
1934         (match_operand:OI 1 "vector_move_operand"  "C ,vm,v"))]
1935   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1937   switch (get_attr_type (insn))
1938     {
1939     case TYPE_SSELOG1:
1940       return standard_sse_constant_opcode (insn, operands[1]);
1942     case TYPE_SSEMOV:
1943       if (misaligned_operand (operands[0], OImode)
1944           || misaligned_operand (operands[1], OImode))
1945         {
1946           if (get_attr_mode (insn) == MODE_V8SF)
1947             return "vmovups\t{%1, %0|%0, %1}";
1948           else if (get_attr_mode (insn) == MODE_XI)
1949             return "vmovdqu32\t{%1, %0|%0, %1}";
1950           else
1951             return "vmovdqu\t{%1, %0|%0, %1}";
1952         }
1953       else
1954         {
1955           if (get_attr_mode (insn) == MODE_V8SF)
1956             return "vmovaps\t{%1, %0|%0, %1}";
1957           else if (get_attr_mode (insn) == MODE_XI)
1958             return "vmovdqa32\t{%1, %0|%0, %1}";
1959           else
1960             return "vmovdqa\t{%1, %0|%0, %1}";
1961         }
1963     default:
1964       gcc_unreachable ();
1965     }
1967   [(set_attr "type" "sselog1,ssemov,ssemov")
1968    (set_attr "prefix" "vex")
1969    (set (attr "mode")
1970         (cond [(ior (match_operand 0 "ext_sse_reg_operand")
1971                     (match_operand 1 "ext_sse_reg_operand"))
1972                  (const_string "XI")
1973                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1974                  (const_string "V8SF")
1975                (and (eq_attr "alternative" "2")
1976                     (match_test "TARGET_SSE_TYPELESS_STORES"))
1977                  (const_string "V8SF")
1978               ]
1979               (const_string "OI")))])
1981 (define_insn "*movti_internal"
1982   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,m")
1983         (match_operand:TI 1 "general_operand"      "riFo,re,C,vm,v"))]
1984   "(TARGET_64BIT || TARGET_SSE)
1985    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1987   switch (get_attr_type (insn))
1988     {
1989     case TYPE_MULTI:
1990       return "#";
1992     case TYPE_SSELOG1:
1993       return standard_sse_constant_opcode (insn, operands[1]);
1995     case TYPE_SSEMOV:
1996       /* TDmode values are passed as TImode on the stack.  Moving them
1997          to stack may result in unaligned memory access.  */
1998       if (misaligned_operand (operands[0], TImode)
1999           || misaligned_operand (operands[1], TImode))
2000         {
2001           if (get_attr_mode (insn) == MODE_V4SF)
2002             return "%vmovups\t{%1, %0|%0, %1}";
2003           else if (get_attr_mode (insn) == MODE_XI)
2004             return "vmovdqu32\t{%1, %0|%0, %1}";
2005           else
2006             return "%vmovdqu\t{%1, %0|%0, %1}";
2007         }
2008       else
2009         {
2010           if (get_attr_mode (insn) == MODE_V4SF)
2011             return "%vmovaps\t{%1, %0|%0, %1}";
2012           else if (get_attr_mode (insn) == MODE_XI)
2013             return "vmovdqa32\t{%1, %0|%0, %1}";
2014           else
2015             return "%vmovdqa\t{%1, %0|%0, %1}";
2016         }
2018     default:
2019       gcc_unreachable ();
2020     }
2022   [(set_attr "isa" "x64,x64,*,*,*")
2023    (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
2024    (set (attr "prefix")
2025      (if_then_else (eq_attr "type" "sselog1,ssemov")
2026        (const_string "maybe_vex")
2027        (const_string "orig")))
2028    (set (attr "mode")
2029         (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2030                     (match_operand 1 "ext_sse_reg_operand"))
2031                  (const_string "XI")
2032                (eq_attr "alternative" "0,1")
2033                  (const_string "DI")
2034                (ior (not (match_test "TARGET_SSE2"))
2035                     (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2036                  (const_string "V4SF")
2037                (and (eq_attr "alternative" "4")
2038                     (match_test "TARGET_SSE_TYPELESS_STORES"))
2039                  (const_string "V4SF")
2040                (match_test "TARGET_AVX")
2041                  (const_string "TI")
2042                (match_test "optimize_function_for_size_p (cfun)")
2043                  (const_string "V4SF")
2044                ]
2045                (const_string "TI")))])
2047 (define_split
2048   [(set (match_operand:TI 0 "nonimmediate_operand")
2049         (match_operand:TI 1 "general_operand"))]
2050   "reload_completed
2051    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
2052   [(const_int 0)]
2053   "ix86_split_long_move (operands); DONE;")
2055 (define_insn "*movdi_internal"
2056   [(set (match_operand:DI 0 "nonimmediate_operand"
2057     "=r  ,o  ,r,r  ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,?r ,?r,?*Yi,?*Ym,?*Yi,*k,*k ,*r ,*m")
2058         (match_operand:DI 1 "general_operand"
2059     "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"))]
2060   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2062   switch (get_attr_type (insn))
2063     {
2064     case TYPE_MSKMOV:
2065       return "kmovq\t{%1, %0|%0, %1}";
2067     case TYPE_MULTI:
2068       return "#";
2070     case TYPE_MMX:
2071       return "pxor\t%0, %0";
2073     case TYPE_MMXMOV:
2074       /* Handle broken assemblers that require movd instead of movq.  */
2075       if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2076           && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2077         return "movd\t{%1, %0|%0, %1}";
2078       return "movq\t{%1, %0|%0, %1}";
2080     case TYPE_SSELOG1:
2081       if (GENERAL_REG_P (operands[0]))
2082         return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2084       return standard_sse_constant_opcode (insn, operands[1]);
2086     case TYPE_SSEMOV:
2087       switch (get_attr_mode (insn))
2088         {
2089         case MODE_DI:
2090           /* Handle broken assemblers that require movd instead of movq.  */
2091           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2092               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2093             return "%vmovd\t{%1, %0|%0, %1}";
2094           return "%vmovq\t{%1, %0|%0, %1}";
2095         case MODE_TI:
2096           return "%vmovdqa\t{%1, %0|%0, %1}";
2097         case MODE_XI:
2098           return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2100         case MODE_V2SF:
2101           gcc_assert (!TARGET_AVX);
2102           return "movlps\t{%1, %0|%0, %1}";
2103         case MODE_V4SF:
2104           return "%vmovaps\t{%1, %0|%0, %1}";
2106         default:
2107           gcc_unreachable ();
2108         }
2110     case TYPE_SSECVT:
2111       if (SSE_REG_P (operands[0]))
2112         return "movq2dq\t{%1, %0|%0, %1}";
2113       else
2114         return "movdq2q\t{%1, %0|%0, %1}";
2116     case TYPE_LEA:
2117       return "lea{q}\t{%E1, %0|%0, %E1}";
2119     case TYPE_IMOV:
2120       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2121       if (get_attr_mode (insn) == MODE_SI)
2122         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2123       else if (which_alternative == 4)
2124         return "movabs{q}\t{%1, %0|%0, %1}";
2125       else if (ix86_use_lea_for_mov (insn, operands))
2126         return "lea{q}\t{%E1, %0|%0, %E1}";
2127       else
2128         return "mov{q}\t{%1, %0|%0, %1}";
2130     default:
2131       gcc_unreachable ();
2132     }
2134   [(set (attr "isa")
2135      (cond [(eq_attr "alternative" "0,1")
2136               (const_string "nox64")
2137             (eq_attr "alternative" "2,3,4,5,10,11,16,18,21,23")
2138               (const_string "x64")
2139             (eq_attr "alternative" "17")
2140               (const_string "x64_sse4")
2141            ]
2142            (const_string "*")))
2143    (set (attr "type")
2144      (cond [(eq_attr "alternative" "0,1")
2145               (const_string "multi")
2146             (eq_attr "alternative" "6")
2147               (const_string "mmx")
2148             (eq_attr "alternative" "7,8,9,10,11")
2149               (const_string "mmxmov")
2150             (eq_attr "alternative" "12,17")
2151               (const_string "sselog1")
2152             (eq_attr "alternative" "13,14,15,16,18")
2153               (const_string "ssemov")
2154             (eq_attr "alternative" "19,20")
2155               (const_string "ssecvt")
2156             (eq_attr "alternative" "21,22,23,24")
2157               (const_string "mskmov")
2158             (match_operand 1 "pic_32bit_operand")
2159               (const_string "lea")
2160            ]
2161            (const_string "imov")))
2162    (set (attr "modrm")
2163      (if_then_else
2164        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2165          (const_string "0")
2166          (const_string "*")))
2167    (set (attr "length_immediate")
2168      (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2169               (const_string "8")
2170             (eq_attr "alternative" "17")
2171               (const_string "1")
2172            ]
2173            (const_string "*")))
2174    (set (attr "prefix_rex")
2175      (if_then_else (eq_attr "alternative" "10,11,16,17,18")
2176        (const_string "1")
2177        (const_string "*")))
2178    (set (attr "prefix_extra")
2179      (if_then_else (eq_attr "alternative" "17")
2180        (const_string "1")
2181        (const_string "*")))
2182    (set (attr "prefix")
2183      (if_then_else (eq_attr "type" "sselog1,ssemov")
2184        (const_string "maybe_vex")
2185        (const_string "orig")))
2186    (set (attr "prefix_data16")
2187      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2188        (const_string "1")
2189        (const_string "*")))
2190    (set (attr "mode")
2191      (cond [(eq_attr "alternative" "2")
2192               (const_string "SI")
2193             (eq_attr "alternative" "12,13")
2194               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2195                           (match_operand 1 "ext_sse_reg_operand"))
2196                        (const_string "XI")
2197                      (ior (not (match_test "TARGET_SSE2"))
2198                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2199                        (const_string "V4SF")
2200                      (match_test "TARGET_AVX")
2201                        (const_string "TI")
2202                      (match_test "optimize_function_for_size_p (cfun)")
2203                        (const_string "V4SF")
2204                     ]
2205                     (const_string "TI"))
2207             (and (eq_attr "alternative" "14,15")
2208                  (not (match_test "TARGET_SSE2")))
2209               (const_string "V2SF")
2210             (eq_attr "alternative" "17")
2211               (const_string "TI")
2212            ]
2213            (const_string "DI")))])
2215 (define_split
2216   [(set (match_operand:DI 0 "nonimmediate_operand")
2217         (match_operand:DI 1 "general_operand"))]
2218   "!TARGET_64BIT && reload_completed
2219    && !(MMX_REG_P (operands[0])
2220         || SSE_REG_P (operands[0])
2221         || MASK_REG_P (operands[0]))
2222    && !(MMX_REG_P (operands[1])
2223         || SSE_REG_P (operands[1])
2224         || MASK_REG_P (operands[1]))"
2225   [(const_int 0)]
2226   "ix86_split_long_move (operands); DONE;")
2228 (define_insn "*movsi_internal"
2229   [(set (match_operand:SI 0 "nonimmediate_operand"
2230                         "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi,*k  ,*rm")
2231         (match_operand:SI 1 "general_operand"
2232                         "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r   ,*krm,*k"))]
2233   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2235   switch (get_attr_type (insn))
2236     {
2237     case TYPE_SSELOG1:
2238       if (GENERAL_REG_P (operands[0]))
2239         return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2241       return standard_sse_constant_opcode (insn, operands[1]);
2243     case TYPE_MSKMOV:
2244       return "kmovd\t{%1, %0|%0, %1}";
2246     case TYPE_SSEMOV:
2247       switch (get_attr_mode (insn))
2248         {
2249         case MODE_SI:
2250           return "%vmovd\t{%1, %0|%0, %1}";
2251         case MODE_TI:
2252           return "%vmovdqa\t{%1, %0|%0, %1}";
2253         case MODE_XI:
2254           return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2256         case MODE_V4SF:
2257           return "%vmovaps\t{%1, %0|%0, %1}";
2259         case MODE_SF:
2260           gcc_assert (!TARGET_AVX);
2261           return "movss\t{%1, %0|%0, %1}";
2263         default:
2264           gcc_unreachable ();
2265         }
2267     case TYPE_MMX:
2268       return "pxor\t%0, %0";
2270     case TYPE_MMXMOV:
2271       switch (get_attr_mode (insn))
2272         {
2273         case MODE_DI:
2274           return "movq\t{%1, %0|%0, %1}";
2275         case MODE_SI:
2276           return "movd\t{%1, %0|%0, %1}";
2278         default:
2279           gcc_unreachable ();
2280         }
2282     case TYPE_LEA:
2283       return "lea{l}\t{%E1, %0|%0, %E1}";
2285     case TYPE_IMOV:
2286       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2287       if (ix86_use_lea_for_mov (insn, operands))
2288         return "lea{l}\t{%E1, %0|%0, %E1}";
2289       else
2290         return "mov{l}\t{%1, %0|%0, %1}";
2292     default:
2293       gcc_unreachable ();
2294     }
2296   [(set (attr "isa")
2297      (if_then_else (eq_attr "alternative" "11")
2298        (const_string "sse4")
2299        (const_string "*")))
2300    (set (attr "type")
2301      (cond [(eq_attr "alternative" "2")
2302               (const_string "mmx")
2303             (eq_attr "alternative" "3,4,5")
2304               (const_string "mmxmov")
2305             (eq_attr "alternative" "6,11")
2306               (const_string "sselog1")
2307             (eq_attr "alternative" "7,8,9,10,12")
2308               (const_string "ssemov")
2309             (eq_attr "alternative" "13,14")
2310               (const_string "mskmov")
2311             (match_operand 1 "pic_32bit_operand")
2312               (const_string "lea")
2313            ]
2314            (const_string "imov")))
2315    (set (attr "length_immediate")
2316      (if_then_else (eq_attr "alternative" "11")
2317        (const_string "1")
2318        (const_string "*")))
2319    (set (attr "prefix_extra")
2320      (if_then_else (eq_attr "alternative" "11")
2321        (const_string "1")
2322        (const_string "*")))
2323    (set (attr "prefix")
2324      (if_then_else (eq_attr "type" "sselog1,ssemov")
2325        (const_string "maybe_vex")
2326        (const_string "orig")))
2327    (set (attr "prefix_data16")
2328      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2329        (const_string "1")
2330        (const_string "*")))
2331    (set (attr "mode")
2332      (cond [(eq_attr "alternative" "2,3")
2333               (const_string "DI")
2334             (eq_attr "alternative" "6,7")
2335               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2336                           (match_operand 1 "ext_sse_reg_operand"))
2337                        (const_string "XI")
2338                      (ior (not (match_test "TARGET_SSE2"))
2339                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2340                        (const_string "V4SF")
2341                      (match_test "TARGET_AVX")
2342                        (const_string "TI")
2343                      (match_test "optimize_function_for_size_p (cfun)")
2344                        (const_string "V4SF")
2345                     ]
2346                     (const_string "TI"))
2348             (and (eq_attr "alternative" "8,9")
2349                  (not (match_test "TARGET_SSE2")))
2350               (const_string "SF")
2351             (eq_attr "alternative" "11")
2352               (const_string "TI")
2353            ]
2354            (const_string "SI")))])
2356 (define_insn "kmovw"
2357   [(set (match_operand:HI 0 "nonimmediate_operand" "=k,k")
2358         (unspec:HI
2359           [(match_operand:HI 1 "nonimmediate_operand" "rm,k")]
2360           UNSPEC_KMOV))]
2361   "!(MEM_P (operands[0]) && MEM_P (operands[1])) && TARGET_AVX512F"
2362   "@
2363    kmovw\t{%k1, %0|%0, %k1}
2364    kmovw\t{%1, %0|%0, %1}";
2365   [(set_attr "mode" "HI")
2366    (set_attr "type" "mskmov")
2367    (set_attr "prefix" "vex")])
2370 (define_insn "*movhi_internal"
2371   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k,rm")
2372         (match_operand:HI 1 "general_operand"      "r ,rn,rm,rn,rm,k,k"))]
2373   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2375   switch (get_attr_type (insn))
2376     {
2377     case TYPE_IMOVX:
2378       /* movzwl is faster than movw on p2 due to partial word stalls,
2379          though not as fast as an aligned movl.  */
2380       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2382     case TYPE_MSKMOV:
2383       switch (which_alternative)
2384         {
2385         case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2386         case 5: return "kmovw\t{%1, %0|%0, %1}";
2387         case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2388         default: gcc_unreachable ();
2389         }
2391     default:
2392       if (get_attr_mode (insn) == MODE_SI)
2393         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2394       else
2395         return "mov{w}\t{%1, %0|%0, %1}";
2396     }
2398   [(set (attr "type")
2399      (cond [(eq_attr "alternative" "4,5,6")
2400               (const_string "mskmov")
2401             (match_test "optimize_function_for_size_p (cfun)")
2402               (const_string "imov")
2403             (and (eq_attr "alternative" "0")
2404                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2405                       (not (match_test "TARGET_HIMODE_MATH"))))
2406               (const_string "imov")
2407             (and (eq_attr "alternative" "1,2")
2408                  (match_operand:HI 1 "aligned_operand"))
2409               (const_string "imov")
2410             (and (match_test "TARGET_MOVX")
2411                  (eq_attr "alternative" "0,2"))
2412               (const_string "imovx")
2413            ]
2414            (const_string "imov")))
2415     (set (attr "prefix")
2416       (if_then_else (eq_attr "alternative" "4,5,6")
2417         (const_string "vex")
2418         (const_string "orig")))
2419     (set (attr "mode")
2420       (cond [(eq_attr "type" "imovx")
2421                (const_string "SI")
2422              (and (eq_attr "alternative" "1,2")
2423                   (match_operand:HI 1 "aligned_operand"))
2424                (const_string "SI")
2425              (and (eq_attr "alternative" "0")
2426                   (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2427                        (not (match_test "TARGET_HIMODE_MATH"))))
2428                (const_string "SI")
2429             ]
2430             (const_string "HI")))])
2432 ;; Situation is quite tricky about when to choose full sized (SImode) move
2433 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2434 ;; partial register dependency machines (such as AMD Athlon), where QImode
2435 ;; moves issue extra dependency and for partial register stalls machines
2436 ;; that don't use QImode patterns (and QImode move cause stall on the next
2437 ;; instruction).
2439 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2440 ;; register stall machines with, where we use QImode instructions, since
2441 ;; partial register stall can be caused there.  Then we use movzx.
2443 (define_insn "*movqi_internal"
2444   [(set (match_operand:QI 0 "nonimmediate_operand"
2445                         "=q,q ,q ,r,r ,?r,m ,k,k,r ,m,k")
2446         (match_operand:QI 1 "general_operand"
2447                         "q ,qn,qm,q,rn,qm,qn,r ,k,k,k,m"))]
2448   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2450   switch (get_attr_type (insn))
2451     {
2452     case TYPE_IMOVX:
2453       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2454       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2456     case TYPE_MSKMOV:
2457       switch (which_alternative)
2458         {
2459         case 7: return TARGET_AVX512DQ ? "kmovb\t{%k1, %0|%0, %k1}"
2460                                        : "kmovw\t{%k1, %0|%0, %k1}";
2461         case 8: return TARGET_AVX512DQ ? "kmovb\t{%1, %0|%0, %1}"
2462                                        : "kmovw\t{%1, %0|%0, %1}";
2463         case 9: return TARGET_AVX512DQ ? "kmovb\t{%1, %k0|%k0, %1}"
2464                                        : "kmovw\t{%1, %k0|%k0, %1}";
2465         case 10:
2466         case 11:
2467           gcc_assert (TARGET_AVX512DQ);
2468           return "kmovb\t{%1, %0|%0, %1}";
2469         default: gcc_unreachable ();
2470         }
2472     default:
2473       if (get_attr_mode (insn) == MODE_SI)
2474         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2475       else
2476         return "mov{b}\t{%1, %0|%0, %1}";
2477     }
2479   [(set_attr "isa" "*,*,*,*,*,*,*,*,*,*,avx512dq,avx512dq")
2480    (set (attr "type")
2481      (cond [(eq_attr "alternative" "3,5")
2482               (const_string "imovx")
2483             (eq_attr "alternative" "7,8,9,10,11")
2484               (const_string "mskmov")
2485             (and (eq_attr "alternative" "5")
2486                  (not (match_operand:QI 1 "aligned_operand")))
2487               (const_string "imovx")
2488             (match_test "optimize_function_for_size_p (cfun)")
2489               (const_string "imov")
2490             (and (eq_attr "alternative" "3")
2491                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2492                       (not (match_test "TARGET_QIMODE_MATH"))))
2493               (const_string "imov")
2494             (and (match_test "TARGET_MOVX")
2495                  (eq_attr "alternative" "2"))
2496               (const_string "imovx")
2497            ]
2498            (const_string "imov")))
2499    (set (attr "prefix")
2500      (if_then_else (eq_attr "alternative" "7,8,9")
2501        (const_string "vex")
2502        (const_string "orig")))
2503    (set (attr "mode")
2504       (cond [(eq_attr "alternative" "3,4,5")
2505                (const_string "SI")
2506              (eq_attr "alternative" "6")
2507                (const_string "QI")
2508              (eq_attr "type" "imovx")
2509                (const_string "SI")
2510              (and (eq_attr "type" "imov")
2511                   (and (eq_attr "alternative" "0,1")
2512                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2513                             (and (not (match_test "optimize_function_for_size_p (cfun)"))
2514                                  (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2515                (const_string "SI")
2516              ;; Avoid partial register stalls when not using QImode arithmetic
2517              (and (eq_attr "type" "imov")
2518                   (and (eq_attr "alternative" "0,1")
2519                        (and (match_test "TARGET_PARTIAL_REG_STALL")
2520                             (not (match_test "TARGET_QIMODE_MATH")))))
2521                (const_string "SI")
2522            ]
2523            (const_string "QI")))])
2525 ;; Stores and loads of ax to arbitrary constant address.
2526 ;; We fake an second form of instruction to force reload to load address
2527 ;; into register when rax is not available
2528 (define_insn "*movabs<mode>_1"
2529   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2530         (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2531   "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2532   "@
2533    movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2534    mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2535   [(set_attr "type" "imov")
2536    (set_attr "modrm" "0,*")
2537    (set_attr "length_address" "8,0")
2538    (set_attr "length_immediate" "0,*")
2539    (set_attr "memory" "store")
2540    (set_attr "mode" "<MODE>")])
2542 (define_insn "*movabs<mode>_2"
2543   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2544         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2545   "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2546   "@
2547    movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2548    mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2549   [(set_attr "type" "imov")
2550    (set_attr "modrm" "0,*")
2551    (set_attr "length_address" "8,0")
2552    (set_attr "length_immediate" "0")
2553    (set_attr "memory" "load")
2554    (set_attr "mode" "<MODE>")])
2556 (define_insn "*swap<mode>"
2557   [(set (match_operand:SWI48 0 "register_operand" "+r")
2558         (match_operand:SWI48 1 "register_operand" "+r"))
2559    (set (match_dup 1)
2560         (match_dup 0))]
2561   ""
2562   "xchg{<imodesuffix>}\t%1, %0"
2563   [(set_attr "type" "imov")
2564    (set_attr "mode" "<MODE>")
2565    (set_attr "pent_pair" "np")
2566    (set_attr "athlon_decode" "vector")
2567    (set_attr "amdfam10_decode" "double")
2568    (set_attr "bdver1_decode" "double")])
2570 (define_insn "*swap<mode>_1"
2571   [(set (match_operand:SWI12 0 "register_operand" "+r")
2572         (match_operand:SWI12 1 "register_operand" "+r"))
2573    (set (match_dup 1)
2574         (match_dup 0))]
2575   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2576   "xchg{l}\t%k1, %k0"
2577   [(set_attr "type" "imov")
2578    (set_attr "mode" "SI")
2579    (set_attr "pent_pair" "np")
2580    (set_attr "athlon_decode" "vector")
2581    (set_attr "amdfam10_decode" "double")
2582    (set_attr "bdver1_decode" "double")])
2584 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2585 ;; is disabled for AMDFAM10
2586 (define_insn "*swap<mode>_2"
2587   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2588         (match_operand:SWI12 1 "register_operand" "+<r>"))
2589    (set (match_dup 1)
2590         (match_dup 0))]
2591   "TARGET_PARTIAL_REG_STALL"
2592   "xchg{<imodesuffix>}\t%1, %0"
2593   [(set_attr "type" "imov")
2594    (set_attr "mode" "<MODE>")
2595    (set_attr "pent_pair" "np")
2596    (set_attr "athlon_decode" "vector")])
2598 (define_expand "movstrict<mode>"
2599   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2600         (match_operand:SWI12 1 "general_operand"))]
2601   ""
2603   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2604     FAIL;
2605   if (GET_CODE (operands[0]) == SUBREG
2606       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2607     FAIL;
2608   /* Don't generate memory->memory moves, go through a register */
2609   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2610     operands[1] = force_reg (<MODE>mode, operands[1]);
2613 (define_insn "*movstrict<mode>_1"
2614   [(set (strict_low_part
2615           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2616         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2617   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2618    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2619   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2620   [(set_attr "type" "imov")
2621    (set_attr "mode" "<MODE>")])
2623 (define_insn "*movstrict<mode>_xor"
2624   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2625         (match_operand:SWI12 1 "const0_operand"))
2626    (clobber (reg:CC FLAGS_REG))]
2627   "reload_completed"
2628   "xor{<imodesuffix>}\t%0, %0"
2629   [(set_attr "type" "alu1")
2630    (set_attr "mode" "<MODE>")
2631    (set_attr "length_immediate" "0")])
2633 (define_insn "*mov<mode>_extv_1"
2634   [(set (match_operand:SWI24 0 "register_operand" "=R")
2635         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2636                             (const_int 8)
2637                             (const_int 8)))]
2638   ""
2639   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2640   [(set_attr "type" "imovx")
2641    (set_attr "mode" "SI")])
2643 (define_insn "*movqi_extv_1"
2644   [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2645         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2646                          (const_int 8)
2647                          (const_int 8)))]
2648   ""
2650   switch (get_attr_type (insn))
2651     {
2652     case TYPE_IMOVX:
2653       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2654     default:
2655       return "mov{b}\t{%h1, %0|%0, %h1}";
2656     }
2658   [(set_attr "isa" "*,*,nox64")
2659    (set (attr "type")
2660      (if_then_else (and (match_operand:QI 0 "register_operand")
2661                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2662                              (match_test "TARGET_MOVX")))
2663         (const_string "imovx")
2664         (const_string "imov")))
2665    (set (attr "mode")
2666      (if_then_else (eq_attr "type" "imovx")
2667         (const_string "SI")
2668         (const_string "QI")))])
2670 (define_insn "*mov<mode>_extzv_1"
2671   [(set (match_operand:SWI48 0 "register_operand" "=R")
2672         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2673                             (const_int 8)
2674                             (const_int 8)))]
2675   ""
2676   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2677   [(set_attr "type" "imovx")
2678    (set_attr "mode" "SI")])
2680 (define_insn "*movqi_extzv_2"
2681   [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2682         (subreg:QI
2683           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2684                            (const_int 8)
2685                            (const_int 8)) 0))]
2686   ""
2688   switch (get_attr_type (insn))
2689     {
2690     case TYPE_IMOVX:
2691       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2692     default:
2693       return "mov{b}\t{%h1, %0|%0, %h1}";
2694     }
2696   [(set_attr "isa" "*,*,nox64")
2697    (set (attr "type")
2698      (if_then_else (and (match_operand:QI 0 "register_operand")
2699                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2700                              (match_test "TARGET_MOVX")))
2701         (const_string "imovx")
2702         (const_string "imov")))
2703    (set (attr "mode")
2704      (if_then_else (eq_attr "type" "imovx")
2705         (const_string "SI")
2706         (const_string "QI")))])
2708 (define_insn "mov<mode>_insv_1"
2709   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2710                              (const_int 8)
2711                              (const_int 8))
2712         (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2713   ""
2715   if (CONST_INT_P (operands[1]))
2716     operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2717   return "mov{b}\t{%b1, %h0|%h0, %b1}";
2719   [(set_attr "isa" "*,nox64")
2720    (set_attr "type" "imov")
2721    (set_attr "mode" "QI")])
2723 (define_insn "*movqi_insv_2"
2724   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2725                          (const_int 8)
2726                          (const_int 8))
2727         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2728                      (const_int 8)))]
2729   ""
2730   "mov{b}\t{%h1, %h0|%h0, %h1}"
2731   [(set_attr "type" "imov")
2732    (set_attr "mode" "QI")])
2734 ;; Floating point push instructions.
2736 ;; %%% Remove CONST_DOUBLE workaround after PR63620 is fixed!
2737 (define_insn "*pushtf"
2738   [(set (match_operand:TF 0 "push_operand" "=<,<")
2739         (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2740   "(TARGET_64BIT || TARGET_SSE)
2741    && (!can_create_pseudo_p ()
2742        || GET_CODE (operands[1]) != CONST_DOUBLE
2743        || standard_sse_constant_p (operands[1]))"
2745   /* This insn should be already split before reg-stack.  */
2746   gcc_unreachable ();
2748   [(set_attr "isa" "*,x64")
2749    (set_attr "type" "multi")
2750    (set_attr "unit" "sse,*")
2751    (set_attr "mode" "TF,DI")])
2753 ;; %%% Kill this when call knows how to work this out.
2754 (define_split
2755   [(set (match_operand:TF 0 "push_operand")
2756         (match_operand:TF 1 "sse_reg_operand"))]
2757   "TARGET_SSE && reload_completed"
2758   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2759    (set (match_dup 0) (match_dup 1))]
2761   /* Preserve memory attributes. */
2762   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2765 ;; %%% Remove CONST_DOUBLE workaround after PR63620 is fixed!
2766 (define_insn "*pushxf"
2767   [(set (match_operand:XF 0 "push_operand" "=<,<")
2768         (match_operand:XF 1 "general_no_elim_operand" "f,Yx*roF"))]
2769   "!can_create_pseudo_p ()
2770    || GET_CODE (operands[1]) != CONST_DOUBLE
2771    || standard_80387_constant_p (operands[1]) > 0"
2773   /* This insn should be already split before reg-stack.  */
2774   gcc_unreachable ();
2776   [(set_attr "type" "multi")
2777    (set_attr "unit" "i387,*")
2778    (set (attr "mode")
2779         (cond [(eq_attr "alternative" "1")
2780                  (if_then_else (match_test "TARGET_64BIT")
2781                    (const_string "DI")
2782                    (const_string "SI"))
2783               ]
2784               (const_string "XF")))])
2786 ;; %%% Kill this when call knows how to work this out.
2787 (define_split
2788   [(set (match_operand:XF 0 "push_operand")
2789         (match_operand:XF 1 "fp_register_operand"))]
2790   "reload_completed"
2791   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2792    (set (match_dup 0) (match_dup 1))]
2794   operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
2795   /* Preserve memory attributes. */
2796   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2799 ;; %%% Remove CONST_DOUBLE workaround after PR63620 is fixed!
2800 (define_insn "*pushdf"
2801   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2802         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*roF,rmF,x"))]
2803   "!can_create_pseudo_p ()
2804    || GET_CODE (operands[1]) != CONST_DOUBLE
2805    || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2806        && standard_80387_constant_p (operands[1]) > 0)
2807    || (TARGET_SSE2 && TARGET_SSE_MATH
2808        && standard_sse_constant_p (operands[1]))"
2810   /* This insn should be already split before reg-stack.  */
2811   gcc_unreachable ();
2813   [(set_attr "isa" "*,nox64,x64,sse2")
2814    (set_attr "type" "multi")
2815    (set_attr "unit" "i387,*,*,sse")
2816    (set_attr "mode" "DF,SI,DI,DF")])
2818 ;; %%% Kill this when call knows how to work this out.
2819 (define_split
2820   [(set (match_operand:DF 0 "push_operand")
2821         (match_operand:DF 1 "any_fp_register_operand"))]
2822   "reload_completed"
2823   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2824    (set (match_dup 0) (match_dup 1))]
2826   /* Preserve memory attributes. */
2827   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2830 (define_insn "*pushsf_rex64"
2831   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2832         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2833   "TARGET_64BIT"
2835   /* Anything else should be already split before reg-stack.  */
2836   gcc_assert (which_alternative == 1);
2837   return "push{q}\t%q1";
2839   [(set_attr "type" "multi,push,multi")
2840    (set_attr "unit" "i387,*,*")
2841    (set_attr "mode" "SF,DI,SF")])
2843 (define_insn "*pushsf"
2844   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2845         (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2846   "!TARGET_64BIT"
2848   /* Anything else should be already split before reg-stack.  */
2849   gcc_assert (which_alternative == 1);
2850   return "push{l}\t%1";
2852   [(set_attr "type" "multi,push,multi")
2853    (set_attr "unit" "i387,*,*")
2854    (set_attr "mode" "SF,SI,SF")])
2856 ;; %%% Kill this when call knows how to work this out.
2857 (define_split
2858   [(set (match_operand:SF 0 "push_operand")
2859         (match_operand:SF 1 "any_fp_register_operand"))]
2860   "reload_completed"
2861   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2862    (set (match_dup 0) (match_dup 1))]
2864   rtx op = XEXP (operands[0], 0);
2865   if (GET_CODE (op) == PRE_DEC)
2866     {
2867       gcc_assert (!TARGET_64BIT);
2868       op = GEN_INT (-4);
2869     }
2870   else
2871     {
2872       op = XEXP (XEXP (op, 1), 1);
2873       gcc_assert (CONST_INT_P (op));
2874     }
2875   operands[2] = op;
2876   /* Preserve memory attributes. */
2877   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2880 (define_split
2881   [(set (match_operand:SF 0 "push_operand")
2882         (match_operand:SF 1 "memory_operand"))]
2883   "reload_completed
2884    && (operands[2] = find_constant_src (insn))"
2885   [(set (match_dup 0) (match_dup 2))])
2887 (define_split
2888   [(set (match_operand 0 "push_operand")
2889         (match_operand 1 "general_operand"))]
2890   "reload_completed
2891    && (GET_MODE (operands[0]) == TFmode
2892        || GET_MODE (operands[0]) == XFmode
2893        || GET_MODE (operands[0]) == DFmode)
2894    && !ANY_FP_REG_P (operands[1])"
2895   [(const_int 0)]
2896   "ix86_split_long_move (operands); DONE;")
2898 ;; Floating point move instructions.
2900 (define_expand "movtf"
2901   [(set (match_operand:TF 0 "nonimmediate_operand")
2902         (match_operand:TF 1 "nonimmediate_operand"))]
2903   "TARGET_64BIT || TARGET_SSE"
2904   "ix86_expand_move (TFmode, operands); DONE;")
2906 (define_expand "mov<mode>"
2907   [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2908         (match_operand:X87MODEF 1 "general_operand"))]
2909   ""
2910   "ix86_expand_move (<MODE>mode, operands); DONE;")
2912 (define_insn "*movtf_internal"
2913   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2914         (match_operand:TF 1 "general_operand"      "C ,xm,x,*roF,*rC"))]
2915   "(TARGET_64BIT || TARGET_SSE)
2916    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2917    && (!can_create_pseudo_p ()
2918        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2919        || GET_CODE (operands[1]) != CONST_DOUBLE
2920        || (optimize_function_for_size_p (cfun)
2921            && standard_sse_constant_p (operands[1])
2922            && !memory_operand (operands[0], TFmode))
2923        || (!TARGET_MEMORY_MISMATCH_STALL
2924            && memory_operand (operands[0], TFmode)))"
2926   switch (get_attr_type (insn))
2927     {
2928     case TYPE_SSELOG1:
2929       return standard_sse_constant_opcode (insn, operands[1]);
2931     case TYPE_SSEMOV:
2932       /* Handle misaligned load/store since we
2933          don't have movmisaligntf pattern. */
2934       if (misaligned_operand (operands[0], TFmode)
2935           || misaligned_operand (operands[1], TFmode))
2936         {
2937           if (get_attr_mode (insn) == MODE_V4SF)
2938             return "%vmovups\t{%1, %0|%0, %1}";
2939           else
2940             return "%vmovdqu\t{%1, %0|%0, %1}";
2941         }
2942       else
2943         {
2944           if (get_attr_mode (insn) == MODE_V4SF)
2945             return "%vmovaps\t{%1, %0|%0, %1}";
2946           else
2947             return "%vmovdqa\t{%1, %0|%0, %1}";
2948         }
2950     case TYPE_MULTI:
2951         return "#";
2953     default:
2954       gcc_unreachable ();
2955     }
2957   [(set_attr "isa" "*,*,*,x64,x64")
2958    (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
2959    (set (attr "prefix")
2960      (if_then_else (eq_attr "type" "sselog1,ssemov")
2961        (const_string "maybe_vex")
2962        (const_string "orig")))
2963    (set (attr "mode")
2964         (cond [(eq_attr "alternative" "3,4")
2965                  (const_string "DI")
2966                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2967                  (const_string "V4SF")
2968                (and (eq_attr "alternative" "2")
2969                     (match_test "TARGET_SSE_TYPELESS_STORES"))
2970                  (const_string "V4SF")
2971                (match_test "TARGET_AVX")
2972                  (const_string "TI")
2973                (ior (not (match_test "TARGET_SSE2"))
2974                     (match_test "optimize_function_for_size_p (cfun)"))
2975                  (const_string "V4SF")
2976                ]
2977                (const_string "TI")))])
2979 ;; Possible store forwarding (partial memory) stall in alternatives 4 and 5.
2980 (define_insn "*movxf_internal"
2981   [(set (match_operand:XF 0 "nonimmediate_operand"
2982          "=f,m,f,?Yx*r ,!o   ,!o")
2983         (match_operand:XF 1 "general_operand"
2984          "fm,f,G,Yx*roF,Yx*rF,Yx*rC"))]
2985   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2986    && (!can_create_pseudo_p ()
2987        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2988        || GET_CODE (operands[1]) != CONST_DOUBLE
2989        || (optimize_function_for_size_p (cfun)
2990            && standard_80387_constant_p (operands[1]) > 0
2991            && !memory_operand (operands[0], XFmode))
2992        || (!TARGET_MEMORY_MISMATCH_STALL
2993            && memory_operand (operands[0], XFmode)))"
2995   switch (get_attr_type (insn))
2996     {
2997     case TYPE_FMOV:
2998       if (which_alternative == 2)
2999         return standard_80387_constant_opcode (operands[1]);
3000       return output_387_reg_move (insn, operands);
3002     case TYPE_MULTI:
3003       return "#";
3005     default:
3006       gcc_unreachable ();
3007     }
3009   [(set_attr "isa" "*,*,*,*,nox64,x64")
3010    (set_attr "type" "fmov,fmov,fmov,multi,multi,multi")
3011    (set (attr "mode")
3012         (cond [(eq_attr "alternative" "3,4,5")
3013                  (if_then_else (match_test "TARGET_64BIT")
3014                    (const_string "DI")
3015                    (const_string "SI"))
3016               ]
3017               (const_string "XF")))])
3019 ;; Possible store forwarding (partial memory) stall in alternative 4.
3020 (define_insn "*movdf_internal"
3021   [(set (match_operand:DF 0 "nonimmediate_operand"
3022     "=Yf*f,m   ,Yf*f,?Yd*r ,!o   ,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi")
3023         (match_operand:DF 1 "general_operand"
3024     "Yf*fm,Yf*f,G   ,Yd*roF,Yd*rF,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))]
3025   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3026    && (!can_create_pseudo_p ()
3027        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3028        || GET_CODE (operands[1]) != CONST_DOUBLE
3029        || (optimize_function_for_size_p (cfun)
3030            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3031                 && standard_80387_constant_p (operands[1]) > 0)
3032                || (TARGET_SSE2 && TARGET_SSE_MATH
3033                    && standard_sse_constant_p (operands[1])))
3034            && !memory_operand (operands[0], DFmode))
3035        || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3036            && memory_operand (operands[0], DFmode)))"
3038   switch (get_attr_type (insn))
3039     {
3040     case TYPE_FMOV:
3041       if (which_alternative == 2)
3042         return standard_80387_constant_opcode (operands[1]);
3043       return output_387_reg_move (insn, operands);
3045     case TYPE_MULTI:
3046       return "#";
3048     case TYPE_IMOV:
3049       if (get_attr_mode (insn) == MODE_SI)
3050         return "mov{l}\t{%1, %k0|%k0, %1}";
3051       else if (which_alternative == 8)
3052         return "movabs{q}\t{%1, %0|%0, %1}";
3053       else
3054         return "mov{q}\t{%1, %0|%0, %1}";
3056     case TYPE_SSELOG1:
3057       return standard_sse_constant_opcode (insn, operands[1]);
3059     case TYPE_SSEMOV:
3060       switch (get_attr_mode (insn))
3061         {
3062         case MODE_DF:
3063           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3064             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3065           return "%vmovsd\t{%1, %0|%0, %1}";
3067         case MODE_V4SF:
3068           return "%vmovaps\t{%1, %0|%0, %1}";
3069         case MODE_V8DF:
3070           return "vmovapd\t{%g1, %g0|%g0, %g1}";
3071         case MODE_V2DF:
3072           return "%vmovapd\t{%1, %0|%0, %1}";
3074         case MODE_V2SF:
3075           gcc_assert (!TARGET_AVX);
3076           return "movlps\t{%1, %0|%0, %1}";
3077         case MODE_V1DF:
3078           gcc_assert (!TARGET_AVX);
3079           return "movlpd\t{%1, %0|%0, %1}";
3081         case MODE_DI:
3082           /* Handle broken assemblers that require movd instead of movq.  */
3083           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3084               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3085             return "%vmovd\t{%1, %0|%0, %1}";
3086           return "%vmovq\t{%1, %0|%0, %1}";
3088         default:
3089           gcc_unreachable ();
3090         }
3092     default:
3093       gcc_unreachable ();
3094     }
3096   [(set (attr "isa")
3097         (cond [(eq_attr "alternative" "3,4")
3098                  (const_string "nox64")
3099                (eq_attr "alternative" "5,6,7,8,17,18")
3100                  (const_string "x64")
3101                (eq_attr "alternative" "9,10,11,12")
3102                  (const_string "sse2")
3103               ]
3104               (const_string "*")))
3105    (set (attr "type")
3106         (cond [(eq_attr "alternative" "0,1,2")
3107                  (const_string "fmov")
3108                (eq_attr "alternative" "3,4")
3109                  (const_string "multi")
3110                (eq_attr "alternative" "5,6,7,8")
3111                  (const_string "imov")
3112                (eq_attr "alternative" "9,13")
3113                  (const_string "sselog1")
3114               ]
3115               (const_string "ssemov")))
3116    (set (attr "modrm")
3117      (if_then_else (eq_attr "alternative" "8")
3118        (const_string "0")
3119        (const_string "*")))
3120    (set (attr "length_immediate")
3121      (if_then_else (eq_attr "alternative" "8")
3122        (const_string "8")
3123        (const_string "*")))
3124    (set (attr "prefix")
3125      (if_then_else (eq_attr "type" "sselog1,ssemov")
3126        (const_string "maybe_vex")
3127        (const_string "orig")))
3128    (set (attr "prefix_data16")
3129      (if_then_else
3130        (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3131             (eq_attr "mode" "V1DF"))
3132        (const_string "1")
3133        (const_string "*")))
3134    (set (attr "mode")
3135         (cond [(eq_attr "alternative" "3,4,7")
3136                  (const_string "SI")
3137                (eq_attr "alternative" "5,6,8,17,18")
3138                  (const_string "DI")
3140                /* xorps is one byte shorter for non-AVX targets.  */
3141                (eq_attr "alternative" "9,13")
3142                  (cond [(not (match_test "TARGET_SSE2"))
3143                           (const_string "V4SF")
3144                         (match_test "TARGET_AVX512F")
3145                           (const_string "XI")
3146                         (match_test "TARGET_AVX")
3147                           (const_string "V2DF")
3148                         (match_test "optimize_function_for_size_p (cfun)")
3149                           (const_string "V4SF")
3150                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3151                           (const_string "TI")
3152                        ]
3153                        (const_string "V2DF"))
3155                /* For architectures resolving dependencies on
3156                   whole SSE registers use movapd to break dependency
3157                   chains, otherwise use short move to avoid extra work.  */
3159                /* movaps is one byte shorter for non-AVX targets.  */
3160                (eq_attr "alternative" "10,14")
3161                  (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3162                              (match_operand 1 "ext_sse_reg_operand"))
3163                           (const_string "V8DF")
3164                         (ior (not (match_test "TARGET_SSE2"))
3165                              (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3166                           (const_string "V4SF")
3167                         (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3168                           (const_string "V2DF")
3169                         (match_test "TARGET_AVX")
3170                           (const_string "DF")
3171                         (match_test "optimize_function_for_size_p (cfun)")
3172                           (const_string "V4SF")
3173                        ]
3174                        (const_string "DF"))
3176                /* For architectures resolving dependencies on register
3177                   parts we may avoid extra work to zero out upper part
3178                   of register.  */
3179                (eq_attr "alternative" "11,15")
3180                  (cond [(not (match_test "TARGET_SSE2"))
3181                           (const_string "V2SF")
3182                         (match_test "TARGET_AVX")
3183                           (const_string "DF")
3184                         (match_test "TARGET_SSE_SPLIT_REGS")
3185                           (const_string "V1DF")
3186                        ]
3187                        (const_string "DF"))
3189                (and (eq_attr "alternative" "12,16")
3190                     (not (match_test "TARGET_SSE2")))
3191                  (const_string "V2SF")
3192               ]
3193               (const_string "DF")))])
3195 (define_insn "*movsf_internal"
3196   [(set (match_operand:SF 0 "nonimmediate_operand"
3197           "=Yf*f,m   ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
3198         (match_operand:SF 1 "general_operand"
3199           "Yf*fm,Yf*f,G   ,rmF,rF,C,v,m,v,Yj,r  ,*y ,m  ,*y,*Yn,r"))]
3200   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3201    && (!can_create_pseudo_p ()
3202        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3203        || GET_CODE (operands[1]) != CONST_DOUBLE
3204        || (optimize_function_for_size_p (cfun)
3205            && ((!TARGET_SSE_MATH
3206                 && standard_80387_constant_p (operands[1]) > 0)
3207                || (TARGET_SSE_MATH
3208                    && standard_sse_constant_p (operands[1]))))
3209        || memory_operand (operands[0], SFmode))"
3211   switch (get_attr_type (insn))
3212     {
3213     case TYPE_FMOV:
3214       if (which_alternative == 2)
3215         return standard_80387_constant_opcode (operands[1]);
3216       return output_387_reg_move (insn, operands);
3218     case TYPE_IMOV:
3219       return "mov{l}\t{%1, %0|%0, %1}";
3221     case TYPE_SSELOG1:
3222       return standard_sse_constant_opcode (insn, operands[1]);
3224     case TYPE_SSEMOV:
3225       switch (get_attr_mode (insn))
3226         {
3227         case MODE_SF:
3228           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3229             return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3230           return "%vmovss\t{%1, %0|%0, %1}";
3232         case MODE_V16SF:
3233           return "vmovaps\t{%g1, %g0|%g0, %g1}";
3234         case MODE_V4SF:
3235           return "%vmovaps\t{%1, %0|%0, %1}";
3237         case MODE_SI:
3238           return "%vmovd\t{%1, %0|%0, %1}";
3240         default:
3241           gcc_unreachable ();
3242         }
3244     case TYPE_MMXMOV:
3245       switch (get_attr_mode (insn))
3246         {
3247         case MODE_DI:
3248           return "movq\t{%1, %0|%0, %1}";
3249         case MODE_SI:
3250           return "movd\t{%1, %0|%0, %1}";
3252         default:
3253           gcc_unreachable ();
3254         }
3256     default:
3257       gcc_unreachable ();
3258     }
3260   [(set (attr "type")
3261         (cond [(eq_attr "alternative" "0,1,2")
3262                  (const_string "fmov")
3263                (eq_attr "alternative" "3,4")
3264                  (const_string "imov")
3265                (eq_attr "alternative" "5")
3266                  (const_string "sselog1")
3267                (eq_attr "alternative" "11,12,13,14,15")
3268                  (const_string "mmxmov")
3269               ]
3270               (const_string "ssemov")))
3271    (set (attr "prefix")
3272      (if_then_else (eq_attr "type" "sselog1,ssemov")
3273        (const_string "maybe_vex")
3274        (const_string "orig")))
3275    (set (attr "prefix_data16")
3276      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3277        (const_string "1")
3278        (const_string "*")))
3279    (set (attr "mode")
3280         (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15")
3281                  (const_string "SI")
3282                (eq_attr "alternative" "11")
3283                  (const_string "DI")
3284                (eq_attr "alternative" "5")
3285                  (cond [(not (match_test "TARGET_SSE2"))
3286                           (const_string "V4SF")
3287                         (match_test "TARGET_AVX512F")
3288                           (const_string "V16SF")
3289                         (match_test "TARGET_AVX")
3290                           (const_string "V4SF")
3291                         (match_test "optimize_function_for_size_p (cfun)")
3292                           (const_string "V4SF")
3293                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3294                           (const_string "TI")
3295                        ]
3296                        (const_string "V4SF"))
3298                /* For architectures resolving dependencies on
3299                   whole SSE registers use APS move to break dependency
3300                   chains, otherwise use short move to avoid extra work.
3302                   Do the same for architectures resolving dependencies on
3303                   the parts.  While in DF mode it is better to always handle
3304                   just register parts, the SF mode is different due to lack
3305                   of instructions to load just part of the register.  It is
3306                   better to maintain the whole registers in single format
3307                   to avoid problems on using packed logical operations.  */
3308                (eq_attr "alternative" "6")
3309                  (cond [(ior  (match_operand 0 "ext_sse_reg_operand")
3310                               (match_operand 1 "ext_sse_reg_operand"))
3311                           (const_string "V16SF")
3312                         (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3313                              (match_test "TARGET_SSE_SPLIT_REGS"))
3314                           (const_string "V4SF")
3315                        ]
3316                        (const_string "SF"))
3317               ]
3318               (const_string "SF")))])
3320 (define_split
3321   [(set (match_operand 0 "any_fp_register_operand")
3322         (match_operand 1 "memory_operand"))]
3323   "reload_completed
3324    && (GET_MODE (operands[0]) == TFmode
3325        || GET_MODE (operands[0]) == XFmode
3326        || GET_MODE (operands[0]) == DFmode
3327        || GET_MODE (operands[0]) == SFmode)
3328    && (operands[2] = find_constant_src (insn))"
3329   [(set (match_dup 0) (match_dup 2))]
3331   rtx c = operands[2];
3332   int r = REGNO (operands[0]);
3334   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3335       || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3336     FAIL;
3339 (define_split
3340   [(set (match_operand 0 "any_fp_register_operand")
3341         (float_extend (match_operand 1 "memory_operand")))]
3342   "reload_completed
3343    && (GET_MODE (operands[0]) == TFmode
3344        || GET_MODE (operands[0]) == XFmode
3345        || GET_MODE (operands[0]) == DFmode)
3346    && (operands[2] = find_constant_src (insn))"
3347   [(set (match_dup 0) (match_dup 2))]
3349   rtx c = operands[2];
3350   int r = REGNO (operands[0]);
3352   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3353       || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3354     FAIL;
3357 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3358 (define_split
3359   [(set (match_operand:X87MODEF 0 "fp_register_operand")
3360         (match_operand:X87MODEF 1 "immediate_operand"))]
3361   "reload_completed
3362    && (standard_80387_constant_p (operands[1]) == 8
3363        || standard_80387_constant_p (operands[1]) == 9)"
3364   [(set (match_dup 0)(match_dup 1))
3365    (set (match_dup 0)
3366         (neg:X87MODEF (match_dup 0)))]
3368   REAL_VALUE_TYPE r;
3370   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3371   if (real_isnegzero (&r))
3372     operands[1] = CONST0_RTX (<MODE>mode);
3373   else
3374     operands[1] = CONST1_RTX (<MODE>mode);
3377 (define_split
3378   [(set (match_operand 0 "nonimmediate_operand")
3379         (match_operand 1 "general_operand"))]
3380   "reload_completed
3381    && (GET_MODE (operands[0]) == TFmode
3382        || GET_MODE (operands[0]) == XFmode
3383        || GET_MODE (operands[0]) == DFmode)
3384    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3385   [(const_int 0)]
3386   "ix86_split_long_move (operands); DONE;")
3388 (define_insn "swapxf"
3389   [(set (match_operand:XF 0 "register_operand" "+f")
3390         (match_operand:XF 1 "register_operand" "+f"))
3391    (set (match_dup 1)
3392         (match_dup 0))]
3393   "TARGET_80387"
3395   if (STACK_TOP_P (operands[0]))
3396     return "fxch\t%1";
3397   else
3398     return "fxch\t%0";
3400   [(set_attr "type" "fxch")
3401    (set_attr "mode" "XF")])
3403 (define_insn "*swap<mode>"
3404   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3405         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3406    (set (match_dup 1)
3407         (match_dup 0))]
3408   "TARGET_80387 || reload_completed"
3410   if (STACK_TOP_P (operands[0]))
3411     return "fxch\t%1";
3412   else
3413     return "fxch\t%0";
3415   [(set_attr "type" "fxch")
3416    (set_attr "mode" "<MODE>")])
3418 ;; Zero extension instructions
3420 (define_expand "zero_extendsidi2"
3421   [(set (match_operand:DI 0 "nonimmediate_operand")
3422         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3424 (define_insn "*zero_extendsidi2"
3425   [(set (match_operand:DI 0 "nonimmediate_operand"
3426                         "=r,?r,?o,r   ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3427         (zero_extend:DI
3428          (match_operand:SI 1 "x86_64_zext_operand"
3429                         "0 ,rm,r ,rmWz,0,r   ,m   ,*Yj,*x,r   ,m")))]
3430   ""
3432   switch (get_attr_type (insn))
3433     {
3434     case TYPE_IMOVX:
3435       if (ix86_use_lea_for_mov (insn, operands))
3436         return "lea{l}\t{%E1, %k0|%k0, %E1}";
3437       else
3438         return "mov{l}\t{%1, %k0|%k0, %1}";
3440     case TYPE_MULTI:
3441       return "#";
3443     case TYPE_MMXMOV:
3444       return "movd\t{%1, %0|%0, %1}";
3446     case TYPE_SSELOG1:
3447       return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3449     case TYPE_SSEMOV:
3450       if (GENERAL_REG_P (operands[0]))
3451         return "%vmovd\t{%1, %k0|%k0, %1}";
3453       return "%vmovd\t{%1, %0|%0, %1}";
3455     default:
3456       gcc_unreachable ();
3457     }
3459   [(set (attr "isa")
3460      (cond [(eq_attr "alternative" "0,1,2")
3461               (const_string "nox64")
3462             (eq_attr "alternative" "3,7")
3463               (const_string "x64")
3464             (eq_attr "alternative" "8")
3465               (const_string "x64_sse4")
3466             (eq_attr "alternative" "10")
3467               (const_string "sse2")
3468            ]
3469            (const_string "*")))
3470    (set (attr "type")
3471      (cond [(eq_attr "alternative" "0,1,2,4")
3472               (const_string "multi")
3473             (eq_attr "alternative" "5,6")
3474               (const_string "mmxmov")
3475             (eq_attr "alternative" "7,9,10")
3476               (const_string "ssemov")
3477             (eq_attr "alternative" "8")
3478               (const_string "sselog1")
3479            ]
3480            (const_string "imovx")))
3481    (set (attr "prefix_extra")
3482      (if_then_else (eq_attr "alternative" "8")
3483        (const_string "1")
3484        (const_string "*")))
3485    (set (attr "length_immediate")
3486      (if_then_else (eq_attr "alternative" "8")
3487        (const_string "1")
3488        (const_string "*")))
3489    (set (attr "prefix")
3490      (if_then_else (eq_attr "type" "ssemov,sselog1")
3491        (const_string "maybe_vex")
3492        (const_string "orig")))
3493    (set (attr "prefix_0f")
3494      (if_then_else (eq_attr "type" "imovx")
3495        (const_string "0")
3496        (const_string "*")))
3497    (set (attr "mode")
3498      (cond [(eq_attr "alternative" "5,6")
3499               (const_string "DI")
3500             (eq_attr "alternative" "7,8,9")
3501               (const_string "TI")
3502            ]
3503            (const_string "SI")))])
3505 (define_split
3506   [(set (match_operand:DI 0 "memory_operand")
3507         (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3508   "reload_completed"
3509   [(set (match_dup 4) (const_int 0))]
3510   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3512 (define_split
3513   [(set (match_operand:DI 0 "register_operand")
3514         (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3515   "!TARGET_64BIT && reload_completed
3516    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3517    && true_regnum (operands[0]) == true_regnum (operands[1])"
3518   [(set (match_dup 4) (const_int 0))]
3519   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3521 (define_split
3522   [(set (match_operand:DI 0 "nonimmediate_operand")
3523         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3524   "!TARGET_64BIT && reload_completed
3525    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3526    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3527   [(set (match_dup 3) (match_dup 1))
3528    (set (match_dup 4) (const_int 0))]
3529   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3531 (define_insn "zero_extend<mode>di2"
3532   [(set (match_operand:DI 0 "register_operand" "=r")
3533         (zero_extend:DI
3534          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3535   "TARGET_64BIT"
3536   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3537   [(set_attr "type" "imovx")
3538    (set_attr "mode" "SI")])
3540 (define_expand "zero_extend<mode>si2"
3541   [(set (match_operand:SI 0 "register_operand")
3542         (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3543   ""
3545   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3546     {
3547       operands[1] = force_reg (<MODE>mode, operands[1]);
3548       emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3549       DONE;
3550     }
3553 (define_insn_and_split "zero_extend<mode>si2_and"
3554   [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3555         (zero_extend:SI
3556           (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3557    (clobber (reg:CC FLAGS_REG))]
3558   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3559   "#"
3560   "&& reload_completed"
3561   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3562               (clobber (reg:CC FLAGS_REG))])]
3564   if (true_regnum (operands[0]) != true_regnum (operands[1]))
3565     {
3566       ix86_expand_clear (operands[0]);
3568       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3569       emit_insn (gen_movstrict<mode>
3570                   (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3571       DONE;
3572     }
3574   operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3576   [(set_attr "type" "alu1")
3577    (set_attr "mode" "SI")])
3579 (define_insn "*zero_extend<mode>si2"
3580   [(set (match_operand:SI 0 "register_operand" "=r")
3581         (zero_extend:SI
3582           (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3583   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3584   "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3585   [(set_attr "type" "imovx")
3586    (set_attr "mode" "SI")])
3588 (define_expand "zero_extendqihi2"
3589   [(set (match_operand:HI 0 "register_operand")
3590         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3591   ""
3593   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3594     {
3595       operands[1] = force_reg (QImode, operands[1]);
3596       emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3597       DONE;
3598     }
3601 (define_insn_and_split "zero_extendqihi2_and"
3602   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3603         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3604    (clobber (reg:CC FLAGS_REG))]
3605   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3606   "#"
3607   "&& reload_completed"
3608   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3609               (clobber (reg:CC FLAGS_REG))])]
3611   if (true_regnum (operands[0]) != true_regnum (operands[1]))
3612     {
3613       ix86_expand_clear (operands[0]);
3615       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3616       emit_insn (gen_movstrictqi
3617                   (gen_lowpart (QImode, operands[0]), operands[1]));
3618       DONE;
3619     }
3621   operands[0] = gen_lowpart (SImode, operands[0]);
3623   [(set_attr "type" "alu1")
3624    (set_attr "mode" "SI")])
3626 ; zero extend to SImode to avoid partial register stalls
3627 (define_insn "*zero_extendqihi2"
3628   [(set (match_operand:HI 0 "register_operand" "=r")
3629         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3630   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3631   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3632   [(set_attr "type" "imovx")
3633    (set_attr "mode" "SI")])
3635 ;; Sign extension instructions
3637 (define_expand "extendsidi2"
3638   [(set (match_operand:DI 0 "register_operand")
3639         (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3640   ""
3642   if (!TARGET_64BIT)
3643     {
3644       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3645       DONE;
3646     }
3649 (define_insn "*extendsidi2_rex64"
3650   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3651         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3652   "TARGET_64BIT"
3653   "@
3654    {cltq|cdqe}
3655    movs{lq|x}\t{%1, %0|%0, %1}"
3656   [(set_attr "type" "imovx")
3657    (set_attr "mode" "DI")
3658    (set_attr "prefix_0f" "0")
3659    (set_attr "modrm" "0,1")])
3661 (define_insn "extendsidi2_1"
3662   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3663         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3664    (clobber (reg:CC FLAGS_REG))
3665    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3666   "!TARGET_64BIT"
3667   "#")
3669 ;; Split the memory case.  If the source register doesn't die, it will stay
3670 ;; this way, if it does die, following peephole2s take care of it.
3671 (define_split
3672   [(set (match_operand:DI 0 "memory_operand")
3673         (sign_extend:DI (match_operand:SI 1 "register_operand")))
3674    (clobber (reg:CC FLAGS_REG))
3675    (clobber (match_operand:SI 2 "register_operand"))]
3676   "reload_completed"
3677   [(const_int 0)]
3679   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3681   emit_move_insn (operands[3], operands[1]);
3683   /* Generate a cltd if possible and doing so it profitable.  */
3684   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3685       && true_regnum (operands[1]) == AX_REG
3686       && true_regnum (operands[2]) == DX_REG)
3687     {
3688       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3689     }
3690   else
3691     {
3692       emit_move_insn (operands[2], operands[1]);
3693       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3694     }
3695   emit_move_insn (operands[4], operands[2]);
3696   DONE;
3699 ;; Peepholes for the case where the source register does die, after
3700 ;; being split with the above splitter.
3701 (define_peephole2
3702   [(set (match_operand:SI 0 "memory_operand")
3703         (match_operand:SI 1 "register_operand"))
3704    (set (match_operand:SI 2 "register_operand") (match_dup 1))
3705    (parallel [(set (match_dup 2)
3706                    (ashiftrt:SI (match_dup 2) (const_int 31)))
3707                (clobber (reg:CC FLAGS_REG))])
3708    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3709   "REGNO (operands[1]) != REGNO (operands[2])
3710    && peep2_reg_dead_p (2, operands[1])
3711    && peep2_reg_dead_p (4, operands[2])
3712    && !reg_mentioned_p (operands[2], operands[3])"
3713   [(set (match_dup 0) (match_dup 1))
3714    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3715               (clobber (reg:CC FLAGS_REG))])
3716    (set (match_dup 3) (match_dup 1))])
3718 (define_peephole2
3719   [(set (match_operand:SI 0 "memory_operand")
3720         (match_operand:SI 1 "register_operand"))
3721    (parallel [(set (match_operand:SI 2 "register_operand")
3722                    (ashiftrt:SI (match_dup 1) (const_int 31)))
3723                (clobber (reg:CC FLAGS_REG))])
3724    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3725   "/* cltd is shorter than sarl $31, %eax */
3726    !optimize_function_for_size_p (cfun)
3727    && true_regnum (operands[1]) == AX_REG
3728    && true_regnum (operands[2]) == DX_REG
3729    && peep2_reg_dead_p (2, operands[1])
3730    && peep2_reg_dead_p (3, operands[2])
3731    && !reg_mentioned_p (operands[2], operands[3])"
3732   [(set (match_dup 0) (match_dup 1))
3733    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3734               (clobber (reg:CC FLAGS_REG))])
3735    (set (match_dup 3) (match_dup 1))])
3737 ;; Extend to register case.  Optimize case where source and destination
3738 ;; registers match and cases where we can use cltd.
3739 (define_split
3740   [(set (match_operand:DI 0 "register_operand")
3741         (sign_extend:DI (match_operand:SI 1 "register_operand")))
3742    (clobber (reg:CC FLAGS_REG))
3743    (clobber (match_scratch:SI 2))]
3744   "reload_completed"
3745   [(const_int 0)]
3747   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3749   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3750     emit_move_insn (operands[3], operands[1]);
3752   /* Generate a cltd if possible and doing so it profitable.  */
3753   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3754       && true_regnum (operands[3]) == AX_REG
3755       && true_regnum (operands[4]) == DX_REG)
3756     {
3757       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3758       DONE;
3759     }
3761   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3762     emit_move_insn (operands[4], operands[1]);
3764   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3765   DONE;
3768 (define_insn "extend<mode>di2"
3769   [(set (match_operand:DI 0 "register_operand" "=r")
3770         (sign_extend:DI
3771          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3772   "TARGET_64BIT"
3773   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3774   [(set_attr "type" "imovx")
3775    (set_attr "mode" "DI")])
3777 (define_insn "extendhisi2"
3778   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3779         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3780   ""
3782   switch (get_attr_prefix_0f (insn))
3783     {
3784     case 0:
3785       return "{cwtl|cwde}";
3786     default:
3787       return "movs{wl|x}\t{%1, %0|%0, %1}";
3788     }
3790   [(set_attr "type" "imovx")
3791    (set_attr "mode" "SI")
3792    (set (attr "prefix_0f")
3793      ;; movsx is short decodable while cwtl is vector decoded.
3794      (if_then_else (and (eq_attr "cpu" "!k6")
3795                         (eq_attr "alternative" "0"))
3796         (const_string "0")
3797         (const_string "1")))
3798    (set (attr "modrm")
3799      (if_then_else (eq_attr "prefix_0f" "0")
3800         (const_string "0")
3801         (const_string "1")))])
3803 (define_insn "*extendhisi2_zext"
3804   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3805         (zero_extend:DI
3806          (sign_extend:SI
3807           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3808   "TARGET_64BIT"
3810   switch (get_attr_prefix_0f (insn))
3811     {
3812     case 0:
3813       return "{cwtl|cwde}";
3814     default:
3815       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3816     }
3818   [(set_attr "type" "imovx")
3819    (set_attr "mode" "SI")
3820    (set (attr "prefix_0f")
3821      ;; movsx is short decodable while cwtl is vector decoded.
3822      (if_then_else (and (eq_attr "cpu" "!k6")
3823                         (eq_attr "alternative" "0"))
3824         (const_string "0")
3825         (const_string "1")))
3826    (set (attr "modrm")
3827      (if_then_else (eq_attr "prefix_0f" "0")
3828         (const_string "0")
3829         (const_string "1")))])
3831 (define_insn "extendqisi2"
3832   [(set (match_operand:SI 0 "register_operand" "=r")
3833         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3834   ""
3835   "movs{bl|x}\t{%1, %0|%0, %1}"
3836    [(set_attr "type" "imovx")
3837     (set_attr "mode" "SI")])
3839 (define_insn "*extendqisi2_zext"
3840   [(set (match_operand:DI 0 "register_operand" "=r")
3841         (zero_extend:DI
3842           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3843   "TARGET_64BIT"
3844   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3845    [(set_attr "type" "imovx")
3846     (set_attr "mode" "SI")])
3848 (define_insn "extendqihi2"
3849   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3850         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3851   ""
3853   switch (get_attr_prefix_0f (insn))
3854     {
3855     case 0:
3856       return "{cbtw|cbw}";
3857     default:
3858       return "movs{bw|x}\t{%1, %0|%0, %1}";
3859     }
3861   [(set_attr "type" "imovx")
3862    (set_attr "mode" "HI")
3863    (set (attr "prefix_0f")
3864      ;; movsx is short decodable while cwtl is vector decoded.
3865      (if_then_else (and (eq_attr "cpu" "!k6")
3866                         (eq_attr "alternative" "0"))
3867         (const_string "0")
3868         (const_string "1")))
3869    (set (attr "modrm")
3870      (if_then_else (eq_attr "prefix_0f" "0")
3871         (const_string "0")
3872         (const_string "1")))])
3874 ;; Conversions between float and double.
3876 ;; These are all no-ops in the model used for the 80387.
3877 ;; So just emit moves.
3879 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3880 (define_split
3881   [(set (match_operand:DF 0 "push_operand")
3882         (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3883   "reload_completed"
3884   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3885    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3887 (define_split
3888   [(set (match_operand:XF 0 "push_operand")
3889         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3890   "reload_completed"
3891   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3892    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3893   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3895 (define_expand "extendsfdf2"
3896   [(set (match_operand:DF 0 "nonimmediate_operand")
3897         (float_extend:DF (match_operand:SF 1 "general_operand")))]
3898   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3900   /* ??? Needed for compress_float_constant since all fp constants
3901      are TARGET_LEGITIMATE_CONSTANT_P.  */
3902   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3903     {
3904       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3905           && standard_80387_constant_p (operands[1]) > 0)
3906         {
3907           operands[1] = simplify_const_unary_operation
3908             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3909           emit_move_insn_1 (operands[0], operands[1]);
3910           DONE;
3911         }
3912       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3913     }
3916 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3917    cvtss2sd:
3918       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3919       cvtps2pd xmm2,xmm1
3920    We do the conversion post reload to avoid producing of 128bit spills
3921    that might lead to ICE on 32bit target.  The sequence unlikely combine
3922    anyway.  */
3923 (define_split
3924   [(set (match_operand:DF 0 "register_operand")
3925         (float_extend:DF
3926           (match_operand:SF 1 "nonimmediate_operand")))]
3927   "TARGET_USE_VECTOR_FP_CONVERTS
3928    && optimize_insn_for_speed_p ()
3929    && reload_completed && SSE_REG_P (operands[0])"
3930    [(set (match_dup 2)
3931          (float_extend:V2DF
3932            (vec_select:V2SF
3933              (match_dup 3)
3934              (parallel [(const_int 0) (const_int 1)]))))]
3936   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3937   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3938   /* Use movss for loading from memory, unpcklps reg, reg for registers.
3939      Try to avoid move when unpacking can be done in source.  */
3940   if (REG_P (operands[1]))
3941     {
3942       /* If it is unsafe to overwrite upper half of source, we need
3943          to move to destination and unpack there.  */
3944       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3945            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3946           && true_regnum (operands[0]) != true_regnum (operands[1]))
3947         {
3948           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3949           emit_move_insn (tmp, operands[1]);
3950         }
3951       else
3952         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3953       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3954                                              operands[3]));
3955     }
3956   else
3957     emit_insn (gen_vec_setv4sf_0 (operands[3],
3958                                   CONST0_RTX (V4SFmode), operands[1]));
3961 ;; It's more profitable to split and then extend in the same register.
3962 (define_peephole2
3963   [(set (match_operand:DF 0 "register_operand")
3964         (float_extend:DF
3965           (match_operand:SF 1 "memory_operand")))]
3966   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
3967    && optimize_insn_for_speed_p ()
3968    && SSE_REG_P (operands[0])"
3969   [(set (match_dup 2) (match_dup 1))
3970    (set (match_dup 0) (float_extend:DF (match_dup 2)))]
3971   "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
3973 (define_insn "*extendsfdf2_mixed"
3974   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3975         (float_extend:DF
3976           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3977   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3979   switch (which_alternative)
3980     {
3981     case 0:
3982     case 1:
3983       return output_387_reg_move (insn, operands);
3985     case 2:
3986       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3988     default:
3989       gcc_unreachable ();
3990     }
3992   [(set_attr "type" "fmov,fmov,ssecvt")
3993    (set_attr "prefix" "orig,orig,maybe_vex")
3994    (set_attr "mode" "SF,XF,DF")])
3996 (define_insn "*extendsfdf2_sse"
3997   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3998         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3999   "TARGET_SSE2 && TARGET_SSE_MATH"
4000   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4001   [(set_attr "type" "ssecvt")
4002    (set_attr "prefix" "maybe_vex")
4003    (set_attr "mode" "DF")])
4005 (define_insn "*extendsfdf2_i387"
4006   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4007         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4008   "TARGET_80387"
4009   "* return output_387_reg_move (insn, operands);"
4010   [(set_attr "type" "fmov")
4011    (set_attr "mode" "SF,XF")])
4013 (define_expand "extend<mode>xf2"
4014   [(set (match_operand:XF 0 "nonimmediate_operand")
4015         (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4016   "TARGET_80387"
4018   /* ??? Needed for compress_float_constant since all fp constants
4019      are TARGET_LEGITIMATE_CONSTANT_P.  */
4020   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4021     {
4022       if (standard_80387_constant_p (operands[1]) > 0)
4023         {
4024           operands[1] = simplify_const_unary_operation
4025             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4026           emit_move_insn_1 (operands[0], operands[1]);
4027           DONE;
4028         }
4029       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4030     }
4033 (define_insn "*extend<mode>xf2_i387"
4034   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4035         (float_extend:XF
4036           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4037   "TARGET_80387"
4038   "* return output_387_reg_move (insn, operands);"
4039   [(set_attr "type" "fmov")
4040    (set_attr "mode" "<MODE>,XF")])
4042 ;; %%% This seems bad bad news.
4043 ;; This cannot output into an f-reg because there is no way to be sure
4044 ;; of truncating in that case.  Otherwise this is just like a simple move
4045 ;; insn.  So we pretend we can output to a reg in order to get better
4046 ;; register preferencing, but we really use a stack slot.
4048 ;; Conversion from DFmode to SFmode.
4050 (define_expand "truncdfsf2"
4051   [(set (match_operand:SF 0 "nonimmediate_operand")
4052         (float_truncate:SF
4053           (match_operand:DF 1 "nonimmediate_operand")))]
4054   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4056   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4057     ;
4058   else if (flag_unsafe_math_optimizations)
4059     ;
4060   else
4061     {
4062       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4063       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4064       DONE;
4065     }
4068 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4069    cvtsd2ss:
4070       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4071       cvtpd2ps xmm2,xmm1
4072    We do the conversion post reload to avoid producing of 128bit spills
4073    that might lead to ICE on 32bit target.  The sequence unlikely combine
4074    anyway.  */
4075 (define_split
4076   [(set (match_operand:SF 0 "register_operand")
4077         (float_truncate:SF
4078           (match_operand:DF 1 "nonimmediate_operand")))]
4079   "TARGET_USE_VECTOR_FP_CONVERTS
4080    && optimize_insn_for_speed_p ()
4081    && reload_completed && SSE_REG_P (operands[0])"
4082    [(set (match_dup 2)
4083          (vec_concat:V4SF
4084            (float_truncate:V2SF
4085              (match_dup 4))
4086            (match_dup 3)))]
4088   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4089   operands[3] = CONST0_RTX (V2SFmode);
4090   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4091   /* Use movsd for loading from memory, unpcklpd for registers.
4092      Try to avoid move when unpacking can be done in source, or SSE3
4093      movddup is available.  */
4094   if (REG_P (operands[1]))
4095     {
4096       if (!TARGET_SSE3
4097           && true_regnum (operands[0]) != true_regnum (operands[1])
4098           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4099               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4100         {
4101           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4102           emit_move_insn (tmp, operands[1]);
4103           operands[1] = tmp;
4104         }
4105       else if (!TARGET_SSE3)
4106         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4107       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4108     }
4109   else
4110     emit_insn (gen_sse2_loadlpd (operands[4],
4111                                  CONST0_RTX (V2DFmode), operands[1]));
4114 ;; It's more profitable to split and then extend in the same register.
4115 (define_peephole2
4116   [(set (match_operand:SF 0 "register_operand")
4117         (float_truncate:SF
4118           (match_operand:DF 1 "memory_operand")))]
4119   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4120    && optimize_insn_for_speed_p ()
4121    && SSE_REG_P (operands[0])"
4122   [(set (match_dup 2) (match_dup 1))
4123    (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4124   "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
4126 (define_expand "truncdfsf2_with_temp"
4127   [(parallel [(set (match_operand:SF 0)
4128                    (float_truncate:SF (match_operand:DF 1)))
4129               (clobber (match_operand:SF 2))])])
4131 (define_insn "*truncdfsf_fast_mixed"
4132   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4133         (float_truncate:SF
4134           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4135   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4137   switch (which_alternative)
4138     {
4139     case 0:
4140       return output_387_reg_move (insn, operands);
4141     case 1:
4142       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4143     default:
4144       gcc_unreachable ();
4145     }
4147   [(set_attr "type" "fmov,ssecvt")
4148    (set_attr "prefix" "orig,maybe_vex")
4149    (set_attr "mode" "SF")])
4151 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4152 ;; because nothing we do here is unsafe.
4153 (define_insn "*truncdfsf_fast_sse"
4154   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4155         (float_truncate:SF
4156           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4157   "TARGET_SSE2 && TARGET_SSE_MATH"
4158   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4159   [(set_attr "type" "ssecvt")
4160    (set_attr "prefix" "maybe_vex")
4161    (set_attr "mode" "SF")])
4163 (define_insn "*truncdfsf_fast_i387"
4164   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4165         (float_truncate:SF
4166           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4167   "TARGET_80387 && flag_unsafe_math_optimizations"
4168   "* return output_387_reg_move (insn, operands);"
4169   [(set_attr "type" "fmov")
4170    (set_attr "mode" "SF")])
4172 (define_insn "*truncdfsf_mixed"
4173   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,x ,?f,?x,?*r")
4174         (float_truncate:SF
4175           (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4176    (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
4177   "TARGET_MIX_SSE_I387"
4179   switch (which_alternative)
4180     {
4181     case 0:
4182       return output_387_reg_move (insn, operands);
4183     case 1:
4184       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4186     default:
4187       return "#";
4188     }
4190   [(set_attr "isa" "*,sse2,*,*,*")
4191    (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4192    (set_attr "unit" "*,*,i387,i387,i387")
4193    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4194    (set_attr "mode" "SF")])
4196 (define_insn "*truncdfsf_i387"
4197   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4198         (float_truncate:SF
4199           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4200    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4201   "TARGET_80387"
4203   switch (which_alternative)
4204     {
4205     case 0:
4206       return output_387_reg_move (insn, operands);
4208     default:
4209       return "#";
4210     }
4212   [(set_attr "type" "fmov,multi,multi,multi")
4213    (set_attr "unit" "*,i387,i387,i387")
4214    (set_attr "mode" "SF")])
4216 (define_insn "*truncdfsf2_i387_1"
4217   [(set (match_operand:SF 0 "memory_operand" "=m")
4218         (float_truncate:SF
4219           (match_operand:DF 1 "register_operand" "f")))]
4220   "TARGET_80387
4221    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4222    && !TARGET_MIX_SSE_I387"
4223   "* return output_387_reg_move (insn, operands);"
4224   [(set_attr "type" "fmov")
4225    (set_attr "mode" "SF")])
4227 (define_split
4228   [(set (match_operand:SF 0 "register_operand")
4229         (float_truncate:SF
4230          (match_operand:DF 1 "fp_register_operand")))
4231    (clobber (match_operand 2))]
4232   "reload_completed"
4233   [(set (match_dup 2) (match_dup 1))
4234    (set (match_dup 0) (match_dup 2))]
4235   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4237 ;; Conversion from XFmode to {SF,DF}mode
4239 (define_expand "truncxf<mode>2"
4240   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4241                    (float_truncate:MODEF
4242                      (match_operand:XF 1 "register_operand")))
4243               (clobber (match_dup 2))])]
4244   "TARGET_80387"
4246   if (flag_unsafe_math_optimizations)
4247     {
4248       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4249       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4250       if (reg != operands[0])
4251         emit_move_insn (operands[0], reg);
4252       DONE;
4253     }
4254   else
4255     operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4258 (define_insn "*truncxfsf2_mixed"
4259   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4260         (float_truncate:SF
4261           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4262    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4263   "TARGET_80387"
4265   gcc_assert (!which_alternative);
4266   return output_387_reg_move (insn, operands);
4268   [(set_attr "type" "fmov,multi,multi,multi")
4269    (set_attr "unit" "*,i387,i387,i387")
4270    (set_attr "mode" "SF")])
4272 (define_insn "*truncxfdf2_mixed"
4273   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4274         (float_truncate:DF
4275           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4276    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4277   "TARGET_80387"
4279   gcc_assert (!which_alternative);
4280   return output_387_reg_move (insn, operands);
4282   [(set_attr "isa" "*,*,sse2,*")
4283    (set_attr "type" "fmov,multi,multi,multi")
4284    (set_attr "unit" "*,i387,i387,i387")
4285    (set_attr "mode" "DF")])
4287 (define_insn "truncxf<mode>2_i387_noop"
4288   [(set (match_operand:MODEF 0 "register_operand" "=f")
4289         (float_truncate:MODEF
4290           (match_operand:XF 1 "register_operand" "f")))]
4291   "TARGET_80387 && flag_unsafe_math_optimizations"
4292   "* return output_387_reg_move (insn, operands);"
4293   [(set_attr "type" "fmov")
4294    (set_attr "mode" "<MODE>")])
4296 (define_insn "*truncxf<mode>2_i387"
4297   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4298         (float_truncate:MODEF
4299           (match_operand:XF 1 "register_operand" "f")))]
4300   "TARGET_80387"
4301   "* return output_387_reg_move (insn, operands);"
4302   [(set_attr "type" "fmov")
4303    (set_attr "mode" "<MODE>")])
4305 (define_split
4306   [(set (match_operand:MODEF 0 "register_operand")
4307         (float_truncate:MODEF
4308           (match_operand:XF 1 "register_operand")))
4309    (clobber (match_operand:MODEF 2 "memory_operand"))]
4310   "TARGET_80387 && reload_completed"
4311   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4312    (set (match_dup 0) (match_dup 2))])
4314 (define_split
4315   [(set (match_operand:MODEF 0 "memory_operand")
4316         (float_truncate:MODEF
4317           (match_operand:XF 1 "register_operand")))
4318    (clobber (match_operand:MODEF 2 "memory_operand"))]
4319   "TARGET_80387"
4320   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4322 ;; Signed conversion to DImode.
4324 (define_expand "fix_truncxfdi2"
4325   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4326                    (fix:DI (match_operand:XF 1 "register_operand")))
4327               (clobber (reg:CC FLAGS_REG))])]
4328   "TARGET_80387"
4330   if (TARGET_FISTTP)
4331    {
4332      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4333      DONE;
4334    }
4337 (define_expand "fix_trunc<mode>di2"
4338   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4339                    (fix:DI (match_operand:MODEF 1 "register_operand")))
4340               (clobber (reg:CC FLAGS_REG))])]
4341   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4343   if (TARGET_FISTTP
4344       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4345    {
4346      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4347      DONE;
4348    }
4349   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4350    {
4351      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4352      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4353      if (out != operands[0])
4354         emit_move_insn (operands[0], out);
4355      DONE;
4356    }
4359 ;; Signed conversion to SImode.
4361 (define_expand "fix_truncxfsi2"
4362   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4363                    (fix:SI (match_operand:XF 1 "register_operand")))
4364               (clobber (reg:CC FLAGS_REG))])]
4365   "TARGET_80387"
4367   if (TARGET_FISTTP)
4368    {
4369      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4370      DONE;
4371    }
4374 (define_expand "fix_trunc<mode>si2"
4375   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4376                    (fix:SI (match_operand:MODEF 1 "register_operand")))
4377               (clobber (reg:CC FLAGS_REG))])]
4378   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4380   if (TARGET_FISTTP
4381       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4382    {
4383      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4384      DONE;
4385    }
4386   if (SSE_FLOAT_MODE_P (<MODE>mode))
4387    {
4388      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4389      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4390      if (out != operands[0])
4391         emit_move_insn (operands[0], out);
4392      DONE;
4393    }
4396 ;; Signed conversion to HImode.
4398 (define_expand "fix_trunc<mode>hi2"
4399   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4400                    (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4401               (clobber (reg:CC FLAGS_REG))])]
4402   "TARGET_80387
4403    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4405   if (TARGET_FISTTP)
4406    {
4407      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4408      DONE;
4409    }
4412 ;; Unsigned conversion to SImode.
4414 (define_expand "fixuns_trunc<mode>si2"
4415   [(parallel
4416     [(set (match_operand:SI 0 "register_operand")
4417           (unsigned_fix:SI
4418             (match_operand:MODEF 1 "nonimmediate_operand")))
4419      (use (match_dup 2))
4420      (clobber (match_scratch:<ssevecmode> 3))
4421      (clobber (match_scratch:<ssevecmode> 4))])]
4422   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4424   machine_mode mode = <MODE>mode;
4425   machine_mode vecmode = <ssevecmode>mode;
4426   REAL_VALUE_TYPE TWO31r;
4427   rtx two31;
4429   if (optimize_insn_for_size_p ())
4430     FAIL;
4432   real_ldexp (&TWO31r, &dconst1, 31);
4433   two31 = const_double_from_real_value (TWO31r, mode);
4434   two31 = ix86_build_const_vector (vecmode, true, two31);
4435   operands[2] = force_reg (vecmode, two31);
4438 (define_insn_and_split "*fixuns_trunc<mode>_1"
4439   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4440         (unsigned_fix:SI
4441           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4442    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4443    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4444    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4445   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4446    && optimize_function_for_speed_p (cfun)"
4447   "#"
4448   "&& reload_completed"
4449   [(const_int 0)]
4451   ix86_split_convert_uns_si_sse (operands);
4452   DONE;
4455 ;; Unsigned conversion to HImode.
4456 ;; Without these patterns, we'll try the unsigned SI conversion which
4457 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4459 (define_expand "fixuns_trunc<mode>hi2"
4460   [(set (match_dup 2)
4461         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4462    (set (match_operand:HI 0 "nonimmediate_operand")
4463         (subreg:HI (match_dup 2) 0))]
4464   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4465   "operands[2] = gen_reg_rtx (SImode);")
4467 ;; When SSE is available, it is always faster to use it!
4468 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4469   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4470         (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4471   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4472    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4473   "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4474   [(set_attr "type" "sseicvt")
4475    (set_attr "prefix" "maybe_vex")
4476    (set (attr "prefix_rex")
4477         (if_then_else
4478           (match_test "<SWI48:MODE>mode == DImode")
4479           (const_string "1")
4480           (const_string "*")))
4481    (set_attr "mode" "<MODEF:MODE>")
4482    (set_attr "athlon_decode" "double,vector")
4483    (set_attr "amdfam10_decode" "double,double")
4484    (set_attr "bdver1_decode" "double,double")])
4486 ;; Avoid vector decoded forms of the instruction.
4487 (define_peephole2
4488   [(match_scratch:MODEF 2 "x")
4489    (set (match_operand:SWI48 0 "register_operand")
4490         (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4491   "TARGET_AVOID_VECTOR_DECODE
4492    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4493    && optimize_insn_for_speed_p ()"
4494   [(set (match_dup 2) (match_dup 1))
4495    (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4497 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4498   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4499         (fix:SWI248x (match_operand 1 "register_operand")))]
4500   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4501    && TARGET_FISTTP
4502    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4503          && (TARGET_64BIT || <MODE>mode != DImode))
4504         && TARGET_SSE_MATH)
4505    && can_create_pseudo_p ()"
4506   "#"
4507   "&& 1"
4508   [(const_int 0)]
4510   if (memory_operand (operands[0], VOIDmode))
4511     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4512   else
4513     {
4514       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4515       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4516                                                             operands[1],
4517                                                             operands[2]));
4518     }
4519   DONE;
4521   [(set_attr "type" "fisttp")
4522    (set_attr "mode" "<MODE>")])
4524 (define_insn "fix_trunc<mode>_i387_fisttp"
4525   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4526         (fix:SWI248x (match_operand 1 "register_operand" "f")))
4527    (clobber (match_scratch:XF 2 "=&1f"))]
4528   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4529    && TARGET_FISTTP
4530    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4531          && (TARGET_64BIT || <MODE>mode != DImode))
4532         && TARGET_SSE_MATH)"
4533   "* return output_fix_trunc (insn, operands, true);"
4534   [(set_attr "type" "fisttp")
4535    (set_attr "mode" "<MODE>")])
4537 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4538   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4539         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4540    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4541    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4542   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4543    && TARGET_FISTTP
4544    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4545         && (TARGET_64BIT || <MODE>mode != DImode))
4546         && TARGET_SSE_MATH)"
4547   "#"
4548   [(set_attr "type" "fisttp")
4549    (set_attr "mode" "<MODE>")])
4551 (define_split
4552   [(set (match_operand:SWI248x 0 "register_operand")
4553         (fix:SWI248x (match_operand 1 "register_operand")))
4554    (clobber (match_operand:SWI248x 2 "memory_operand"))
4555    (clobber (match_scratch 3))]
4556   "reload_completed"
4557   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4558               (clobber (match_dup 3))])
4559    (set (match_dup 0) (match_dup 2))])
4561 (define_split
4562   [(set (match_operand:SWI248x 0 "memory_operand")
4563         (fix:SWI248x (match_operand 1 "register_operand")))
4564    (clobber (match_operand:SWI248x 2 "memory_operand"))
4565    (clobber (match_scratch 3))]
4566   "reload_completed"
4567   [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4568               (clobber (match_dup 3))])])
4570 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4571 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4572 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4573 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4574 ;; function in i386.c.
4575 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4576   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4577         (fix:SWI248x (match_operand 1 "register_operand")))
4578    (clobber (reg:CC FLAGS_REG))]
4579   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4580    && !TARGET_FISTTP
4581    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4582          && (TARGET_64BIT || <MODE>mode != DImode))
4583    && can_create_pseudo_p ()"
4584   "#"
4585   "&& 1"
4586   [(const_int 0)]
4588   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4590   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4591   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4592   if (memory_operand (operands[0], VOIDmode))
4593     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4594                                          operands[2], operands[3]));
4595   else
4596     {
4597       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4598       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4599                                                      operands[2], operands[3],
4600                                                      operands[4]));
4601     }
4602   DONE;
4604   [(set_attr "type" "fistp")
4605    (set_attr "i387_cw" "trunc")
4606    (set_attr "mode" "<MODE>")])
4608 (define_insn "fix_truncdi_i387"
4609   [(set (match_operand:DI 0 "memory_operand" "=m")
4610         (fix:DI (match_operand 1 "register_operand" "f")))
4611    (use (match_operand:HI 2 "memory_operand" "m"))
4612    (use (match_operand:HI 3 "memory_operand" "m"))
4613    (clobber (match_scratch:XF 4 "=&1f"))]
4614   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4615    && !TARGET_FISTTP
4616    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4617   "* return output_fix_trunc (insn, operands, false);"
4618   [(set_attr "type" "fistp")
4619    (set_attr "i387_cw" "trunc")
4620    (set_attr "mode" "DI")])
4622 (define_insn "fix_truncdi_i387_with_temp"
4623   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4624         (fix:DI (match_operand 1 "register_operand" "f,f")))
4625    (use (match_operand:HI 2 "memory_operand" "m,m"))
4626    (use (match_operand:HI 3 "memory_operand" "m,m"))
4627    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4628    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4629   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4630    && !TARGET_FISTTP
4631    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4632   "#"
4633   [(set_attr "type" "fistp")
4634    (set_attr "i387_cw" "trunc")
4635    (set_attr "mode" "DI")])
4637 (define_split
4638   [(set (match_operand:DI 0 "register_operand")
4639         (fix:DI (match_operand 1 "register_operand")))
4640    (use (match_operand:HI 2 "memory_operand"))
4641    (use (match_operand:HI 3 "memory_operand"))
4642    (clobber (match_operand:DI 4 "memory_operand"))
4643    (clobber (match_scratch 5))]
4644   "reload_completed"
4645   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4646               (use (match_dup 2))
4647               (use (match_dup 3))
4648               (clobber (match_dup 5))])
4649    (set (match_dup 0) (match_dup 4))])
4651 (define_split
4652   [(set (match_operand:DI 0 "memory_operand")
4653         (fix:DI (match_operand 1 "register_operand")))
4654    (use (match_operand:HI 2 "memory_operand"))
4655    (use (match_operand:HI 3 "memory_operand"))
4656    (clobber (match_operand:DI 4 "memory_operand"))
4657    (clobber (match_scratch 5))]
4658   "reload_completed"
4659   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4660               (use (match_dup 2))
4661               (use (match_dup 3))
4662               (clobber (match_dup 5))])])
4664 (define_insn "fix_trunc<mode>_i387"
4665   [(set (match_operand:SWI24 0 "memory_operand" "=m")
4666         (fix:SWI24 (match_operand 1 "register_operand" "f")))
4667    (use (match_operand:HI 2 "memory_operand" "m"))
4668    (use (match_operand:HI 3 "memory_operand" "m"))]
4669   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4670    && !TARGET_FISTTP
4671    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4672   "* return output_fix_trunc (insn, operands, false);"
4673   [(set_attr "type" "fistp")
4674    (set_attr "i387_cw" "trunc")
4675    (set_attr "mode" "<MODE>")])
4677 (define_insn "fix_trunc<mode>_i387_with_temp"
4678   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4679         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4680    (use (match_operand:HI 2 "memory_operand" "m,m"))
4681    (use (match_operand:HI 3 "memory_operand" "m,m"))
4682    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4683   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4684    && !TARGET_FISTTP
4685    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4686   "#"
4687   [(set_attr "type" "fistp")
4688    (set_attr "i387_cw" "trunc")
4689    (set_attr "mode" "<MODE>")])
4691 (define_split
4692   [(set (match_operand:SWI24 0 "register_operand")
4693         (fix:SWI24 (match_operand 1 "register_operand")))
4694    (use (match_operand:HI 2 "memory_operand"))
4695    (use (match_operand:HI 3 "memory_operand"))
4696    (clobber (match_operand:SWI24 4 "memory_operand"))]
4697   "reload_completed"
4698   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4699               (use (match_dup 2))
4700               (use (match_dup 3))])
4701    (set (match_dup 0) (match_dup 4))])
4703 (define_split
4704   [(set (match_operand:SWI24 0 "memory_operand")
4705         (fix:SWI24 (match_operand 1 "register_operand")))
4706    (use (match_operand:HI 2 "memory_operand"))
4707    (use (match_operand:HI 3 "memory_operand"))
4708    (clobber (match_operand:SWI24 4 "memory_operand"))]
4709   "reload_completed"
4710   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4711               (use (match_dup 2))
4712               (use (match_dup 3))])])
4714 (define_insn "x86_fnstcw_1"
4715   [(set (match_operand:HI 0 "memory_operand" "=m")
4716         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4717   "TARGET_80387"
4718   "fnstcw\t%0"
4719   [(set (attr "length")
4720         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4721    (set_attr "mode" "HI")
4722    (set_attr "unit" "i387")
4723    (set_attr "bdver1_decode" "vector")])
4725 (define_insn "x86_fldcw_1"
4726   [(set (reg:HI FPCR_REG)
4727         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4728   "TARGET_80387"
4729   "fldcw\t%0"
4730   [(set (attr "length")
4731         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4732    (set_attr "mode" "HI")
4733    (set_attr "unit" "i387")
4734    (set_attr "athlon_decode" "vector")
4735    (set_attr "amdfam10_decode" "vector")
4736    (set_attr "bdver1_decode" "vector")])
4738 ;; Conversion between fixed point and floating point.
4740 ;; Even though we only accept memory inputs, the backend _really_
4741 ;; wants to be able to do this between registers.  Thankfully, LRA
4742 ;; will fix this up for us during register allocation.
4744 (define_insn "floathi<mode>2"
4745   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4746         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
4747   "TARGET_80387
4748    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4749        || TARGET_MIX_SSE_I387)"
4750   "fild%Z1\t%1"
4751   [(set_attr "type" "fmov")
4752    (set_attr "mode" "<MODE>")
4753    (set_attr "fp_int_src" "true")])
4755 (define_insn "float<SWI48x:mode>xf2"
4756   [(set (match_operand:XF 0 "register_operand" "=f")
4757         (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4758   "TARGET_80387"
4759   "fild%Z1\t%1"
4760   [(set_attr "type" "fmov")
4761    (set_attr "mode" "XF")
4762    (set_attr "fp_int_src" "true")])
4764 (define_expand "float<SWI48:mode><MODEF:mode>2"
4765   [(set (match_operand:MODEF 0 "register_operand")
4766         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4767   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
4769   if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
4770       && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
4771     {
4772       rtx reg = gen_reg_rtx (XFmode);
4773       rtx (*insn)(rtx, rtx);
4775       emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
4777       if (<MODEF:MODE>mode == SFmode)
4778         insn = gen_truncxfsf2;
4779       else if (<MODEF:MODE>mode == DFmode)
4780         insn = gen_truncxfdf2;
4781       else
4782         gcc_unreachable ();
4784       emit_insn (insn (operands[0], reg));
4785       DONE;
4786     }
4789 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse"
4790   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4791         (float:MODEF
4792           (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4793   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4794   "@
4795    fild%Z1\t%1
4796    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4797    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4798   [(set_attr "type" "fmov,sseicvt,sseicvt")
4799    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4800    (set_attr "mode" "<MODEF:MODE>")
4801    (set (attr "prefix_rex")
4802      (if_then_else
4803        (and (eq_attr "prefix" "maybe_vex")
4804             (match_test "<SWI48:MODE>mode == DImode"))
4805        (const_string "1")
4806        (const_string "*")))
4807    (set_attr "unit" "i387,*,*")
4808    (set_attr "athlon_decode" "*,double,direct")
4809    (set_attr "amdfam10_decode" "*,vector,double")
4810    (set_attr "bdver1_decode" "*,double,direct")
4811    (set_attr "fp_int_src" "true")
4812    (set (attr "enabled")
4813      (cond [(eq_attr "alternative" "0")
4814               (symbol_ref "TARGET_MIX_SSE_I387
4815                            && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
4816                                                 <SWI48:MODE>mode)")
4817            ]
4818            (symbol_ref "true")))
4819    (set (attr "preferred_for_speed")
4820      (cond [(eq_attr "alternative" "1")
4821               (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
4822            (symbol_ref "true")))
4823    ])
4825 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
4826   [(set (match_operand:MODEF 0 "register_operand" "=f")
4827         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4828   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
4829   "fild%Z1\t%1"
4830   [(set_attr "type" "fmov")
4831    (set_attr "mode" "<MODEF:MODE>")
4832    (set_attr "fp_int_src" "true")])
4834 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
4835 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
4836 ;; alternative in sse2_loadld.
4837 (define_split
4838   [(set (match_operand:MODEF 0 "register_operand")
4839         (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
4840   "TARGET_SSE2 && TARGET_SSE_MATH
4841    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4842    && reload_completed && SSE_REG_P (operands[0])
4843    && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)"
4844   [(const_int 0)]
4846   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4847                                      <MODE>mode, 0);
4848   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4850   emit_insn (gen_sse2_loadld (operands[4],
4851                               CONST0_RTX (V4SImode), operands[1]));
4853   if (<ssevecmode>mode == V4SFmode)
4854     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4855   else
4856     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4857   DONE;
4860 ;; Avoid partial SSE register dependency stalls
4861 (define_split
4862   [(set (match_operand:MODEF 0 "register_operand")
4863         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4864   "TARGET_SSE2 && TARGET_SSE_MATH
4865    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4866    && optimize_function_for_speed_p (cfun)
4867    && reload_completed && SSE_REG_P (operands[0])"
4868   [(const_int 0)]
4870   const machine_mode vmode = <MODEF:ssevecmode>mode;
4871   const machine_mode mode = <MODEF:MODE>mode;
4872   rtx t, op0 = simplify_gen_subreg (vmode, operands[0], mode, 0);
4874   emit_move_insn (op0, CONST0_RTX (vmode));
4876   t = gen_rtx_FLOAT (mode, operands[1]);
4877   t = gen_rtx_VEC_DUPLICATE (vmode, t);
4878   t = gen_rtx_VEC_MERGE (vmode, t, op0, const1_rtx);
4879   emit_insn (gen_rtx_SET (VOIDmode, op0, t));
4880   DONE;
4883 ;; Break partial reg stall for cvtsd2ss.
4885 (define_peephole2
4886   [(set (match_operand:SF 0 "register_operand")
4887         (float_truncate:SF
4888           (match_operand:DF 1 "nonimmediate_operand")))]
4889   "TARGET_SSE2 && TARGET_SSE_MATH
4890    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4891    && optimize_function_for_speed_p (cfun)
4892    && SSE_REG_P (operands[0])
4893    && (!SSE_REG_P (operands[1])
4894        || REGNO (operands[0]) != REGNO (operands[1]))"
4895   [(set (match_dup 0)
4896         (vec_merge:V4SF
4897           (vec_duplicate:V4SF
4898             (float_truncate:V2SF
4899               (match_dup 1)))
4900           (match_dup 0)
4901           (const_int 1)))]
4903   operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
4904                                      SFmode, 0);
4905   operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
4906                                      DFmode, 0);
4907   emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
4910 ;; Break partial reg stall for cvtss2sd.
4912 (define_peephole2
4913   [(set (match_operand:DF 0 "register_operand")
4914         (float_extend:DF
4915           (match_operand:SF 1 "nonimmediate_operand")))]
4916   "TARGET_SSE2 && TARGET_SSE_MATH
4917    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4918    && optimize_function_for_speed_p (cfun)
4919    && SSE_REG_P (operands[0])
4920    && (!SSE_REG_P (operands[1])
4921        || REGNO (operands[0]) != REGNO (operands[1]))"
4922   [(set (match_dup 0)
4923         (vec_merge:V2DF
4924           (float_extend:V2DF
4925             (vec_select:V2SF
4926               (match_dup 1)
4927               (parallel [(const_int 0) (const_int 1)])))
4928           (match_dup 0)
4929           (const_int 1)))]
4931   operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
4932                                      DFmode, 0);
4933   operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
4934                                      SFmode, 0);
4935   emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
4938 ;; Avoid store forwarding (partial memory) stall penalty
4939 ;; by passing DImode value through XMM registers.  */
4941 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
4942   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4943         (float:X87MODEF
4944           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
4945    (clobber (match_scratch:V4SI 3 "=X,x"))
4946    (clobber (match_scratch:V4SI 4 "=X,x"))
4947    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
4948   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4949    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4950    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
4951   "#"
4952   [(set_attr "type" "multi")
4953    (set_attr "mode" "<X87MODEF:MODE>")
4954    (set_attr "unit" "i387")
4955    (set_attr "fp_int_src" "true")])
4957 (define_split
4958   [(set (match_operand:X87MODEF 0 "fp_register_operand")
4959         (float:X87MODEF (match_operand:DI 1 "register_operand")))
4960    (clobber (match_scratch:V4SI 3))
4961    (clobber (match_scratch:V4SI 4))
4962    (clobber (match_operand:DI 2 "memory_operand"))]
4963   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4964    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4965    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
4966    && reload_completed"
4967   [(set (match_dup 2) (match_dup 3))
4968    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
4970   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
4971      Assemble the 64-bit DImode value in an xmm register.  */
4972   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
4973                               gen_rtx_SUBREG (SImode, operands[1], 0)));
4974   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
4975                               gen_rtx_SUBREG (SImode, operands[1], 4)));
4976   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
4977                                          operands[4]));
4979   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
4982 (define_split
4983   [(set (match_operand:X87MODEF 0 "fp_register_operand")
4984         (float:X87MODEF (match_operand:DI 1 "memory_operand")))
4985    (clobber (match_scratch:V4SI 3))
4986    (clobber (match_scratch:V4SI 4))
4987    (clobber (match_operand:DI 2 "memory_operand"))]
4988   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4989    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4990    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
4991    && reload_completed"
4992   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4994 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
4995   [(set (match_operand:MODEF 0 "register_operand")
4996         (unsigned_float:MODEF
4997           (match_operand:SWI12 1 "nonimmediate_operand")))]
4998   "!TARGET_64BIT
4999    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5001   operands[1] = convert_to_mode (SImode, operands[1], 1);
5002   emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5003   DONE;
5006 ;; Avoid store forwarding (partial memory) stall penalty by extending
5007 ;; SImode value to DImode through XMM register instead of pushing two
5008 ;; SImode values to stack. Also note that fild loads from memory only.
5010 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5011   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5012         (unsigned_float:X87MODEF
5013           (match_operand:SI 1 "nonimmediate_operand" "rm")))
5014    (clobber (match_scratch:DI 3 "=x"))
5015    (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5016   "!TARGET_64BIT
5017    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5018    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5019   "#"
5020   "&& reload_completed"
5021   [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5022    (set (match_dup 2) (match_dup 3))
5023    (set (match_dup 0)
5024         (float:X87MODEF (match_dup 2)))]
5025   ""
5026   [(set_attr "type" "multi")
5027    (set_attr "mode" "<MODE>")])
5029 (define_expand "floatunssi<mode>2"
5030   [(parallel
5031      [(set (match_operand:X87MODEF 0 "register_operand")
5032            (unsigned_float:X87MODEF
5033              (match_operand:SI 1 "nonimmediate_operand")))
5034       (clobber (match_scratch:DI 3))
5035       (clobber (match_dup 2))])]
5036   "!TARGET_64BIT
5037    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5038         && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5039        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5041   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5042     {
5043       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5044       DONE;
5045     }
5046   else
5047     operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5050 (define_expand "floatunsdisf2"
5051   [(use (match_operand:SF 0 "register_operand"))
5052    (use (match_operand:DI 1 "nonimmediate_operand"))]
5053   "TARGET_64BIT && TARGET_SSE_MATH"
5054   "x86_emit_floatuns (operands); DONE;")
5056 (define_expand "floatunsdidf2"
5057   [(use (match_operand:DF 0 "register_operand"))
5058    (use (match_operand:DI 1 "nonimmediate_operand"))]
5059   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5060    && TARGET_SSE2 && TARGET_SSE_MATH"
5062   if (TARGET_64BIT)
5063     x86_emit_floatuns (operands);
5064   else
5065     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5066   DONE;
5069 ;; Load effective address instructions
5071 (define_insn_and_split "*lea<mode>"
5072   [(set (match_operand:SWI48 0 "register_operand" "=r")
5073         (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5074   ""
5076   if (SImode_address_operand (operands[1], VOIDmode))
5077     {
5078       gcc_assert (TARGET_64BIT);
5079       return "lea{l}\t{%E1, %k0|%k0, %E1}";
5080     }
5081   else 
5082     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5084   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5085   [(const_int 0)]
5087   machine_mode mode = <MODE>mode;
5088   rtx pat;
5090   /* ix86_avoid_lea_for_addr re-recognizes insn and may
5091      change operands[] array behind our back.  */
5092   pat = PATTERN (curr_insn);
5094   operands[0] = SET_DEST (pat);
5095   operands[1] = SET_SRC (pat);
5097   /* Emit all operations in SImode for zero-extended addresses.  */
5098   if (SImode_address_operand (operands[1], VOIDmode))
5099     mode = SImode;
5101   ix86_split_lea_for_addr (curr_insn, operands, mode);
5103   /* Zero-extend return register to DImode for zero-extended addresses.  */
5104   if (mode != <MODE>mode)
5105     emit_insn (gen_zero_extendsidi2
5106                (operands[0], gen_lowpart (mode, operands[0])));
5108   DONE;
5110   [(set_attr "type" "lea")
5111    (set (attr "mode")
5112      (if_then_else
5113        (match_operand 1 "SImode_address_operand")
5114        (const_string "SI")
5115        (const_string "<MODE>")))])
5117 ;; Add instructions
5119 (define_expand "add<mode>3"
5120   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5121         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5122                     (match_operand:SDWIM 2 "<general_operand>")))]
5123   ""
5124   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5126 (define_insn_and_split "*add<dwi>3_doubleword"
5127   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5128         (plus:<DWI>
5129           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5130           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5131    (clobber (reg:CC FLAGS_REG))]
5132   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5133   "#"
5134   "reload_completed"
5135   [(parallel [(set (reg:CC FLAGS_REG)
5136                    (unspec:CC [(match_dup 1) (match_dup 2)]
5137                               UNSPEC_ADD_CARRY))
5138               (set (match_dup 0)
5139                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5140    (parallel [(set (match_dup 3)
5141                    (plus:DWIH
5142                      (match_dup 4)
5143                      (plus:DWIH
5144                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5145                        (match_dup 5))))
5146               (clobber (reg:CC FLAGS_REG))])]
5147   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5149 (define_insn "*add<mode>3_cc"
5150   [(set (reg:CC FLAGS_REG)
5151         (unspec:CC
5152           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5153            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5154           UNSPEC_ADD_CARRY))
5155    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5156         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5157   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5158   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5159   [(set_attr "type" "alu")
5160    (set_attr "mode" "<MODE>")])
5162 (define_insn "addqi3_cc"
5163   [(set (reg:CC FLAGS_REG)
5164         (unspec:CC
5165           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5166            (match_operand:QI 2 "general_operand" "qn,qm")]
5167           UNSPEC_ADD_CARRY))
5168    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5169         (plus:QI (match_dup 1) (match_dup 2)))]
5170   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5171   "add{b}\t{%2, %0|%0, %2}"
5172   [(set_attr "type" "alu")
5173    (set_attr "mode" "QI")])
5175 (define_insn "*add<mode>_1"
5176   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5177         (plus:SWI48
5178           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5179           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5180    (clobber (reg:CC FLAGS_REG))]
5181   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5183   switch (get_attr_type (insn))
5184     {
5185     case TYPE_LEA:
5186       return "#";
5188     case TYPE_INCDEC:
5189       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5190       if (operands[2] == const1_rtx)
5191         return "inc{<imodesuffix>}\t%0";
5192       else
5193         {
5194           gcc_assert (operands[2] == constm1_rtx);
5195           return "dec{<imodesuffix>}\t%0";
5196         }
5198     default:
5199       /* For most processors, ADD is faster than LEA.  This alternative
5200          was added to use ADD as much as possible.  */
5201       if (which_alternative == 2)
5202         {
5203           rtx tmp;
5204           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5205         }
5206         
5207       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5208       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5209         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5211       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5212     }
5214   [(set (attr "type")
5215      (cond [(eq_attr "alternative" "3")
5216               (const_string "lea")
5217             (match_operand:SWI48 2 "incdec_operand")
5218               (const_string "incdec")
5219            ]
5220            (const_string "alu")))
5221    (set (attr "length_immediate")
5222       (if_then_else
5223         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5224         (const_string "1")
5225         (const_string "*")))
5226    (set_attr "mode" "<MODE>")])
5228 ;; It may seem that nonimmediate operand is proper one for operand 1.
5229 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5230 ;; we take care in ix86_binary_operator_ok to not allow two memory
5231 ;; operands so proper swapping will be done in reload.  This allow
5232 ;; patterns constructed from addsi_1 to match.
5234 (define_insn "addsi_1_zext"
5235   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5236         (zero_extend:DI
5237           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5238                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5239    (clobber (reg:CC FLAGS_REG))]
5240   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5242   switch (get_attr_type (insn))
5243     {
5244     case TYPE_LEA:
5245       return "#";
5247     case TYPE_INCDEC:
5248       if (operands[2] == const1_rtx)
5249         return "inc{l}\t%k0";
5250       else
5251         {
5252           gcc_assert (operands[2] == constm1_rtx);
5253           return "dec{l}\t%k0";
5254         }
5256     default:
5257       /* For most processors, ADD is faster than LEA.  This alternative
5258          was added to use ADD as much as possible.  */
5259       if (which_alternative == 1)
5260         {
5261           rtx tmp;
5262           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5263         }
5265       if (x86_maybe_negate_const_int (&operands[2], SImode))
5266         return "sub{l}\t{%2, %k0|%k0, %2}";
5268       return "add{l}\t{%2, %k0|%k0, %2}";
5269     }
5271   [(set (attr "type")
5272      (cond [(eq_attr "alternative" "2")
5273               (const_string "lea")
5274             (match_operand:SI 2 "incdec_operand")
5275               (const_string "incdec")
5276            ]
5277            (const_string "alu")))
5278    (set (attr "length_immediate")
5279       (if_then_else
5280         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5281         (const_string "1")
5282         (const_string "*")))
5283    (set_attr "mode" "SI")])
5285 (define_insn "*addhi_1"
5286   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5287         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5288                  (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5289    (clobber (reg:CC FLAGS_REG))]
5290   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5292   switch (get_attr_type (insn))
5293     {
5294     case TYPE_LEA:
5295       return "#";
5297     case TYPE_INCDEC:
5298       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5299       if (operands[2] == const1_rtx)
5300         return "inc{w}\t%0";
5301       else
5302         {
5303           gcc_assert (operands[2] == constm1_rtx);
5304           return "dec{w}\t%0";
5305         }
5307     default:
5308       /* For most processors, ADD is faster than LEA.  This alternative
5309          was added to use ADD as much as possible.  */
5310       if (which_alternative == 2)
5311         {
5312           rtx tmp;
5313           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5314         }
5316       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5317       if (x86_maybe_negate_const_int (&operands[2], HImode))
5318         return "sub{w}\t{%2, %0|%0, %2}";
5320       return "add{w}\t{%2, %0|%0, %2}";
5321     }
5323   [(set (attr "type")
5324      (cond [(eq_attr "alternative" "3")
5325               (const_string "lea")
5326             (match_operand:HI 2 "incdec_operand")
5327               (const_string "incdec")
5328            ]
5329            (const_string "alu")))
5330    (set (attr "length_immediate")
5331       (if_then_else
5332         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5333         (const_string "1")
5334         (const_string "*")))
5335    (set_attr "mode" "HI,HI,HI,SI")])
5337 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5338 (define_insn "*addqi_1"
5339   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5340         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5341                  (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5342    (clobber (reg:CC FLAGS_REG))]
5343   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5345   bool widen = (which_alternative == 3 || which_alternative == 4);
5347   switch (get_attr_type (insn))
5348     {
5349     case TYPE_LEA:
5350       return "#";
5352     case TYPE_INCDEC:
5353       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5354       if (operands[2] == const1_rtx)
5355         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5356       else
5357         {
5358           gcc_assert (operands[2] == constm1_rtx);
5359           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5360         }
5362     default:
5363       /* For most processors, ADD is faster than LEA.  These alternatives
5364          were added to use ADD as much as possible.  */
5365       if (which_alternative == 2 || which_alternative == 4)
5366         {
5367           rtx tmp;
5368           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5369         }
5371       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5372       if (x86_maybe_negate_const_int (&operands[2], QImode))
5373         {
5374           if (widen)
5375             return "sub{l}\t{%2, %k0|%k0, %2}";
5376           else
5377             return "sub{b}\t{%2, %0|%0, %2}";
5378         }
5379       if (widen)
5380         return "add{l}\t{%k2, %k0|%k0, %k2}";
5381       else
5382         return "add{b}\t{%2, %0|%0, %2}";
5383     }
5385   [(set (attr "type")
5386      (cond [(eq_attr "alternative" "5")
5387               (const_string "lea")
5388             (match_operand:QI 2 "incdec_operand")
5389               (const_string "incdec")
5390            ]
5391            (const_string "alu")))
5392    (set (attr "length_immediate")
5393       (if_then_else
5394         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5395         (const_string "1")
5396         (const_string "*")))
5397    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5399 (define_insn "*addqi_1_slp"
5400   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5401         (plus:QI (match_dup 0)
5402                  (match_operand:QI 1 "general_operand" "qn,qm")))
5403    (clobber (reg:CC FLAGS_REG))]
5404   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5405    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5407   switch (get_attr_type (insn))
5408     {
5409     case TYPE_INCDEC:
5410       if (operands[1] == const1_rtx)
5411         return "inc{b}\t%0";
5412       else
5413         {
5414           gcc_assert (operands[1] == constm1_rtx);
5415           return "dec{b}\t%0";
5416         }
5418     default:
5419       if (x86_maybe_negate_const_int (&operands[1], QImode))
5420         return "sub{b}\t{%1, %0|%0, %1}";
5422       return "add{b}\t{%1, %0|%0, %1}";
5423     }
5425   [(set (attr "type")
5426      (if_then_else (match_operand:QI 1 "incdec_operand")
5427         (const_string "incdec")
5428         (const_string "alu1")))
5429    (set (attr "memory")
5430      (if_then_else (match_operand 1 "memory_operand")
5431         (const_string "load")
5432         (const_string "none")))
5433    (set_attr "mode" "QI")])
5435 ;; Split non destructive adds if we cannot use lea.
5436 (define_split
5437   [(set (match_operand:SWI48 0 "register_operand")
5438         (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5439                     (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5440    (clobber (reg:CC FLAGS_REG))]
5441   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5442   [(set (match_dup 0) (match_dup 1))
5443    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5444               (clobber (reg:CC FLAGS_REG))])])
5446 ;; Convert add to the lea pattern to avoid flags dependency.
5447 (define_split
5448   [(set (match_operand:SWI 0 "register_operand")
5449         (plus:SWI (match_operand:SWI 1 "register_operand")
5450                   (match_operand:SWI 2 "<nonmemory_operand>")))
5451    (clobber (reg:CC FLAGS_REG))]
5452   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5453   [(const_int 0)]
5455   machine_mode mode = <MODE>mode;
5456   rtx pat;
5458   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
5459     { 
5460       mode = SImode; 
5461       operands[0] = gen_lowpart (mode, operands[0]);
5462       operands[1] = gen_lowpart (mode, operands[1]);
5463       operands[2] = gen_lowpart (mode, operands[2]);
5464     }
5466   pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5468   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5469   DONE;
5472 ;; Split non destructive adds if we cannot use lea.
5473 (define_split
5474   [(set (match_operand:DI 0 "register_operand")
5475         (zero_extend:DI
5476           (plus:SI (match_operand:SI 1 "register_operand")
5477                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5478    (clobber (reg:CC FLAGS_REG))]
5479   "TARGET_64BIT
5480    && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5481   [(set (match_dup 3) (match_dup 1))
5482    (parallel [(set (match_dup 0)
5483                    (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5484               (clobber (reg:CC FLAGS_REG))])]
5485   "operands[3] = gen_lowpart (SImode, operands[0]);")
5487 ;; Convert add to the lea pattern to avoid flags dependency.
5488 (define_split
5489   [(set (match_operand:DI 0 "register_operand")
5490         (zero_extend:DI
5491           (plus:SI (match_operand:SI 1 "register_operand")
5492                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5493    (clobber (reg:CC FLAGS_REG))]
5494   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5495   [(set (match_dup 0)
5496         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5498 (define_insn "*add<mode>_2"
5499   [(set (reg FLAGS_REG)
5500         (compare
5501           (plus:SWI
5502             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5503             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5504           (const_int 0)))
5505    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5506         (plus:SWI (match_dup 1) (match_dup 2)))]
5507   "ix86_match_ccmode (insn, CCGOCmode)
5508    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5510   switch (get_attr_type (insn))
5511     {
5512     case TYPE_INCDEC:
5513       if (operands[2] == const1_rtx)
5514         return "inc{<imodesuffix>}\t%0";
5515       else
5516         {
5517           gcc_assert (operands[2] == constm1_rtx);
5518           return "dec{<imodesuffix>}\t%0";
5519         }
5521     default:
5522       if (which_alternative == 2)
5523         {
5524           rtx tmp;
5525           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5526         }
5527         
5528       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5529       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5530         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5532       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5533     }
5535   [(set (attr "type")
5536      (if_then_else (match_operand:SWI 2 "incdec_operand")
5537         (const_string "incdec")
5538         (const_string "alu")))
5539    (set (attr "length_immediate")
5540       (if_then_else
5541         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5542         (const_string "1")
5543         (const_string "*")))
5544    (set_attr "mode" "<MODE>")])
5546 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5547 (define_insn "*addsi_2_zext"
5548   [(set (reg FLAGS_REG)
5549         (compare
5550           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5551                    (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5552           (const_int 0)))
5553    (set (match_operand:DI 0 "register_operand" "=r,r")
5554         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5555   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5556    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5558   switch (get_attr_type (insn))
5559     {
5560     case TYPE_INCDEC:
5561       if (operands[2] == const1_rtx)
5562         return "inc{l}\t%k0";
5563       else
5564         {
5565           gcc_assert (operands[2] == constm1_rtx);
5566           return "dec{l}\t%k0";
5567         }
5569     default:
5570       if (which_alternative == 1)
5571         {
5572           rtx tmp;
5573           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5574         }
5576       if (x86_maybe_negate_const_int (&operands[2], SImode))
5577         return "sub{l}\t{%2, %k0|%k0, %2}";
5579       return "add{l}\t{%2, %k0|%k0, %2}";
5580     }
5582   [(set (attr "type")
5583      (if_then_else (match_operand:SI 2 "incdec_operand")
5584         (const_string "incdec")
5585         (const_string "alu")))
5586    (set (attr "length_immediate")
5587       (if_then_else
5588         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5589         (const_string "1")
5590         (const_string "*")))
5591    (set_attr "mode" "SI")])
5593 (define_insn "*add<mode>_3"
5594   [(set (reg FLAGS_REG)
5595         (compare
5596           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5597           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5598    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5599   "ix86_match_ccmode (insn, CCZmode)
5600    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5602   switch (get_attr_type (insn))
5603     {
5604     case TYPE_INCDEC:
5605       if (operands[2] == const1_rtx)
5606         return "inc{<imodesuffix>}\t%0";
5607       else
5608         {
5609           gcc_assert (operands[2] == constm1_rtx);
5610           return "dec{<imodesuffix>}\t%0";
5611         }
5613     default:
5614       if (which_alternative == 1)
5615         {
5616           rtx tmp;
5617           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5618         }
5620       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5621       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5622         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5624       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5625     }
5627   [(set (attr "type")
5628      (if_then_else (match_operand:SWI 2 "incdec_operand")
5629         (const_string "incdec")
5630         (const_string "alu")))
5631    (set (attr "length_immediate")
5632       (if_then_else
5633         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5634         (const_string "1")
5635         (const_string "*")))
5636    (set_attr "mode" "<MODE>")])
5638 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5639 (define_insn "*addsi_3_zext"
5640   [(set (reg FLAGS_REG)
5641         (compare
5642           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5643           (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5644    (set (match_operand:DI 0 "register_operand" "=r,r")
5645         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5646   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5647    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5649   switch (get_attr_type (insn))
5650     {
5651     case TYPE_INCDEC:
5652       if (operands[2] == const1_rtx)
5653         return "inc{l}\t%k0";
5654       else
5655         {
5656           gcc_assert (operands[2] == constm1_rtx);
5657           return "dec{l}\t%k0";
5658         }
5660     default:
5661       if (which_alternative == 1)
5662         {
5663           rtx tmp;
5664           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5665         }
5667       if (x86_maybe_negate_const_int (&operands[2], SImode))
5668         return "sub{l}\t{%2, %k0|%k0, %2}";
5670       return "add{l}\t{%2, %k0|%k0, %2}";
5671     }
5673   [(set (attr "type")
5674      (if_then_else (match_operand:SI 2 "incdec_operand")
5675         (const_string "incdec")
5676         (const_string "alu")))
5677    (set (attr "length_immediate")
5678       (if_then_else
5679         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5680         (const_string "1")
5681         (const_string "*")))
5682    (set_attr "mode" "SI")])
5684 ; For comparisons against 1, -1 and 128, we may generate better code
5685 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5686 ; is matched then.  We can't accept general immediate, because for
5687 ; case of overflows,  the result is messed up.
5688 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5689 ; only for comparisons not depending on it.
5691 (define_insn "*adddi_4"
5692   [(set (reg FLAGS_REG)
5693         (compare
5694           (match_operand:DI 1 "nonimmediate_operand" "0")
5695           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5696    (clobber (match_scratch:DI 0 "=rm"))]
5697   "TARGET_64BIT
5698    && ix86_match_ccmode (insn, CCGCmode)"
5700   switch (get_attr_type (insn))
5701     {
5702     case TYPE_INCDEC:
5703       if (operands[2] == constm1_rtx)
5704         return "inc{q}\t%0";
5705       else
5706         {
5707           gcc_assert (operands[2] == const1_rtx);
5708           return "dec{q}\t%0";
5709         }
5711     default:
5712       if (x86_maybe_negate_const_int (&operands[2], DImode))
5713         return "add{q}\t{%2, %0|%0, %2}";
5715       return "sub{q}\t{%2, %0|%0, %2}";
5716     }
5718   [(set (attr "type")
5719      (if_then_else (match_operand:DI 2 "incdec_operand")
5720         (const_string "incdec")
5721         (const_string "alu")))
5722    (set (attr "length_immediate")
5723       (if_then_else
5724         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5725         (const_string "1")
5726         (const_string "*")))
5727    (set_attr "mode" "DI")])
5729 ; For comparisons against 1, -1 and 128, we may generate better code
5730 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5731 ; is matched then.  We can't accept general immediate, because for
5732 ; case of overflows,  the result is messed up.
5733 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5734 ; only for comparisons not depending on it.
5736 (define_insn "*add<mode>_4"
5737   [(set (reg FLAGS_REG)
5738         (compare
5739           (match_operand:SWI124 1 "nonimmediate_operand" "0")
5740           (match_operand:SWI124 2 "const_int_operand" "n")))
5741    (clobber (match_scratch:SWI124 0 "=<r>m"))]
5742   "ix86_match_ccmode (insn, CCGCmode)"
5744   switch (get_attr_type (insn))
5745     {
5746     case TYPE_INCDEC:
5747       if (operands[2] == constm1_rtx)
5748         return "inc{<imodesuffix>}\t%0";
5749       else
5750         {
5751           gcc_assert (operands[2] == const1_rtx);
5752           return "dec{<imodesuffix>}\t%0";
5753         }
5755     default:
5756       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5757         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5759       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5760     }
5762   [(set (attr "type")
5763      (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5764         (const_string "incdec")
5765         (const_string "alu")))
5766    (set (attr "length_immediate")
5767       (if_then_else
5768         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5769         (const_string "1")
5770         (const_string "*")))
5771    (set_attr "mode" "<MODE>")])
5773 (define_insn "*add<mode>_5"
5774   [(set (reg FLAGS_REG)
5775         (compare
5776           (plus:SWI
5777             (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5778             (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5779           (const_int 0)))
5780    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5781   "ix86_match_ccmode (insn, CCGOCmode)
5782    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5784   switch (get_attr_type (insn))
5785     {
5786     case TYPE_INCDEC:
5787       if (operands[2] == const1_rtx)
5788         return "inc{<imodesuffix>}\t%0";
5789       else
5790         {
5791           gcc_assert (operands[2] == constm1_rtx);
5792           return "dec{<imodesuffix>}\t%0";
5793         }
5795     default:
5796       if (which_alternative == 1)
5797         {
5798           rtx tmp;
5799           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5800         }
5802       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5803       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5804         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5806       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5807     }
5809   [(set (attr "type")
5810      (if_then_else (match_operand:SWI 2 "incdec_operand")
5811         (const_string "incdec")
5812         (const_string "alu")))
5813    (set (attr "length_immediate")
5814       (if_then_else
5815         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5816         (const_string "1")
5817         (const_string "*")))
5818    (set_attr "mode" "<MODE>")])
5820 (define_insn "addqi_ext_1"
5821   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
5822                          (const_int 8)
5823                          (const_int 8))
5824         (plus:SI
5825           (zero_extract:SI
5826             (match_operand 1 "ext_register_operand" "0,0")
5827             (const_int 8)
5828             (const_int 8))
5829           (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
5830    (clobber (reg:CC FLAGS_REG))]
5831   ""
5833   switch (get_attr_type (insn))
5834     {
5835     case TYPE_INCDEC:
5836       if (operands[2] == const1_rtx)
5837         return "inc{b}\t%h0";
5838       else
5839         {
5840           gcc_assert (operands[2] == constm1_rtx);
5841           return "dec{b}\t%h0";
5842         }
5844     default:
5845       return "add{b}\t{%2, %h0|%h0, %2}";
5846     }
5848   [(set_attr "isa" "*,nox64")
5849    (set (attr "type")
5850      (if_then_else (match_operand:QI 2 "incdec_operand")
5851         (const_string "incdec")
5852         (const_string "alu")))
5853    (set_attr "modrm" "1")
5854    (set_attr "mode" "QI")])
5856 (define_insn "*addqi_ext_2"
5857   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5858                          (const_int 8)
5859                          (const_int 8))
5860         (plus:SI
5861           (zero_extract:SI
5862             (match_operand 1 "ext_register_operand" "%0")
5863             (const_int 8)
5864             (const_int 8))
5865           (zero_extract:SI
5866             (match_operand 2 "ext_register_operand" "Q")
5867             (const_int 8)
5868             (const_int 8))))
5869    (clobber (reg:CC FLAGS_REG))]
5870   ""
5871   "add{b}\t{%h2, %h0|%h0, %h2}"
5872   [(set_attr "type" "alu")
5873    (set_attr "mode" "QI")])
5875 ;; Add with jump on overflow.
5876 (define_expand "addv<mode>4"
5877   [(parallel [(set (reg:CCO FLAGS_REG)
5878                    (eq:CCO (plus:<DWI>
5879                               (sign_extend:<DWI>
5880                                  (match_operand:SWI 1 "nonimmediate_operand"))
5881                               (match_dup 4))
5882                            (sign_extend:<DWI>
5883                               (plus:SWI (match_dup 1)
5884                                         (match_operand:SWI 2
5885                                            "<general_operand>")))))
5886               (set (match_operand:SWI 0 "register_operand")
5887                    (plus:SWI (match_dup 1) (match_dup 2)))])
5888    (set (pc) (if_then_else
5889                (eq (reg:CCO FLAGS_REG) (const_int 0))
5890                (label_ref (match_operand 3))
5891                (pc)))]
5892   ""
5894   ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
5895   if (CONST_INT_P (operands[2]))
5896     operands[4] = operands[2];
5897   else
5898     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
5901 (define_insn "*addv<mode>4"
5902   [(set (reg:CCO FLAGS_REG)
5903         (eq:CCO (plus:<DWI>
5904                    (sign_extend:<DWI>
5905                       (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
5906                    (sign_extend:<DWI>
5907                       (match_operand:SWI 2 "<general_sext_operand>"
5908                                            "<r>mWe,<r>We")))
5909                 (sign_extend:<DWI>
5910                    (plus:SWI (match_dup 1) (match_dup 2)))))
5911    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5912         (plus:SWI (match_dup 1) (match_dup 2)))]
5913   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5914   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5915   [(set_attr "type" "alu")
5916    (set_attr "mode" "<MODE>")])
5918 (define_insn "*addv<mode>4_1"
5919   [(set (reg:CCO FLAGS_REG)
5920         (eq:CCO (plus:<DWI>
5921                    (sign_extend:<DWI>
5922                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
5923                    (match_operand:<DWI> 3 "const_int_operand" "i"))
5924                 (sign_extend:<DWI>
5925                    (plus:SWI (match_dup 1)
5926                              (match_operand:SWI 2 "x86_64_immediate_operand"
5927                                                   "<i>")))))
5928    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
5929         (plus:SWI (match_dup 1) (match_dup 2)))]
5930   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
5931    && CONST_INT_P (operands[2])
5932    && INTVAL (operands[2]) == INTVAL (operands[3])"
5933   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5934   [(set_attr "type" "alu")
5935    (set_attr "mode" "<MODE>")
5936    (set (attr "length_immediate")
5937         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
5938                   (const_string "1")
5939                (match_test "<MODE_SIZE> == 8")
5940                   (const_string "4")]
5941               (const_string "<MODE_SIZE>")))])
5943 ;; The lea patterns for modes less than 32 bits need to be matched by
5944 ;; several insns converted to real lea by splitters.
5946 (define_insn_and_split "*lea_general_1"
5947   [(set (match_operand 0 "register_operand" "=r")
5948         (plus (plus (match_operand 1 "index_register_operand" "l")
5949                     (match_operand 2 "register_operand" "r"))
5950               (match_operand 3 "immediate_operand" "i")))]
5951   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5952    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5953    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5954    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5955    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5956        || GET_MODE (operands[3]) == VOIDmode)"
5957   "#"
5958   "&& reload_completed"
5959   [(const_int 0)]
5961   machine_mode mode = SImode;
5962   rtx pat;
5964   operands[0] = gen_lowpart (mode, operands[0]);
5965   operands[1] = gen_lowpart (mode, operands[1]);
5966   operands[2] = gen_lowpart (mode, operands[2]);
5967   operands[3] = gen_lowpart (mode, operands[3]);
5969   pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
5970                       operands[3]);
5972   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5973   DONE;
5975   [(set_attr "type" "lea")
5976    (set_attr "mode" "SI")])
5978 (define_insn_and_split "*lea_general_2"
5979   [(set (match_operand 0 "register_operand" "=r")
5980         (plus (mult (match_operand 1 "index_register_operand" "l")
5981                     (match_operand 2 "const248_operand" "n"))
5982               (match_operand 3 "nonmemory_operand" "ri")))]
5983   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5984    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5985    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5986    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5987        || GET_MODE (operands[3]) == VOIDmode)"
5988   "#"
5989   "&& reload_completed"
5990   [(const_int 0)]
5992   machine_mode mode = SImode;
5993   rtx pat;
5995   operands[0] = gen_lowpart (mode, operands[0]);
5996   operands[1] = gen_lowpart (mode, operands[1]);
5997   operands[3] = gen_lowpart (mode, operands[3]);
5999   pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6000                       operands[3]);
6002   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6003   DONE;
6005   [(set_attr "type" "lea")
6006    (set_attr "mode" "SI")])
6008 (define_insn_and_split "*lea_general_3"
6009   [(set (match_operand 0 "register_operand" "=r")
6010         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6011                           (match_operand 2 "const248_operand" "n"))
6012                     (match_operand 3 "register_operand" "r"))
6013               (match_operand 4 "immediate_operand" "i")))]
6014   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6015    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6016    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6017    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6018   "#"
6019   "&& reload_completed"
6020   [(const_int 0)]
6022   machine_mode mode = SImode;
6023   rtx pat;
6025   operands[0] = gen_lowpart (mode, operands[0]);
6026   operands[1] = gen_lowpart (mode, operands[1]);
6027   operands[3] = gen_lowpart (mode, operands[3]);
6028   operands[4] = gen_lowpart (mode, operands[4]);
6030   pat = gen_rtx_PLUS (mode,
6031                       gen_rtx_PLUS (mode,
6032                                     gen_rtx_MULT (mode, operands[1],
6033                                                         operands[2]),
6034                                     operands[3]),
6035                       operands[4]);
6037   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6038   DONE;
6040   [(set_attr "type" "lea")
6041    (set_attr "mode" "SI")])
6043 (define_insn_and_split "*lea_general_4"
6044   [(set (match_operand 0 "register_operand" "=r")
6045         (any_or (ashift
6046                   (match_operand 1 "index_register_operand" "l")
6047                   (match_operand 2 "const_int_operand" "n"))
6048                 (match_operand 3 "const_int_operand" "n")))]
6049   "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6050       && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6051     || GET_MODE (operands[0]) == SImode
6052     || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6053    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6054    && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6055    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6056        < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6057   "#"
6058   "&& reload_completed"
6059   [(const_int 0)]
6061   machine_mode mode = GET_MODE (operands[0]);
6062   rtx pat;
6064   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6065     { 
6066       mode = SImode; 
6067       operands[0] = gen_lowpart (mode, operands[0]);
6068       operands[1] = gen_lowpart (mode, operands[1]);
6069     }
6071   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6073   pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6074                        INTVAL (operands[3]));
6076   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6077   DONE;
6079   [(set_attr "type" "lea")
6080    (set (attr "mode")
6081       (if_then_else (match_operand:DI 0)
6082         (const_string "DI")
6083         (const_string "SI")))])
6085 ;; Subtract instructions
6087 (define_expand "sub<mode>3"
6088   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6089         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6090                      (match_operand:SDWIM 2 "<general_operand>")))]
6091   ""
6092   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6094 (define_insn_and_split "*sub<dwi>3_doubleword"
6095   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6096         (minus:<DWI>
6097           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6098           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6099    (clobber (reg:CC FLAGS_REG))]
6100   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6101   "#"
6102   "reload_completed"
6103   [(parallel [(set (reg:CC FLAGS_REG)
6104                    (compare:CC (match_dup 1) (match_dup 2)))
6105               (set (match_dup 0)
6106                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6107    (parallel [(set (match_dup 3)
6108                    (minus:DWIH
6109                      (match_dup 4)
6110                      (plus:DWIH
6111                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6112                        (match_dup 5))))
6113               (clobber (reg:CC FLAGS_REG))])]
6114   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6116 (define_insn "*sub<mode>_1"
6117   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6118         (minus:SWI
6119           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6120           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6121    (clobber (reg:CC FLAGS_REG))]
6122   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6123   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6124   [(set_attr "type" "alu")
6125    (set_attr "mode" "<MODE>")])
6127 (define_insn "*subsi_1_zext"
6128   [(set (match_operand:DI 0 "register_operand" "=r")
6129         (zero_extend:DI
6130           (minus:SI (match_operand:SI 1 "register_operand" "0")
6131                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6132    (clobber (reg:CC FLAGS_REG))]
6133   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6134   "sub{l}\t{%2, %k0|%k0, %2}"
6135   [(set_attr "type" "alu")
6136    (set_attr "mode" "SI")])
6138 (define_insn "*subqi_1_slp"
6139   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6140         (minus:QI (match_dup 0)
6141                   (match_operand:QI 1 "general_operand" "qn,qm")))
6142    (clobber (reg:CC FLAGS_REG))]
6143   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6144    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6145   "sub{b}\t{%1, %0|%0, %1}"
6146   [(set_attr "type" "alu1")
6147    (set_attr "mode" "QI")])
6149 (define_insn "*sub<mode>_2"
6150   [(set (reg FLAGS_REG)
6151         (compare
6152           (minus:SWI
6153             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6154             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6155           (const_int 0)))
6156    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6157         (minus:SWI (match_dup 1) (match_dup 2)))]
6158   "ix86_match_ccmode (insn, CCGOCmode)
6159    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6160   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6161   [(set_attr "type" "alu")
6162    (set_attr "mode" "<MODE>")])
6164 (define_insn "*subsi_2_zext"
6165   [(set (reg FLAGS_REG)
6166         (compare
6167           (minus:SI (match_operand:SI 1 "register_operand" "0")
6168                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6169           (const_int 0)))
6170    (set (match_operand:DI 0 "register_operand" "=r")
6171         (zero_extend:DI
6172           (minus:SI (match_dup 1)
6173                     (match_dup 2))))]
6174   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6175    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6176   "sub{l}\t{%2, %k0|%k0, %2}"
6177   [(set_attr "type" "alu")
6178    (set_attr "mode" "SI")])
6180 ;; Subtract with jump on overflow.
6181 (define_expand "subv<mode>4"
6182   [(parallel [(set (reg:CCO FLAGS_REG)
6183                    (eq:CCO (minus:<DWI>
6184                               (sign_extend:<DWI>
6185                                  (match_operand:SWI 1 "nonimmediate_operand"))
6186                               (match_dup 4))
6187                            (sign_extend:<DWI>
6188                               (minus:SWI (match_dup 1)
6189                                          (match_operand:SWI 2
6190                                             "<general_operand>")))))
6191               (set (match_operand:SWI 0 "register_operand")
6192                    (minus:SWI (match_dup 1) (match_dup 2)))])
6193    (set (pc) (if_then_else
6194                (eq (reg:CCO FLAGS_REG) (const_int 0))
6195                (label_ref (match_operand 3))
6196                (pc)))]
6197   ""
6199   ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6200   if (CONST_INT_P (operands[2]))
6201     operands[4] = operands[2];
6202   else
6203     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6206 (define_insn "*subv<mode>4"
6207   [(set (reg:CCO FLAGS_REG)
6208         (eq:CCO (minus:<DWI>
6209                    (sign_extend:<DWI>
6210                       (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6211                    (sign_extend:<DWI>
6212                       (match_operand:SWI 2 "<general_sext_operand>"
6213                                            "<r>We,<r>m")))
6214                 (sign_extend:<DWI>
6215                    (minus:SWI (match_dup 1) (match_dup 2)))))
6216    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6217         (minus:SWI (match_dup 1) (match_dup 2)))]
6218   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6219   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6220   [(set_attr "type" "alu")
6221    (set_attr "mode" "<MODE>")])
6223 (define_insn "*subv<mode>4_1"
6224   [(set (reg:CCO FLAGS_REG)
6225         (eq:CCO (minus:<DWI>
6226                    (sign_extend:<DWI>
6227                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
6228                    (match_operand:<DWI> 3 "const_int_operand" "i"))
6229                 (sign_extend:<DWI>
6230                    (minus:SWI (match_dup 1)
6231                               (match_operand:SWI 2 "x86_64_immediate_operand"
6232                                                    "<i>")))))
6233    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6234         (minus:SWI (match_dup 1) (match_dup 2)))]
6235   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6236    && CONST_INT_P (operands[2])
6237    && INTVAL (operands[2]) == INTVAL (operands[3])"
6238   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6239   [(set_attr "type" "alu")
6240    (set_attr "mode" "<MODE>")
6241    (set (attr "length_immediate")
6242         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6243                   (const_string "1")
6244                (match_test "<MODE_SIZE> == 8")
6245                   (const_string "4")]
6246               (const_string "<MODE_SIZE>")))])
6248 (define_insn "*sub<mode>_3"
6249   [(set (reg FLAGS_REG)
6250         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6251                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6252    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6253         (minus:SWI (match_dup 1) (match_dup 2)))]
6254   "ix86_match_ccmode (insn, CCmode)
6255    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6256   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6257   [(set_attr "type" "alu")
6258    (set_attr "mode" "<MODE>")])
6260 (define_insn "*subsi_3_zext"
6261   [(set (reg FLAGS_REG)
6262         (compare (match_operand:SI 1 "register_operand" "0")
6263                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6264    (set (match_operand:DI 0 "register_operand" "=r")
6265         (zero_extend:DI
6266           (minus:SI (match_dup 1)
6267                     (match_dup 2))))]
6268   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6269    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6270   "sub{l}\t{%2, %1|%1, %2}"
6271   [(set_attr "type" "alu")
6272    (set_attr "mode" "SI")])
6274 ;; Add with carry and subtract with borrow
6276 (define_expand "<plusminus_insn><mode>3_carry"
6277   [(parallel
6278     [(set (match_operand:SWI 0 "nonimmediate_operand")
6279           (plusminus:SWI
6280             (match_operand:SWI 1 "nonimmediate_operand")
6281             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6282                        [(match_operand 3 "flags_reg_operand")
6283                         (const_int 0)])
6284                       (match_operand:SWI 2 "<general_operand>"))))
6285      (clobber (reg:CC FLAGS_REG))])]
6286   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6288 (define_insn "*<plusminus_insn><mode>3_carry"
6289   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6290         (plusminus:SWI
6291           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6292           (plus:SWI
6293             (match_operator 3 "ix86_carry_flag_operator"
6294              [(reg FLAGS_REG) (const_int 0)])
6295             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6296    (clobber (reg:CC FLAGS_REG))]
6297   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6298   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6299   [(set_attr "type" "alu")
6300    (set_attr "use_carry" "1")
6301    (set_attr "pent_pair" "pu")
6302    (set_attr "mode" "<MODE>")])
6304 (define_insn "*addsi3_carry_zext"
6305   [(set (match_operand:DI 0 "register_operand" "=r")
6306         (zero_extend:DI
6307           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6308                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6309                              [(reg FLAGS_REG) (const_int 0)])
6310                             (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6311    (clobber (reg:CC FLAGS_REG))]
6312   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6313   "adc{l}\t{%2, %k0|%k0, %2}"
6314   [(set_attr "type" "alu")
6315    (set_attr "use_carry" "1")
6316    (set_attr "pent_pair" "pu")
6317    (set_attr "mode" "SI")])
6319 (define_insn "*subsi3_carry_zext"
6320   [(set (match_operand:DI 0 "register_operand" "=r")
6321         (zero_extend:DI
6322           (minus:SI (match_operand:SI 1 "register_operand" "0")
6323                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6324                               [(reg FLAGS_REG) (const_int 0)])
6325                              (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6326    (clobber (reg:CC FLAGS_REG))]
6327   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6328   "sbb{l}\t{%2, %k0|%k0, %2}"
6329   [(set_attr "type" "alu")
6330    (set_attr "pent_pair" "pu")
6331    (set_attr "mode" "SI")])
6333 ;; ADCX instruction
6335 (define_insn "adcx<mode>3"
6336   [(set (reg:CCC FLAGS_REG)
6337         (compare:CCC
6338           (plus:SWI48
6339             (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6340             (plus:SWI48
6341               (match_operator 4 "ix86_carry_flag_operator"
6342                [(match_operand 3 "flags_reg_operand") (const_int 0)])
6343               (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6344           (const_int 0)))
6345    (set (match_operand:SWI48 0 "register_operand" "=r")
6346         (plus:SWI48 (match_dup 1)
6347                     (plus:SWI48 (match_op_dup 4
6348                                  [(match_dup 3) (const_int 0)])
6349                                 (match_dup 2))))]
6350   "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6351   "adcx\t{%2, %0|%0, %2}"
6352   [(set_attr "type" "alu")
6353    (set_attr "use_carry" "1")
6354    (set_attr "mode" "<MODE>")])
6356 ;; Overflow setting add instructions
6358 (define_insn "*add<mode>3_cconly_overflow"
6359   [(set (reg:CCC FLAGS_REG)
6360         (compare:CCC
6361           (plus:SWI
6362             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6363             (match_operand:SWI 2 "<general_operand>" "<g>"))
6364           (match_dup 1)))
6365    (clobber (match_scratch:SWI 0 "=<r>"))]
6366   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6367   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6368   [(set_attr "type" "alu")
6369    (set_attr "mode" "<MODE>")])
6371 (define_insn "*add<mode>3_cc_overflow"
6372   [(set (reg:CCC FLAGS_REG)
6373         (compare:CCC
6374             (plus:SWI
6375                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6376                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6377             (match_dup 1)))
6378    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6379         (plus:SWI (match_dup 1) (match_dup 2)))]
6380   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6381   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6382   [(set_attr "type" "alu")
6383    (set_attr "mode" "<MODE>")])
6385 (define_insn "*addsi3_zext_cc_overflow"
6386   [(set (reg:CCC FLAGS_REG)
6387         (compare:CCC
6388           (plus:SI
6389             (match_operand:SI 1 "nonimmediate_operand" "%0")
6390             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6391           (match_dup 1)))
6392    (set (match_operand:DI 0 "register_operand" "=r")
6393         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6394   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6395   "add{l}\t{%2, %k0|%k0, %2}"
6396   [(set_attr "type" "alu")
6397    (set_attr "mode" "SI")])
6399 ;; The patterns that match these are at the end of this file.
6401 (define_expand "<plusminus_insn>xf3"
6402   [(set (match_operand:XF 0 "register_operand")
6403         (plusminus:XF
6404           (match_operand:XF 1 "register_operand")
6405           (match_operand:XF 2 "register_operand")))]
6406   "TARGET_80387")
6408 (define_expand "<plusminus_insn><mode>3"
6409   [(set (match_operand:MODEF 0 "register_operand")
6410         (plusminus:MODEF
6411           (match_operand:MODEF 1 "register_operand")
6412           (match_operand:MODEF 2 "nonimmediate_operand")))]
6413   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6414     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6416 ;; Multiply instructions
6418 (define_expand "mul<mode>3"
6419   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6420                    (mult:SWIM248
6421                      (match_operand:SWIM248 1 "register_operand")
6422                      (match_operand:SWIM248 2 "<general_operand>")))
6423               (clobber (reg:CC FLAGS_REG))])])
6425 (define_expand "mulqi3"
6426   [(parallel [(set (match_operand:QI 0 "register_operand")
6427                    (mult:QI
6428                      (match_operand:QI 1 "register_operand")
6429                      (match_operand:QI 2 "nonimmediate_operand")))
6430               (clobber (reg:CC FLAGS_REG))])]
6431   "TARGET_QIMODE_MATH")
6433 ;; On AMDFAM10
6434 ;; IMUL reg32/64, reg32/64, imm8        Direct
6435 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6436 ;; IMUL reg32/64, reg32/64, imm32       Direct
6437 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6438 ;; IMUL reg32/64, reg32/64              Direct
6439 ;; IMUL reg32/64, mem32/64              Direct
6441 ;; On BDVER1, all above IMULs use DirectPath
6443 (define_insn "*mul<mode>3_1"
6444   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6445         (mult:SWI48
6446           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6447           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6448    (clobber (reg:CC FLAGS_REG))]
6449   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6450   "@
6451    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6452    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6453    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6454   [(set_attr "type" "imul")
6455    (set_attr "prefix_0f" "0,0,1")
6456    (set (attr "athlon_decode")
6457         (cond [(eq_attr "cpu" "athlon")
6458                   (const_string "vector")
6459                (eq_attr "alternative" "1")
6460                   (const_string "vector")
6461                (and (eq_attr "alternative" "2")
6462                     (match_operand 1 "memory_operand"))
6463                   (const_string "vector")]
6464               (const_string "direct")))
6465    (set (attr "amdfam10_decode")
6466         (cond [(and (eq_attr "alternative" "0,1")
6467                     (match_operand 1 "memory_operand"))
6468                   (const_string "vector")]
6469               (const_string "direct")))
6470    (set_attr "bdver1_decode" "direct")
6471    (set_attr "mode" "<MODE>")])
6473 (define_insn "*mulsi3_1_zext"
6474   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6475         (zero_extend:DI
6476           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6477                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6478    (clobber (reg:CC FLAGS_REG))]
6479   "TARGET_64BIT
6480    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6481   "@
6482    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6483    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6484    imul{l}\t{%2, %k0|%k0, %2}"
6485   [(set_attr "type" "imul")
6486    (set_attr "prefix_0f" "0,0,1")
6487    (set (attr "athlon_decode")
6488         (cond [(eq_attr "cpu" "athlon")
6489                   (const_string "vector")
6490                (eq_attr "alternative" "1")
6491                   (const_string "vector")
6492                (and (eq_attr "alternative" "2")
6493                     (match_operand 1 "memory_operand"))
6494                   (const_string "vector")]
6495               (const_string "direct")))
6496    (set (attr "amdfam10_decode")
6497         (cond [(and (eq_attr "alternative" "0,1")
6498                     (match_operand 1 "memory_operand"))
6499                   (const_string "vector")]
6500               (const_string "direct")))
6501    (set_attr "bdver1_decode" "direct")
6502    (set_attr "mode" "SI")])
6504 ;; On AMDFAM10
6505 ;; IMUL reg16, reg16, imm8      VectorPath
6506 ;; IMUL reg16, mem16, imm8      VectorPath
6507 ;; IMUL reg16, reg16, imm16     VectorPath
6508 ;; IMUL reg16, mem16, imm16     VectorPath
6509 ;; IMUL reg16, reg16            Direct
6510 ;; IMUL reg16, mem16            Direct
6512 ;; On BDVER1, all HI MULs use DoublePath
6514 (define_insn "*mulhi3_1"
6515   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6516         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6517                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6518    (clobber (reg:CC FLAGS_REG))]
6519   "TARGET_HIMODE_MATH
6520    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6521   "@
6522    imul{w}\t{%2, %1, %0|%0, %1, %2}
6523    imul{w}\t{%2, %1, %0|%0, %1, %2}
6524    imul{w}\t{%2, %0|%0, %2}"
6525   [(set_attr "type" "imul")
6526    (set_attr "prefix_0f" "0,0,1")
6527    (set (attr "athlon_decode")
6528         (cond [(eq_attr "cpu" "athlon")
6529                   (const_string "vector")
6530                (eq_attr "alternative" "1,2")
6531                   (const_string "vector")]
6532               (const_string "direct")))
6533    (set (attr "amdfam10_decode")
6534         (cond [(eq_attr "alternative" "0,1")
6535                   (const_string "vector")]
6536               (const_string "direct")))
6537    (set_attr "bdver1_decode" "double")
6538    (set_attr "mode" "HI")])
6540 ;;On AMDFAM10 and BDVER1
6541 ;; MUL reg8     Direct
6542 ;; MUL mem8     Direct
6544 (define_insn "*mulqi3_1"
6545   [(set (match_operand:QI 0 "register_operand" "=a")
6546         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6547                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6548    (clobber (reg:CC FLAGS_REG))]
6549   "TARGET_QIMODE_MATH
6550    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6551   "mul{b}\t%2"
6552   [(set_attr "type" "imul")
6553    (set_attr "length_immediate" "0")
6554    (set (attr "athlon_decode")
6555      (if_then_else (eq_attr "cpu" "athlon")
6556         (const_string "vector")
6557         (const_string "direct")))
6558    (set_attr "amdfam10_decode" "direct")
6559    (set_attr "bdver1_decode" "direct")
6560    (set_attr "mode" "QI")])
6562 ;; Multiply with jump on overflow.
6563 (define_expand "mulv<mode>4"
6564   [(parallel [(set (reg:CCO FLAGS_REG)
6565                    (eq:CCO (mult:<DWI>
6566                               (sign_extend:<DWI>
6567                                  (match_operand:SWI48 1 "register_operand"))
6568                               (match_dup 4))
6569                            (sign_extend:<DWI>
6570                               (mult:SWI48 (match_dup 1)
6571                                           (match_operand:SWI48 2
6572                                              "<general_operand>")))))
6573               (set (match_operand:SWI48 0 "register_operand")
6574                    (mult:SWI48 (match_dup 1) (match_dup 2)))])
6575    (set (pc) (if_then_else
6576                (eq (reg:CCO FLAGS_REG) (const_int 0))
6577                (label_ref (match_operand 3))
6578                (pc)))]
6579   ""
6581   if (CONST_INT_P (operands[2]))
6582     operands[4] = operands[2];
6583   else
6584     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6587 (define_insn "*mulv<mode>4"
6588   [(set (reg:CCO FLAGS_REG)
6589         (eq:CCO (mult:<DWI>
6590                    (sign_extend:<DWI>
6591                       (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6592                    (sign_extend:<DWI>
6593                       (match_operand:SWI48 2 "<general_sext_operand>"
6594                                              "We,mr")))
6595                 (sign_extend:<DWI>
6596                    (mult:SWI48 (match_dup 1) (match_dup 2)))))
6597    (set (match_operand:SWI48 0 "register_operand" "=r,r")
6598         (mult:SWI48 (match_dup 1) (match_dup 2)))]
6599   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6600   "@
6601    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6602    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6603   [(set_attr "type" "imul")
6604    (set_attr "prefix_0f" "0,1")
6605    (set (attr "athlon_decode")
6606         (cond [(eq_attr "cpu" "athlon")
6607                   (const_string "vector")
6608                (eq_attr "alternative" "0")
6609                   (const_string "vector")
6610                (and (eq_attr "alternative" "1")
6611                     (match_operand 1 "memory_operand"))
6612                   (const_string "vector")]
6613               (const_string "direct")))
6614    (set (attr "amdfam10_decode")
6615         (cond [(and (eq_attr "alternative" "1")
6616                     (match_operand 1 "memory_operand"))
6617                   (const_string "vector")]
6618               (const_string "direct")))
6619    (set_attr "bdver1_decode" "direct")
6620    (set_attr "mode" "<MODE>")])
6622 (define_insn "*mulv<mode>4_1"
6623   [(set (reg:CCO FLAGS_REG)
6624         (eq:CCO (mult:<DWI>
6625                    (sign_extend:<DWI>
6626                       (match_operand:SWI48 1 "nonimmediate_operand" "rm,rm"))
6627                    (match_operand:<DWI> 3 "const_int_operand" "K,i"))
6628                 (sign_extend:<DWI>
6629                    (mult:SWI48 (match_dup 1)
6630                                (match_operand:SWI 2 "x86_64_immediate_operand"
6631                                                     "K,<i>")))))
6632    (set (match_operand:SWI48 0 "register_operand" "=r,r")
6633         (mult:SWI48 (match_dup 1) (match_dup 2)))]
6634   "!(MEM_P (operands[1]) && MEM_P (operands[2]))
6635    && CONST_INT_P (operands[2])
6636    && INTVAL (operands[2]) == INTVAL (operands[3])"
6637   "@
6638    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6639    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6640   [(set_attr "type" "imul")
6641    (set (attr "athlon_decode")
6642         (cond [(eq_attr "cpu" "athlon")
6643                   (const_string "vector")
6644                (eq_attr "alternative" "1")
6645                   (const_string "vector")]
6646               (const_string "direct")))
6647    (set (attr "amdfam10_decode")
6648         (cond [(match_operand 1 "memory_operand")
6649                   (const_string "vector")]
6650               (const_string "direct")))
6651    (set_attr "bdver1_decode" "direct")
6652    (set_attr "mode" "<MODE>")
6653    (set (attr "length_immediate")
6654         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6655                   (const_string "1")
6656                (match_test "<MODE_SIZE> == 8")
6657                   (const_string "4")]
6658               (const_string "<MODE_SIZE>")))])
6660 (define_expand "<u>mul<mode><dwi>3"
6661   [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6662                    (mult:<DWI>
6663                      (any_extend:<DWI>
6664                        (match_operand:DWIH 1 "nonimmediate_operand"))
6665                      (any_extend:<DWI>
6666                        (match_operand:DWIH 2 "register_operand"))))
6667               (clobber (reg:CC FLAGS_REG))])])
6669 (define_expand "<u>mulqihi3"
6670   [(parallel [(set (match_operand:HI 0 "register_operand")
6671                    (mult:HI
6672                      (any_extend:HI
6673                        (match_operand:QI 1 "nonimmediate_operand"))
6674                      (any_extend:HI
6675                        (match_operand:QI 2 "register_operand"))))
6676               (clobber (reg:CC FLAGS_REG))])]
6677   "TARGET_QIMODE_MATH")
6679 (define_insn "*bmi2_umulditi3_1"
6680   [(set (match_operand:DI 0 "register_operand" "=r")
6681         (mult:DI
6682           (match_operand:DI 2 "nonimmediate_operand" "%d")
6683           (match_operand:DI 3 "nonimmediate_operand" "rm")))
6684    (set (match_operand:DI 1 "register_operand" "=r")
6685         (truncate:DI
6686           (lshiftrt:TI
6687             (mult:TI (zero_extend:TI (match_dup 2))
6688                      (zero_extend:TI (match_dup 3)))
6689             (const_int 64))))]
6690   "TARGET_64BIT && TARGET_BMI2
6691    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6692   "mulx\t{%3, %0, %1|%1, %0, %3}"
6693   [(set_attr "type" "imulx")
6694    (set_attr "prefix" "vex")
6695    (set_attr "mode" "DI")])
6697 (define_insn "*bmi2_umulsidi3_1"
6698   [(set (match_operand:SI 0 "register_operand" "=r")
6699         (mult:SI
6700           (match_operand:SI 2 "nonimmediate_operand" "%d")
6701           (match_operand:SI 3 "nonimmediate_operand" "rm")))
6702    (set (match_operand:SI 1 "register_operand" "=r")
6703         (truncate:SI
6704           (lshiftrt:DI
6705             (mult:DI (zero_extend:DI (match_dup 2))
6706                      (zero_extend:DI (match_dup 3)))
6707             (const_int 32))))]
6708   "!TARGET_64BIT && TARGET_BMI2
6709    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6710   "mulx\t{%3, %0, %1|%1, %0, %3}"
6711   [(set_attr "type" "imulx")
6712    (set_attr "prefix" "vex")
6713    (set_attr "mode" "SI")])
6715 (define_insn "*umul<mode><dwi>3_1"
6716   [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6717         (mult:<DWI>
6718           (zero_extend:<DWI>
6719             (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6720           (zero_extend:<DWI>
6721             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6722    (clobber (reg:CC FLAGS_REG))]
6723   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6724   "@
6725    #
6726    mul{<imodesuffix>}\t%2"
6727   [(set_attr "isa" "bmi2,*")
6728    (set_attr "type" "imulx,imul")
6729    (set_attr "length_immediate" "*,0")
6730    (set (attr "athlon_decode")
6731         (cond [(eq_attr "alternative" "1")
6732                  (if_then_else (eq_attr "cpu" "athlon")
6733                    (const_string "vector")
6734                    (const_string "double"))]
6735               (const_string "*")))
6736    (set_attr "amdfam10_decode" "*,double")
6737    (set_attr "bdver1_decode" "*,direct")
6738    (set_attr "prefix" "vex,orig")
6739    (set_attr "mode" "<MODE>")])
6741 ;; Convert mul to the mulx pattern to avoid flags dependency.
6742 (define_split
6743  [(set (match_operand:<DWI> 0 "register_operand")
6744        (mult:<DWI>
6745          (zero_extend:<DWI>
6746            (match_operand:DWIH 1 "register_operand"))
6747          (zero_extend:<DWI>
6748            (match_operand:DWIH 2 "nonimmediate_operand"))))
6749   (clobber (reg:CC FLAGS_REG))]
6750  "TARGET_BMI2 && reload_completed
6751   && true_regnum (operands[1]) == DX_REG"
6752   [(parallel [(set (match_dup 3)
6753                    (mult:DWIH (match_dup 1) (match_dup 2)))
6754               (set (match_dup 4)
6755                    (truncate:DWIH
6756                      (lshiftrt:<DWI>
6757                        (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6758                                    (zero_extend:<DWI> (match_dup 2)))
6759                        (match_dup 5))))])]
6761   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6763   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6766 (define_insn "*mul<mode><dwi>3_1"
6767   [(set (match_operand:<DWI> 0 "register_operand" "=A")
6768         (mult:<DWI>
6769           (sign_extend:<DWI>
6770             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6771           (sign_extend:<DWI>
6772             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6773    (clobber (reg:CC FLAGS_REG))]
6774   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6775   "imul{<imodesuffix>}\t%2"
6776   [(set_attr "type" "imul")
6777    (set_attr "length_immediate" "0")
6778    (set (attr "athlon_decode")
6779      (if_then_else (eq_attr "cpu" "athlon")
6780         (const_string "vector")
6781         (const_string "double")))
6782    (set_attr "amdfam10_decode" "double")
6783    (set_attr "bdver1_decode" "direct")
6784    (set_attr "mode" "<MODE>")])
6786 (define_insn "*<u>mulqihi3_1"
6787   [(set (match_operand:HI 0 "register_operand" "=a")
6788         (mult:HI
6789           (any_extend:HI
6790             (match_operand:QI 1 "nonimmediate_operand" "%0"))
6791           (any_extend:HI
6792             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6793    (clobber (reg:CC FLAGS_REG))]
6794   "TARGET_QIMODE_MATH
6795    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6796   "<sgnprefix>mul{b}\t%2"
6797   [(set_attr "type" "imul")
6798    (set_attr "length_immediate" "0")
6799    (set (attr "athlon_decode")
6800      (if_then_else (eq_attr "cpu" "athlon")
6801         (const_string "vector")
6802         (const_string "direct")))
6803    (set_attr "amdfam10_decode" "direct")
6804    (set_attr "bdver1_decode" "direct")
6805    (set_attr "mode" "QI")])
6807 (define_expand "<s>mul<mode>3_highpart"
6808   [(parallel [(set (match_operand:SWI48 0 "register_operand")
6809                    (truncate:SWI48
6810                      (lshiftrt:<DWI>
6811                        (mult:<DWI>
6812                          (any_extend:<DWI>
6813                            (match_operand:SWI48 1 "nonimmediate_operand"))
6814                          (any_extend:<DWI>
6815                            (match_operand:SWI48 2 "register_operand")))
6816                        (match_dup 4))))
6817               (clobber (match_scratch:SWI48 3))
6818               (clobber (reg:CC FLAGS_REG))])]
6819   ""
6820   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6822 (define_insn "*<s>muldi3_highpart_1"
6823   [(set (match_operand:DI 0 "register_operand" "=d")
6824         (truncate:DI
6825           (lshiftrt:TI
6826             (mult:TI
6827               (any_extend:TI
6828                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6829               (any_extend:TI
6830                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6831             (const_int 64))))
6832    (clobber (match_scratch:DI 3 "=1"))
6833    (clobber (reg:CC FLAGS_REG))]
6834   "TARGET_64BIT
6835    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6836   "<sgnprefix>mul{q}\t%2"
6837   [(set_attr "type" "imul")
6838    (set_attr "length_immediate" "0")
6839    (set (attr "athlon_decode")
6840      (if_then_else (eq_attr "cpu" "athlon")
6841         (const_string "vector")
6842         (const_string "double")))
6843    (set_attr "amdfam10_decode" "double")
6844    (set_attr "bdver1_decode" "direct")
6845    (set_attr "mode" "DI")])
6847 (define_insn "*<s>mulsi3_highpart_1"
6848   [(set (match_operand:SI 0 "register_operand" "=d")
6849         (truncate:SI
6850           (lshiftrt:DI
6851             (mult:DI
6852               (any_extend:DI
6853                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6854               (any_extend:DI
6855                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6856             (const_int 32))))
6857    (clobber (match_scratch:SI 3 "=1"))
6858    (clobber (reg:CC FLAGS_REG))]
6859   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6860   "<sgnprefix>mul{l}\t%2"
6861   [(set_attr "type" "imul")
6862    (set_attr "length_immediate" "0")
6863    (set (attr "athlon_decode")
6864      (if_then_else (eq_attr "cpu" "athlon")
6865         (const_string "vector")
6866         (const_string "double")))
6867    (set_attr "amdfam10_decode" "double")
6868    (set_attr "bdver1_decode" "direct")
6869    (set_attr "mode" "SI")])
6871 (define_insn "*<s>mulsi3_highpart_zext"
6872   [(set (match_operand:DI 0 "register_operand" "=d")
6873         (zero_extend:DI (truncate:SI
6874           (lshiftrt:DI
6875             (mult:DI (any_extend:DI
6876                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
6877                      (any_extend:DI
6878                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
6879             (const_int 32)))))
6880    (clobber (match_scratch:SI 3 "=1"))
6881    (clobber (reg:CC FLAGS_REG))]
6882   "TARGET_64BIT
6883    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6884   "<sgnprefix>mul{l}\t%2"
6885   [(set_attr "type" "imul")
6886    (set_attr "length_immediate" "0")
6887    (set (attr "athlon_decode")
6888      (if_then_else (eq_attr "cpu" "athlon")
6889         (const_string "vector")
6890         (const_string "double")))
6891    (set_attr "amdfam10_decode" "double")
6892    (set_attr "bdver1_decode" "direct")
6893    (set_attr "mode" "SI")])
6895 ;; The patterns that match these are at the end of this file.
6897 (define_expand "mulxf3"
6898   [(set (match_operand:XF 0 "register_operand")
6899         (mult:XF (match_operand:XF 1 "register_operand")
6900                  (match_operand:XF 2 "register_operand")))]
6901   "TARGET_80387")
6903 (define_expand "mul<mode>3"
6904   [(set (match_operand:MODEF 0 "register_operand")
6905         (mult:MODEF (match_operand:MODEF 1 "register_operand")
6906                     (match_operand:MODEF 2 "nonimmediate_operand")))]
6907   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6908     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6910 ;; Divide instructions
6912 ;; The patterns that match these are at the end of this file.
6914 (define_expand "divxf3"
6915   [(set (match_operand:XF 0 "register_operand")
6916         (div:XF (match_operand:XF 1 "register_operand")
6917                 (match_operand:XF 2 "register_operand")))]
6918   "TARGET_80387")
6920 (define_expand "divdf3"
6921   [(set (match_operand:DF 0 "register_operand")
6922         (div:DF (match_operand:DF 1 "register_operand")
6923                 (match_operand:DF 2 "nonimmediate_operand")))]
6924    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6925     || (TARGET_SSE2 && TARGET_SSE_MATH)")
6927 (define_expand "divsf3"
6928   [(set (match_operand:SF 0 "register_operand")
6929         (div:SF (match_operand:SF 1 "register_operand")
6930                 (match_operand:SF 2 "nonimmediate_operand")))]
6931   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
6932     || TARGET_SSE_MATH"
6934   if (TARGET_SSE_MATH
6935       && TARGET_RECIP_DIV
6936       && optimize_insn_for_speed_p ()
6937       && flag_finite_math_only && !flag_trapping_math
6938       && flag_unsafe_math_optimizations)
6939     {
6940       ix86_emit_swdivsf (operands[0], operands[1],
6941                          operands[2], SFmode);
6942       DONE;
6943     }
6946 ;; Divmod instructions.
6948 (define_expand "divmod<mode>4"
6949   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6950                    (div:SWIM248
6951                      (match_operand:SWIM248 1 "register_operand")
6952                      (match_operand:SWIM248 2 "nonimmediate_operand")))
6953               (set (match_operand:SWIM248 3 "register_operand")
6954                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
6955               (clobber (reg:CC FLAGS_REG))])])
6957 ;; Split with 8bit unsigned divide:
6958 ;;      if (dividend an divisor are in [0-255])
6959 ;;         use 8bit unsigned integer divide
6960 ;;       else
6961 ;;         use original integer divide
6962 (define_split
6963   [(set (match_operand:SWI48 0 "register_operand")
6964         (div:SWI48 (match_operand:SWI48 2 "register_operand")
6965                     (match_operand:SWI48 3 "nonimmediate_operand")))
6966    (set (match_operand:SWI48 1 "register_operand")
6967         (mod:SWI48 (match_dup 2) (match_dup 3)))
6968    (clobber (reg:CC FLAGS_REG))]
6969   "TARGET_USE_8BIT_IDIV
6970    && TARGET_QIMODE_MATH
6971    && can_create_pseudo_p ()
6972    && !optimize_insn_for_size_p ()"
6973   [(const_int 0)]
6974   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
6976 (define_insn_and_split "divmod<mode>4_1"
6977   [(set (match_operand:SWI48 0 "register_operand" "=a")
6978         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
6979                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
6980    (set (match_operand:SWI48 1 "register_operand" "=&d")
6981         (mod:SWI48 (match_dup 2) (match_dup 3)))
6982    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
6983    (clobber (reg:CC FLAGS_REG))]
6984   ""
6985   "#"
6986   "reload_completed"
6987   [(parallel [(set (match_dup 1)
6988                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
6989               (clobber (reg:CC FLAGS_REG))])
6990    (parallel [(set (match_dup 0)
6991                    (div:SWI48 (match_dup 2) (match_dup 3)))
6992               (set (match_dup 1)
6993                    (mod:SWI48 (match_dup 2) (match_dup 3)))
6994               (use (match_dup 1))
6995               (clobber (reg:CC FLAGS_REG))])]
6997   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
6999   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7000     operands[4] = operands[2];
7001   else
7002     {
7003       /* Avoid use of cltd in favor of a mov+shift.  */
7004       emit_move_insn (operands[1], operands[2]);
7005       operands[4] = operands[1];
7006     }
7008   [(set_attr "type" "multi")
7009    (set_attr "mode" "<MODE>")])
7011 (define_insn_and_split "*divmod<mode>4"
7012   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7013         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7014                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7015    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7016         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7017    (clobber (reg:CC FLAGS_REG))]
7018   ""
7019   "#"
7020   "reload_completed"
7021   [(parallel [(set (match_dup 1)
7022                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7023               (clobber (reg:CC FLAGS_REG))])
7024    (parallel [(set (match_dup 0)
7025                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7026               (set (match_dup 1)
7027                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7028               (use (match_dup 1))
7029               (clobber (reg:CC FLAGS_REG))])]
7031   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7033   if (<MODE>mode != HImode
7034       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7035     operands[4] = operands[2];
7036   else
7037     {
7038       /* Avoid use of cltd in favor of a mov+shift.  */
7039       emit_move_insn (operands[1], operands[2]);
7040       operands[4] = operands[1];
7041     }
7043   [(set_attr "type" "multi")
7044    (set_attr "mode" "<MODE>")])
7046 (define_insn "*divmod<mode>4_noext"
7047   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7048         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7049                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7050    (set (match_operand:SWIM248 1 "register_operand" "=d")
7051         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7052    (use (match_operand:SWIM248 4 "register_operand" "1"))
7053    (clobber (reg:CC FLAGS_REG))]
7054   ""
7055   "idiv{<imodesuffix>}\t%3"
7056   [(set_attr "type" "idiv")
7057    (set_attr "mode" "<MODE>")])
7059 (define_expand "divmodqi4"
7060   [(parallel [(set (match_operand:QI 0 "register_operand")
7061                    (div:QI
7062                      (match_operand:QI 1 "register_operand")
7063                      (match_operand:QI 2 "nonimmediate_operand")))
7064               (set (match_operand:QI 3 "register_operand")
7065                    (mod:QI (match_dup 1) (match_dup 2)))
7066               (clobber (reg:CC FLAGS_REG))])]
7067   "TARGET_QIMODE_MATH"
7069   rtx div, mod, insn;
7070   rtx tmp0, tmp1;
7071   
7072   tmp0 = gen_reg_rtx (HImode);
7073   tmp1 = gen_reg_rtx (HImode);
7075   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7076      in AX.  */
7077   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7078   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7080   /* Extract remainder from AH.  */
7081   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7082   insn = emit_move_insn (operands[3], tmp1);
7084   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7085   set_unique_reg_note (insn, REG_EQUAL, mod);
7087   /* Extract quotient from AL.  */
7088   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7090   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7091   set_unique_reg_note (insn, REG_EQUAL, div);
7093   DONE;
7096 ;; Divide AX by r/m8, with result stored in
7097 ;; AL <- Quotient
7098 ;; AH <- Remainder
7099 ;; Change div/mod to HImode and extend the second argument to HImode
7100 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7101 ;; combine may fail.
7102 (define_insn "divmodhiqi3"
7103   [(set (match_operand:HI 0 "register_operand" "=a")
7104         (ior:HI
7105           (ashift:HI
7106             (zero_extend:HI
7107               (truncate:QI
7108                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7109                         (sign_extend:HI
7110                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7111             (const_int 8))
7112           (zero_extend:HI
7113             (truncate:QI
7114               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7115    (clobber (reg:CC FLAGS_REG))]
7116   "TARGET_QIMODE_MATH"
7117   "idiv{b}\t%2"
7118   [(set_attr "type" "idiv")
7119    (set_attr "mode" "QI")])
7121 (define_expand "udivmod<mode>4"
7122   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7123                    (udiv:SWIM248
7124                      (match_operand:SWIM248 1 "register_operand")
7125                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7126               (set (match_operand:SWIM248 3 "register_operand")
7127                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7128               (clobber (reg:CC FLAGS_REG))])])
7130 ;; Split with 8bit unsigned divide:
7131 ;;      if (dividend an divisor are in [0-255])
7132 ;;         use 8bit unsigned integer divide
7133 ;;       else
7134 ;;         use original integer divide
7135 (define_split
7136   [(set (match_operand:SWI48 0 "register_operand")
7137         (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7138                     (match_operand:SWI48 3 "nonimmediate_operand")))
7139    (set (match_operand:SWI48 1 "register_operand")
7140         (umod:SWI48 (match_dup 2) (match_dup 3)))
7141    (clobber (reg:CC FLAGS_REG))]
7142   "TARGET_USE_8BIT_IDIV
7143    && TARGET_QIMODE_MATH
7144    && can_create_pseudo_p ()
7145    && !optimize_insn_for_size_p ()"
7146   [(const_int 0)]
7147   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7149 (define_insn_and_split "udivmod<mode>4_1"
7150   [(set (match_operand:SWI48 0 "register_operand" "=a")
7151         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7152                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7153    (set (match_operand:SWI48 1 "register_operand" "=&d")
7154         (umod:SWI48 (match_dup 2) (match_dup 3)))
7155    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7156    (clobber (reg:CC FLAGS_REG))]
7157   ""
7158   "#"
7159   "reload_completed"
7160   [(set (match_dup 1) (const_int 0))
7161    (parallel [(set (match_dup 0)
7162                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7163               (set (match_dup 1)
7164                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7165               (use (match_dup 1))
7166               (clobber (reg:CC FLAGS_REG))])]
7167   ""
7168   [(set_attr "type" "multi")
7169    (set_attr "mode" "<MODE>")])
7171 (define_insn_and_split "*udivmod<mode>4"
7172   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7173         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7174                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7175    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7176         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7177    (clobber (reg:CC FLAGS_REG))]
7178   ""
7179   "#"
7180   "reload_completed"
7181   [(set (match_dup 1) (const_int 0))
7182    (parallel [(set (match_dup 0)
7183                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7184               (set (match_dup 1)
7185                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7186               (use (match_dup 1))
7187               (clobber (reg:CC FLAGS_REG))])]
7188   ""
7189   [(set_attr "type" "multi")
7190    (set_attr "mode" "<MODE>")])
7192 (define_insn "*udivmod<mode>4_noext"
7193   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7194         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7195                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7196    (set (match_operand:SWIM248 1 "register_operand" "=d")
7197         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7198    (use (match_operand:SWIM248 4 "register_operand" "1"))
7199    (clobber (reg:CC FLAGS_REG))]
7200   ""
7201   "div{<imodesuffix>}\t%3"
7202   [(set_attr "type" "idiv")
7203    (set_attr "mode" "<MODE>")])
7205 (define_expand "udivmodqi4"
7206   [(parallel [(set (match_operand:QI 0 "register_operand")
7207                    (udiv:QI
7208                      (match_operand:QI 1 "register_operand")
7209                      (match_operand:QI 2 "nonimmediate_operand")))
7210               (set (match_operand:QI 3 "register_operand")
7211                    (umod:QI (match_dup 1) (match_dup 2)))
7212               (clobber (reg:CC FLAGS_REG))])]
7213   "TARGET_QIMODE_MATH"
7215   rtx div, mod, insn;
7216   rtx tmp0, tmp1;
7217   
7218   tmp0 = gen_reg_rtx (HImode);
7219   tmp1 = gen_reg_rtx (HImode);
7221   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7222      in AX.  */
7223   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7224   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7226   /* Extract remainder from AH.  */
7227   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7228   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7229   insn = emit_move_insn (operands[3], tmp1);
7231   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7232   set_unique_reg_note (insn, REG_EQUAL, mod);
7234   /* Extract quotient from AL.  */
7235   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7237   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7238   set_unique_reg_note (insn, REG_EQUAL, div);
7240   DONE;
7243 (define_insn "udivmodhiqi3"
7244   [(set (match_operand:HI 0 "register_operand" "=a")
7245         (ior:HI
7246           (ashift:HI
7247             (zero_extend:HI
7248               (truncate:QI
7249                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7250                         (zero_extend:HI
7251                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7252             (const_int 8))
7253           (zero_extend:HI
7254             (truncate:QI
7255               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7256    (clobber (reg:CC FLAGS_REG))]
7257   "TARGET_QIMODE_MATH"
7258   "div{b}\t%2"
7259   [(set_attr "type" "idiv")
7260    (set_attr "mode" "QI")])
7262 ;; We cannot use div/idiv for double division, because it causes
7263 ;; "division by zero" on the overflow and that's not what we expect
7264 ;; from truncate.  Because true (non truncating) double division is
7265 ;; never generated, we can't create this insn anyway.
7267 ;(define_insn ""
7268 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7269 ;       (truncate:SI
7270 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7271 ;                  (zero_extend:DI
7272 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7273 ;   (set (match_operand:SI 3 "register_operand" "=d")
7274 ;       (truncate:SI
7275 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7276 ;   (clobber (reg:CC FLAGS_REG))]
7277 ;  ""
7278 ;  "div{l}\t{%2, %0|%0, %2}"
7279 ;  [(set_attr "type" "idiv")])
7281 ;;- Logical AND instructions
7283 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7284 ;; Note that this excludes ah.
7286 (define_expand "testsi_ccno_1"
7287   [(set (reg:CCNO FLAGS_REG)
7288         (compare:CCNO
7289           (and:SI (match_operand:SI 0 "nonimmediate_operand")
7290                   (match_operand:SI 1 "x86_64_nonmemory_operand"))
7291           (const_int 0)))])
7293 (define_expand "testqi_ccz_1"
7294   [(set (reg:CCZ FLAGS_REG)
7295         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7296                              (match_operand:QI 1 "nonmemory_operand"))
7297                  (const_int 0)))])
7299 (define_expand "testdi_ccno_1"
7300   [(set (reg:CCNO FLAGS_REG)
7301         (compare:CCNO
7302           (and:DI (match_operand:DI 0 "nonimmediate_operand")
7303                   (match_operand:DI 1 "x86_64_szext_general_operand"))
7304           (const_int 0)))]
7305   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7307 (define_insn "*testdi_1"
7308   [(set (reg FLAGS_REG)
7309         (compare
7310          (and:DI
7311           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7312           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7313          (const_int 0)))]
7314   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7315    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7316   "@
7317    test{l}\t{%k1, %k0|%k0, %k1}
7318    test{l}\t{%k1, %k0|%k0, %k1}
7319    test{q}\t{%1, %0|%0, %1}
7320    test{q}\t{%1, %0|%0, %1}
7321    test{q}\t{%1, %0|%0, %1}"
7322   [(set_attr "type" "test")
7323    (set_attr "modrm" "0,1,0,1,1")
7324    (set_attr "mode" "SI,SI,DI,DI,DI")])
7326 (define_insn "*testqi_1_maybe_si"
7327   [(set (reg FLAGS_REG)
7328         (compare
7329           (and:QI
7330             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7331             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7332           (const_int 0)))]
7333    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7334     && ix86_match_ccmode (insn,
7335                          CONST_INT_P (operands[1])
7336                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7338   if (which_alternative == 3)
7339     {
7340       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7341         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7342       return "test{l}\t{%1, %k0|%k0, %1}";
7343     }
7344   return "test{b}\t{%1, %0|%0, %1}";
7346   [(set_attr "type" "test")
7347    (set_attr "modrm" "0,1,1,1")
7348    (set_attr "mode" "QI,QI,QI,SI")
7349    (set_attr "pent_pair" "uv,np,uv,np")])
7351 (define_insn "*test<mode>_1"
7352   [(set (reg FLAGS_REG)
7353         (compare
7354          (and:SWI124
7355           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7356           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7357          (const_int 0)))]
7358   "ix86_match_ccmode (insn, CCNOmode)
7359    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7360   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7361   [(set_attr "type" "test")
7362    (set_attr "modrm" "0,1,1")
7363    (set_attr "mode" "<MODE>")
7364    (set_attr "pent_pair" "uv,np,uv")])
7366 (define_expand "testqi_ext_ccno_0"
7367   [(set (reg:CCNO FLAGS_REG)
7368         (compare:CCNO
7369           (and:SI
7370             (zero_extract:SI
7371               (match_operand 0 "ext_register_operand")
7372               (const_int 8)
7373               (const_int 8))
7374             (match_operand 1 "const_int_operand"))
7375           (const_int 0)))])
7377 (define_insn "*testqi_ext_0"
7378   [(set (reg FLAGS_REG)
7379         (compare
7380           (and:SI
7381             (zero_extract:SI
7382               (match_operand 0 "ext_register_operand" "Q")
7383               (const_int 8)
7384               (const_int 8))
7385             (match_operand 1 "const_int_operand" "n"))
7386           (const_int 0)))]
7387   "ix86_match_ccmode (insn, CCNOmode)"
7388   "test{b}\t{%1, %h0|%h0, %1}"
7389   [(set_attr "type" "test")
7390    (set_attr "mode" "QI")
7391    (set_attr "length_immediate" "1")
7392    (set_attr "modrm" "1")
7393    (set_attr "pent_pair" "np")])
7395 (define_insn "*testqi_ext_1"
7396   [(set (reg FLAGS_REG)
7397         (compare
7398           (and:SI
7399             (zero_extract:SI
7400               (match_operand 0 "ext_register_operand" "Q,Q")
7401               (const_int 8)
7402               (const_int 8))
7403             (zero_extend:SI
7404               (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7405           (const_int 0)))]
7406   "ix86_match_ccmode (insn, CCNOmode)"
7407   "test{b}\t{%1, %h0|%h0, %1}"
7408   [(set_attr "isa" "*,nox64")
7409    (set_attr "type" "test")
7410    (set_attr "mode" "QI")])
7412 (define_insn "*testqi_ext_2"
7413   [(set (reg FLAGS_REG)
7414         (compare
7415           (and:SI
7416             (zero_extract:SI
7417               (match_operand 0 "ext_register_operand" "Q")
7418               (const_int 8)
7419               (const_int 8))
7420             (zero_extract:SI
7421               (match_operand 1 "ext_register_operand" "Q")
7422               (const_int 8)
7423               (const_int 8)))
7424           (const_int 0)))]
7425   "ix86_match_ccmode (insn, CCNOmode)"
7426   "test{b}\t{%h1, %h0|%h0, %h1}"
7427   [(set_attr "type" "test")
7428    (set_attr "mode" "QI")])
7430 ;; Combine likes to form bit extractions for some tests.  Humor it.
7431 (define_insn "*testqi_ext_3"
7432   [(set (reg FLAGS_REG)
7433         (compare (zero_extract:SWI48
7434                    (match_operand 0 "nonimmediate_operand" "rm")
7435                    (match_operand:SWI48 1 "const_int_operand")
7436                    (match_operand:SWI48 2 "const_int_operand"))
7437                  (const_int 0)))]
7438   "ix86_match_ccmode (insn, CCNOmode)
7439    && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7440        || GET_MODE (operands[0]) == SImode
7441        || GET_MODE (operands[0]) == HImode
7442        || GET_MODE (operands[0]) == QImode)
7443    /* Ensure that resulting mask is zero or sign extended operand.  */
7444    && INTVAL (operands[2]) >= 0
7445    && ((INTVAL (operands[1]) > 0
7446         && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7447        || (<MODE>mode == DImode
7448            && INTVAL (operands[1]) > 32
7449            && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7450   "#")
7452 (define_split
7453   [(set (match_operand 0 "flags_reg_operand")
7454         (match_operator 1 "compare_operator"
7455           [(zero_extract
7456              (match_operand 2 "nonimmediate_operand")
7457              (match_operand 3 "const_int_operand")
7458              (match_operand 4 "const_int_operand"))
7459            (const_int 0)]))]
7460   "ix86_match_ccmode (insn, CCNOmode)"
7461   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7463   rtx val = operands[2];
7464   HOST_WIDE_INT len = INTVAL (operands[3]);
7465   HOST_WIDE_INT pos = INTVAL (operands[4]);
7466   HOST_WIDE_INT mask;
7467   machine_mode mode, submode;
7469   mode = GET_MODE (val);
7470   if (MEM_P (val))
7471     {
7472       /* ??? Combine likes to put non-volatile mem extractions in QImode
7473          no matter the size of the test.  So find a mode that works.  */
7474       if (! MEM_VOLATILE_P (val))
7475         {
7476           mode = smallest_mode_for_size (pos + len, MODE_INT);
7477           val = adjust_address (val, mode, 0);
7478         }
7479     }
7480   else if (GET_CODE (val) == SUBREG
7481            && (submode = GET_MODE (SUBREG_REG (val)),
7482                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7483            && pos + len <= GET_MODE_BITSIZE (submode)
7484            && GET_MODE_CLASS (submode) == MODE_INT)
7485     {
7486       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7487       mode = submode;
7488       val = SUBREG_REG (val);
7489     }
7490   else if (mode == HImode && pos + len <= 8)
7491     {
7492       /* Small HImode tests can be converted to QImode.  */
7493       mode = QImode;
7494       val = gen_lowpart (QImode, val);
7495     }
7497   if (len == HOST_BITS_PER_WIDE_INT)
7498     mask = -1;
7499   else
7500     mask = ((HOST_WIDE_INT)1 << len) - 1;
7501   mask <<= pos;
7503   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7506 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7507 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7508 ;; this is relatively important trick.
7509 ;; Do the conversion only post-reload to avoid limiting of the register class
7510 ;; to QI regs.
7511 (define_split
7512   [(set (match_operand 0 "flags_reg_operand")
7513         (match_operator 1 "compare_operator"
7514           [(and (match_operand 2 "register_operand")
7515                 (match_operand 3 "const_int_operand"))
7516            (const_int 0)]))]
7517    "reload_completed
7518     && QI_REG_P (operands[2])
7519     && GET_MODE (operands[2]) != QImode
7520     && ((ix86_match_ccmode (insn, CCZmode)
7521          && !(INTVAL (operands[3]) & ~(255 << 8)))
7522         || (ix86_match_ccmode (insn, CCNOmode)
7523             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7524   [(set (match_dup 0)
7525         (match_op_dup 1
7526           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7527                    (match_dup 3))
7528            (const_int 0)]))]
7530   operands[2] = gen_lowpart (SImode, operands[2]);
7531   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7534 (define_split
7535   [(set (match_operand 0 "flags_reg_operand")
7536         (match_operator 1 "compare_operator"
7537           [(and (match_operand 2 "nonimmediate_operand")
7538                 (match_operand 3 "const_int_operand"))
7539            (const_int 0)]))]
7540    "reload_completed
7541     && GET_MODE (operands[2]) != QImode
7542     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7543     && ((ix86_match_ccmode (insn, CCZmode)
7544          && !(INTVAL (operands[3]) & ~255))
7545         || (ix86_match_ccmode (insn, CCNOmode)
7546             && !(INTVAL (operands[3]) & ~127)))"
7547   [(set (match_dup 0)
7548         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7549                          (const_int 0)]))]
7551   operands[2] = gen_lowpart (QImode, operands[2]);
7552   operands[3] = gen_lowpart (QImode, operands[3]);
7555 (define_split
7556   [(set (match_operand:SWI1248x 0 "mask_reg_operand")
7557         (any_logic:SWI1248x (match_operand:SWI1248x 1 "mask_reg_operand")
7558                             (match_operand:SWI1248x 2 "mask_reg_operand")))
7559    (clobber (reg:CC FLAGS_REG))]
7560   "TARGET_AVX512F && reload_completed"
7561   [(set (match_dup 0)
7562         (any_logic:SWI1248x (match_dup 1)
7563                             (match_dup 2)))])
7565 (define_insn "*k<logic><mode>"
7566   [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand" "=k")
7567         (any_logic:SWI1248_AVX512BW (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand" "k")
7568                           (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand" "k")))]
7569   "TARGET_AVX512F"
7570   {
7571     if (!TARGET_AVX512DQ && <MODE>mode == QImode)
7572       return "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7573     else
7574       return "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
7575   }
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   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   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   machine_mode mode = GET_MODE (operands[0]);
8750   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_code_label *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   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_code_label *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 "*sibcall"
11496   [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
11497          (match_operand 1))]
11498   "SIBLING_CALL_P (insn)"
11499   "* return ix86_output_call_insn (insn, operands[0]);"
11500   [(set_attr "type" "call")])
11502 (define_insn "*sibcall_memory"
11503   [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
11504          (match_operand 1))
11505    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11506   "!TARGET_X32"
11507   "* return ix86_output_call_insn (insn, operands[0]);"
11508   [(set_attr "type" "call")])
11510 (define_peephole2
11511   [(set (match_operand:W 0 "register_operand")
11512         (match_operand:W 1 "memory_operand"))
11513    (call (mem:QI (match_dup 0))
11514          (match_operand 3))]
11515   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11516    && peep2_reg_dead_p (2, operands[0])"
11517   [(parallel [(call (mem:QI (match_dup 1))
11518                     (match_dup 3))
11519               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11521 (define_peephole2
11522   [(set (match_operand:W 0 "register_operand")
11523         (match_operand:W 1 "memory_operand"))
11524    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11525    (call (mem:QI (match_dup 0))
11526          (match_operand 3))]
11527   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11528    && peep2_reg_dead_p (3, operands[0])"
11529   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11530    (parallel [(call (mem:QI (match_dup 1))
11531                     (match_dup 3))
11532               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11534 (define_expand "call_pop"
11535   [(parallel [(call (match_operand:QI 0)
11536                     (match_operand:SI 1))
11537               (set (reg:SI SP_REG)
11538                    (plus:SI (reg:SI SP_REG)
11539                             (match_operand:SI 3)))])]
11540   "!TARGET_64BIT"
11542   ix86_expand_call (NULL, operands[0], operands[1],
11543                     operands[2], operands[3], false);
11544   DONE;
11547 (define_insn "*call_pop"
11548   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
11549          (match_operand 1))
11550    (set (reg:SI SP_REG)
11551         (plus:SI (reg:SI SP_REG)
11552                  (match_operand:SI 2 "immediate_operand" "i")))]
11553   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11554   "* return ix86_output_call_insn (insn, operands[0]);"
11555   [(set_attr "type" "call")])
11557 (define_insn "*sibcall_pop"
11558   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
11559          (match_operand 1))
11560    (set (reg:SI SP_REG)
11561         (plus:SI (reg:SI SP_REG)
11562                  (match_operand:SI 2 "immediate_operand" "i")))]
11563   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11564   "* return ix86_output_call_insn (insn, operands[0]);"
11565   [(set_attr "type" "call")])
11567 (define_insn "*sibcall_pop_memory"
11568   [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
11569          (match_operand 1))
11570    (set (reg:SI SP_REG)
11571         (plus:SI (reg:SI SP_REG)
11572                  (match_operand:SI 2 "immediate_operand" "i")))
11573    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11574   "!TARGET_64BIT"
11575   "* return ix86_output_call_insn (insn, operands[0]);"
11576   [(set_attr "type" "call")])
11578 (define_peephole2
11579   [(set (match_operand:SI 0 "register_operand")
11580         (match_operand:SI 1 "memory_operand"))
11581    (parallel [(call (mem:QI (match_dup 0))
11582                     (match_operand 3))
11583               (set (reg:SI SP_REG)
11584                    (plus:SI (reg:SI SP_REG)
11585                             (match_operand:SI 4 "immediate_operand")))])]
11586   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11587    && peep2_reg_dead_p (2, operands[0])"
11588   [(parallel [(call (mem:QI (match_dup 1))
11589                     (match_dup 3))
11590               (set (reg:SI SP_REG)
11591                    (plus:SI (reg:SI SP_REG)
11592                             (match_dup 4)))
11593               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11595 (define_peephole2
11596   [(set (match_operand:SI 0 "register_operand")
11597         (match_operand:SI 1 "memory_operand"))
11598    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11599    (parallel [(call (mem:QI (match_dup 0))
11600                     (match_operand 3))
11601               (set (reg:SI SP_REG)
11602                    (plus:SI (reg:SI SP_REG)
11603                             (match_operand:SI 4 "immediate_operand")))])]
11604   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11605    && peep2_reg_dead_p (3, operands[0])"
11606   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11607    (parallel [(call (mem:QI (match_dup 1))
11608                     (match_dup 3))
11609               (set (reg:SI SP_REG)
11610                    (plus:SI (reg:SI SP_REG)
11611                             (match_dup 4)))
11612               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11614 ;; Combining simple memory jump instruction
11616 (define_peephole2
11617   [(set (match_operand:W 0 "register_operand")
11618         (match_operand:W 1 "memory_operand"))
11619    (set (pc) (match_dup 0))]
11620   "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
11621   [(set (pc) (match_dup 1))])
11623 ;; Call subroutine, returning value in operand 0
11625 (define_expand "call_value"
11626   [(set (match_operand 0)
11627         (call (match_operand:QI 1)
11628               (match_operand 2)))
11629    (use (match_operand 3))]
11630   ""
11632   ix86_expand_call (operands[0], operands[1], operands[2],
11633                     operands[3], NULL, false);
11634   DONE;
11637 (define_expand "sibcall_value"
11638   [(set (match_operand 0)
11639         (call (match_operand:QI 1)
11640               (match_operand 2)))
11641    (use (match_operand 3))]
11642   ""
11644   ix86_expand_call (operands[0], operands[1], operands[2],
11645                     operands[3], NULL, true);
11646   DONE;
11649 (define_insn "*call_value"
11650   [(set (match_operand 0)
11651         (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
11652               (match_operand 2)))]
11653   "!SIBLING_CALL_P (insn)"
11654   "* return ix86_output_call_insn (insn, operands[1]);"
11655   [(set_attr "type" "callv")])
11657 (define_insn "*sibcall_value"
11658   [(set (match_operand 0)
11659         (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
11660               (match_operand 2)))]
11661   "SIBLING_CALL_P (insn)"
11662   "* return ix86_output_call_insn (insn, operands[1]);"
11663   [(set_attr "type" "callv")])
11665 (define_insn "*sibcall_value_memory"
11666   [(set (match_operand 0)
11667         (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
11668               (match_operand 2)))
11669    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11670   "!TARGET_X32"
11671   "* return ix86_output_call_insn (insn, operands[1]);"
11672   [(set_attr "type" "callv")])
11674 (define_peephole2
11675   [(set (match_operand:W 0 "register_operand")
11676         (match_operand:W 1 "memory_operand"))
11677    (set (match_operand 2)
11678    (call (mem:QI (match_dup 0))
11679                  (match_operand 3)))]
11680   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11681    && peep2_reg_dead_p (2, operands[0])"
11682   [(parallel [(set (match_dup 2)
11683                    (call (mem:QI (match_dup 1))
11684                          (match_dup 3)))
11685               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11687 (define_peephole2
11688   [(set (match_operand:W 0 "register_operand")
11689         (match_operand:W 1 "memory_operand"))
11690    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11691    (set (match_operand 2)
11692         (call (mem:QI (match_dup 0))
11693               (match_operand 3)))]
11694   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11695    && peep2_reg_dead_p (3, operands[0])"
11696   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11697    (parallel [(set (match_dup 2)
11698                    (call (mem:QI (match_dup 1))
11699                          (match_dup 3)))
11700               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11702 (define_expand "call_value_pop"
11703   [(parallel [(set (match_operand 0)
11704                    (call (match_operand:QI 1)
11705                          (match_operand:SI 2)))
11706               (set (reg:SI SP_REG)
11707                    (plus:SI (reg:SI SP_REG)
11708                             (match_operand:SI 4)))])]
11709   "!TARGET_64BIT"
11711   ix86_expand_call (operands[0], operands[1], operands[2],
11712                     operands[3], operands[4], false);
11713   DONE;
11716 (define_insn "*call_value_pop"
11717   [(set (match_operand 0)
11718         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
11719               (match_operand 2)))
11720    (set (reg:SI SP_REG)
11721         (plus:SI (reg:SI SP_REG)
11722                  (match_operand:SI 3 "immediate_operand" "i")))]
11723   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11724   "* return ix86_output_call_insn (insn, operands[1]);"
11725   [(set_attr "type" "callv")])
11727 (define_insn "*sibcall_value_pop"
11728   [(set (match_operand 0)
11729         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
11730               (match_operand 2)))
11731    (set (reg:SI SP_REG)
11732         (plus:SI (reg:SI SP_REG)
11733                  (match_operand:SI 3 "immediate_operand" "i")))]
11734   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11735   "* return ix86_output_call_insn (insn, operands[1]);"
11736   [(set_attr "type" "callv")])
11738 (define_insn "*sibcall_value_pop_memory"
11739   [(set (match_operand 0)
11740         (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
11741               (match_operand 2)))
11742    (set (reg:SI SP_REG)
11743         (plus:SI (reg:SI SP_REG)
11744                  (match_operand:SI 3 "immediate_operand" "i")))
11745    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11746   "!TARGET_64BIT"
11747   "* return ix86_output_call_insn (insn, operands[1]);"
11748   [(set_attr "type" "callv")])
11750 (define_peephole2
11751   [(set (match_operand:SI 0 "register_operand")
11752         (match_operand:SI 1 "memory_operand"))
11753    (parallel [(set (match_operand 2)
11754                    (call (mem:QI (match_dup 0))
11755                          (match_operand 3)))
11756               (set (reg:SI SP_REG)
11757                    (plus:SI (reg:SI SP_REG)
11758                             (match_operand:SI 4 "immediate_operand")))])]
11759   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11760    && peep2_reg_dead_p (2, operands[0])"
11761   [(parallel [(set (match_dup 2)
11762                    (call (mem:QI (match_dup 1))
11763                          (match_dup 3)))
11764               (set (reg:SI SP_REG)
11765                    (plus:SI (reg:SI SP_REG)
11766                             (match_dup 4)))
11767               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11769 (define_peephole2
11770   [(set (match_operand:SI 0 "register_operand")
11771         (match_operand:SI 1 "memory_operand"))
11772    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11773    (parallel [(set (match_operand 2)
11774                    (call (mem:QI (match_dup 0))
11775                          (match_operand 3)))
11776               (set (reg:SI SP_REG)
11777                    (plus:SI (reg:SI SP_REG)
11778                             (match_operand:SI 4 "immediate_operand")))])]
11779   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11780    && peep2_reg_dead_p (3, operands[0])"
11781   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11782    (parallel [(set (match_dup 2)
11783                    (call (mem:QI (match_dup 1))
11784                          (match_dup 3)))
11785               (set (reg:SI SP_REG)
11786                    (plus:SI (reg:SI SP_REG)
11787                             (match_dup 4)))
11788               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11790 ;; Call subroutine returning any type.
11792 (define_expand "untyped_call"
11793   [(parallel [(call (match_operand 0)
11794                     (const_int 0))
11795               (match_operand 1)
11796               (match_operand 2)])]
11797   ""
11799   int i;
11801   /* In order to give reg-stack an easier job in validating two
11802      coprocessor registers as containing a possible return value,
11803      simply pretend the untyped call returns a complex long double
11804      value. 
11806      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11807      and should have the default ABI.  */
11809   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11810                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11811                     operands[0], const0_rtx,
11812                     GEN_INT ((TARGET_64BIT
11813                               ? (ix86_abi == SYSV_ABI
11814                                  ? X86_64_SSE_REGPARM_MAX
11815                                  : X86_64_MS_SSE_REGPARM_MAX)
11816                               : X86_32_SSE_REGPARM_MAX)
11817                              - 1),
11818                     NULL, false);
11820   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11821     {
11822       rtx set = XVECEXP (operands[2], 0, i);
11823       emit_move_insn (SET_DEST (set), SET_SRC (set));
11824     }
11826   /* The optimizer does not know that the call sets the function value
11827      registers we stored in the result block.  We avoid problems by
11828      claiming that all hard registers are used and clobbered at this
11829      point.  */
11830   emit_insn (gen_blockage ());
11832   DONE;
11835 ;; Prologue and epilogue instructions
11837 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11838 ;; all of memory.  This blocks insns from being moved across this point.
11840 (define_insn "blockage"
11841   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11842   ""
11843   ""
11844   [(set_attr "length" "0")])
11846 ;; Do not schedule instructions accessing memory across this point.
11848 (define_expand "memory_blockage"
11849   [(set (match_dup 0)
11850         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11851   ""
11853   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11854   MEM_VOLATILE_P (operands[0]) = 1;
11857 (define_insn "*memory_blockage"
11858   [(set (match_operand:BLK 0)
11859         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11860   ""
11861   ""
11862   [(set_attr "length" "0")])
11864 ;; As USE insns aren't meaningful after reload, this is used instead
11865 ;; to prevent deleting instructions setting registers for PIC code
11866 (define_insn "prologue_use"
11867   [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11868   ""
11869   ""
11870   [(set_attr "length" "0")])
11872 ;; Insn emitted into the body of a function to return from a function.
11873 ;; This is only done if the function's epilogue is known to be simple.
11874 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11876 (define_expand "return"
11877   [(simple_return)]
11878   "ix86_can_use_return_insn_p ()"
11880   if (crtl->args.pops_args)
11881     {
11882       rtx popc = GEN_INT (crtl->args.pops_args);
11883       emit_jump_insn (gen_simple_return_pop_internal (popc));
11884       DONE;
11885     }
11888 ;; We need to disable this for TARGET_SEH, as otherwise
11889 ;; shrink-wrapped prologue gets enabled too.  This might exceed
11890 ;; the maximum size of prologue in unwind information.
11892 (define_expand "simple_return"
11893   [(simple_return)]
11894   "!TARGET_SEH"
11896   if (crtl->args.pops_args)
11897     {
11898       rtx popc = GEN_INT (crtl->args.pops_args);
11899       emit_jump_insn (gen_simple_return_pop_internal (popc));
11900       DONE;
11901     }
11904 (define_insn "simple_return_internal"
11905   [(simple_return)]
11906   "reload_completed"
11907   "ret"
11908   [(set_attr "length" "1")
11909    (set_attr "atom_unit" "jeu")
11910    (set_attr "length_immediate" "0")
11911    (set_attr "modrm" "0")])
11913 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11914 ;; instruction Athlon and K8 have.
11916 (define_insn "simple_return_internal_long"
11917   [(simple_return)
11918    (unspec [(const_int 0)] UNSPEC_REP)]
11919   "reload_completed"
11920   "rep%; ret"
11921   [(set_attr "length" "2")
11922    (set_attr "atom_unit" "jeu")
11923    (set_attr "length_immediate" "0")
11924    (set_attr "prefix_rep" "1")
11925    (set_attr "modrm" "0")])
11927 (define_insn "simple_return_pop_internal"
11928   [(simple_return)
11929    (use (match_operand:SI 0 "const_int_operand"))]
11930   "reload_completed"
11931   "ret\t%0"
11932   [(set_attr "length" "3")
11933    (set_attr "atom_unit" "jeu")
11934    (set_attr "length_immediate" "2")
11935    (set_attr "modrm" "0")])
11937 (define_insn "simple_return_indirect_internal"
11938   [(simple_return)
11939    (use (match_operand:SI 0 "register_operand" "r"))]
11940   "reload_completed"
11941   "jmp\t%A0"
11942   [(set_attr "type" "ibr")
11943    (set_attr "length_immediate" "0")])
11945 (define_insn "nop"
11946   [(const_int 0)]
11947   ""
11948   "nop"
11949   [(set_attr "length" "1")
11950    (set_attr "length_immediate" "0")
11951    (set_attr "modrm" "0")])
11953 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
11954 (define_insn "nops"
11955   [(unspec_volatile [(match_operand 0 "const_int_operand")]
11956                     UNSPECV_NOPS)]
11957   "reload_completed"
11959   int num = INTVAL (operands[0]);
11961   gcc_assert (IN_RANGE (num, 1, 8));
11963   while (num--)
11964     fputs ("\tnop\n", asm_out_file);
11966   return "";
11968   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11969    (set_attr "length_immediate" "0")
11970    (set_attr "modrm" "0")])
11972 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11973 ;; branch prediction penalty for the third jump in a 16-byte
11974 ;; block on K8.
11976 (define_insn "pad"
11977   [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11978   ""
11980 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11981   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11982 #else
11983   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11984      The align insn is used to avoid 3 jump instructions in the row to improve
11985      branch prediction and the benefits hardly outweigh the cost of extra 8
11986      nops on the average inserted by full alignment pseudo operation.  */
11987 #endif
11988   return "";
11990   [(set_attr "length" "16")])
11992 (define_expand "prologue"
11993   [(const_int 0)]
11994   ""
11995   "ix86_expand_prologue (); DONE;")
11997 (define_insn "set_got"
11998   [(set (match_operand:SI 0 "register_operand" "=r")
11999         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12000    (clobber (reg:CC FLAGS_REG))]
12001   "!TARGET_64BIT"
12002   "* return output_set_got (operands[0], NULL_RTX);"
12003   [(set_attr "type" "multi")
12004    (set_attr "length" "12")])
12006 (define_insn "set_got_labelled"
12007   [(set (match_operand:SI 0 "register_operand" "=r")
12008         (unspec:SI [(label_ref (match_operand 1))]
12009          UNSPEC_SET_GOT))
12010    (clobber (reg:CC FLAGS_REG))]
12011   "!TARGET_64BIT"
12012   "* return output_set_got (operands[0], operands[1]);"
12013   [(set_attr "type" "multi")
12014    (set_attr "length" "12")])
12016 (define_insn "set_got_rex64"
12017   [(set (match_operand:DI 0 "register_operand" "=r")
12018         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12019   "TARGET_64BIT"
12020   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12021   [(set_attr "type" "lea")
12022    (set_attr "length_address" "4")
12023    (set_attr "mode" "DI")])
12025 (define_insn "set_rip_rex64"
12026   [(set (match_operand:DI 0 "register_operand" "=r")
12027         (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12028   "TARGET_64BIT"
12029   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12030   [(set_attr "type" "lea")
12031    (set_attr "length_address" "4")
12032    (set_attr "mode" "DI")])
12034 (define_insn "set_got_offset_rex64"
12035   [(set (match_operand:DI 0 "register_operand" "=r")
12036         (unspec:DI
12037           [(label_ref (match_operand 1))]
12038           UNSPEC_SET_GOT_OFFSET))]
12039   "TARGET_LP64"
12040   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12041   [(set_attr "type" "imov")
12042    (set_attr "length_immediate" "0")
12043    (set_attr "length_address" "8")
12044    (set_attr "mode" "DI")])
12046 (define_expand "epilogue"
12047   [(const_int 0)]
12048   ""
12049   "ix86_expand_epilogue (1); DONE;")
12051 (define_expand "sibcall_epilogue"
12052   [(const_int 0)]
12053   ""
12054   "ix86_expand_epilogue (0); DONE;")
12056 (define_expand "eh_return"
12057   [(use (match_operand 0 "register_operand"))]
12058   ""
12060   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12062   /* Tricky bit: we write the address of the handler to which we will
12063      be returning into someone else's stack frame, one word below the
12064      stack address we wish to restore.  */
12065   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12066   tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12067   tmp = gen_rtx_MEM (Pmode, tmp);
12068   emit_move_insn (tmp, ra);
12070   emit_jump_insn (gen_eh_return_internal ());
12071   emit_barrier ();
12072   DONE;
12075 (define_insn_and_split "eh_return_internal"
12076   [(eh_return)]
12077   ""
12078   "#"
12079   "epilogue_completed"
12080   [(const_int 0)]
12081   "ix86_expand_epilogue (2); DONE;")
12083 (define_insn "leave"
12084   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12085    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12086    (clobber (mem:BLK (scratch)))]
12087   "!TARGET_64BIT"
12088   "leave"
12089   [(set_attr "type" "leave")])
12091 (define_insn "leave_rex64"
12092   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12093    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12094    (clobber (mem:BLK (scratch)))]
12095   "TARGET_64BIT"
12096   "leave"
12097   [(set_attr "type" "leave")])
12099 ;; Handle -fsplit-stack.
12101 (define_expand "split_stack_prologue"
12102   [(const_int 0)]
12103   ""
12105   ix86_expand_split_stack_prologue ();
12106   DONE;
12109 ;; In order to support the call/return predictor, we use a return
12110 ;; instruction which the middle-end doesn't see.
12111 (define_insn "split_stack_return"
12112   [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12113                      UNSPECV_SPLIT_STACK_RETURN)]
12114   ""
12116   if (operands[0] == const0_rtx)
12117     return "ret";
12118   else
12119     return "ret\t%0";
12121   [(set_attr "atom_unit" "jeu")
12122    (set_attr "modrm" "0")
12123    (set (attr "length")
12124         (if_then_else (match_operand:SI 0 "const0_operand")
12125                       (const_int 1)
12126                       (const_int 3)))
12127    (set (attr "length_immediate")
12128         (if_then_else (match_operand:SI 0 "const0_operand")
12129                       (const_int 0)
12130                       (const_int 2)))])
12132 ;; If there are operand 0 bytes available on the stack, jump to
12133 ;; operand 1.
12135 (define_expand "split_stack_space_check"
12136   [(set (pc) (if_then_else
12137               (ltu (minus (reg SP_REG)
12138                           (match_operand 0 "register_operand"))
12139                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12140               (label_ref (match_operand 1))
12141               (pc)))]
12142   ""
12144   rtx reg, size, limit;
12146   reg = gen_reg_rtx (Pmode);
12147   size = force_reg (Pmode, operands[0]);
12148   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12149   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12150                           UNSPEC_STACK_CHECK);
12151   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12152   ix86_expand_branch (GEU, reg, limit, operands[1]);
12154   DONE;
12157 ;; Bit manipulation instructions.
12159 (define_expand "ffs<mode>2"
12160   [(set (match_dup 2) (const_int -1))
12161    (parallel [(set (match_dup 3) (match_dup 4))
12162               (set (match_operand:SWI48 0 "register_operand")
12163                    (ctz:SWI48
12164                      (match_operand:SWI48 1 "nonimmediate_operand")))])
12165    (set (match_dup 0) (if_then_else:SWI48
12166                         (eq (match_dup 3) (const_int 0))
12167                         (match_dup 2)
12168                         (match_dup 0)))
12169    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12170               (clobber (reg:CC FLAGS_REG))])]
12171   ""
12173   machine_mode flags_mode;
12175   if (<MODE>mode == SImode && !TARGET_CMOVE)
12176     {
12177       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12178       DONE;
12179     }
12181   flags_mode
12182     = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12184   operands[2] = gen_reg_rtx (<MODE>mode);
12185   operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12186   operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12189 (define_insn_and_split "ffssi2_no_cmove"
12190   [(set (match_operand:SI 0 "register_operand" "=r")
12191         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12192    (clobber (match_scratch:SI 2 "=&q"))
12193    (clobber (reg:CC FLAGS_REG))]
12194   "!TARGET_CMOVE"
12195   "#"
12196   "&& reload_completed"
12197   [(parallel [(set (match_dup 4) (match_dup 5))
12198               (set (match_dup 0) (ctz:SI (match_dup 1)))])
12199    (set (strict_low_part (match_dup 3))
12200         (eq:QI (match_dup 4) (const_int 0)))
12201    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12202               (clobber (reg:CC FLAGS_REG))])
12203    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12204               (clobber (reg:CC FLAGS_REG))])
12205    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12206               (clobber (reg:CC FLAGS_REG))])]
12208   machine_mode flags_mode
12209     = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12211   operands[3] = gen_lowpart (QImode, operands[2]);
12212   operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12213   operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12215   ix86_expand_clear (operands[2]);
12218 (define_insn "*tzcnt<mode>_1"
12219   [(set (reg:CCC FLAGS_REG)
12220         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12221                      (const_int 0)))
12222    (set (match_operand:SWI48 0 "register_operand" "=r")
12223         (ctz:SWI48 (match_dup 1)))]
12224   "TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI"
12225   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12226   [(set_attr "type" "alu1")
12227    (set_attr "prefix_0f" "1")
12228    (set_attr "prefix_rep" "1")
12229    (set_attr "btver2_decode" "double")
12230    (set_attr "mode" "<MODE>")])
12232 (define_insn "*bsf<mode>_1"
12233   [(set (reg:CCZ FLAGS_REG)
12234         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12235                      (const_int 0)))
12236    (set (match_operand:SWI48 0 "register_operand" "=r")
12237         (ctz:SWI48 (match_dup 1)))]
12238   ""
12239   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12240   [(set_attr "type" "alu1")
12241    (set_attr "prefix_0f" "1")
12242    (set_attr "btver2_decode" "double")
12243    (set_attr "mode" "<MODE>")])
12245 (define_expand "ctz<mode>2"
12246   [(parallel
12247     [(set (match_operand:SWI248 0 "register_operand")
12248           (ctz:SWI248
12249             (match_operand:SWI248 1 "nonimmediate_operand")))
12250      (clobber (reg:CC FLAGS_REG))])])
12252 ; False dependency happens when destination is only updated by tzcnt,
12253 ; lzcnt or popcnt.  There is no false dependency when destination is
12254 ; also used in source.
12255 (define_insn_and_split "*ctz<mode>2_falsedep_1"
12256   [(set (match_operand:SWI48 0 "register_operand" "=r")
12257         (ctz:SWI48
12258           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12259    (clobber (reg:CC FLAGS_REG))]
12260   "(TARGET_BMI || TARGET_GENERIC)
12261    && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12262   "#"
12263   "&& reload_completed"
12264   [(parallel
12265     [(set (match_dup 0)
12266           (ctz:SWI48 (match_dup 1)))
12267      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12268      (clobber (reg:CC FLAGS_REG))])]
12270   if (!reg_mentioned_p (operands[0], operands[1]))
12271     ix86_expand_clear (operands[0]);
12274 (define_insn "*ctz<mode>2_falsedep"
12275   [(set (match_operand:SWI48 0 "register_operand" "=r")
12276         (ctz:SWI48
12277           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12278    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12279            UNSPEC_INSN_FALSE_DEP)
12280    (clobber (reg:CC FLAGS_REG))]
12281   ""
12283   if (TARGET_BMI)
12284     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12285   else if (TARGET_GENERIC)
12286     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
12287     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12288   else
12289     gcc_unreachable ();
12291   [(set_attr "type" "alu1")
12292    (set_attr "prefix_0f" "1")
12293    (set_attr "prefix_rep" "1")
12294    (set_attr "mode" "<MODE>")])
12296 (define_insn "*ctz<mode>2"
12297   [(set (match_operand:SWI248 0 "register_operand" "=r")
12298         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12299    (clobber (reg:CC FLAGS_REG))]
12300   ""
12302   if (TARGET_BMI)
12303     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12304   else if (optimize_function_for_size_p (cfun))
12305     ;
12306   else if (TARGET_GENERIC)
12307     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
12308     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12310   return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12312   [(set_attr "type" "alu1")
12313    (set_attr "prefix_0f" "1")
12314    (set (attr "prefix_rep")
12315      (if_then_else
12316        (ior (match_test "TARGET_BMI")
12317             (and (not (match_test "optimize_function_for_size_p (cfun)"))
12318                  (match_test "TARGET_GENERIC")))
12319        (const_string "1")
12320        (const_string "0")))
12321    (set_attr "mode" "<MODE>")])
12323 (define_expand "clz<mode>2"
12324   [(parallel
12325      [(set (match_operand:SWI248 0 "register_operand")
12326            (minus:SWI248
12327              (match_dup 2)
12328              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12329       (clobber (reg:CC FLAGS_REG))])
12330    (parallel
12331      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12332       (clobber (reg:CC FLAGS_REG))])]
12333   ""
12335   if (TARGET_LZCNT)
12336     {
12337       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12338       DONE;
12339     }
12340   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12343 (define_expand "clz<mode>2_lzcnt"
12344   [(parallel
12345     [(set (match_operand:SWI248 0 "register_operand")
12346           (clz:SWI248
12347             (match_operand:SWI248 1 "nonimmediate_operand")))
12348      (clobber (reg:CC FLAGS_REG))])]
12349   "TARGET_LZCNT")
12351 (define_insn_and_split "*clz<mode>2_lzcnt_falsedep_1"
12352   [(set (match_operand:SWI48 0 "register_operand" "=r")
12353         (clz:SWI48
12354           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12355    (clobber (reg:CC FLAGS_REG))]
12356   "TARGET_LZCNT
12357    && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12358   "#"
12359   "&& reload_completed"
12360   [(parallel
12361     [(set (match_dup 0)
12362           (clz:SWI48 (match_dup 1)))
12363      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12364      (clobber (reg:CC FLAGS_REG))])]
12366   if (!reg_mentioned_p (operands[0], operands[1]))
12367     ix86_expand_clear (operands[0]);
12370 (define_insn "*clz<mode>2_lzcnt_falsedep"
12371   [(set (match_operand:SWI48 0 "register_operand" "=r")
12372         (clz:SWI48
12373           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12374    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12375            UNSPEC_INSN_FALSE_DEP)
12376    (clobber (reg:CC FLAGS_REG))]
12377   "TARGET_LZCNT"
12378   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12379   [(set_attr "prefix_rep" "1")
12380    (set_attr "type" "bitmanip")
12381    (set_attr "mode" "<MODE>")])
12383 (define_insn "*clz<mode>2_lzcnt"
12384   [(set (match_operand:SWI248 0 "register_operand" "=r")
12385         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12386    (clobber (reg:CC FLAGS_REG))]
12387   "TARGET_LZCNT"
12388   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12389   [(set_attr "prefix_rep" "1")
12390    (set_attr "type" "bitmanip")
12391    (set_attr "mode" "<MODE>")])
12393 ;; BMI instructions.
12394 (define_insn "*bmi_andn_<mode>"
12395   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12396         (and:SWI48
12397           (not:SWI48
12398             (match_operand:SWI48 1 "register_operand" "r,r"))
12399             (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12400    (clobber (reg:CC FLAGS_REG))]
12401   "TARGET_BMI"
12402   "andn\t{%2, %1, %0|%0, %1, %2}"
12403   [(set_attr "type" "bitmanip")
12404    (set_attr "btver2_decode" "direct, double")
12405    (set_attr "mode" "<MODE>")])
12407 (define_insn "bmi_bextr_<mode>"
12408   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12409         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12410                        (match_operand:SWI48 2 "register_operand" "r,r")]
12411                        UNSPEC_BEXTR))
12412    (clobber (reg:CC FLAGS_REG))]
12413   "TARGET_BMI"
12414   "bextr\t{%2, %1, %0|%0, %1, %2}"
12415   [(set_attr "type" "bitmanip")
12416    (set_attr "btver2_decode" "direct, double")
12417    (set_attr "mode" "<MODE>")])
12419 (define_insn "*bmi_blsi_<mode>"
12420   [(set (match_operand:SWI48 0 "register_operand" "=r")
12421         (and:SWI48
12422           (neg:SWI48
12423             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12424           (match_dup 1)))
12425    (clobber (reg:CC FLAGS_REG))]
12426   "TARGET_BMI"
12427   "blsi\t{%1, %0|%0, %1}"
12428   [(set_attr "type" "bitmanip")
12429    (set_attr "btver2_decode" "double")
12430    (set_attr "mode" "<MODE>")])
12432 (define_insn "*bmi_blsmsk_<mode>"
12433   [(set (match_operand:SWI48 0 "register_operand" "=r")
12434         (xor:SWI48
12435           (plus:SWI48
12436             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12437             (const_int -1))
12438           (match_dup 1)))
12439    (clobber (reg:CC FLAGS_REG))]
12440   "TARGET_BMI"
12441   "blsmsk\t{%1, %0|%0, %1}"
12442   [(set_attr "type" "bitmanip")
12443    (set_attr "btver2_decode" "double")
12444    (set_attr "mode" "<MODE>")])
12446 (define_insn "*bmi_blsr_<mode>"
12447   [(set (match_operand:SWI48 0 "register_operand" "=r")
12448         (and:SWI48
12449           (plus:SWI48
12450             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12451             (const_int -1))
12452           (match_dup 1)))
12453    (clobber (reg:CC FLAGS_REG))]
12454    "TARGET_BMI"
12455    "blsr\t{%1, %0|%0, %1}"
12456   [(set_attr "type" "bitmanip")
12457    (set_attr "btver2_decode" "double")
12458    (set_attr "mode" "<MODE>")])
12460 ;; BMI2 instructions.
12461 (define_insn "bmi2_bzhi_<mode>3"
12462   [(set (match_operand:SWI48 0 "register_operand" "=r")
12463         (and:SWI48 (lshiftrt:SWI48 (const_int -1)
12464                                    (match_operand:SWI48 2 "register_operand" "r"))
12465                    (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12466    (clobber (reg:CC FLAGS_REG))]
12467   "TARGET_BMI2"
12468   "bzhi\t{%2, %1, %0|%0, %1, %2}"
12469   [(set_attr "type" "bitmanip")
12470    (set_attr "prefix" "vex")
12471    (set_attr "mode" "<MODE>")])
12473 (define_insn "bmi2_pdep_<mode>3"
12474   [(set (match_operand:SWI48 0 "register_operand" "=r")
12475         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12476                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12477                        UNSPEC_PDEP))]
12478   "TARGET_BMI2"
12479   "pdep\t{%2, %1, %0|%0, %1, %2}"
12480   [(set_attr "type" "bitmanip")
12481    (set_attr "prefix" "vex")
12482    (set_attr "mode" "<MODE>")])
12484 (define_insn "bmi2_pext_<mode>3"
12485   [(set (match_operand:SWI48 0 "register_operand" "=r")
12486         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12487                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12488                        UNSPEC_PEXT))]
12489   "TARGET_BMI2"
12490   "pext\t{%2, %1, %0|%0, %1, %2}"
12491   [(set_attr "type" "bitmanip")
12492    (set_attr "prefix" "vex")
12493    (set_attr "mode" "<MODE>")])
12495 ;; TBM instructions.
12496 (define_insn "tbm_bextri_<mode>"
12497   [(set (match_operand:SWI48 0 "register_operand" "=r")
12498         (zero_extract:SWI48
12499           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12500           (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12501           (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12502    (clobber (reg:CC FLAGS_REG))]
12503    "TARGET_TBM"
12505   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12506   return "bextr\t{%2, %1, %0|%0, %1, %2}";
12508   [(set_attr "type" "bitmanip")
12509    (set_attr "mode" "<MODE>")])
12511 (define_insn "*tbm_blcfill_<mode>"
12512   [(set (match_operand:SWI48 0 "register_operand" "=r")
12513         (and:SWI48
12514           (plus:SWI48
12515             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12516             (const_int 1))
12517           (match_dup 1)))
12518    (clobber (reg:CC FLAGS_REG))]
12519    "TARGET_TBM"
12520    "blcfill\t{%1, %0|%0, %1}"
12521   [(set_attr "type" "bitmanip")
12522    (set_attr "mode" "<MODE>")])
12524 (define_insn "*tbm_blci_<mode>"
12525   [(set (match_operand:SWI48 0 "register_operand" "=r")
12526         (ior:SWI48
12527           (not:SWI48
12528             (plus:SWI48
12529               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12530               (const_int 1)))
12531           (match_dup 1)))
12532    (clobber (reg:CC FLAGS_REG))]
12533    "TARGET_TBM"
12534    "blci\t{%1, %0|%0, %1}"
12535   [(set_attr "type" "bitmanip")
12536    (set_attr "mode" "<MODE>")])
12538 (define_insn "*tbm_blcic_<mode>"
12539   [(set (match_operand:SWI48 0 "register_operand" "=r")
12540         (and:SWI48
12541           (plus:SWI48
12542             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12543             (const_int 1))
12544           (not:SWI48
12545             (match_dup 1))))
12546    (clobber (reg:CC FLAGS_REG))]
12547    "TARGET_TBM"
12548    "blcic\t{%1, %0|%0, %1}"
12549   [(set_attr "type" "bitmanip")
12550    (set_attr "mode" "<MODE>")])
12552 (define_insn "*tbm_blcmsk_<mode>"
12553   [(set (match_operand:SWI48 0 "register_operand" "=r")
12554         (xor:SWI48
12555           (plus:SWI48
12556             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12557             (const_int 1))
12558           (match_dup 1)))
12559    (clobber (reg:CC FLAGS_REG))]
12560    "TARGET_TBM"
12561    "blcmsk\t{%1, %0|%0, %1}"
12562   [(set_attr "type" "bitmanip")
12563    (set_attr "mode" "<MODE>")])
12565 (define_insn "*tbm_blcs_<mode>"
12566   [(set (match_operand:SWI48 0 "register_operand" "=r")
12567         (ior:SWI48
12568           (plus:SWI48
12569             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12570             (const_int 1))
12571           (match_dup 1)))
12572    (clobber (reg:CC FLAGS_REG))]
12573    "TARGET_TBM"
12574    "blcs\t{%1, %0|%0, %1}"
12575   [(set_attr "type" "bitmanip")
12576    (set_attr "mode" "<MODE>")])
12578 (define_insn "*tbm_blsfill_<mode>"
12579   [(set (match_operand:SWI48 0 "register_operand" "=r")
12580         (ior:SWI48
12581           (plus:SWI48
12582             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12583             (const_int -1))
12584           (match_dup 1)))
12585    (clobber (reg:CC FLAGS_REG))]
12586    "TARGET_TBM"
12587    "blsfill\t{%1, %0|%0, %1}"
12588   [(set_attr "type" "bitmanip")
12589    (set_attr "mode" "<MODE>")])
12591 (define_insn "*tbm_blsic_<mode>"
12592   [(set (match_operand:SWI48 0 "register_operand" "=r")
12593         (ior:SWI48
12594           (plus:SWI48
12595             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12596             (const_int -1))
12597           (not:SWI48
12598             (match_dup 1))))
12599    (clobber (reg:CC FLAGS_REG))]
12600    "TARGET_TBM"
12601    "blsic\t{%1, %0|%0, %1}"
12602   [(set_attr "type" "bitmanip")
12603    (set_attr "mode" "<MODE>")])
12605 (define_insn "*tbm_t1mskc_<mode>"
12606   [(set (match_operand:SWI48 0 "register_operand" "=r")
12607         (ior:SWI48
12608           (plus:SWI48
12609             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12610             (const_int 1))
12611           (not:SWI48
12612             (match_dup 1))))
12613    (clobber (reg:CC FLAGS_REG))]
12614    "TARGET_TBM"
12615    "t1mskc\t{%1, %0|%0, %1}"
12616   [(set_attr "type" "bitmanip")
12617    (set_attr "mode" "<MODE>")])
12619 (define_insn "*tbm_tzmsk_<mode>"
12620   [(set (match_operand:SWI48 0 "register_operand" "=r")
12621         (and:SWI48
12622           (plus:SWI48
12623             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12624             (const_int -1))
12625           (not:SWI48
12626             (match_dup 1))))
12627    (clobber (reg:CC FLAGS_REG))]
12628    "TARGET_TBM"
12629    "tzmsk\t{%1, %0|%0, %1}"
12630   [(set_attr "type" "bitmanip")
12631    (set_attr "mode" "<MODE>")])
12633 (define_insn "bsr_rex64"
12634   [(set (match_operand:DI 0 "register_operand" "=r")
12635         (minus:DI (const_int 63)
12636                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12637    (clobber (reg:CC FLAGS_REG))]
12638   "TARGET_64BIT"
12639   "bsr{q}\t{%1, %0|%0, %1}"
12640   [(set_attr "type" "alu1")
12641    (set_attr "prefix_0f" "1")
12642    (set_attr "mode" "DI")])
12644 (define_insn "bsr"
12645   [(set (match_operand:SI 0 "register_operand" "=r")
12646         (minus:SI (const_int 31)
12647                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12648    (clobber (reg:CC FLAGS_REG))]
12649   ""
12650   "bsr{l}\t{%1, %0|%0, %1}"
12651   [(set_attr "type" "alu1")
12652    (set_attr "prefix_0f" "1")
12653    (set_attr "mode" "SI")])
12655 (define_insn "*bsrhi"
12656   [(set (match_operand:HI 0 "register_operand" "=r")
12657         (minus:HI (const_int 15)
12658                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12659    (clobber (reg:CC FLAGS_REG))]
12660   ""
12661   "bsr{w}\t{%1, %0|%0, %1}"
12662   [(set_attr "type" "alu1")
12663    (set_attr "prefix_0f" "1")
12664    (set_attr "mode" "HI")])
12666 (define_expand "popcount<mode>2"
12667   [(parallel
12668     [(set (match_operand:SWI248 0 "register_operand")
12669           (popcount:SWI248
12670             (match_operand:SWI248 1 "nonimmediate_operand")))
12671      (clobber (reg:CC FLAGS_REG))])]
12672   "TARGET_POPCNT")
12674 (define_insn_and_split "*popcount<mode>2_falsedep_1"
12675   [(set (match_operand:SWI48 0 "register_operand" "=r")
12676         (popcount:SWI48
12677           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12678    (clobber (reg:CC FLAGS_REG))]
12679   "TARGET_POPCNT
12680    && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12681   "#"
12682   "&& reload_completed"
12683   [(parallel
12684     [(set (match_dup 0)
12685           (popcount:SWI48 (match_dup 1)))
12686      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12687      (clobber (reg:CC FLAGS_REG))])]
12689   if (!reg_mentioned_p (operands[0], operands[1]))
12690     ix86_expand_clear (operands[0]);
12693 (define_insn "*popcount<mode>2_falsedep"
12694   [(set (match_operand:SWI48 0 "register_operand" "=r")
12695         (popcount:SWI48
12696           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12697    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12698            UNSPEC_INSN_FALSE_DEP)
12699    (clobber (reg:CC FLAGS_REG))]
12700   "TARGET_POPCNT"
12702 #if TARGET_MACHO
12703   return "popcnt\t{%1, %0|%0, %1}";
12704 #else
12705   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12706 #endif
12708   [(set_attr "prefix_rep" "1")
12709    (set_attr "type" "bitmanip")
12710    (set_attr "mode" "<MODE>")])
12712 (define_insn "*popcount<mode>2"
12713   [(set (match_operand:SWI248 0 "register_operand" "=r")
12714         (popcount:SWI248
12715           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12716    (clobber (reg:CC FLAGS_REG))]
12717   "TARGET_POPCNT"
12719 #if TARGET_MACHO
12720   return "popcnt\t{%1, %0|%0, %1}";
12721 #else
12722   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12723 #endif
12725   [(set_attr "prefix_rep" "1")
12726    (set_attr "type" "bitmanip")
12727    (set_attr "mode" "<MODE>")])
12729 (define_expand "bswapdi2"
12730   [(set (match_operand:DI 0 "register_operand")
12731         (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12732   "TARGET_64BIT"
12734   if (!TARGET_MOVBE)
12735     operands[1] = force_reg (DImode, operands[1]);
12738 (define_expand "bswapsi2"
12739   [(set (match_operand:SI 0 "register_operand")
12740         (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12741   ""
12743   if (TARGET_MOVBE)
12744     ;
12745   else if (TARGET_BSWAP)
12746     operands[1] = force_reg (SImode, operands[1]);
12747   else
12748     {
12749       rtx x = operands[0];
12751       emit_move_insn (x, operands[1]);
12752       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12753       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12754       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12755       DONE;
12756     }
12759 (define_insn "*bswap<mode>2_movbe"
12760   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12761         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12762   "TARGET_MOVBE
12763    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12764   "@
12765     bswap\t%0
12766     movbe\t{%1, %0|%0, %1}
12767     movbe\t{%1, %0|%0, %1}"
12768   [(set_attr "type" "bitmanip,imov,imov")
12769    (set_attr "modrm" "0,1,1")
12770    (set_attr "prefix_0f" "*,1,1")
12771    (set_attr "prefix_extra" "*,1,1")
12772    (set_attr "mode" "<MODE>")])
12774 (define_insn "*bswap<mode>2"
12775   [(set (match_operand:SWI48 0 "register_operand" "=r")
12776         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12777   "TARGET_BSWAP"
12778   "bswap\t%0"
12779   [(set_attr "type" "bitmanip")
12780    (set_attr "modrm" "0")
12781    (set_attr "mode" "<MODE>")])
12783 (define_insn "*bswaphi_lowpart_1"
12784   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12785         (bswap:HI (match_dup 0)))
12786    (clobber (reg:CC FLAGS_REG))]
12787   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12788   "@
12789     xchg{b}\t{%h0, %b0|%b0, %h0}
12790     rol{w}\t{$8, %0|%0, 8}"
12791   [(set_attr "length" "2,4")
12792    (set_attr "mode" "QI,HI")])
12794 (define_insn "bswaphi_lowpart"
12795   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12796         (bswap:HI (match_dup 0)))
12797    (clobber (reg:CC FLAGS_REG))]
12798   ""
12799   "rol{w}\t{$8, %0|%0, 8}"
12800   [(set_attr "length" "4")
12801    (set_attr "mode" "HI")])
12803 (define_expand "paritydi2"
12804   [(set (match_operand:DI 0 "register_operand")
12805         (parity:DI (match_operand:DI 1 "register_operand")))]
12806   "! TARGET_POPCNT"
12808   rtx scratch = gen_reg_rtx (QImode);
12809   rtx cond;
12811   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12812                                 NULL_RTX, operands[1]));
12814   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12815                          gen_rtx_REG (CCmode, FLAGS_REG),
12816                          const0_rtx);
12817   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12819   if (TARGET_64BIT)
12820     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12821   else
12822     {
12823       rtx tmp = gen_reg_rtx (SImode);
12825       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12826       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12827     }
12828   DONE;
12831 (define_expand "paritysi2"
12832   [(set (match_operand:SI 0 "register_operand")
12833         (parity:SI (match_operand:SI 1 "register_operand")))]
12834   "! TARGET_POPCNT"
12836   rtx scratch = gen_reg_rtx (QImode);
12837   rtx cond;
12839   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12841   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12842                          gen_rtx_REG (CCmode, FLAGS_REG),
12843                          const0_rtx);
12844   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12846   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12847   DONE;
12850 (define_insn_and_split "paritydi2_cmp"
12851   [(set (reg:CC FLAGS_REG)
12852         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12853                    UNSPEC_PARITY))
12854    (clobber (match_scratch:DI 0 "=r"))
12855    (clobber (match_scratch:SI 1 "=&r"))
12856    (clobber (match_scratch:HI 2 "=Q"))]
12857   "! TARGET_POPCNT"
12858   "#"
12859   "&& reload_completed"
12860   [(parallel
12861      [(set (match_dup 1)
12862            (xor:SI (match_dup 1) (match_dup 4)))
12863       (clobber (reg:CC FLAGS_REG))])
12864    (parallel
12865      [(set (reg:CC FLAGS_REG)
12866            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12867       (clobber (match_dup 1))
12868       (clobber (match_dup 2))])]
12870   operands[4] = gen_lowpart (SImode, operands[3]);
12872   if (TARGET_64BIT)
12873     {
12874       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12875       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12876     }
12877   else
12878     operands[1] = gen_highpart (SImode, operands[3]);
12881 (define_insn_and_split "paritysi2_cmp"
12882   [(set (reg:CC FLAGS_REG)
12883         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12884                    UNSPEC_PARITY))
12885    (clobber (match_scratch:SI 0 "=r"))
12886    (clobber (match_scratch:HI 1 "=&Q"))]
12887   "! TARGET_POPCNT"
12888   "#"
12889   "&& reload_completed"
12890   [(parallel
12891      [(set (match_dup 1)
12892            (xor:HI (match_dup 1) (match_dup 3)))
12893       (clobber (reg:CC FLAGS_REG))])
12894    (parallel
12895      [(set (reg:CC FLAGS_REG)
12896            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12897       (clobber (match_dup 1))])]
12899   operands[3] = gen_lowpart (HImode, operands[2]);
12901   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12902   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12905 (define_insn "*parityhi2_cmp"
12906   [(set (reg:CC FLAGS_REG)
12907         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12908                    UNSPEC_PARITY))
12909    (clobber (match_scratch:HI 0 "=Q"))]
12910   "! TARGET_POPCNT"
12911   "xor{b}\t{%h0, %b0|%b0, %h0}"
12912   [(set_attr "length" "2")
12913    (set_attr "mode" "HI")])
12916 ;; Thread-local storage patterns for ELF.
12918 ;; Note that these code sequences must appear exactly as shown
12919 ;; in order to allow linker relaxation.
12921 (define_insn "*tls_global_dynamic_32_gnu"
12922   [(set (match_operand:SI 0 "register_operand" "=a")
12923         (unspec:SI
12924          [(match_operand:SI 1 "register_operand" "b")
12925           (match_operand 2 "tls_symbolic_operand")
12926           (match_operand 3 "constant_call_address_operand" "Bz")
12927           (reg:SI SP_REG)]
12928          UNSPEC_TLS_GD))
12929    (clobber (match_scratch:SI 4 "=d"))
12930    (clobber (match_scratch:SI 5 "=c"))
12931    (clobber (reg:CC FLAGS_REG))]
12932   "!TARGET_64BIT && TARGET_GNU_TLS"
12934   output_asm_insn
12935     ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12936   if (TARGET_SUN_TLS)
12937 #ifdef HAVE_AS_IX86_TLSGDPLT
12938     return "call\t%a2@tlsgdplt";
12939 #else
12940     return "call\t%p3@plt";
12941 #endif
12942   return "call\t%P3";
12944   [(set_attr "type" "multi")
12945    (set_attr "length" "12")])
12947 (define_expand "tls_global_dynamic_32"
12948   [(parallel
12949     [(set (match_operand:SI 0 "register_operand")
12950           (unspec:SI [(match_operand:SI 2 "register_operand")
12951                       (match_operand 1 "tls_symbolic_operand")
12952                       (match_operand 3 "constant_call_address_operand")
12953                       (reg:SI SP_REG)]
12954                      UNSPEC_TLS_GD))
12955      (clobber (match_scratch:SI 4))
12956      (clobber (match_scratch:SI 5))
12957      (clobber (reg:CC FLAGS_REG))])]
12958   ""
12959   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
12961 (define_insn "*tls_global_dynamic_64_<mode>"
12962   [(set (match_operand:P 0 "register_operand" "=a")
12963         (call:P
12964          (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
12965          (match_operand 3)))
12966    (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12967              UNSPEC_TLS_GD)]
12968   "TARGET_64BIT"
12970   if (!TARGET_X32)
12971     fputs (ASM_BYTE "0x66\n", asm_out_file);
12972   output_asm_insn
12973     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12974   fputs (ASM_SHORT "0x6666\n", asm_out_file);
12975   fputs ("\trex64\n", asm_out_file);
12976   if (TARGET_SUN_TLS)
12977     return "call\t%p2@plt";
12978   return "call\t%P2";
12980   [(set_attr "type" "multi")
12981    (set (attr "length")
12982         (symbol_ref "TARGET_X32 ? 15 : 16"))])
12984 (define_insn "*tls_global_dynamic_64_largepic"
12985   [(set (match_operand:DI 0 "register_operand" "=a")
12986         (call:DI
12987          (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
12988                           (match_operand:DI 3 "immediate_operand" "i")))
12989          (match_operand 4)))
12990    (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12991              UNSPEC_TLS_GD)]
12992   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
12993    && GET_CODE (operands[3]) == CONST
12994    && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
12995    && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
12997   output_asm_insn
12998     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12999   output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
13000   output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
13001   return "call\t{*%%rax|rax}";
13003   [(set_attr "type" "multi")
13004    (set_attr "length" "22")])
13006 (define_expand "tls_global_dynamic_64_<mode>"
13007   [(parallel
13008     [(set (match_operand:P 0 "register_operand")
13009           (call:P
13010            (mem:QI (match_operand 2))
13011            (const_int 0)))
13012      (unspec:P [(match_operand 1 "tls_symbolic_operand")]
13013                UNSPEC_TLS_GD)])]
13014   "TARGET_64BIT"
13015   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13017 (define_insn "*tls_local_dynamic_base_32_gnu"
13018   [(set (match_operand:SI 0 "register_operand" "=a")
13019         (unspec:SI
13020          [(match_operand:SI 1 "register_operand" "b")
13021           (match_operand 2 "constant_call_address_operand" "Bz")
13022           (reg:SI SP_REG)]
13023          UNSPEC_TLS_LD_BASE))
13024    (clobber (match_scratch:SI 3 "=d"))
13025    (clobber (match_scratch:SI 4 "=c"))
13026    (clobber (reg:CC FLAGS_REG))]
13027   "!TARGET_64BIT && TARGET_GNU_TLS"
13029   output_asm_insn
13030     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
13031   if (TARGET_SUN_TLS)
13032     {
13033       if (HAVE_AS_IX86_TLSLDMPLT)
13034         return "call\t%&@tlsldmplt";
13035       else
13036         return "call\t%p2@plt";
13037     }
13038   return "call\t%P2";
13040   [(set_attr "type" "multi")
13041    (set_attr "length" "11")])
13043 (define_expand "tls_local_dynamic_base_32"
13044   [(parallel
13045      [(set (match_operand:SI 0 "register_operand")
13046            (unspec:SI
13047             [(match_operand:SI 1 "register_operand")
13048              (match_operand 2 "constant_call_address_operand")
13049              (reg:SI SP_REG)]
13050             UNSPEC_TLS_LD_BASE))
13051       (clobber (match_scratch:SI 3))
13052       (clobber (match_scratch:SI 4))
13053       (clobber (reg:CC FLAGS_REG))])]
13054   ""
13055   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13057 (define_insn "*tls_local_dynamic_base_64_<mode>"
13058   [(set (match_operand:P 0 "register_operand" "=a")
13059         (call:P
13060          (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
13061          (match_operand 2)))
13062    (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13063   "TARGET_64BIT"
13065   output_asm_insn
13066     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13067   if (TARGET_SUN_TLS)
13068     return "call\t%p1@plt";
13069   return "call\t%P1";
13071   [(set_attr "type" "multi")
13072    (set_attr "length" "12")])
13074 (define_insn "*tls_local_dynamic_base_64_largepic"
13075   [(set (match_operand:DI 0 "register_operand" "=a")
13076         (call:DI
13077          (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13078                           (match_operand:DI 2 "immediate_operand" "i")))
13079          (match_operand 3)))
13080    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13081   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13082    && GET_CODE (operands[2]) == CONST
13083    && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13084    && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13086   output_asm_insn
13087     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13088   output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13089   output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13090   return "call\t{*%%rax|rax}";
13092   [(set_attr "type" "multi")
13093    (set_attr "length" "22")])
13095 (define_expand "tls_local_dynamic_base_64_<mode>"
13096   [(parallel
13097      [(set (match_operand:P 0 "register_operand")
13098            (call:P
13099             (mem:QI (match_operand 1))
13100             (const_int 0)))
13101       (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13102   "TARGET_64BIT"
13103   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13105 ;; Local dynamic of a single variable is a lose.  Show combine how
13106 ;; to convert that back to global dynamic.
13108 (define_insn_and_split "*tls_local_dynamic_32_once"
13109   [(set (match_operand:SI 0 "register_operand" "=a")
13110         (plus:SI
13111          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13112                      (match_operand 2 "constant_call_address_operand" "Bz")
13113                      (reg:SI SP_REG)]
13114                     UNSPEC_TLS_LD_BASE)
13115          (const:SI (unspec:SI
13116                     [(match_operand 3 "tls_symbolic_operand")]
13117                     UNSPEC_DTPOFF))))
13118    (clobber (match_scratch:SI 4 "=d"))
13119    (clobber (match_scratch:SI 5 "=c"))
13120    (clobber (reg:CC FLAGS_REG))]
13121   ""
13122   "#"
13123   ""
13124   [(parallel
13125      [(set (match_dup 0)
13126            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13127                        (reg:SI SP_REG)]
13128                       UNSPEC_TLS_GD))
13129       (clobber (match_dup 4))
13130       (clobber (match_dup 5))
13131       (clobber (reg:CC FLAGS_REG))])])
13133 ;; Segment register for the thread base ptr load
13134 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13136 ;; Load and add the thread base pointer from %<tp_seg>:0.
13137 (define_insn "*load_tp_x32"
13138   [(set (match_operand:SI 0 "register_operand" "=r")
13139         (unspec:SI [(const_int 0)] UNSPEC_TP))]
13140   "TARGET_X32"
13141   "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13142   [(set_attr "type" "imov")
13143    (set_attr "modrm" "0")
13144    (set_attr "length" "7")
13145    (set_attr "memory" "load")
13146    (set_attr "imm_disp" "false")])
13148 (define_insn "*load_tp_x32_zext"
13149   [(set (match_operand:DI 0 "register_operand" "=r")
13150         (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13151   "TARGET_X32"
13152   "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13153   [(set_attr "type" "imov")
13154    (set_attr "modrm" "0")
13155    (set_attr "length" "7")
13156    (set_attr "memory" "load")
13157    (set_attr "imm_disp" "false")])
13159 (define_insn "*load_tp_<mode>"
13160   [(set (match_operand:P 0 "register_operand" "=r")
13161         (unspec:P [(const_int 0)] UNSPEC_TP))]
13162   "!TARGET_X32"
13163   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13164   [(set_attr "type" "imov")
13165    (set_attr "modrm" "0")
13166    (set_attr "length" "7")
13167    (set_attr "memory" "load")
13168    (set_attr "imm_disp" "false")])
13170 (define_insn "*add_tp_x32"
13171   [(set (match_operand:SI 0 "register_operand" "=r")
13172         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13173                  (match_operand:SI 1 "register_operand" "0")))
13174    (clobber (reg:CC FLAGS_REG))]
13175   "TARGET_X32"
13176   "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13177   [(set_attr "type" "alu")
13178    (set_attr "modrm" "0")
13179    (set_attr "length" "7")
13180    (set_attr "memory" "load")
13181    (set_attr "imm_disp" "false")])
13183 (define_insn "*add_tp_x32_zext"
13184   [(set (match_operand:DI 0 "register_operand" "=r")
13185         (zero_extend:DI
13186           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13187                    (match_operand:SI 1 "register_operand" "0"))))
13188    (clobber (reg:CC FLAGS_REG))]
13189   "TARGET_X32"
13190   "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13191   [(set_attr "type" "alu")
13192    (set_attr "modrm" "0")
13193    (set_attr "length" "7")
13194    (set_attr "memory" "load")
13195    (set_attr "imm_disp" "false")])
13197 (define_insn "*add_tp_<mode>"
13198   [(set (match_operand:P 0 "register_operand" "=r")
13199         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13200                 (match_operand:P 1 "register_operand" "0")))
13201    (clobber (reg:CC FLAGS_REG))]
13202   "!TARGET_X32"
13203   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13204   [(set_attr "type" "alu")
13205    (set_attr "modrm" "0")
13206    (set_attr "length" "7")
13207    (set_attr "memory" "load")
13208    (set_attr "imm_disp" "false")])
13210 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13211 ;; %rax as destination of the initial executable code sequence.
13212 (define_insn "tls_initial_exec_64_sun"
13213   [(set (match_operand:DI 0 "register_operand" "=a")
13214         (unspec:DI
13215          [(match_operand 1 "tls_symbolic_operand")]
13216          UNSPEC_TLS_IE_SUN))
13217    (clobber (reg:CC FLAGS_REG))]
13218   "TARGET_64BIT && TARGET_SUN_TLS"
13220   output_asm_insn
13221     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13222   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13224   [(set_attr "type" "multi")])
13226 ;; GNU2 TLS patterns can be split.
13228 (define_expand "tls_dynamic_gnu2_32"
13229   [(set (match_dup 3)
13230         (plus:SI (match_operand:SI 2 "register_operand")
13231                  (const:SI
13232                   (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13233                              UNSPEC_TLSDESC))))
13234    (parallel
13235     [(set (match_operand:SI 0 "register_operand")
13236           (unspec:SI [(match_dup 1) (match_dup 3)
13237                       (match_dup 2) (reg:SI SP_REG)]
13238                       UNSPEC_TLSDESC))
13239      (clobber (reg:CC FLAGS_REG))])]
13240   "!TARGET_64BIT && TARGET_GNU2_TLS"
13242   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13243   ix86_tls_descriptor_calls_expanded_in_cfun = true;
13246 (define_insn "*tls_dynamic_gnu2_lea_32"
13247   [(set (match_operand:SI 0 "register_operand" "=r")
13248         (plus:SI (match_operand:SI 1 "register_operand" "b")
13249                  (const:SI
13250                   (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13251                               UNSPEC_TLSDESC))))]
13252   "!TARGET_64BIT && TARGET_GNU2_TLS"
13253   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13254   [(set_attr "type" "lea")
13255    (set_attr "mode" "SI")
13256    (set_attr "length" "6")
13257    (set_attr "length_address" "4")])
13259 (define_insn "*tls_dynamic_gnu2_call_32"
13260   [(set (match_operand:SI 0 "register_operand" "=a")
13261         (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13262                     (match_operand:SI 2 "register_operand" "0")
13263                     ;; we have to make sure %ebx still points to the GOT
13264                     (match_operand:SI 3 "register_operand" "b")
13265                     (reg:SI SP_REG)]
13266                    UNSPEC_TLSDESC))
13267    (clobber (reg:CC FLAGS_REG))]
13268   "!TARGET_64BIT && TARGET_GNU2_TLS"
13269   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13270   [(set_attr "type" "call")
13271    (set_attr "length" "2")
13272    (set_attr "length_address" "0")])
13274 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13275   [(set (match_operand:SI 0 "register_operand" "=&a")
13276         (plus:SI
13277          (unspec:SI [(match_operand 3 "tls_modbase_operand")
13278                      (match_operand:SI 4)
13279                      (match_operand:SI 2 "register_operand" "b")
13280                      (reg:SI SP_REG)]
13281                     UNSPEC_TLSDESC)
13282          (const:SI (unspec:SI
13283                     [(match_operand 1 "tls_symbolic_operand")]
13284                     UNSPEC_DTPOFF))))
13285    (clobber (reg:CC FLAGS_REG))]
13286   "!TARGET_64BIT && TARGET_GNU2_TLS"
13287   "#"
13288   ""
13289   [(set (match_dup 0) (match_dup 5))]
13291   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13292   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13295 (define_expand "tls_dynamic_gnu2_64"
13296   [(set (match_dup 2)
13297         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13298                    UNSPEC_TLSDESC))
13299    (parallel
13300     [(set (match_operand:DI 0 "register_operand")
13301           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13302                      UNSPEC_TLSDESC))
13303      (clobber (reg:CC FLAGS_REG))])]
13304   "TARGET_64BIT && TARGET_GNU2_TLS"
13306   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13307   ix86_tls_descriptor_calls_expanded_in_cfun = true;
13310 (define_insn "*tls_dynamic_gnu2_lea_64"
13311   [(set (match_operand:DI 0 "register_operand" "=r")
13312         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13313                    UNSPEC_TLSDESC))]
13314   "TARGET_64BIT && TARGET_GNU2_TLS"
13315   "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13316   [(set_attr "type" "lea")
13317    (set_attr "mode" "DI")
13318    (set_attr "length" "7")
13319    (set_attr "length_address" "4")])
13321 (define_insn "*tls_dynamic_gnu2_call_64"
13322   [(set (match_operand:DI 0 "register_operand" "=a")
13323         (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13324                     (match_operand:DI 2 "register_operand" "0")
13325                     (reg:DI SP_REG)]
13326                    UNSPEC_TLSDESC))
13327    (clobber (reg:CC FLAGS_REG))]
13328   "TARGET_64BIT && TARGET_GNU2_TLS"
13329   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13330   [(set_attr "type" "call")
13331    (set_attr "length" "2")
13332    (set_attr "length_address" "0")])
13334 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13335   [(set (match_operand:DI 0 "register_operand" "=&a")
13336         (plus:DI
13337          (unspec:DI [(match_operand 2 "tls_modbase_operand")
13338                      (match_operand:DI 3)
13339                      (reg:DI SP_REG)]
13340                     UNSPEC_TLSDESC)
13341          (const:DI (unspec:DI
13342                     [(match_operand 1 "tls_symbolic_operand")]
13343                     UNSPEC_DTPOFF))))
13344    (clobber (reg:CC FLAGS_REG))]
13345   "TARGET_64BIT && TARGET_GNU2_TLS"
13346   "#"
13347   ""
13348   [(set (match_dup 0) (match_dup 4))]
13350   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13351   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13354 ;; These patterns match the binary 387 instructions for addM3, subM3,
13355 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
13356 ;; SFmode.  The first is the normal insn, the second the same insn but
13357 ;; with one operand a conversion, and the third the same insn but with
13358 ;; the other operand a conversion.  The conversion may be SFmode or
13359 ;; SImode if the target mode DFmode, but only SImode if the target mode
13360 ;; is SFmode.
13362 ;; Gcc is slightly more smart about handling normal two address instructions
13363 ;; so use special patterns for add and mull.
13365 (define_insn "*fop_<mode>_comm_mixed"
13366   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13367         (match_operator:MODEF 3 "binary_fp_operator"
13368           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13369            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13370   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13371    && COMMUTATIVE_ARITH_P (operands[3])
13372    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13373   "* return output_387_binary_op (insn, operands);"
13374   [(set (attr "type")
13375         (if_then_else (eq_attr "alternative" "1,2")
13376            (if_then_else (match_operand:MODEF 3 "mult_operator")
13377               (const_string "ssemul")
13378               (const_string "sseadd"))
13379            (if_then_else (match_operand:MODEF 3 "mult_operator")
13380               (const_string "fmul")
13381               (const_string "fop"))))
13382    (set_attr "isa" "*,noavx,avx")
13383    (set_attr "prefix" "orig,orig,vex")
13384    (set_attr "mode" "<MODE>")])
13386 (define_insn "*fop_<mode>_comm_sse"
13387   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
13388         (match_operator:MODEF 3 "binary_fp_operator"
13389           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
13390            (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]))]
13391   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13392    && COMMUTATIVE_ARITH_P (operands[3])
13393    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13394   "* return output_387_binary_op (insn, operands);"
13395   [(set (attr "type")
13396         (if_then_else (match_operand:MODEF 3 "mult_operator")
13397            (const_string "ssemul")
13398            (const_string "sseadd")))
13399    (set_attr "isa" "noavx,avx")
13400    (set_attr "prefix" "orig,vex")
13401    (set_attr "mode" "<MODE>")])
13403 (define_insn "*fop_<mode>_comm_i387"
13404   [(set (match_operand:MODEF 0 "register_operand" "=f")
13405         (match_operator:MODEF 3 "binary_fp_operator"
13406           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13407            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13408   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13409    && COMMUTATIVE_ARITH_P (operands[3])
13410    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13411   "* return output_387_binary_op (insn, operands);"
13412   [(set (attr "type")
13413         (if_then_else (match_operand:MODEF 3 "mult_operator")
13414            (const_string "fmul")
13415            (const_string "fop")))
13416    (set_attr "mode" "<MODE>")])
13418 (define_insn "*fop_<mode>_1_mixed"
13419   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13420         (match_operator:MODEF 3 "binary_fp_operator"
13421           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13422            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13423   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13424    && !COMMUTATIVE_ARITH_P (operands[3])
13425    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13426   "* return output_387_binary_op (insn, operands);"
13427   [(set (attr "type")
13428         (cond [(and (eq_attr "alternative" "2,3")
13429                     (match_operand:MODEF 3 "mult_operator"))
13430                  (const_string "ssemul")
13431                (and (eq_attr "alternative" "2,3")
13432                     (match_operand:MODEF 3 "div_operator"))
13433                  (const_string "ssediv")
13434                (eq_attr "alternative" "2,3")
13435                  (const_string "sseadd")
13436                (match_operand:MODEF 3 "mult_operator")
13437                  (const_string "fmul")
13438                (match_operand:MODEF 3 "div_operator")
13439                  (const_string "fdiv")
13440               ]
13441               (const_string "fop")))
13442    (set_attr "isa" "*,*,noavx,avx")
13443    (set_attr "prefix" "orig,orig,orig,vex")
13444    (set_attr "mode" "<MODE>")])
13446 (define_insn "*rcpsf2_sse"
13447   [(set (match_operand:SF 0 "register_operand" "=x")
13448         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13449                    UNSPEC_RCP))]
13450   "TARGET_SSE_MATH"
13451   "%vrcpss\t{%1, %d0|%d0, %1}"
13452   [(set_attr "type" "sse")
13453    (set_attr "atom_sse_attr" "rcp")
13454    (set_attr "btver2_sse_attr" "rcp")
13455    (set_attr "prefix" "maybe_vex")
13456    (set_attr "mode" "SF")])
13458 (define_insn "*fop_<mode>_1_sse"
13459   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13460         (match_operator:MODEF 3 "binary_fp_operator"
13461           [(match_operand:MODEF 1 "register_operand" "0,x")
13462            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13463   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13464    && !COMMUTATIVE_ARITH_P (operands[3])"
13465   "* return output_387_binary_op (insn, operands);"
13466   [(set (attr "type")
13467         (cond [(match_operand:MODEF 3 "mult_operator")
13468                  (const_string "ssemul")
13469                (match_operand:MODEF 3 "div_operator")
13470                  (const_string "ssediv")
13471               ]
13472               (const_string "sseadd")))
13473    (set_attr "isa" "noavx,avx")
13474    (set_attr "prefix" "orig,vex")
13475    (set_attr "mode" "<MODE>")])
13477 ;; This pattern is not fully shadowed by the pattern above.
13478 (define_insn "*fop_<mode>_1_i387"
13479   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13480         (match_operator:MODEF 3 "binary_fp_operator"
13481           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13482            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13483   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13484    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13485    && !COMMUTATIVE_ARITH_P (operands[3])
13486    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13487   "* return output_387_binary_op (insn, operands);"
13488   [(set (attr "type")
13489         (cond [(match_operand:MODEF 3 "mult_operator")
13490                  (const_string "fmul")
13491                (match_operand:MODEF 3 "div_operator")
13492                  (const_string "fdiv")
13493               ]
13494               (const_string "fop")))
13495    (set_attr "mode" "<MODE>")])
13497 ;; ??? Add SSE splitters for these!
13498 (define_insn "*fop_<MODEF:mode>_2_i387"
13499   [(set (match_operand:MODEF 0 "register_operand" "=f")
13500         (match_operator:MODEF 3 "binary_fp_operator"
13501           [(float:MODEF
13502              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13503            (match_operand:MODEF 2 "register_operand" "0")]))]
13504   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13505    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13506    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13507        || optimize_function_for_size_p (cfun))"
13508   { return output_387_binary_op (insn, operands); }
13509   [(set (attr "type")
13510         (cond [(match_operand:MODEF 3 "mult_operator")
13511                  (const_string "fmul")
13512                (match_operand:MODEF 3 "div_operator")
13513                  (const_string "fdiv")
13514               ]
13515               (const_string "fop")))
13516    (set_attr "fp_int_src" "true")
13517    (set_attr "mode" "<SWI24:MODE>")])
13519 (define_insn "*fop_<MODEF:mode>_3_i387"
13520   [(set (match_operand:MODEF 0 "register_operand" "=f")
13521         (match_operator:MODEF 3 "binary_fp_operator"
13522           [(match_operand:MODEF 1 "register_operand" "0")
13523            (float:MODEF
13524              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13525   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13526    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13527    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13528        || optimize_function_for_size_p (cfun))"
13529   { return output_387_binary_op (insn, operands); }
13530   [(set (attr "type")
13531         (cond [(match_operand:MODEF 3 "mult_operator")
13532                  (const_string "fmul")
13533                (match_operand:MODEF 3 "div_operator")
13534                  (const_string "fdiv")
13535               ]
13536               (const_string "fop")))
13537    (set_attr "fp_int_src" "true")
13538    (set_attr "mode" "<MODE>")])
13540 (define_insn "*fop_df_4_i387"
13541   [(set (match_operand:DF 0 "register_operand" "=f,f")
13542         (match_operator:DF 3 "binary_fp_operator"
13543            [(float_extend:DF
13544              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13545             (match_operand:DF 2 "register_operand" "0,f")]))]
13546   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13547    && !(TARGET_SSE2 && TARGET_SSE_MATH)
13548    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13549   "* return output_387_binary_op (insn, operands);"
13550   [(set (attr "type")
13551         (cond [(match_operand:DF 3 "mult_operator")
13552                  (const_string "fmul")
13553                (match_operand:DF 3 "div_operator")
13554                  (const_string "fdiv")
13555               ]
13556               (const_string "fop")))
13557    (set_attr "mode" "SF")])
13559 (define_insn "*fop_df_5_i387"
13560   [(set (match_operand:DF 0 "register_operand" "=f,f")
13561         (match_operator:DF 3 "binary_fp_operator"
13562           [(match_operand:DF 1 "register_operand" "0,f")
13563            (float_extend:DF
13564             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13565   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13566    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13567   "* return output_387_binary_op (insn, operands);"
13568   [(set (attr "type")
13569         (cond [(match_operand:DF 3 "mult_operator")
13570                  (const_string "fmul")
13571                (match_operand:DF 3 "div_operator")
13572                  (const_string "fdiv")
13573               ]
13574               (const_string "fop")))
13575    (set_attr "mode" "SF")])
13577 (define_insn "*fop_df_6_i387"
13578   [(set (match_operand:DF 0 "register_operand" "=f,f")
13579         (match_operator:DF 3 "binary_fp_operator"
13580           [(float_extend:DF
13581             (match_operand:SF 1 "register_operand" "0,f"))
13582            (float_extend:DF
13583             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13584   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13585    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13586   "* return output_387_binary_op (insn, operands);"
13587   [(set (attr "type")
13588         (cond [(match_operand:DF 3 "mult_operator")
13589                  (const_string "fmul")
13590                (match_operand:DF 3 "div_operator")
13591                  (const_string "fdiv")
13592               ]
13593               (const_string "fop")))
13594    (set_attr "mode" "SF")])
13596 (define_insn "*fop_xf_comm_i387"
13597   [(set (match_operand:XF 0 "register_operand" "=f")
13598         (match_operator:XF 3 "binary_fp_operator"
13599                         [(match_operand:XF 1 "register_operand" "%0")
13600                          (match_operand:XF 2 "register_operand" "f")]))]
13601   "TARGET_80387
13602    && COMMUTATIVE_ARITH_P (operands[3])"
13603   "* return output_387_binary_op (insn, operands);"
13604   [(set (attr "type")
13605         (if_then_else (match_operand:XF 3 "mult_operator")
13606            (const_string "fmul")
13607            (const_string "fop")))
13608    (set_attr "mode" "XF")])
13610 (define_insn "*fop_xf_1_i387"
13611   [(set (match_operand:XF 0 "register_operand" "=f,f")
13612         (match_operator:XF 3 "binary_fp_operator"
13613                         [(match_operand:XF 1 "register_operand" "0,f")
13614                          (match_operand:XF 2 "register_operand" "f,0")]))]
13615   "TARGET_80387
13616    && !COMMUTATIVE_ARITH_P (operands[3])"
13617   "* return output_387_binary_op (insn, operands);"
13618   [(set (attr "type")
13619         (cond [(match_operand:XF 3 "mult_operator")
13620                  (const_string "fmul")
13621                (match_operand:XF 3 "div_operator")
13622                  (const_string "fdiv")
13623               ]
13624               (const_string "fop")))
13625    (set_attr "mode" "XF")])
13627 (define_insn "*fop_xf_2_i387"
13628   [(set (match_operand:XF 0 "register_operand" "=f")
13629         (match_operator:XF 3 "binary_fp_operator"
13630           [(float:XF
13631              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13632            (match_operand:XF 2 "register_operand" "0")]))]
13633   "TARGET_80387
13634    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13635   { return output_387_binary_op (insn, operands); }
13636   [(set (attr "type")
13637         (cond [(match_operand:XF 3 "mult_operator")
13638                  (const_string "fmul")
13639                (match_operand:XF 3 "div_operator")
13640                  (const_string "fdiv")
13641               ]
13642               (const_string "fop")))
13643    (set_attr "fp_int_src" "true")
13644    (set_attr "mode" "<MODE>")])
13646 (define_insn "*fop_xf_3_i387"
13647   [(set (match_operand:XF 0 "register_operand" "=f")
13648         (match_operator:XF 3 "binary_fp_operator"
13649           [(match_operand:XF 1 "register_operand" "0")
13650            (float:XF
13651              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13652   "TARGET_80387
13653    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13654   { return output_387_binary_op (insn, operands); }
13655   [(set (attr "type")
13656         (cond [(match_operand:XF 3 "mult_operator")
13657                  (const_string "fmul")
13658                (match_operand:XF 3 "div_operator")
13659                  (const_string "fdiv")
13660               ]
13661               (const_string "fop")))
13662    (set_attr "fp_int_src" "true")
13663    (set_attr "mode" "<MODE>")])
13665 (define_insn "*fop_xf_4_i387"
13666   [(set (match_operand:XF 0 "register_operand" "=f,f")
13667         (match_operator:XF 3 "binary_fp_operator"
13668            [(float_extend:XF
13669               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13670             (match_operand:XF 2 "register_operand" "0,f")]))]
13671   "TARGET_80387"
13672   "* return output_387_binary_op (insn, operands);"
13673   [(set (attr "type")
13674         (cond [(match_operand:XF 3 "mult_operator")
13675                  (const_string "fmul")
13676                (match_operand:XF 3 "div_operator")
13677                  (const_string "fdiv")
13678               ]
13679               (const_string "fop")))
13680    (set_attr "mode" "<MODE>")])
13682 (define_insn "*fop_xf_5_i387"
13683   [(set (match_operand:XF 0 "register_operand" "=f,f")
13684         (match_operator:XF 3 "binary_fp_operator"
13685           [(match_operand:XF 1 "register_operand" "0,f")
13686            (float_extend:XF
13687              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13688   "TARGET_80387"
13689   "* return output_387_binary_op (insn, operands);"
13690   [(set (attr "type")
13691         (cond [(match_operand:XF 3 "mult_operator")
13692                  (const_string "fmul")
13693                (match_operand:XF 3 "div_operator")
13694                  (const_string "fdiv")
13695               ]
13696               (const_string "fop")))
13697    (set_attr "mode" "<MODE>")])
13699 (define_insn "*fop_xf_6_i387"
13700   [(set (match_operand:XF 0 "register_operand" "=f,f")
13701         (match_operator:XF 3 "binary_fp_operator"
13702           [(float_extend:XF
13703              (match_operand:MODEF 1 "register_operand" "0,f"))
13704            (float_extend:XF
13705              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13706   "TARGET_80387"
13707   "* return output_387_binary_op (insn, operands);"
13708   [(set (attr "type")
13709         (cond [(match_operand:XF 3 "mult_operator")
13710                  (const_string "fmul")
13711                (match_operand:XF 3 "div_operator")
13712                  (const_string "fdiv")
13713               ]
13714               (const_string "fop")))
13715    (set_attr "mode" "<MODE>")])
13717 ;; FPU special functions.
13719 ;; This pattern implements a no-op XFmode truncation for
13720 ;; all fancy i386 XFmode math functions.
13722 (define_insn "truncxf<mode>2_i387_noop_unspec"
13723   [(set (match_operand:MODEF 0 "register_operand" "=f")
13724         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13725         UNSPEC_TRUNC_NOOP))]
13726   "TARGET_USE_FANCY_MATH_387"
13727   "* return output_387_reg_move (insn, operands);"
13728   [(set_attr "type" "fmov")
13729    (set_attr "mode" "<MODE>")])
13731 (define_insn "sqrtxf2"
13732   [(set (match_operand:XF 0 "register_operand" "=f")
13733         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13734   "TARGET_USE_FANCY_MATH_387"
13735   "fsqrt"
13736   [(set_attr "type" "fpspc")
13737    (set_attr "mode" "XF")
13738    (set_attr "athlon_decode" "direct")
13739    (set_attr "amdfam10_decode" "direct")
13740    (set_attr "bdver1_decode" "direct")])
13742 (define_insn "sqrt_extend<mode>xf2_i387"
13743   [(set (match_operand:XF 0 "register_operand" "=f")
13744         (sqrt:XF
13745           (float_extend:XF
13746             (match_operand:MODEF 1 "register_operand" "0"))))]
13747   "TARGET_USE_FANCY_MATH_387"
13748   "fsqrt"
13749   [(set_attr "type" "fpspc")
13750    (set_attr "mode" "XF")
13751    (set_attr "athlon_decode" "direct")
13752    (set_attr "amdfam10_decode" "direct")
13753    (set_attr "bdver1_decode" "direct")])
13755 (define_insn "*rsqrtsf2_sse"
13756   [(set (match_operand:SF 0 "register_operand" "=x")
13757         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13758                    UNSPEC_RSQRT))]
13759   "TARGET_SSE_MATH"
13760   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13761   [(set_attr "type" "sse")
13762    (set_attr "atom_sse_attr" "rcp")
13763    (set_attr "btver2_sse_attr" "rcp")
13764    (set_attr "prefix" "maybe_vex")
13765    (set_attr "mode" "SF")])
13767 (define_expand "rsqrtsf2"
13768   [(set (match_operand:SF 0 "register_operand")
13769         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13770                    UNSPEC_RSQRT))]
13771   "TARGET_SSE_MATH"
13773   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13774   DONE;
13777 (define_insn "*sqrt<mode>2_sse"
13778   [(set (match_operand:MODEF 0 "register_operand" "=x")
13779         (sqrt:MODEF
13780           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13781   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13782   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13783   [(set_attr "type" "sse")
13784    (set_attr "atom_sse_attr" "sqrt")
13785    (set_attr "btver2_sse_attr" "sqrt")
13786    (set_attr "prefix" "maybe_vex")
13787    (set_attr "mode" "<MODE>")
13788    (set_attr "athlon_decode" "*")
13789    (set_attr "amdfam10_decode" "*")
13790    (set_attr "bdver1_decode" "*")])
13792 (define_expand "sqrt<mode>2"
13793   [(set (match_operand:MODEF 0 "register_operand")
13794         (sqrt:MODEF
13795           (match_operand:MODEF 1 "nonimmediate_operand")))]
13796   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13797    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13799   if (<MODE>mode == SFmode
13800       && TARGET_SSE_MATH
13801       && TARGET_RECIP_SQRT
13802       && !optimize_function_for_size_p (cfun)
13803       && flag_finite_math_only && !flag_trapping_math
13804       && flag_unsafe_math_optimizations)
13805     {
13806       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13807       DONE;
13808     }
13810   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13811     {
13812       rtx op0 = gen_reg_rtx (XFmode);
13813       rtx op1 = force_reg (<MODE>mode, operands[1]);
13815       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13816       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13817       DONE;
13818    }
13821 (define_insn "fpremxf4_i387"
13822   [(set (match_operand:XF 0 "register_operand" "=f")
13823         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13824                     (match_operand:XF 3 "register_operand" "1")]
13825                    UNSPEC_FPREM_F))
13826    (set (match_operand:XF 1 "register_operand" "=u")
13827         (unspec:XF [(match_dup 2) (match_dup 3)]
13828                    UNSPEC_FPREM_U))
13829    (set (reg:CCFP FPSR_REG)
13830         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13831                      UNSPEC_C2_FLAG))]
13832   "TARGET_USE_FANCY_MATH_387
13833    && flag_finite_math_only"
13834   "fprem"
13835   [(set_attr "type" "fpspc")
13836    (set_attr "mode" "XF")])
13838 (define_expand "fmodxf3"
13839   [(use (match_operand:XF 0 "register_operand"))
13840    (use (match_operand:XF 1 "general_operand"))
13841    (use (match_operand:XF 2 "general_operand"))]
13842   "TARGET_USE_FANCY_MATH_387
13843    && flag_finite_math_only"
13845   rtx_code_label *label = gen_label_rtx ();
13847   rtx op1 = gen_reg_rtx (XFmode);
13848   rtx op2 = gen_reg_rtx (XFmode);
13850   emit_move_insn (op2, operands[2]);
13851   emit_move_insn (op1, operands[1]);
13853   emit_label (label);
13854   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13855   ix86_emit_fp_unordered_jump (label);
13856   LABEL_NUSES (label) = 1;
13858   emit_move_insn (operands[0], op1);
13859   DONE;
13862 (define_expand "fmod<mode>3"
13863   [(use (match_operand:MODEF 0 "register_operand"))
13864    (use (match_operand:MODEF 1 "general_operand"))
13865    (use (match_operand:MODEF 2 "general_operand"))]
13866   "TARGET_USE_FANCY_MATH_387
13867    && flag_finite_math_only"
13869   rtx (*gen_truncxf) (rtx, rtx);
13871   rtx_code_label *label = gen_label_rtx ();
13873   rtx op1 = gen_reg_rtx (XFmode);
13874   rtx op2 = gen_reg_rtx (XFmode);
13876   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13877   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13879   emit_label (label);
13880   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13881   ix86_emit_fp_unordered_jump (label);
13882   LABEL_NUSES (label) = 1;
13884   /* Truncate the result properly for strict SSE math.  */
13885   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13886       && !TARGET_MIX_SSE_I387)
13887     gen_truncxf = gen_truncxf<mode>2;
13888   else
13889     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13891   emit_insn (gen_truncxf (operands[0], op1));
13892   DONE;
13895 (define_insn "fprem1xf4_i387"
13896   [(set (match_operand:XF 0 "register_operand" "=f")
13897         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13898                     (match_operand:XF 3 "register_operand" "1")]
13899                    UNSPEC_FPREM1_F))
13900    (set (match_operand:XF 1 "register_operand" "=u")
13901         (unspec:XF [(match_dup 2) (match_dup 3)]
13902                    UNSPEC_FPREM1_U))
13903    (set (reg:CCFP FPSR_REG)
13904         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13905                      UNSPEC_C2_FLAG))]
13906   "TARGET_USE_FANCY_MATH_387
13907    && flag_finite_math_only"
13908   "fprem1"
13909   [(set_attr "type" "fpspc")
13910    (set_attr "mode" "XF")])
13912 (define_expand "remainderxf3"
13913   [(use (match_operand:XF 0 "register_operand"))
13914    (use (match_operand:XF 1 "general_operand"))
13915    (use (match_operand:XF 2 "general_operand"))]
13916   "TARGET_USE_FANCY_MATH_387
13917    && flag_finite_math_only"
13919   rtx_code_label *label = gen_label_rtx ();
13921   rtx op1 = gen_reg_rtx (XFmode);
13922   rtx op2 = gen_reg_rtx (XFmode);
13924   emit_move_insn (op2, operands[2]);
13925   emit_move_insn (op1, operands[1]);
13927   emit_label (label);
13928   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13929   ix86_emit_fp_unordered_jump (label);
13930   LABEL_NUSES (label) = 1;
13932   emit_move_insn (operands[0], op1);
13933   DONE;
13936 (define_expand "remainder<mode>3"
13937   [(use (match_operand:MODEF 0 "register_operand"))
13938    (use (match_operand:MODEF 1 "general_operand"))
13939    (use (match_operand:MODEF 2 "general_operand"))]
13940   "TARGET_USE_FANCY_MATH_387
13941    && flag_finite_math_only"
13943   rtx (*gen_truncxf) (rtx, rtx);
13945   rtx_code_label *label = gen_label_rtx ();
13947   rtx op1 = gen_reg_rtx (XFmode);
13948   rtx op2 = gen_reg_rtx (XFmode);
13950   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13951   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13953   emit_label (label);
13955   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13956   ix86_emit_fp_unordered_jump (label);
13957   LABEL_NUSES (label) = 1;
13959   /* Truncate the result properly for strict SSE math.  */
13960   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13961       && !TARGET_MIX_SSE_I387)
13962     gen_truncxf = gen_truncxf<mode>2;
13963   else
13964     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13966   emit_insn (gen_truncxf (operands[0], op1));
13967   DONE;
13970 (define_int_iterator SINCOS
13971         [UNSPEC_SIN
13972          UNSPEC_COS])
13974 (define_int_attr sincos
13975         [(UNSPEC_SIN "sin")
13976          (UNSPEC_COS "cos")])
13978 (define_insn "*<sincos>xf2_i387"
13979   [(set (match_operand:XF 0 "register_operand" "=f")
13980         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13981                    SINCOS))]
13982   "TARGET_USE_FANCY_MATH_387
13983    && flag_unsafe_math_optimizations"
13984   "f<sincos>"
13985   [(set_attr "type" "fpspc")
13986    (set_attr "mode" "XF")])
13988 (define_insn "*<sincos>_extend<mode>xf2_i387"
13989   [(set (match_operand:XF 0 "register_operand" "=f")
13990         (unspec:XF [(float_extend:XF
13991                       (match_operand:MODEF 1 "register_operand" "0"))]
13992                    SINCOS))]
13993   "TARGET_USE_FANCY_MATH_387
13994    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13995        || TARGET_MIX_SSE_I387)
13996    && flag_unsafe_math_optimizations"
13997   "f<sincos>"
13998   [(set_attr "type" "fpspc")
13999    (set_attr "mode" "XF")])
14001 ;; When sincos pattern is defined, sin and cos builtin functions will be
14002 ;; expanded to sincos pattern with one of its outputs left unused.
14003 ;; CSE pass will figure out if two sincos patterns can be combined,
14004 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14005 ;; depending on the unused output.
14007 (define_insn "sincosxf3"
14008   [(set (match_operand:XF 0 "register_operand" "=f")
14009         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14010                    UNSPEC_SINCOS_COS))
14011    (set (match_operand:XF 1 "register_operand" "=u")
14012         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14013   "TARGET_USE_FANCY_MATH_387
14014    && flag_unsafe_math_optimizations"
14015   "fsincos"
14016   [(set_attr "type" "fpspc")
14017    (set_attr "mode" "XF")])
14019 (define_split
14020   [(set (match_operand:XF 0 "register_operand")
14021         (unspec:XF [(match_operand:XF 2 "register_operand")]
14022                    UNSPEC_SINCOS_COS))
14023    (set (match_operand:XF 1 "register_operand")
14024         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14025   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14026    && can_create_pseudo_p ()"
14027   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
14029 (define_split
14030   [(set (match_operand:XF 0 "register_operand")
14031         (unspec:XF [(match_operand:XF 2 "register_operand")]
14032                    UNSPEC_SINCOS_COS))
14033    (set (match_operand:XF 1 "register_operand")
14034         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14035   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14036    && can_create_pseudo_p ()"
14037   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
14039 (define_insn "sincos_extend<mode>xf3_i387"
14040   [(set (match_operand:XF 0 "register_operand" "=f")
14041         (unspec:XF [(float_extend:XF
14042                       (match_operand:MODEF 2 "register_operand" "0"))]
14043                    UNSPEC_SINCOS_COS))
14044    (set (match_operand:XF 1 "register_operand" "=u")
14045         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14046   "TARGET_USE_FANCY_MATH_387
14047    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14048        || TARGET_MIX_SSE_I387)
14049    && flag_unsafe_math_optimizations"
14050   "fsincos"
14051   [(set_attr "type" "fpspc")
14052    (set_attr "mode" "XF")])
14054 (define_split
14055   [(set (match_operand:XF 0 "register_operand")
14056         (unspec:XF [(float_extend:XF
14057                       (match_operand:MODEF 2 "register_operand"))]
14058                    UNSPEC_SINCOS_COS))
14059    (set (match_operand:XF 1 "register_operand")
14060         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14061   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14062    && can_create_pseudo_p ()"
14063   [(set (match_dup 1)
14064         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14066 (define_split
14067   [(set (match_operand:XF 0 "register_operand")
14068         (unspec:XF [(float_extend:XF
14069                       (match_operand:MODEF 2 "register_operand"))]
14070                    UNSPEC_SINCOS_COS))
14071    (set (match_operand:XF 1 "register_operand")
14072         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14073   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14074    && can_create_pseudo_p ()"
14075   [(set (match_dup 0)
14076         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14078 (define_expand "sincos<mode>3"
14079   [(use (match_operand:MODEF 0 "register_operand"))
14080    (use (match_operand:MODEF 1 "register_operand"))
14081    (use (match_operand:MODEF 2 "register_operand"))]
14082   "TARGET_USE_FANCY_MATH_387
14083    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14084        || TARGET_MIX_SSE_I387)
14085    && flag_unsafe_math_optimizations"
14087   rtx op0 = gen_reg_rtx (XFmode);
14088   rtx op1 = gen_reg_rtx (XFmode);
14090   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14091   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14092   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14093   DONE;
14096 (define_insn "fptanxf4_i387"
14097   [(set (match_operand:XF 0 "register_operand" "=f")
14098         (match_operand:XF 3 "const_double_operand" "F"))
14099    (set (match_operand:XF 1 "register_operand" "=u")
14100         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14101                    UNSPEC_TAN))]
14102   "TARGET_USE_FANCY_MATH_387
14103    && flag_unsafe_math_optimizations
14104    && standard_80387_constant_p (operands[3]) == 2"
14105   "fptan"
14106   [(set_attr "type" "fpspc")
14107    (set_attr "mode" "XF")])
14109 (define_insn "fptan_extend<mode>xf4_i387"
14110   [(set (match_operand:MODEF 0 "register_operand" "=f")
14111         (match_operand:MODEF 3 "const_double_operand" "F"))
14112    (set (match_operand:XF 1 "register_operand" "=u")
14113         (unspec:XF [(float_extend:XF
14114                       (match_operand:MODEF 2 "register_operand" "0"))]
14115                    UNSPEC_TAN))]
14116   "TARGET_USE_FANCY_MATH_387
14117    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14118        || TARGET_MIX_SSE_I387)
14119    && flag_unsafe_math_optimizations
14120    && standard_80387_constant_p (operands[3]) == 2"
14121   "fptan"
14122   [(set_attr "type" "fpspc")
14123    (set_attr "mode" "XF")])
14125 (define_expand "tanxf2"
14126   [(use (match_operand:XF 0 "register_operand"))
14127    (use (match_operand:XF 1 "register_operand"))]
14128   "TARGET_USE_FANCY_MATH_387
14129    && flag_unsafe_math_optimizations"
14131   rtx one = gen_reg_rtx (XFmode);
14132   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14134   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14135   DONE;
14138 (define_expand "tan<mode>2"
14139   [(use (match_operand:MODEF 0 "register_operand"))
14140    (use (match_operand:MODEF 1 "register_operand"))]
14141   "TARGET_USE_FANCY_MATH_387
14142    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14143        || TARGET_MIX_SSE_I387)
14144    && flag_unsafe_math_optimizations"
14146   rtx op0 = gen_reg_rtx (XFmode);
14148   rtx one = gen_reg_rtx (<MODE>mode);
14149   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14151   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14152                                              operands[1], op2));
14153   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14154   DONE;
14157 (define_insn "*fpatanxf3_i387"
14158   [(set (match_operand:XF 0 "register_operand" "=f")
14159         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14160                     (match_operand:XF 2 "register_operand" "u")]
14161                    UNSPEC_FPATAN))
14162    (clobber (match_scratch:XF 3 "=2"))]
14163   "TARGET_USE_FANCY_MATH_387
14164    && flag_unsafe_math_optimizations"
14165   "fpatan"
14166   [(set_attr "type" "fpspc")
14167    (set_attr "mode" "XF")])
14169 (define_insn "fpatan_extend<mode>xf3_i387"
14170   [(set (match_operand:XF 0 "register_operand" "=f")
14171         (unspec:XF [(float_extend:XF
14172                       (match_operand:MODEF 1 "register_operand" "0"))
14173                     (float_extend:XF
14174                       (match_operand:MODEF 2 "register_operand" "u"))]
14175                    UNSPEC_FPATAN))
14176    (clobber (match_scratch:XF 3 "=2"))]
14177   "TARGET_USE_FANCY_MATH_387
14178    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14179        || TARGET_MIX_SSE_I387)
14180    && flag_unsafe_math_optimizations"
14181   "fpatan"
14182   [(set_attr "type" "fpspc")
14183    (set_attr "mode" "XF")])
14185 (define_expand "atan2xf3"
14186   [(parallel [(set (match_operand:XF 0 "register_operand")
14187                    (unspec:XF [(match_operand:XF 2 "register_operand")
14188                                (match_operand:XF 1 "register_operand")]
14189                               UNSPEC_FPATAN))
14190               (clobber (match_scratch:XF 3))])]
14191   "TARGET_USE_FANCY_MATH_387
14192    && flag_unsafe_math_optimizations")
14194 (define_expand "atan2<mode>3"
14195   [(use (match_operand:MODEF 0 "register_operand"))
14196    (use (match_operand:MODEF 1 "register_operand"))
14197    (use (match_operand:MODEF 2 "register_operand"))]
14198   "TARGET_USE_FANCY_MATH_387
14199    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14200        || TARGET_MIX_SSE_I387)
14201    && flag_unsafe_math_optimizations"
14203   rtx op0 = gen_reg_rtx (XFmode);
14205   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14206   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14207   DONE;
14210 (define_expand "atanxf2"
14211   [(parallel [(set (match_operand:XF 0 "register_operand")
14212                    (unspec:XF [(match_dup 2)
14213                                (match_operand:XF 1 "register_operand")]
14214                               UNSPEC_FPATAN))
14215               (clobber (match_scratch:XF 3))])]
14216   "TARGET_USE_FANCY_MATH_387
14217    && flag_unsafe_math_optimizations"
14219   operands[2] = gen_reg_rtx (XFmode);
14220   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
14223 (define_expand "atan<mode>2"
14224   [(use (match_operand:MODEF 0 "register_operand"))
14225    (use (match_operand:MODEF 1 "register_operand"))]
14226   "TARGET_USE_FANCY_MATH_387
14227    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14228        || TARGET_MIX_SSE_I387)
14229    && flag_unsafe_math_optimizations"
14231   rtx op0 = gen_reg_rtx (XFmode);
14233   rtx op2 = gen_reg_rtx (<MODE>mode);
14234   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
14236   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14237   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14238   DONE;
14241 (define_expand "asinxf2"
14242   [(set (match_dup 2)
14243         (mult:XF (match_operand:XF 1 "register_operand")
14244                  (match_dup 1)))
14245    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14246    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14247    (parallel [(set (match_operand:XF 0 "register_operand")
14248                    (unspec:XF [(match_dup 5) (match_dup 1)]
14249                               UNSPEC_FPATAN))
14250               (clobber (match_scratch:XF 6))])]
14251   "TARGET_USE_FANCY_MATH_387
14252    && flag_unsafe_math_optimizations"
14254   int i;
14256   if (optimize_insn_for_size_p ())
14257     FAIL;
14259   for (i = 2; i < 6; i++)
14260     operands[i] = gen_reg_rtx (XFmode);
14262   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14265 (define_expand "asin<mode>2"
14266   [(use (match_operand:MODEF 0 "register_operand"))
14267    (use (match_operand:MODEF 1 "general_operand"))]
14268  "TARGET_USE_FANCY_MATH_387
14269    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14270        || TARGET_MIX_SSE_I387)
14271    && flag_unsafe_math_optimizations"
14273   rtx op0 = gen_reg_rtx (XFmode);
14274   rtx op1 = gen_reg_rtx (XFmode);
14276   if (optimize_insn_for_size_p ())
14277     FAIL;
14279   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14280   emit_insn (gen_asinxf2 (op0, op1));
14281   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14282   DONE;
14285 (define_expand "acosxf2"
14286   [(set (match_dup 2)
14287         (mult:XF (match_operand:XF 1 "register_operand")
14288                  (match_dup 1)))
14289    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14290    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14291    (parallel [(set (match_operand:XF 0 "register_operand")
14292                    (unspec:XF [(match_dup 1) (match_dup 5)]
14293                               UNSPEC_FPATAN))
14294               (clobber (match_scratch:XF 6))])]
14295   "TARGET_USE_FANCY_MATH_387
14296    && flag_unsafe_math_optimizations"
14298   int i;
14300   if (optimize_insn_for_size_p ())
14301     FAIL;
14303   for (i = 2; i < 6; i++)
14304     operands[i] = gen_reg_rtx (XFmode);
14306   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14309 (define_expand "acos<mode>2"
14310   [(use (match_operand:MODEF 0 "register_operand"))
14311    (use (match_operand:MODEF 1 "general_operand"))]
14312  "TARGET_USE_FANCY_MATH_387
14313    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14314        || TARGET_MIX_SSE_I387)
14315    && flag_unsafe_math_optimizations"
14317   rtx op0 = gen_reg_rtx (XFmode);
14318   rtx op1 = gen_reg_rtx (XFmode);
14320   if (optimize_insn_for_size_p ())
14321     FAIL;
14323   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14324   emit_insn (gen_acosxf2 (op0, op1));
14325   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14326   DONE;
14329 (define_insn "fyl2xxf3_i387"
14330   [(set (match_operand:XF 0 "register_operand" "=f")
14331         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14332                     (match_operand:XF 2 "register_operand" "u")]
14333                    UNSPEC_FYL2X))
14334    (clobber (match_scratch:XF 3 "=2"))]
14335   "TARGET_USE_FANCY_MATH_387
14336    && flag_unsafe_math_optimizations"
14337   "fyl2x"
14338   [(set_attr "type" "fpspc")
14339    (set_attr "mode" "XF")])
14341 (define_insn "fyl2x_extend<mode>xf3_i387"
14342   [(set (match_operand:XF 0 "register_operand" "=f")
14343         (unspec:XF [(float_extend:XF
14344                       (match_operand:MODEF 1 "register_operand" "0"))
14345                     (match_operand:XF 2 "register_operand" "u")]
14346                    UNSPEC_FYL2X))
14347    (clobber (match_scratch:XF 3 "=2"))]
14348   "TARGET_USE_FANCY_MATH_387
14349    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14350        || TARGET_MIX_SSE_I387)
14351    && flag_unsafe_math_optimizations"
14352   "fyl2x"
14353   [(set_attr "type" "fpspc")
14354    (set_attr "mode" "XF")])
14356 (define_expand "logxf2"
14357   [(parallel [(set (match_operand:XF 0 "register_operand")
14358                    (unspec:XF [(match_operand:XF 1 "register_operand")
14359                                (match_dup 2)] UNSPEC_FYL2X))
14360               (clobber (match_scratch:XF 3))])]
14361   "TARGET_USE_FANCY_MATH_387
14362    && flag_unsafe_math_optimizations"
14364   operands[2] = gen_reg_rtx (XFmode);
14365   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14368 (define_expand "log<mode>2"
14369   [(use (match_operand:MODEF 0 "register_operand"))
14370    (use (match_operand:MODEF 1 "register_operand"))]
14371   "TARGET_USE_FANCY_MATH_387
14372    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14373        || TARGET_MIX_SSE_I387)
14374    && flag_unsafe_math_optimizations"
14376   rtx op0 = gen_reg_rtx (XFmode);
14378   rtx op2 = gen_reg_rtx (XFmode);
14379   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14381   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14382   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14383   DONE;
14386 (define_expand "log10xf2"
14387   [(parallel [(set (match_operand:XF 0 "register_operand")
14388                    (unspec:XF [(match_operand:XF 1 "register_operand")
14389                                (match_dup 2)] UNSPEC_FYL2X))
14390               (clobber (match_scratch:XF 3))])]
14391   "TARGET_USE_FANCY_MATH_387
14392    && flag_unsafe_math_optimizations"
14394   operands[2] = gen_reg_rtx (XFmode);
14395   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14398 (define_expand "log10<mode>2"
14399   [(use (match_operand:MODEF 0 "register_operand"))
14400    (use (match_operand:MODEF 1 "register_operand"))]
14401   "TARGET_USE_FANCY_MATH_387
14402    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14403        || TARGET_MIX_SSE_I387)
14404    && flag_unsafe_math_optimizations"
14406   rtx op0 = gen_reg_rtx (XFmode);
14408   rtx op2 = gen_reg_rtx (XFmode);
14409   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14411   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14412   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14413   DONE;
14416 (define_expand "log2xf2"
14417   [(parallel [(set (match_operand:XF 0 "register_operand")
14418                    (unspec:XF [(match_operand:XF 1 "register_operand")
14419                                (match_dup 2)] UNSPEC_FYL2X))
14420               (clobber (match_scratch:XF 3))])]
14421   "TARGET_USE_FANCY_MATH_387
14422    && flag_unsafe_math_optimizations"
14424   operands[2] = gen_reg_rtx (XFmode);
14425   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14428 (define_expand "log2<mode>2"
14429   [(use (match_operand:MODEF 0 "register_operand"))
14430    (use (match_operand:MODEF 1 "register_operand"))]
14431   "TARGET_USE_FANCY_MATH_387
14432    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14433        || TARGET_MIX_SSE_I387)
14434    && flag_unsafe_math_optimizations"
14436   rtx op0 = gen_reg_rtx (XFmode);
14438   rtx op2 = gen_reg_rtx (XFmode);
14439   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14441   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14442   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14443   DONE;
14446 (define_insn "fyl2xp1xf3_i387"
14447   [(set (match_operand:XF 0 "register_operand" "=f")
14448         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14449                     (match_operand:XF 2 "register_operand" "u")]
14450                    UNSPEC_FYL2XP1))
14451    (clobber (match_scratch:XF 3 "=2"))]
14452   "TARGET_USE_FANCY_MATH_387
14453    && flag_unsafe_math_optimizations"
14454   "fyl2xp1"
14455   [(set_attr "type" "fpspc")
14456    (set_attr "mode" "XF")])
14458 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14459   [(set (match_operand:XF 0 "register_operand" "=f")
14460         (unspec:XF [(float_extend:XF
14461                       (match_operand:MODEF 1 "register_operand" "0"))
14462                     (match_operand:XF 2 "register_operand" "u")]
14463                    UNSPEC_FYL2XP1))
14464    (clobber (match_scratch:XF 3 "=2"))]
14465   "TARGET_USE_FANCY_MATH_387
14466    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14467        || TARGET_MIX_SSE_I387)
14468    && flag_unsafe_math_optimizations"
14469   "fyl2xp1"
14470   [(set_attr "type" "fpspc")
14471    (set_attr "mode" "XF")])
14473 (define_expand "log1pxf2"
14474   [(use (match_operand:XF 0 "register_operand"))
14475    (use (match_operand:XF 1 "register_operand"))]
14476   "TARGET_USE_FANCY_MATH_387
14477    && flag_unsafe_math_optimizations"
14479   if (optimize_insn_for_size_p ())
14480     FAIL;
14482   ix86_emit_i387_log1p (operands[0], operands[1]);
14483   DONE;
14486 (define_expand "log1p<mode>2"
14487   [(use (match_operand:MODEF 0 "register_operand"))
14488    (use (match_operand:MODEF 1 "register_operand"))]
14489   "TARGET_USE_FANCY_MATH_387
14490    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14491        || TARGET_MIX_SSE_I387)
14492    && flag_unsafe_math_optimizations"
14494   rtx op0;
14496   if (optimize_insn_for_size_p ())
14497     FAIL;
14499   op0 = gen_reg_rtx (XFmode);
14501   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14503   ix86_emit_i387_log1p (op0, operands[1]);
14504   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14505   DONE;
14508 (define_insn "fxtractxf3_i387"
14509   [(set (match_operand:XF 0 "register_operand" "=f")
14510         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14511                    UNSPEC_XTRACT_FRACT))
14512    (set (match_operand:XF 1 "register_operand" "=u")
14513         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14514   "TARGET_USE_FANCY_MATH_387
14515    && flag_unsafe_math_optimizations"
14516   "fxtract"
14517   [(set_attr "type" "fpspc")
14518    (set_attr "mode" "XF")])
14520 (define_insn "fxtract_extend<mode>xf3_i387"
14521   [(set (match_operand:XF 0 "register_operand" "=f")
14522         (unspec:XF [(float_extend:XF
14523                       (match_operand:MODEF 2 "register_operand" "0"))]
14524                    UNSPEC_XTRACT_FRACT))
14525    (set (match_operand:XF 1 "register_operand" "=u")
14526         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14527   "TARGET_USE_FANCY_MATH_387
14528    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14529        || TARGET_MIX_SSE_I387)
14530    && flag_unsafe_math_optimizations"
14531   "fxtract"
14532   [(set_attr "type" "fpspc")
14533    (set_attr "mode" "XF")])
14535 (define_expand "logbxf2"
14536   [(parallel [(set (match_dup 2)
14537                    (unspec:XF [(match_operand:XF 1 "register_operand")]
14538                               UNSPEC_XTRACT_FRACT))
14539               (set (match_operand:XF 0 "register_operand")
14540                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14541   "TARGET_USE_FANCY_MATH_387
14542    && flag_unsafe_math_optimizations"
14543   "operands[2] = gen_reg_rtx (XFmode);")
14545 (define_expand "logb<mode>2"
14546   [(use (match_operand:MODEF 0 "register_operand"))
14547    (use (match_operand:MODEF 1 "register_operand"))]
14548   "TARGET_USE_FANCY_MATH_387
14549    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14550        || TARGET_MIX_SSE_I387)
14551    && flag_unsafe_math_optimizations"
14553   rtx op0 = gen_reg_rtx (XFmode);
14554   rtx op1 = gen_reg_rtx (XFmode);
14556   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14557   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14558   DONE;
14561 (define_expand "ilogbxf2"
14562   [(use (match_operand:SI 0 "register_operand"))
14563    (use (match_operand:XF 1 "register_operand"))]
14564   "TARGET_USE_FANCY_MATH_387
14565    && flag_unsafe_math_optimizations"
14567   rtx op0, op1;
14569   if (optimize_insn_for_size_p ())
14570     FAIL;
14572   op0 = gen_reg_rtx (XFmode);
14573   op1 = gen_reg_rtx (XFmode);
14575   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14576   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14577   DONE;
14580 (define_expand "ilogb<mode>2"
14581   [(use (match_operand:SI 0 "register_operand"))
14582    (use (match_operand:MODEF 1 "register_operand"))]
14583   "TARGET_USE_FANCY_MATH_387
14584    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14585        || TARGET_MIX_SSE_I387)
14586    && flag_unsafe_math_optimizations"
14588   rtx op0, op1;
14590   if (optimize_insn_for_size_p ())
14591     FAIL;
14593   op0 = gen_reg_rtx (XFmode);
14594   op1 = gen_reg_rtx (XFmode);
14596   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14597   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14598   DONE;
14601 (define_insn "*f2xm1xf2_i387"
14602   [(set (match_operand:XF 0 "register_operand" "=f")
14603         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14604                    UNSPEC_F2XM1))]
14605   "TARGET_USE_FANCY_MATH_387
14606    && flag_unsafe_math_optimizations"
14607   "f2xm1"
14608   [(set_attr "type" "fpspc")
14609    (set_attr "mode" "XF")])
14611 (define_insn "fscalexf4_i387"
14612   [(set (match_operand:XF 0 "register_operand" "=f")
14613         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14614                     (match_operand:XF 3 "register_operand" "1")]
14615                    UNSPEC_FSCALE_FRACT))
14616    (set (match_operand:XF 1 "register_operand" "=u")
14617         (unspec:XF [(match_dup 2) (match_dup 3)]
14618                    UNSPEC_FSCALE_EXP))]
14619   "TARGET_USE_FANCY_MATH_387
14620    && flag_unsafe_math_optimizations"
14621   "fscale"
14622   [(set_attr "type" "fpspc")
14623    (set_attr "mode" "XF")])
14625 (define_expand "expNcorexf3"
14626   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14627                                (match_operand:XF 2 "register_operand")))
14628    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14629    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14630    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14631    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14632    (parallel [(set (match_operand:XF 0 "register_operand")
14633                    (unspec:XF [(match_dup 8) (match_dup 4)]
14634                               UNSPEC_FSCALE_FRACT))
14635               (set (match_dup 9)
14636                    (unspec:XF [(match_dup 8) (match_dup 4)]
14637                               UNSPEC_FSCALE_EXP))])]
14638   "TARGET_USE_FANCY_MATH_387
14639    && flag_unsafe_math_optimizations"
14641   int i;
14643   if (optimize_insn_for_size_p ())
14644     FAIL;
14646   for (i = 3; i < 10; i++)
14647     operands[i] = gen_reg_rtx (XFmode);
14649   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14652 (define_expand "expxf2"
14653   [(use (match_operand:XF 0 "register_operand"))
14654    (use (match_operand:XF 1 "register_operand"))]
14655   "TARGET_USE_FANCY_MATH_387
14656    && flag_unsafe_math_optimizations"
14658   rtx op2;
14660   if (optimize_insn_for_size_p ())
14661     FAIL;
14663   op2 = gen_reg_rtx (XFmode);
14664   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14666   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14667   DONE;
14670 (define_expand "exp<mode>2"
14671   [(use (match_operand:MODEF 0 "register_operand"))
14672    (use (match_operand:MODEF 1 "general_operand"))]
14673  "TARGET_USE_FANCY_MATH_387
14674    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14675        || TARGET_MIX_SSE_I387)
14676    && flag_unsafe_math_optimizations"
14678   rtx op0, op1;
14680   if (optimize_insn_for_size_p ())
14681     FAIL;
14683   op0 = gen_reg_rtx (XFmode);
14684   op1 = gen_reg_rtx (XFmode);
14686   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14687   emit_insn (gen_expxf2 (op0, op1));
14688   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14689   DONE;
14692 (define_expand "exp10xf2"
14693   [(use (match_operand:XF 0 "register_operand"))
14694    (use (match_operand:XF 1 "register_operand"))]
14695   "TARGET_USE_FANCY_MATH_387
14696    && flag_unsafe_math_optimizations"
14698   rtx op2;
14700   if (optimize_insn_for_size_p ())
14701     FAIL;
14703   op2 = gen_reg_rtx (XFmode);
14704   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14706   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14707   DONE;
14710 (define_expand "exp10<mode>2"
14711   [(use (match_operand:MODEF 0 "register_operand"))
14712    (use (match_operand:MODEF 1 "general_operand"))]
14713  "TARGET_USE_FANCY_MATH_387
14714    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14715        || TARGET_MIX_SSE_I387)
14716    && flag_unsafe_math_optimizations"
14718   rtx op0, op1;
14720   if (optimize_insn_for_size_p ())
14721     FAIL;
14723   op0 = gen_reg_rtx (XFmode);
14724   op1 = gen_reg_rtx (XFmode);
14726   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14727   emit_insn (gen_exp10xf2 (op0, op1));
14728   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14729   DONE;
14732 (define_expand "exp2xf2"
14733   [(use (match_operand:XF 0 "register_operand"))
14734    (use (match_operand:XF 1 "register_operand"))]
14735   "TARGET_USE_FANCY_MATH_387
14736    && flag_unsafe_math_optimizations"
14738   rtx op2;
14740   if (optimize_insn_for_size_p ())
14741     FAIL;
14743   op2 = gen_reg_rtx (XFmode);
14744   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14746   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14747   DONE;
14750 (define_expand "exp2<mode>2"
14751   [(use (match_operand:MODEF 0 "register_operand"))
14752    (use (match_operand:MODEF 1 "general_operand"))]
14753  "TARGET_USE_FANCY_MATH_387
14754    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14755        || TARGET_MIX_SSE_I387)
14756    && flag_unsafe_math_optimizations"
14758   rtx op0, op1;
14760   if (optimize_insn_for_size_p ())
14761     FAIL;
14763   op0 = gen_reg_rtx (XFmode);
14764   op1 = gen_reg_rtx (XFmode);
14766   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14767   emit_insn (gen_exp2xf2 (op0, op1));
14768   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14769   DONE;
14772 (define_expand "expm1xf2"
14773   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14774                                (match_dup 2)))
14775    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14776    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14777    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14778    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14779    (parallel [(set (match_dup 7)
14780                    (unspec:XF [(match_dup 6) (match_dup 4)]
14781                               UNSPEC_FSCALE_FRACT))
14782               (set (match_dup 8)
14783                    (unspec:XF [(match_dup 6) (match_dup 4)]
14784                               UNSPEC_FSCALE_EXP))])
14785    (parallel [(set (match_dup 10)
14786                    (unspec:XF [(match_dup 9) (match_dup 8)]
14787                               UNSPEC_FSCALE_FRACT))
14788               (set (match_dup 11)
14789                    (unspec:XF [(match_dup 9) (match_dup 8)]
14790                               UNSPEC_FSCALE_EXP))])
14791    (set (match_dup 12) (minus:XF (match_dup 10)
14792                                  (float_extend:XF (match_dup 13))))
14793    (set (match_operand:XF 0 "register_operand")
14794         (plus:XF (match_dup 12) (match_dup 7)))]
14795   "TARGET_USE_FANCY_MATH_387
14796    && flag_unsafe_math_optimizations"
14798   int i;
14800   if (optimize_insn_for_size_p ())
14801     FAIL;
14803   for (i = 2; i < 13; i++)
14804     operands[i] = gen_reg_rtx (XFmode);
14806   operands[13]
14807     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14809   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14812 (define_expand "expm1<mode>2"
14813   [(use (match_operand:MODEF 0 "register_operand"))
14814    (use (match_operand:MODEF 1 "general_operand"))]
14815  "TARGET_USE_FANCY_MATH_387
14816    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14817        || TARGET_MIX_SSE_I387)
14818    && flag_unsafe_math_optimizations"
14820   rtx op0, op1;
14822   if (optimize_insn_for_size_p ())
14823     FAIL;
14825   op0 = gen_reg_rtx (XFmode);
14826   op1 = gen_reg_rtx (XFmode);
14828   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14829   emit_insn (gen_expm1xf2 (op0, op1));
14830   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14831   DONE;
14834 (define_expand "ldexpxf3"
14835   [(match_operand:XF 0 "register_operand")
14836    (match_operand:XF 1 "register_operand")
14837    (match_operand:SI 2 "register_operand")]
14838   "TARGET_USE_FANCY_MATH_387
14839    && flag_unsafe_math_optimizations"
14841   rtx tmp1, tmp2;
14842   if (optimize_insn_for_size_p ())
14843     FAIL;
14845   tmp1 = gen_reg_rtx (XFmode);
14846   tmp2 = gen_reg_rtx (XFmode);
14848   emit_insn (gen_floatsixf2 (tmp1, operands[2]));
14849   emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
14850                                  operands[1], tmp1));
14851   DONE;
14854 (define_expand "ldexp<mode>3"
14855   [(use (match_operand:MODEF 0 "register_operand"))
14856    (use (match_operand:MODEF 1 "general_operand"))
14857    (use (match_operand:SI 2 "register_operand"))]
14858  "TARGET_USE_FANCY_MATH_387
14859    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14860        || TARGET_MIX_SSE_I387)
14861    && flag_unsafe_math_optimizations"
14863   rtx op0, op1;
14865   if (optimize_insn_for_size_p ())
14866     FAIL;
14868   op0 = gen_reg_rtx (XFmode);
14869   op1 = gen_reg_rtx (XFmode);
14871   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14872   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14873   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14874   DONE;
14877 (define_expand "scalbxf3"
14878   [(parallel [(set (match_operand:XF 0 " register_operand")
14879                    (unspec:XF [(match_operand:XF 1 "register_operand")
14880                                (match_operand:XF 2 "register_operand")]
14881                               UNSPEC_FSCALE_FRACT))
14882               (set (match_dup 3)
14883                    (unspec:XF [(match_dup 1) (match_dup 2)]
14884                               UNSPEC_FSCALE_EXP))])]
14885   "TARGET_USE_FANCY_MATH_387
14886    && flag_unsafe_math_optimizations"
14888   if (optimize_insn_for_size_p ())
14889     FAIL;
14891   operands[3] = gen_reg_rtx (XFmode);
14894 (define_expand "scalb<mode>3"
14895   [(use (match_operand:MODEF 0 "register_operand"))
14896    (use (match_operand:MODEF 1 "general_operand"))
14897    (use (match_operand:MODEF 2 "general_operand"))]
14898  "TARGET_USE_FANCY_MATH_387
14899    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14900        || TARGET_MIX_SSE_I387)
14901    && flag_unsafe_math_optimizations"
14903   rtx op0, op1, op2;
14905   if (optimize_insn_for_size_p ())
14906     FAIL;
14908   op0 = gen_reg_rtx (XFmode);
14909   op1 = gen_reg_rtx (XFmode);
14910   op2 = gen_reg_rtx (XFmode);
14912   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14913   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14914   emit_insn (gen_scalbxf3 (op0, op1, op2));
14915   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14916   DONE;
14919 (define_expand "significandxf2"
14920   [(parallel [(set (match_operand:XF 0 "register_operand")
14921                    (unspec:XF [(match_operand:XF 1 "register_operand")]
14922                               UNSPEC_XTRACT_FRACT))
14923               (set (match_dup 2)
14924                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14925   "TARGET_USE_FANCY_MATH_387
14926    && flag_unsafe_math_optimizations"
14927   "operands[2] = gen_reg_rtx (XFmode);")
14929 (define_expand "significand<mode>2"
14930   [(use (match_operand:MODEF 0 "register_operand"))
14931    (use (match_operand:MODEF 1 "register_operand"))]
14932   "TARGET_USE_FANCY_MATH_387
14933    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14934        || TARGET_MIX_SSE_I387)
14935    && flag_unsafe_math_optimizations"
14937   rtx op0 = gen_reg_rtx (XFmode);
14938   rtx op1 = gen_reg_rtx (XFmode);
14940   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14941   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14942   DONE;
14946 (define_insn "sse4_1_round<mode>2"
14947   [(set (match_operand:MODEF 0 "register_operand" "=x")
14948         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14949                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14950                       UNSPEC_ROUND))]
14951   "TARGET_ROUND"
14952   "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14953   [(set_attr "type" "ssecvt")
14954    (set_attr "prefix_extra" "1")
14955    (set_attr "prefix" "maybe_vex")
14956    (set_attr "mode" "<MODE>")])
14958 (define_insn "rintxf2"
14959   [(set (match_operand:XF 0 "register_operand" "=f")
14960         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14961                    UNSPEC_FRNDINT))]
14962   "TARGET_USE_FANCY_MATH_387
14963    && flag_unsafe_math_optimizations"
14964   "frndint"
14965   [(set_attr "type" "fpspc")
14966    (set_attr "mode" "XF")])
14968 (define_expand "rint<mode>2"
14969   [(use (match_operand:MODEF 0 "register_operand"))
14970    (use (match_operand:MODEF 1 "register_operand"))]
14971   "(TARGET_USE_FANCY_MATH_387
14972     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14973         || TARGET_MIX_SSE_I387)
14974     && flag_unsafe_math_optimizations)
14975    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14976        && !flag_trapping_math)"
14978   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14979       && !flag_trapping_math)
14980     {
14981       if (TARGET_ROUND)
14982         emit_insn (gen_sse4_1_round<mode>2
14983                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14984       else if (optimize_insn_for_size_p ())
14985         FAIL;
14986       else
14987         ix86_expand_rint (operands[0], operands[1]);
14988     }
14989   else
14990     {
14991       rtx op0 = gen_reg_rtx (XFmode);
14992       rtx op1 = gen_reg_rtx (XFmode);
14994       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14995       emit_insn (gen_rintxf2 (op0, op1));
14997       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14998     }
14999   DONE;
15002 (define_expand "round<mode>2"
15003   [(match_operand:X87MODEF 0 "register_operand")
15004    (match_operand:X87MODEF 1 "nonimmediate_operand")]
15005   "(TARGET_USE_FANCY_MATH_387
15006     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15007         || TARGET_MIX_SSE_I387)
15008     && flag_unsafe_math_optimizations)
15009    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15010        && !flag_trapping_math && !flag_rounding_math)"
15012   if (optimize_insn_for_size_p ())
15013     FAIL;
15015   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15016       && !flag_trapping_math && !flag_rounding_math)
15017     {
15018       if (TARGET_ROUND)
15019         {
15020           operands[1] = force_reg (<MODE>mode, operands[1]);
15021           ix86_expand_round_sse4 (operands[0], operands[1]);
15022         }
15023       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15024         ix86_expand_round (operands[0], operands[1]);
15025       else
15026         ix86_expand_rounddf_32 (operands[0], operands[1]);
15027     }
15028   else
15029     {
15030       operands[1] = force_reg (<MODE>mode, operands[1]);
15031       ix86_emit_i387_round (operands[0], operands[1]);
15032     }
15033   DONE;
15036 (define_insn_and_split "*fistdi2_1"
15037   [(set (match_operand:DI 0 "nonimmediate_operand")
15038         (unspec:DI [(match_operand:XF 1 "register_operand")]
15039                    UNSPEC_FIST))]
15040   "TARGET_USE_FANCY_MATH_387
15041    && can_create_pseudo_p ()"
15042   "#"
15043   "&& 1"
15044   [(const_int 0)]
15046   if (memory_operand (operands[0], VOIDmode))
15047     emit_insn (gen_fistdi2 (operands[0], operands[1]));
15048   else
15049     {
15050       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15051       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15052                                          operands[2]));
15053     }
15054   DONE;
15056   [(set_attr "type" "fpspc")
15057    (set_attr "mode" "DI")])
15059 (define_insn "fistdi2"
15060   [(set (match_operand:DI 0 "memory_operand" "=m")
15061         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15062                    UNSPEC_FIST))
15063    (clobber (match_scratch:XF 2 "=&1f"))]
15064   "TARGET_USE_FANCY_MATH_387"
15065   "* return output_fix_trunc (insn, operands, false);"
15066   [(set_attr "type" "fpspc")
15067    (set_attr "mode" "DI")])
15069 (define_insn "fistdi2_with_temp"
15070   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15071         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15072                    UNSPEC_FIST))
15073    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15074    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15075   "TARGET_USE_FANCY_MATH_387"
15076   "#"
15077   [(set_attr "type" "fpspc")
15078    (set_attr "mode" "DI")])
15080 (define_split
15081   [(set (match_operand:DI 0 "register_operand")
15082         (unspec:DI [(match_operand:XF 1 "register_operand")]
15083                    UNSPEC_FIST))
15084    (clobber (match_operand:DI 2 "memory_operand"))
15085    (clobber (match_scratch 3))]
15086   "reload_completed"
15087   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15088               (clobber (match_dup 3))])
15089    (set (match_dup 0) (match_dup 2))])
15091 (define_split
15092   [(set (match_operand:DI 0 "memory_operand")
15093         (unspec:DI [(match_operand:XF 1 "register_operand")]
15094                    UNSPEC_FIST))
15095    (clobber (match_operand:DI 2 "memory_operand"))
15096    (clobber (match_scratch 3))]
15097   "reload_completed"
15098   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15099               (clobber (match_dup 3))])])
15101 (define_insn_and_split "*fist<mode>2_1"
15102   [(set (match_operand:SWI24 0 "register_operand")
15103         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15104                       UNSPEC_FIST))]
15105   "TARGET_USE_FANCY_MATH_387
15106    && can_create_pseudo_p ()"
15107   "#"
15108   "&& 1"
15109   [(const_int 0)]
15111   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15112   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15113                                         operands[2]));
15114   DONE;
15116   [(set_attr "type" "fpspc")
15117    (set_attr "mode" "<MODE>")])
15119 (define_insn "fist<mode>2"
15120   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15121         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15122                       UNSPEC_FIST))]
15123   "TARGET_USE_FANCY_MATH_387"
15124   "* return output_fix_trunc (insn, operands, false);"
15125   [(set_attr "type" "fpspc")
15126    (set_attr "mode" "<MODE>")])
15128 (define_insn "fist<mode>2_with_temp"
15129   [(set (match_operand:SWI24 0 "register_operand" "=r")
15130         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15131                       UNSPEC_FIST))
15132    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15133   "TARGET_USE_FANCY_MATH_387"
15134   "#"
15135   [(set_attr "type" "fpspc")
15136    (set_attr "mode" "<MODE>")])
15138 (define_split
15139   [(set (match_operand:SWI24 0 "register_operand")
15140         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15141                       UNSPEC_FIST))
15142    (clobber (match_operand:SWI24 2 "memory_operand"))]
15143   "reload_completed"
15144   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15145    (set (match_dup 0) (match_dup 2))])
15147 (define_split
15148   [(set (match_operand:SWI24 0 "memory_operand")
15149         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15150                       UNSPEC_FIST))
15151    (clobber (match_operand:SWI24 2 "memory_operand"))]
15152   "reload_completed"
15153   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15155 (define_expand "lrintxf<mode>2"
15156   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15157      (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15158                      UNSPEC_FIST))]
15159   "TARGET_USE_FANCY_MATH_387")
15161 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15162   [(set (match_operand:SWI48 0 "nonimmediate_operand")
15163      (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15164                    UNSPEC_FIX_NOTRUNC))]
15165   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15167 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15168   [(match_operand:SWI248x 0 "nonimmediate_operand")
15169    (match_operand:X87MODEF 1 "register_operand")]
15170   "(TARGET_USE_FANCY_MATH_387
15171     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15172         || TARGET_MIX_SSE_I387)
15173     && flag_unsafe_math_optimizations)
15174    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15175        && <SWI248x:MODE>mode != HImode 
15176        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15177        && !flag_trapping_math && !flag_rounding_math)"
15179   if (optimize_insn_for_size_p ())
15180     FAIL;
15182   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15183       && <SWI248x:MODE>mode != HImode
15184       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15185       && !flag_trapping_math && !flag_rounding_math)
15186     ix86_expand_lround (operands[0], operands[1]);
15187   else
15188     ix86_emit_i387_round (operands[0], operands[1]);
15189   DONE;
15192 (define_int_iterator FRNDINT_ROUNDING
15193         [UNSPEC_FRNDINT_FLOOR
15194          UNSPEC_FRNDINT_CEIL
15195          UNSPEC_FRNDINT_TRUNC])
15197 (define_int_iterator FIST_ROUNDING
15198         [UNSPEC_FIST_FLOOR
15199          UNSPEC_FIST_CEIL])
15201 ;; Base name for define_insn
15202 (define_int_attr rounding_insn
15203         [(UNSPEC_FRNDINT_FLOOR "floor")
15204          (UNSPEC_FRNDINT_CEIL "ceil")
15205          (UNSPEC_FRNDINT_TRUNC "btrunc")
15206          (UNSPEC_FIST_FLOOR "floor")
15207          (UNSPEC_FIST_CEIL "ceil")])
15209 (define_int_attr rounding
15210         [(UNSPEC_FRNDINT_FLOOR "floor")
15211          (UNSPEC_FRNDINT_CEIL "ceil")
15212          (UNSPEC_FRNDINT_TRUNC "trunc")
15213          (UNSPEC_FIST_FLOOR "floor")
15214          (UNSPEC_FIST_CEIL "ceil")])
15216 (define_int_attr ROUNDING
15217         [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15218          (UNSPEC_FRNDINT_CEIL "CEIL")
15219          (UNSPEC_FRNDINT_TRUNC "TRUNC")
15220          (UNSPEC_FIST_FLOOR "FLOOR")
15221          (UNSPEC_FIST_CEIL "CEIL")])
15223 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15224 (define_insn_and_split "frndintxf2_<rounding>"
15225   [(set (match_operand:XF 0 "register_operand")
15226         (unspec:XF [(match_operand:XF 1 "register_operand")]
15227                    FRNDINT_ROUNDING))
15228    (clobber (reg:CC FLAGS_REG))]
15229   "TARGET_USE_FANCY_MATH_387
15230    && flag_unsafe_math_optimizations
15231    && can_create_pseudo_p ()"
15232   "#"
15233   "&& 1"
15234   [(const_int 0)]
15236   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15238   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15239   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15241   emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15242                                              operands[2], operands[3]));
15243   DONE;
15245   [(set_attr "type" "frndint")
15246    (set_attr "i387_cw" "<rounding>")
15247    (set_attr "mode" "XF")])
15249 (define_insn "frndintxf2_<rounding>_i387"
15250   [(set (match_operand:XF 0 "register_operand" "=f")
15251         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15252                    FRNDINT_ROUNDING))
15253    (use (match_operand:HI 2 "memory_operand" "m"))
15254    (use (match_operand:HI 3 "memory_operand" "m"))]
15255   "TARGET_USE_FANCY_MATH_387
15256    && flag_unsafe_math_optimizations"
15257   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15258   [(set_attr "type" "frndint")
15259    (set_attr "i387_cw" "<rounding>")
15260    (set_attr "mode" "XF")])
15262 (define_expand "<rounding_insn>xf2"
15263   [(parallel [(set (match_operand:XF 0 "register_operand")
15264                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15265                               FRNDINT_ROUNDING))
15266               (clobber (reg:CC FLAGS_REG))])]
15267   "TARGET_USE_FANCY_MATH_387
15268    && flag_unsafe_math_optimizations
15269    && !optimize_insn_for_size_p ()")
15271 (define_expand "<rounding_insn><mode>2"
15272   [(parallel [(set (match_operand:MODEF 0 "register_operand")
15273                    (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15274                                  FRNDINT_ROUNDING))
15275               (clobber (reg:CC FLAGS_REG))])]
15276   "(TARGET_USE_FANCY_MATH_387
15277     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15278         || TARGET_MIX_SSE_I387)
15279     && flag_unsafe_math_optimizations)
15280    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15281        && !flag_trapping_math)"
15283   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15284       && !flag_trapping_math)
15285     {
15286       if (TARGET_ROUND)
15287         emit_insn (gen_sse4_1_round<mode>2
15288                    (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15289       else if (optimize_insn_for_size_p ())
15290         FAIL;
15291       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15292         {
15293           if (ROUND_<ROUNDING> == ROUND_FLOOR)
15294             ix86_expand_floorceil (operands[0], operands[1], true);
15295           else if (ROUND_<ROUNDING> == ROUND_CEIL)
15296             ix86_expand_floorceil (operands[0], operands[1], false);
15297           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15298             ix86_expand_trunc (operands[0], operands[1]);
15299           else
15300             gcc_unreachable ();
15301         }
15302       else
15303         {
15304           if (ROUND_<ROUNDING> == ROUND_FLOOR)
15305             ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15306           else if (ROUND_<ROUNDING> == ROUND_CEIL)
15307             ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15308           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15309             ix86_expand_truncdf_32 (operands[0], operands[1]);
15310           else
15311             gcc_unreachable ();
15312         }
15313     }
15314   else
15315     {
15316       rtx op0, op1;
15318       if (optimize_insn_for_size_p ())
15319         FAIL;
15321       op0 = gen_reg_rtx (XFmode);
15322       op1 = gen_reg_rtx (XFmode);
15323       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15324       emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15326       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15327     }
15328   DONE;
15331 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15332 (define_insn_and_split "frndintxf2_mask_pm"
15333   [(set (match_operand:XF 0 "register_operand")
15334         (unspec:XF [(match_operand:XF 1 "register_operand")]
15335                    UNSPEC_FRNDINT_MASK_PM))
15336    (clobber (reg:CC FLAGS_REG))]
15337   "TARGET_USE_FANCY_MATH_387
15338    && flag_unsafe_math_optimizations
15339    && can_create_pseudo_p ()"
15340   "#"
15341   "&& 1"
15342   [(const_int 0)]
15344   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15346   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15347   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15349   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15350                                           operands[2], operands[3]));
15351   DONE;
15353   [(set_attr "type" "frndint")
15354    (set_attr "i387_cw" "mask_pm")
15355    (set_attr "mode" "XF")])
15357 (define_insn "frndintxf2_mask_pm_i387"
15358   [(set (match_operand:XF 0 "register_operand" "=f")
15359         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15360                    UNSPEC_FRNDINT_MASK_PM))
15361    (use (match_operand:HI 2 "memory_operand" "m"))
15362    (use (match_operand:HI 3 "memory_operand" "m"))]
15363   "TARGET_USE_FANCY_MATH_387
15364    && flag_unsafe_math_optimizations"
15365   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15366   [(set_attr "type" "frndint")
15367    (set_attr "i387_cw" "mask_pm")
15368    (set_attr "mode" "XF")])
15370 (define_expand "nearbyintxf2"
15371   [(parallel [(set (match_operand:XF 0 "register_operand")
15372                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15373                               UNSPEC_FRNDINT_MASK_PM))
15374               (clobber (reg:CC FLAGS_REG))])]
15375   "TARGET_USE_FANCY_MATH_387
15376    && flag_unsafe_math_optimizations")
15378 (define_expand "nearbyint<mode>2"
15379   [(use (match_operand:MODEF 0 "register_operand"))
15380    (use (match_operand:MODEF 1 "register_operand"))]
15381   "TARGET_USE_FANCY_MATH_387
15382    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15383        || TARGET_MIX_SSE_I387)
15384    && flag_unsafe_math_optimizations"
15386   rtx op0 = gen_reg_rtx (XFmode);
15387   rtx op1 = gen_reg_rtx (XFmode);
15389   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15390   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15392   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15393   DONE;
15396 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15397 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15398   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15399         (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15400                         FIST_ROUNDING))
15401    (clobber (reg:CC FLAGS_REG))]
15402   "TARGET_USE_FANCY_MATH_387
15403    && flag_unsafe_math_optimizations
15404    && can_create_pseudo_p ()"
15405   "#"
15406   "&& 1"
15407   [(const_int 0)]
15409   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15411   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15412   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15413   if (memory_operand (operands[0], VOIDmode))
15414     emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15415                                            operands[2], operands[3]));
15416   else
15417     {
15418       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15419       emit_insn (gen_fist<mode>2_<rounding>_with_temp
15420                   (operands[0], operands[1], operands[2],
15421                    operands[3], operands[4]));
15422     }
15423   DONE;
15425   [(set_attr "type" "fistp")
15426    (set_attr "i387_cw" "<rounding>")
15427    (set_attr "mode" "<MODE>")])
15429 (define_insn "fistdi2_<rounding>"
15430   [(set (match_operand:DI 0 "memory_operand" "=m")
15431         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15432                    FIST_ROUNDING))
15433    (use (match_operand:HI 2 "memory_operand" "m"))
15434    (use (match_operand:HI 3 "memory_operand" "m"))
15435    (clobber (match_scratch:XF 4 "=&1f"))]
15436   "TARGET_USE_FANCY_MATH_387
15437    && flag_unsafe_math_optimizations"
15438   "* return output_fix_trunc (insn, operands, false);"
15439   [(set_attr "type" "fistp")
15440    (set_attr "i387_cw" "<rounding>")
15441    (set_attr "mode" "DI")])
15443 (define_insn "fistdi2_<rounding>_with_temp"
15444   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15445         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15446                    FIST_ROUNDING))
15447    (use (match_operand:HI 2 "memory_operand" "m,m"))
15448    (use (match_operand:HI 3 "memory_operand" "m,m"))
15449    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15450    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15451   "TARGET_USE_FANCY_MATH_387
15452    && flag_unsafe_math_optimizations"
15453   "#"
15454   [(set_attr "type" "fistp")
15455    (set_attr "i387_cw" "<rounding>")
15456    (set_attr "mode" "DI")])
15458 (define_split
15459   [(set (match_operand:DI 0 "register_operand")
15460         (unspec:DI [(match_operand:XF 1 "register_operand")]
15461                    FIST_ROUNDING))
15462    (use (match_operand:HI 2 "memory_operand"))
15463    (use (match_operand:HI 3 "memory_operand"))
15464    (clobber (match_operand:DI 4 "memory_operand"))
15465    (clobber (match_scratch 5))]
15466   "reload_completed"
15467   [(parallel [(set (match_dup 4)
15468                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15469               (use (match_dup 2))
15470               (use (match_dup 3))
15471               (clobber (match_dup 5))])
15472    (set (match_dup 0) (match_dup 4))])
15474 (define_split
15475   [(set (match_operand:DI 0 "memory_operand")
15476         (unspec:DI [(match_operand:XF 1 "register_operand")]
15477                    FIST_ROUNDING))
15478    (use (match_operand:HI 2 "memory_operand"))
15479    (use (match_operand:HI 3 "memory_operand"))
15480    (clobber (match_operand:DI 4 "memory_operand"))
15481    (clobber (match_scratch 5))]
15482   "reload_completed"
15483   [(parallel [(set (match_dup 0)
15484                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15485               (use (match_dup 2))
15486               (use (match_dup 3))
15487               (clobber (match_dup 5))])])
15489 (define_insn "fist<mode>2_<rounding>"
15490   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15491         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15492                       FIST_ROUNDING))
15493    (use (match_operand:HI 2 "memory_operand" "m"))
15494    (use (match_operand:HI 3 "memory_operand" "m"))]
15495   "TARGET_USE_FANCY_MATH_387
15496    && flag_unsafe_math_optimizations"
15497   "* return output_fix_trunc (insn, operands, false);"
15498   [(set_attr "type" "fistp")
15499    (set_attr "i387_cw" "<rounding>")
15500    (set_attr "mode" "<MODE>")])
15502 (define_insn "fist<mode>2_<rounding>_with_temp"
15503   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15504         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15505                       FIST_ROUNDING))
15506    (use (match_operand:HI 2 "memory_operand" "m,m"))
15507    (use (match_operand:HI 3 "memory_operand" "m,m"))
15508    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15509   "TARGET_USE_FANCY_MATH_387
15510    && flag_unsafe_math_optimizations"
15511   "#"
15512   [(set_attr "type" "fistp")
15513    (set_attr "i387_cw" "<rounding>")
15514    (set_attr "mode" "<MODE>")])
15516 (define_split
15517   [(set (match_operand:SWI24 0 "register_operand")
15518         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15519                       FIST_ROUNDING))
15520    (use (match_operand:HI 2 "memory_operand"))
15521    (use (match_operand:HI 3 "memory_operand"))
15522    (clobber (match_operand:SWI24 4 "memory_operand"))]
15523   "reload_completed"
15524   [(parallel [(set (match_dup 4)
15525                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15526               (use (match_dup 2))
15527               (use (match_dup 3))])
15528    (set (match_dup 0) (match_dup 4))])
15530 (define_split
15531   [(set (match_operand:SWI24 0 "memory_operand")
15532         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15533                       FIST_ROUNDING))
15534    (use (match_operand:HI 2 "memory_operand"))
15535    (use (match_operand:HI 3 "memory_operand"))
15536    (clobber (match_operand:SWI24 4 "memory_operand"))]
15537   "reload_completed"
15538   [(parallel [(set (match_dup 0)
15539                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15540               (use (match_dup 2))
15541               (use (match_dup 3))])])
15543 (define_expand "l<rounding_insn>xf<mode>2"
15544   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15545                    (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15546                                    FIST_ROUNDING))
15547               (clobber (reg:CC FLAGS_REG))])]
15548   "TARGET_USE_FANCY_MATH_387
15549    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15550    && flag_unsafe_math_optimizations")
15552 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15553   [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15554                    (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15555                                  FIST_ROUNDING))
15556               (clobber (reg:CC FLAGS_REG))])]
15557   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15558    && !flag_trapping_math"
15560   if (TARGET_64BIT && optimize_insn_for_size_p ())
15561     FAIL;
15563   if (ROUND_<ROUNDING> == ROUND_FLOOR)
15564     ix86_expand_lfloorceil (operands[0], operands[1], true);
15565   else if (ROUND_<ROUNDING> == ROUND_CEIL)
15566     ix86_expand_lfloorceil (operands[0], operands[1], false);
15567   else
15568     gcc_unreachable ();
15570   DONE;
15573 (define_insn "fxam<mode>2_i387"
15574   [(set (match_operand:HI 0 "register_operand" "=a")
15575         (unspec:HI
15576           [(match_operand:X87MODEF 1 "register_operand" "f")]
15577           UNSPEC_FXAM))]
15578   "TARGET_USE_FANCY_MATH_387"
15579   "fxam\n\tfnstsw\t%0"
15580   [(set_attr "type" "multi")
15581    (set_attr "length" "4")
15582    (set_attr "unit" "i387")
15583    (set_attr "mode" "<MODE>")])
15585 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15586   [(set (match_operand:HI 0 "register_operand")
15587         (unspec:HI
15588           [(match_operand:MODEF 1 "memory_operand")]
15589           UNSPEC_FXAM_MEM))]
15590   "TARGET_USE_FANCY_MATH_387
15591    && can_create_pseudo_p ()"
15592   "#"
15593   "&& 1"
15594   [(set (match_dup 2)(match_dup 1))
15595    (set (match_dup 0)
15596         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15598   operands[2] = gen_reg_rtx (<MODE>mode);
15600   MEM_VOLATILE_P (operands[1]) = 1;
15602   [(set_attr "type" "multi")
15603    (set_attr "unit" "i387")
15604    (set_attr "mode" "<MODE>")])
15606 (define_expand "isinfxf2"
15607   [(use (match_operand:SI 0 "register_operand"))
15608    (use (match_operand:XF 1 "register_operand"))]
15609   "TARGET_USE_FANCY_MATH_387
15610    && ix86_libc_has_function (function_c99_misc)"
15612   rtx mask = GEN_INT (0x45);
15613   rtx val = GEN_INT (0x05);
15615   rtx cond;
15617   rtx scratch = gen_reg_rtx (HImode);
15618   rtx res = gen_reg_rtx (QImode);
15620   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15622   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15623   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15624   cond = gen_rtx_fmt_ee (EQ, QImode,
15625                          gen_rtx_REG (CCmode, FLAGS_REG),
15626                          const0_rtx);
15627   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15628   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15629   DONE;
15632 (define_expand "isinf<mode>2"
15633   [(use (match_operand:SI 0 "register_operand"))
15634    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15635   "TARGET_USE_FANCY_MATH_387
15636    && ix86_libc_has_function (function_c99_misc)
15637    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15639   rtx mask = GEN_INT (0x45);
15640   rtx val = GEN_INT (0x05);
15642   rtx cond;
15644   rtx scratch = gen_reg_rtx (HImode);
15645   rtx res = gen_reg_rtx (QImode);
15647   /* Remove excess precision by forcing value through memory. */
15648   if (memory_operand (operands[1], VOIDmode))
15649     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15650   else
15651     {
15652       rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15654       emit_move_insn (temp, operands[1]);
15655       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15656     }
15658   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15659   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15660   cond = gen_rtx_fmt_ee (EQ, QImode,
15661                          gen_rtx_REG (CCmode, FLAGS_REG),
15662                          const0_rtx);
15663   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15664   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15665   DONE;
15668 (define_expand "signbitxf2"
15669   [(use (match_operand:SI 0 "register_operand"))
15670    (use (match_operand:XF 1 "register_operand"))]
15671   "TARGET_USE_FANCY_MATH_387"
15673   rtx scratch = gen_reg_rtx (HImode);
15675   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15676   emit_insn (gen_andsi3 (operands[0],
15677              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15678   DONE;
15681 (define_insn "movmsk_df"
15682   [(set (match_operand:SI 0 "register_operand" "=r")
15683         (unspec:SI
15684           [(match_operand:DF 1 "register_operand" "x")]
15685           UNSPEC_MOVMSK))]
15686   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15687   "%vmovmskpd\t{%1, %0|%0, %1}"
15688   [(set_attr "type" "ssemov")
15689    (set_attr "prefix" "maybe_vex")
15690    (set_attr "mode" "DF")])
15692 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15693 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15694 (define_expand "signbitdf2"
15695   [(use (match_operand:SI 0 "register_operand"))
15696    (use (match_operand:DF 1 "register_operand"))]
15697   "TARGET_USE_FANCY_MATH_387
15698    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15700   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15701     {
15702       emit_insn (gen_movmsk_df (operands[0], operands[1]));
15703       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15704     }
15705   else
15706     {
15707       rtx scratch = gen_reg_rtx (HImode);
15709       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15710       emit_insn (gen_andsi3 (operands[0],
15711                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15712     }
15713   DONE;
15716 (define_expand "signbitsf2"
15717   [(use (match_operand:SI 0 "register_operand"))
15718    (use (match_operand:SF 1 "register_operand"))]
15719   "TARGET_USE_FANCY_MATH_387
15720    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15722   rtx scratch = gen_reg_rtx (HImode);
15724   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15725   emit_insn (gen_andsi3 (operands[0],
15726              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15727   DONE;
15730 ;; Block operation instructions
15732 (define_insn "cld"
15733   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15734   ""
15735   "cld"
15736   [(set_attr "length" "1")
15737    (set_attr "length_immediate" "0")
15738    (set_attr "modrm" "0")])
15740 (define_expand "movmem<mode>"
15741   [(use (match_operand:BLK 0 "memory_operand"))
15742    (use (match_operand:BLK 1 "memory_operand"))
15743    (use (match_operand:SWI48 2 "nonmemory_operand"))
15744    (use (match_operand:SWI48 3 "const_int_operand"))
15745    (use (match_operand:SI 4 "const_int_operand"))
15746    (use (match_operand:SI 5 "const_int_operand"))
15747    (use (match_operand:SI 6 ""))
15748    (use (match_operand:SI 7 ""))
15749    (use (match_operand:SI 8 ""))]
15750   ""
15752  if (ix86_expand_set_or_movmem (operands[0], operands[1],
15753                                 operands[2], NULL, operands[3],
15754                                 operands[4], operands[5],
15755                                 operands[6], operands[7],
15756                                 operands[8], false))
15757    DONE;
15758  else
15759    FAIL;
15762 ;; Most CPUs don't like single string operations
15763 ;; Handle this case here to simplify previous expander.
15765 (define_expand "strmov"
15766   [(set (match_dup 4) (match_operand 3 "memory_operand"))
15767    (set (match_operand 1 "memory_operand") (match_dup 4))
15768    (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15769               (clobber (reg:CC FLAGS_REG))])
15770    (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15771               (clobber (reg:CC FLAGS_REG))])]
15772   ""
15774   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15776   /* If .md ever supports :P for Pmode, these can be directly
15777      in the pattern above.  */
15778   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15779   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15781   /* Can't use this if the user has appropriated esi or edi.  */
15782   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15783       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15784     {
15785       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15786                                       operands[2], operands[3],
15787                                       operands[5], operands[6]));
15788       DONE;
15789     }
15791   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15794 (define_expand "strmov_singleop"
15795   [(parallel [(set (match_operand 1 "memory_operand")
15796                    (match_operand 3 "memory_operand"))
15797               (set (match_operand 0 "register_operand")
15798                    (match_operand 4))
15799               (set (match_operand 2 "register_operand")
15800                    (match_operand 5))])]
15801   ""
15802   "ix86_current_function_needs_cld = 1;")
15804 (define_insn "*strmovdi_rex_1"
15805   [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15806         (mem:DI (match_operand:P 3 "register_operand" "1")))
15807    (set (match_operand:P 0 "register_operand" "=D")
15808         (plus:P (match_dup 2)
15809                 (const_int 8)))
15810    (set (match_operand:P 1 "register_operand" "=S")
15811         (plus:P (match_dup 3)
15812                 (const_int 8)))]
15813   "TARGET_64BIT
15814    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15815   "%^movsq"
15816   [(set_attr "type" "str")
15817    (set_attr "memory" "both")
15818    (set_attr "mode" "DI")])
15820 (define_insn "*strmovsi_1"
15821   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15822         (mem:SI (match_operand:P 3 "register_operand" "1")))
15823    (set (match_operand:P 0 "register_operand" "=D")
15824         (plus:P (match_dup 2)
15825                 (const_int 4)))
15826    (set (match_operand:P 1 "register_operand" "=S")
15827         (plus:P (match_dup 3)
15828                 (const_int 4)))]
15829   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15830   "%^movs{l|d}"
15831   [(set_attr "type" "str")
15832    (set_attr "memory" "both")
15833    (set_attr "mode" "SI")])
15835 (define_insn "*strmovhi_1"
15836   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15837         (mem:HI (match_operand:P 3 "register_operand" "1")))
15838    (set (match_operand:P 0 "register_operand" "=D")
15839         (plus:P (match_dup 2)
15840                 (const_int 2)))
15841    (set (match_operand:P 1 "register_operand" "=S")
15842         (plus:P (match_dup 3)
15843                 (const_int 2)))]
15844   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15845   "%^movsw"
15846   [(set_attr "type" "str")
15847    (set_attr "memory" "both")
15848    (set_attr "mode" "HI")])
15850 (define_insn "*strmovqi_1"
15851   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15852         (mem:QI (match_operand:P 3 "register_operand" "1")))
15853    (set (match_operand:P 0 "register_operand" "=D")
15854         (plus:P (match_dup 2)
15855                 (const_int 1)))
15856    (set (match_operand:P 1 "register_operand" "=S")
15857         (plus:P (match_dup 3)
15858                 (const_int 1)))]
15859   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15860   "%^movsb"
15861   [(set_attr "type" "str")
15862    (set_attr "memory" "both")
15863    (set (attr "prefix_rex")
15864         (if_then_else
15865           (match_test "<P:MODE>mode == DImode")
15866           (const_string "0")
15867           (const_string "*")))
15868    (set_attr "mode" "QI")])
15870 (define_expand "rep_mov"
15871   [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15872               (set (match_operand 0 "register_operand")
15873                    (match_operand 5))
15874               (set (match_operand 2 "register_operand")
15875                    (match_operand 6))
15876               (set (match_operand 1 "memory_operand")
15877                    (match_operand 3 "memory_operand"))
15878               (use (match_dup 4))])]
15879   ""
15880   "ix86_current_function_needs_cld = 1;")
15882 (define_insn "*rep_movdi_rex64"
15883   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15884    (set (match_operand:P 0 "register_operand" "=D")
15885         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15886                           (const_int 3))
15887                 (match_operand:P 3 "register_operand" "0")))
15888    (set (match_operand:P 1 "register_operand" "=S")
15889         (plus:P (ashift:P (match_dup 5) (const_int 3))
15890                 (match_operand:P 4 "register_operand" "1")))
15891    (set (mem:BLK (match_dup 3))
15892         (mem:BLK (match_dup 4)))
15893    (use (match_dup 5))]
15894   "TARGET_64BIT
15895    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15896   "%^rep{%;} movsq"
15897   [(set_attr "type" "str")
15898    (set_attr "prefix_rep" "1")
15899    (set_attr "memory" "both")
15900    (set_attr "mode" "DI")])
15902 (define_insn "*rep_movsi"
15903   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15904    (set (match_operand:P 0 "register_operand" "=D")
15905         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15906                           (const_int 2))
15907                  (match_operand:P 3 "register_operand" "0")))
15908    (set (match_operand:P 1 "register_operand" "=S")
15909         (plus:P (ashift:P (match_dup 5) (const_int 2))
15910                 (match_operand:P 4 "register_operand" "1")))
15911    (set (mem:BLK (match_dup 3))
15912         (mem:BLK (match_dup 4)))
15913    (use (match_dup 5))]
15914   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15915   "%^rep{%;} movs{l|d}"
15916   [(set_attr "type" "str")
15917    (set_attr "prefix_rep" "1")
15918    (set_attr "memory" "both")
15919    (set_attr "mode" "SI")])
15921 (define_insn "*rep_movqi"
15922   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15923    (set (match_operand:P 0 "register_operand" "=D")
15924         (plus:P (match_operand:P 3 "register_operand" "0")
15925                 (match_operand:P 5 "register_operand" "2")))
15926    (set (match_operand:P 1 "register_operand" "=S")
15927         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15928    (set (mem:BLK (match_dup 3))
15929         (mem:BLK (match_dup 4)))
15930    (use (match_dup 5))]
15931   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15932   "%^rep{%;} movsb"
15933   [(set_attr "type" "str")
15934    (set_attr "prefix_rep" "1")
15935    (set_attr "memory" "both")
15936    (set_attr "mode" "QI")])
15938 (define_expand "setmem<mode>"
15939    [(use (match_operand:BLK 0 "memory_operand"))
15940     (use (match_operand:SWI48 1 "nonmemory_operand"))
15941     (use (match_operand:QI 2 "nonmemory_operand"))
15942     (use (match_operand 3 "const_int_operand"))
15943     (use (match_operand:SI 4 "const_int_operand"))
15944     (use (match_operand:SI 5 "const_int_operand"))
15945     (use (match_operand:SI 6 ""))
15946     (use (match_operand:SI 7 ""))
15947     (use (match_operand:SI 8 ""))]
15948   ""
15950  if (ix86_expand_set_or_movmem (operands[0], NULL,
15951                                 operands[1], operands[2],
15952                                 operands[3], operands[4],
15953                                 operands[5], operands[6],
15954                                 operands[7], operands[8], true))
15955    DONE;
15956  else
15957    FAIL;
15960 ;; Most CPUs don't like single string operations
15961 ;; Handle this case here to simplify previous expander.
15963 (define_expand "strset"
15964   [(set (match_operand 1 "memory_operand")
15965         (match_operand 2 "register_operand"))
15966    (parallel [(set (match_operand 0 "register_operand")
15967                    (match_dup 3))
15968               (clobber (reg:CC FLAGS_REG))])]
15969   ""
15971   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15972     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15974   /* If .md ever supports :P for Pmode, this can be directly
15975      in the pattern above.  */
15976   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15977                               GEN_INT (GET_MODE_SIZE (GET_MODE
15978                                                       (operands[2]))));
15979   /* Can't use this if the user has appropriated eax or edi.  */
15980   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15981       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15982     {
15983       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15984                                       operands[3]));
15985       DONE;
15986     }
15989 (define_expand "strset_singleop"
15990   [(parallel [(set (match_operand 1 "memory_operand")
15991                    (match_operand 2 "register_operand"))
15992               (set (match_operand 0 "register_operand")
15993                    (match_operand 3))
15994               (unspec [(const_int 0)] UNSPEC_STOS)])]
15995   ""
15996   "ix86_current_function_needs_cld = 1;")
15998 (define_insn "*strsetdi_rex_1"
15999   [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16000         (match_operand:DI 2 "register_operand" "a"))
16001    (set (match_operand:P 0 "register_operand" "=D")
16002         (plus:P (match_dup 1)
16003                 (const_int 8)))
16004    (unspec [(const_int 0)] UNSPEC_STOS)]
16005   "TARGET_64BIT
16006    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16007   "%^stosq"
16008   [(set_attr "type" "str")
16009    (set_attr "memory" "store")
16010    (set_attr "mode" "DI")])
16012 (define_insn "*strsetsi_1"
16013   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16014         (match_operand:SI 2 "register_operand" "a"))
16015    (set (match_operand:P 0 "register_operand" "=D")
16016         (plus:P (match_dup 1)
16017                 (const_int 4)))
16018    (unspec [(const_int 0)] UNSPEC_STOS)]
16019   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16020   "%^stos{l|d}"
16021   [(set_attr "type" "str")
16022    (set_attr "memory" "store")
16023    (set_attr "mode" "SI")])
16025 (define_insn "*strsethi_1"
16026   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16027         (match_operand:HI 2 "register_operand" "a"))
16028    (set (match_operand:P 0 "register_operand" "=D")
16029         (plus:P (match_dup 1)
16030                 (const_int 2)))
16031    (unspec [(const_int 0)] UNSPEC_STOS)]
16032   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16033   "%^stosw"
16034   [(set_attr "type" "str")
16035    (set_attr "memory" "store")
16036    (set_attr "mode" "HI")])
16038 (define_insn "*strsetqi_1"
16039   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16040         (match_operand:QI 2 "register_operand" "a"))
16041    (set (match_operand:P 0 "register_operand" "=D")
16042         (plus:P (match_dup 1)
16043                 (const_int 1)))
16044    (unspec [(const_int 0)] UNSPEC_STOS)]
16045   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16046   "%^stosb"
16047   [(set_attr "type" "str")
16048    (set_attr "memory" "store")
16049    (set (attr "prefix_rex")
16050         (if_then_else
16051           (match_test "<P:MODE>mode == DImode")
16052           (const_string "0")
16053           (const_string "*")))
16054    (set_attr "mode" "QI")])
16056 (define_expand "rep_stos"
16057   [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16058               (set (match_operand 0 "register_operand")
16059                    (match_operand 4))
16060               (set (match_operand 2 "memory_operand") (const_int 0))
16061               (use (match_operand 3 "register_operand"))
16062               (use (match_dup 1))])]
16063   ""
16064   "ix86_current_function_needs_cld = 1;")
16066 (define_insn "*rep_stosdi_rex64"
16067   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16068    (set (match_operand:P 0 "register_operand" "=D")
16069         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16070                           (const_int 3))
16071                  (match_operand:P 3 "register_operand" "0")))
16072    (set (mem:BLK (match_dup 3))
16073         (const_int 0))
16074    (use (match_operand:DI 2 "register_operand" "a"))
16075    (use (match_dup 4))]
16076   "TARGET_64BIT
16077    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16078   "%^rep{%;} stosq"
16079   [(set_attr "type" "str")
16080    (set_attr "prefix_rep" "1")
16081    (set_attr "memory" "store")
16082    (set_attr "mode" "DI")])
16084 (define_insn "*rep_stossi"
16085   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16086    (set (match_operand:P 0 "register_operand" "=D")
16087         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16088                           (const_int 2))
16089                  (match_operand:P 3 "register_operand" "0")))
16090    (set (mem:BLK (match_dup 3))
16091         (const_int 0))
16092    (use (match_operand:SI 2 "register_operand" "a"))
16093    (use (match_dup 4))]
16094   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16095   "%^rep{%;} stos{l|d}"
16096   [(set_attr "type" "str")
16097    (set_attr "prefix_rep" "1")
16098    (set_attr "memory" "store")
16099    (set_attr "mode" "SI")])
16101 (define_insn "*rep_stosqi"
16102   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16103    (set (match_operand:P 0 "register_operand" "=D")
16104         (plus:P (match_operand:P 3 "register_operand" "0")
16105                 (match_operand:P 4 "register_operand" "1")))
16106    (set (mem:BLK (match_dup 3))
16107         (const_int 0))
16108    (use (match_operand:QI 2 "register_operand" "a"))
16109    (use (match_dup 4))]
16110   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16111   "%^rep{%;} stosb"
16112   [(set_attr "type" "str")
16113    (set_attr "prefix_rep" "1")
16114    (set_attr "memory" "store")
16115    (set (attr "prefix_rex")
16116         (if_then_else
16117           (match_test "<P:MODE>mode == DImode")
16118           (const_string "0")
16119           (const_string "*")))
16120    (set_attr "mode" "QI")])
16122 (define_expand "cmpstrnsi"
16123   [(set (match_operand:SI 0 "register_operand")
16124         (compare:SI (match_operand:BLK 1 "general_operand")
16125                     (match_operand:BLK 2 "general_operand")))
16126    (use (match_operand 3 "general_operand"))
16127    (use (match_operand 4 "immediate_operand"))]
16128   ""
16130   rtx addr1, addr2, out, outlow, count, countreg, align;
16132   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16133     FAIL;
16135   /* Can't use this if the user has appropriated ecx, esi or edi.  */
16136   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16137     FAIL;
16139   out = operands[0];
16140   if (!REG_P (out))
16141     out = gen_reg_rtx (SImode);
16143   addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16144   addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16145   if (addr1 != XEXP (operands[1], 0))
16146     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16147   if (addr2 != XEXP (operands[2], 0))
16148     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16150   count = operands[3];
16151   countreg = ix86_zero_extend_to_Pmode (count);
16153   /* %%% Iff we are testing strict equality, we can use known alignment
16154      to good advantage.  This may be possible with combine, particularly
16155      once cc0 is dead.  */
16156   align = operands[4];
16158   if (CONST_INT_P (count))
16159     {
16160       if (INTVAL (count) == 0)
16161         {
16162           emit_move_insn (operands[0], const0_rtx);
16163           DONE;
16164         }
16165       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16166                                      operands[1], operands[2]));
16167     }
16168   else
16169     {
16170       rtx (*gen_cmp) (rtx, rtx);
16172       gen_cmp = (TARGET_64BIT
16173                  ? gen_cmpdi_1 : gen_cmpsi_1);
16175       emit_insn (gen_cmp (countreg, countreg));
16176       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16177                                   operands[1], operands[2]));
16178     }
16180   outlow = gen_lowpart (QImode, out);
16181   emit_insn (gen_cmpintqi (outlow));
16182   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16184   if (operands[0] != out)
16185     emit_move_insn (operands[0], out);
16187   DONE;
16190 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16192 (define_expand "cmpintqi"
16193   [(set (match_dup 1)
16194         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16195    (set (match_dup 2)
16196         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16197    (parallel [(set (match_operand:QI 0 "register_operand")
16198                    (minus:QI (match_dup 1)
16199                              (match_dup 2)))
16200               (clobber (reg:CC FLAGS_REG))])]
16201   ""
16203   operands[1] = gen_reg_rtx (QImode);
16204   operands[2] = gen_reg_rtx (QImode);
16207 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16208 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16210 (define_expand "cmpstrnqi_nz_1"
16211   [(parallel [(set (reg:CC FLAGS_REG)
16212                    (compare:CC (match_operand 4 "memory_operand")
16213                                (match_operand 5 "memory_operand")))
16214               (use (match_operand 2 "register_operand"))
16215               (use (match_operand:SI 3 "immediate_operand"))
16216               (clobber (match_operand 0 "register_operand"))
16217               (clobber (match_operand 1 "register_operand"))
16218               (clobber (match_dup 2))])]
16219   ""
16220   "ix86_current_function_needs_cld = 1;")
16222 (define_insn "*cmpstrnqi_nz_1"
16223   [(set (reg:CC FLAGS_REG)
16224         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16225                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16226    (use (match_operand:P 6 "register_operand" "2"))
16227    (use (match_operand:SI 3 "immediate_operand" "i"))
16228    (clobber (match_operand:P 0 "register_operand" "=S"))
16229    (clobber (match_operand:P 1 "register_operand" "=D"))
16230    (clobber (match_operand:P 2 "register_operand" "=c"))]
16231   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16232   "%^repz{%;} cmpsb"
16233   [(set_attr "type" "str")
16234    (set_attr "mode" "QI")
16235    (set (attr "prefix_rex")
16236         (if_then_else
16237           (match_test "<P:MODE>mode == DImode")
16238           (const_string "0")
16239           (const_string "*")))
16240    (set_attr "prefix_rep" "1")])
16242 ;; The same, but the count is not known to not be zero.
16244 (define_expand "cmpstrnqi_1"
16245   [(parallel [(set (reg:CC FLAGS_REG)
16246                 (if_then_else:CC (ne (match_operand 2 "register_operand")
16247                                      (const_int 0))
16248                   (compare:CC (match_operand 4 "memory_operand")
16249                               (match_operand 5 "memory_operand"))
16250                   (const_int 0)))
16251               (use (match_operand:SI 3 "immediate_operand"))
16252               (use (reg:CC FLAGS_REG))
16253               (clobber (match_operand 0 "register_operand"))
16254               (clobber (match_operand 1 "register_operand"))
16255               (clobber (match_dup 2))])]
16256   ""
16257   "ix86_current_function_needs_cld = 1;")
16259 (define_insn "*cmpstrnqi_1"
16260   [(set (reg:CC FLAGS_REG)
16261         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16262                              (const_int 0))
16263           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16264                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
16265           (const_int 0)))
16266    (use (match_operand:SI 3 "immediate_operand" "i"))
16267    (use (reg:CC FLAGS_REG))
16268    (clobber (match_operand:P 0 "register_operand" "=S"))
16269    (clobber (match_operand:P 1 "register_operand" "=D"))
16270    (clobber (match_operand:P 2 "register_operand" "=c"))]
16271   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16272   "%^repz{%;} cmpsb"
16273   [(set_attr "type" "str")
16274    (set_attr "mode" "QI")
16275    (set (attr "prefix_rex")
16276         (if_then_else
16277           (match_test "<P:MODE>mode == DImode")
16278           (const_string "0")
16279           (const_string "*")))
16280    (set_attr "prefix_rep" "1")])
16282 (define_expand "strlen<mode>"
16283   [(set (match_operand:P 0 "register_operand")
16284         (unspec:P [(match_operand:BLK 1 "general_operand")
16285                    (match_operand:QI 2 "immediate_operand")
16286                    (match_operand 3 "immediate_operand")]
16287                   UNSPEC_SCAS))]
16288   ""
16290  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16291    DONE;
16292  else
16293    FAIL;
16296 (define_expand "strlenqi_1"
16297   [(parallel [(set (match_operand 0 "register_operand")
16298                    (match_operand 2))
16299               (clobber (match_operand 1 "register_operand"))
16300               (clobber (reg:CC FLAGS_REG))])]
16301   ""
16302   "ix86_current_function_needs_cld = 1;")
16304 (define_insn "*strlenqi_1"
16305   [(set (match_operand:P 0 "register_operand" "=&c")
16306         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16307                    (match_operand:QI 2 "register_operand" "a")
16308                    (match_operand:P 3 "immediate_operand" "i")
16309                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16310    (clobber (match_operand:P 1 "register_operand" "=D"))
16311    (clobber (reg:CC FLAGS_REG))]
16312   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16313   "%^repnz{%;} scasb"
16314   [(set_attr "type" "str")
16315    (set_attr "mode" "QI")
16316    (set (attr "prefix_rex")
16317         (if_then_else
16318           (match_test "<P:MODE>mode == DImode")
16319           (const_string "0")
16320           (const_string "*")))
16321    (set_attr "prefix_rep" "1")])
16323 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
16324 ;; handled in combine, but it is not currently up to the task.
16325 ;; When used for their truth value, the cmpstrn* expanders generate
16326 ;; code like this:
16328 ;;   repz cmpsb
16329 ;;   seta       %al
16330 ;;   setb       %dl
16331 ;;   cmpb       %al, %dl
16332 ;;   jcc        label
16334 ;; The intermediate three instructions are unnecessary.
16336 ;; This one handles cmpstrn*_nz_1...
16337 (define_peephole2
16338   [(parallel[
16339      (set (reg:CC FLAGS_REG)
16340           (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16341                       (mem:BLK (match_operand 5 "register_operand"))))
16342      (use (match_operand 6 "register_operand"))
16343      (use (match_operand:SI 3 "immediate_operand"))
16344      (clobber (match_operand 0 "register_operand"))
16345      (clobber (match_operand 1 "register_operand"))
16346      (clobber (match_operand 2 "register_operand"))])
16347    (set (match_operand:QI 7 "register_operand")
16348         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16349    (set (match_operand:QI 8 "register_operand")
16350         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16351    (set (reg FLAGS_REG)
16352         (compare (match_dup 7) (match_dup 8)))
16353   ]
16354   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16355   [(parallel[
16356      (set (reg:CC FLAGS_REG)
16357           (compare:CC (mem:BLK (match_dup 4))
16358                       (mem:BLK (match_dup 5))))
16359      (use (match_dup 6))
16360      (use (match_dup 3))
16361      (clobber (match_dup 0))
16362      (clobber (match_dup 1))
16363      (clobber (match_dup 2))])])
16365 ;; ...and this one handles cmpstrn*_1.
16366 (define_peephole2
16367   [(parallel[
16368      (set (reg:CC FLAGS_REG)
16369           (if_then_else:CC (ne (match_operand 6 "register_operand")
16370                                (const_int 0))
16371             (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16372                         (mem:BLK (match_operand 5 "register_operand")))
16373             (const_int 0)))
16374      (use (match_operand:SI 3 "immediate_operand"))
16375      (use (reg:CC FLAGS_REG))
16376      (clobber (match_operand 0 "register_operand"))
16377      (clobber (match_operand 1 "register_operand"))
16378      (clobber (match_operand 2 "register_operand"))])
16379    (set (match_operand:QI 7 "register_operand")
16380         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16381    (set (match_operand:QI 8 "register_operand")
16382         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16383    (set (reg FLAGS_REG)
16384         (compare (match_dup 7) (match_dup 8)))
16385   ]
16386   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16387   [(parallel[
16388      (set (reg:CC FLAGS_REG)
16389           (if_then_else:CC (ne (match_dup 6)
16390                                (const_int 0))
16391             (compare:CC (mem:BLK (match_dup 4))
16392                         (mem:BLK (match_dup 5)))
16393             (const_int 0)))
16394      (use (match_dup 3))
16395      (use (reg:CC FLAGS_REG))
16396      (clobber (match_dup 0))
16397      (clobber (match_dup 1))
16398      (clobber (match_dup 2))])])
16400 ;; Conditional move instructions.
16402 (define_expand "mov<mode>cc"
16403   [(set (match_operand:SWIM 0 "register_operand")
16404         (if_then_else:SWIM (match_operand 1 "comparison_operator")
16405                            (match_operand:SWIM 2 "<general_operand>")
16406                            (match_operand:SWIM 3 "<general_operand>")))]
16407   ""
16408   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16410 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16411 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16412 ;; So just document what we're doing explicitly.
16414 (define_expand "x86_mov<mode>cc_0_m1"
16415   [(parallel
16416     [(set (match_operand:SWI48 0 "register_operand")
16417           (if_then_else:SWI48
16418             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16419              [(match_operand 1 "flags_reg_operand")
16420               (const_int 0)])
16421             (const_int -1)
16422             (const_int 0)))
16423      (clobber (reg:CC FLAGS_REG))])])
16425 (define_insn "*x86_mov<mode>cc_0_m1"
16426   [(set (match_operand:SWI48 0 "register_operand" "=r")
16427         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16428                              [(reg FLAGS_REG) (const_int 0)])
16429           (const_int -1)
16430           (const_int 0)))
16431    (clobber (reg:CC FLAGS_REG))]
16432   ""
16433   "sbb{<imodesuffix>}\t%0, %0"
16434   ; Since we don't have the proper number of operands for an alu insn,
16435   ; fill in all the blanks.
16436   [(set_attr "type" "alu")
16437    (set_attr "use_carry" "1")
16438    (set_attr "pent_pair" "pu")
16439    (set_attr "memory" "none")
16440    (set_attr "imm_disp" "false")
16441    (set_attr "mode" "<MODE>")
16442    (set_attr "length_immediate" "0")])
16444 (define_insn "*x86_mov<mode>cc_0_m1_se"
16445   [(set (match_operand:SWI48 0 "register_operand" "=r")
16446         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16447                              [(reg FLAGS_REG) (const_int 0)])
16448                             (const_int 1)
16449                             (const_int 0)))
16450    (clobber (reg:CC FLAGS_REG))]
16451   ""
16452   "sbb{<imodesuffix>}\t%0, %0"
16453   [(set_attr "type" "alu")
16454    (set_attr "use_carry" "1")
16455    (set_attr "pent_pair" "pu")
16456    (set_attr "memory" "none")
16457    (set_attr "imm_disp" "false")
16458    (set_attr "mode" "<MODE>")
16459    (set_attr "length_immediate" "0")])
16461 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16462   [(set (match_operand:SWI48 0 "register_operand" "=r")
16463         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16464                     [(reg FLAGS_REG) (const_int 0)])))
16465    (clobber (reg:CC FLAGS_REG))]
16466   ""
16467   "sbb{<imodesuffix>}\t%0, %0"
16468   [(set_attr "type" "alu")
16469    (set_attr "use_carry" "1")
16470    (set_attr "pent_pair" "pu")
16471    (set_attr "memory" "none")
16472    (set_attr "imm_disp" "false")
16473    (set_attr "mode" "<MODE>")
16474    (set_attr "length_immediate" "0")])
16476 (define_insn "*mov<mode>cc_noc"
16477   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16478         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16479                                [(reg FLAGS_REG) (const_int 0)])
16480           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16481           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16482   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16483   "@
16484    cmov%O2%C1\t{%2, %0|%0, %2}
16485    cmov%O2%c1\t{%3, %0|%0, %3}"
16486   [(set_attr "type" "icmov")
16487    (set_attr "mode" "<MODE>")])
16489 ;; Don't do conditional moves with memory inputs.  This splitter helps
16490 ;; register starved x86_32 by forcing inputs into registers before reload.
16491 (define_split
16492   [(set (match_operand:SWI248 0 "register_operand")
16493         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16494                                [(reg FLAGS_REG) (const_int 0)])
16495           (match_operand:SWI248 2 "nonimmediate_operand")
16496           (match_operand:SWI248 3 "nonimmediate_operand")))]
16497   "!TARGET_64BIT && TARGET_CMOVE
16498    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16499    && (MEM_P (operands[2]) || MEM_P (operands[3]))
16500    && can_create_pseudo_p ()
16501    && optimize_insn_for_speed_p ()"
16502   [(set (match_dup 0)
16503         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16505   if (MEM_P (operands[2]))
16506     operands[2] = force_reg (<MODE>mode, operands[2]);
16507   if (MEM_P (operands[3]))
16508     operands[3] = force_reg (<MODE>mode, operands[3]);
16511 (define_insn "*movqicc_noc"
16512   [(set (match_operand:QI 0 "register_operand" "=r,r")
16513         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16514                            [(reg FLAGS_REG) (const_int 0)])
16515                       (match_operand:QI 2 "register_operand" "r,0")
16516                       (match_operand:QI 3 "register_operand" "0,r")))]
16517   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16518   "#"
16519   [(set_attr "type" "icmov")
16520    (set_attr "mode" "QI")])
16522 (define_split
16523   [(set (match_operand:SWI12 0 "register_operand")
16524         (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16525                               [(reg FLAGS_REG) (const_int 0)])
16526                       (match_operand:SWI12 2 "register_operand")
16527                       (match_operand:SWI12 3 "register_operand")))]
16528   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16529    && reload_completed"
16530   [(set (match_dup 0)
16531         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16533   operands[0] = gen_lowpart (SImode, operands[0]);
16534   operands[2] = gen_lowpart (SImode, operands[2]);
16535   operands[3] = gen_lowpart (SImode, operands[3]);
16538 ;; Don't do conditional moves with memory inputs
16539 (define_peephole2
16540   [(match_scratch:SWI248 2 "r")
16541    (set (match_operand:SWI248 0 "register_operand")
16542         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16543                                [(reg FLAGS_REG) (const_int 0)])
16544           (match_dup 0)
16545           (match_operand:SWI248 3 "memory_operand")))]
16546   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16547    && optimize_insn_for_speed_p ()"
16548   [(set (match_dup 2) (match_dup 3))
16549    (set (match_dup 0)
16550         (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
16552 (define_peephole2
16553   [(match_scratch:SWI248 2 "r")
16554    (set (match_operand:SWI248 0 "register_operand")
16555         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16556                                [(reg FLAGS_REG) (const_int 0)])
16557           (match_operand:SWI248 3 "memory_operand")
16558           (match_dup 0)))]
16559   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16560    && optimize_insn_for_speed_p ()"
16561   [(set (match_dup 2) (match_dup 3))
16562    (set (match_dup 0)
16563         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
16565 (define_expand "mov<mode>cc"
16566   [(set (match_operand:X87MODEF 0 "register_operand")
16567         (if_then_else:X87MODEF
16568           (match_operand 1 "comparison_operator")
16569           (match_operand:X87MODEF 2 "register_operand")
16570           (match_operand:X87MODEF 3 "register_operand")))]
16571   "(TARGET_80387 && TARGET_CMOVE)
16572    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16573   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16575 (define_insn "*movxfcc_1"
16576   [(set (match_operand:XF 0 "register_operand" "=f,f")
16577         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16578                                 [(reg FLAGS_REG) (const_int 0)])
16579                       (match_operand:XF 2 "register_operand" "f,0")
16580                       (match_operand:XF 3 "register_operand" "0,f")))]
16581   "TARGET_80387 && TARGET_CMOVE"
16582   "@
16583    fcmov%F1\t{%2, %0|%0, %2}
16584    fcmov%f1\t{%3, %0|%0, %3}"
16585   [(set_attr "type" "fcmov")
16586    (set_attr "mode" "XF")])
16588 (define_insn "*movdfcc_1"
16589   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16590         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16591                                 [(reg FLAGS_REG) (const_int 0)])
16592                       (match_operand:DF 2 "nonimmediate_operand"
16593                                                "f ,0,rm,0 ,rm,0")
16594                       (match_operand:DF 3 "nonimmediate_operand"
16595                                                "0 ,f,0 ,rm,0, rm")))]
16596   "TARGET_80387 && TARGET_CMOVE
16597    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16598   "@
16599    fcmov%F1\t{%2, %0|%0, %2}
16600    fcmov%f1\t{%3, %0|%0, %3}
16601    #
16602    #
16603    cmov%O2%C1\t{%2, %0|%0, %2}
16604    cmov%O2%c1\t{%3, %0|%0, %3}"
16605   [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16606    (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16607    (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16609 (define_split
16610   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16611         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16612                                 [(reg FLAGS_REG) (const_int 0)])
16613                       (match_operand:DF 2 "nonimmediate_operand")
16614                       (match_operand:DF 3 "nonimmediate_operand")))]
16615   "!TARGET_64BIT && reload_completed"
16616   [(set (match_dup 2)
16617         (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16618    (set (match_dup 3)
16619         (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16621   split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16622   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16625 (define_insn "*movsfcc_1_387"
16626   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16627         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16628                                 [(reg FLAGS_REG) (const_int 0)])
16629                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16630                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16631   "TARGET_80387 && TARGET_CMOVE
16632    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16633   "@
16634    fcmov%F1\t{%2, %0|%0, %2}
16635    fcmov%f1\t{%3, %0|%0, %3}
16636    cmov%O2%C1\t{%2, %0|%0, %2}
16637    cmov%O2%c1\t{%3, %0|%0, %3}"
16638   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16639    (set_attr "mode" "SF,SF,SI,SI")])
16641 ;; Don't do conditional moves with memory inputs.  This splitter helps
16642 ;; register starved x86_32 by forcing inputs into registers before reload.
16643 (define_split
16644   [(set (match_operand:MODEF 0 "register_operand")
16645         (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16646                               [(reg FLAGS_REG) (const_int 0)])
16647           (match_operand:MODEF 2 "nonimmediate_operand")
16648           (match_operand:MODEF 3 "nonimmediate_operand")))]
16649   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16650    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16651    && (MEM_P (operands[2]) || MEM_P (operands[3]))
16652    && can_create_pseudo_p ()
16653    && optimize_insn_for_speed_p ()"
16654   [(set (match_dup 0)
16655         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16657   if (MEM_P (operands[2]))
16658     operands[2] = force_reg (<MODE>mode, operands[2]);
16659   if (MEM_P (operands[3]))
16660     operands[3] = force_reg (<MODE>mode, operands[3]);
16663 ;; Don't do conditional moves with memory inputs
16664 (define_peephole2
16665   [(match_scratch:MODEF 2 "r")
16666    (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16667         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16668                               [(reg FLAGS_REG) (const_int 0)])
16669           (match_dup 0)
16670           (match_operand:MODEF 3 "memory_operand")))]
16671   "(<MODE>mode != DFmode || TARGET_64BIT)
16672    && TARGET_80387 && TARGET_CMOVE
16673    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16674    && optimize_insn_for_speed_p ()"
16675   [(set (match_dup 2) (match_dup 3))
16676    (set (match_dup 0)
16677         (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16679 (define_peephole2
16680   [(match_scratch:MODEF 2 "r")
16681    (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16682         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16683                               [(reg FLAGS_REG) (const_int 0)])
16684           (match_operand:MODEF 3 "memory_operand")
16685           (match_dup 0)))]
16686   "(<MODE>mode != DFmode || TARGET_64BIT)
16687    && TARGET_80387 && TARGET_CMOVE
16688    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16689    && optimize_insn_for_speed_p ()"
16690   [(set (match_dup 2) (match_dup 3))
16691    (set (match_dup 0)
16692         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16694 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16695 ;; the scalar versions to have only XMM registers as operands.
16697 ;; XOP conditional move
16698 (define_insn "*xop_pcmov_<mode>"
16699   [(set (match_operand:MODEF 0 "register_operand" "=x")
16700         (if_then_else:MODEF
16701           (match_operand:MODEF 1 "register_operand" "x")
16702           (match_operand:MODEF 2 "register_operand" "x")
16703           (match_operand:MODEF 3 "register_operand" "x")))]
16704   "TARGET_XOP"
16705   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16706   [(set_attr "type" "sse4arg")])
16708 ;; These versions of the min/max patterns are intentionally ignorant of
16709 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16710 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16711 ;; are undefined in this condition, we're certain this is correct.
16713 (define_insn "<code><mode>3"
16714   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16715         (smaxmin:MODEF
16716           (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
16717           (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
16718   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16719   "@
16720    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16721    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16722   [(set_attr "isa" "noavx,avx")
16723    (set_attr "prefix" "orig,vex")
16724    (set_attr "type" "sseadd")
16725    (set_attr "mode" "<MODE>")])
16727 ;; These versions of the min/max patterns implement exactly the operations
16728 ;;   min = (op1 < op2 ? op1 : op2)
16729 ;;   max = (!(op1 < op2) ? op1 : op2)
16730 ;; Their operands are not commutative, and thus they may be used in the
16731 ;; presence of -0.0 and NaN.
16733 (define_int_iterator IEEE_MAXMIN
16734         [UNSPEC_IEEE_MAX
16735          UNSPEC_IEEE_MIN])
16737 (define_int_attr ieee_maxmin
16738         [(UNSPEC_IEEE_MAX "max")
16739          (UNSPEC_IEEE_MIN "min")])
16741 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16742   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16743         (unspec:MODEF
16744           [(match_operand:MODEF 1 "register_operand" "0,x")
16745            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16746           IEEE_MAXMIN))]
16747   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16748   "@
16749    <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16750    v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16751   [(set_attr "isa" "noavx,avx")
16752    (set_attr "prefix" "orig,vex")
16753    (set_attr "type" "sseadd")
16754    (set_attr "mode" "<MODE>")])
16756 ;; Make two stack loads independent:
16757 ;;   fld aa              fld aa
16758 ;;   fld %st(0)     ->   fld bb
16759 ;;   fmul bb             fmul %st(1), %st
16761 ;; Actually we only match the last two instructions for simplicity.
16762 (define_peephole2
16763   [(set (match_operand 0 "fp_register_operand")
16764         (match_operand 1 "fp_register_operand"))
16765    (set (match_dup 0)
16766         (match_operator 2 "binary_fp_operator"
16767            [(match_dup 0)
16768             (match_operand 3 "memory_operand")]))]
16769   "REGNO (operands[0]) != REGNO (operands[1])"
16770   [(set (match_dup 0) (match_dup 3))
16771    (set (match_dup 0) (match_dup 4))]
16773   ;; The % modifier is not operational anymore in peephole2's, so we have to
16774   ;; swap the operands manually in the case of addition and multiplication.
16776   rtx op0, op1;
16778   if (COMMUTATIVE_ARITH_P (operands[2]))
16779     op0 = operands[0], op1 = operands[1];
16780   else
16781     op0 = operands[1], op1 = operands[0];
16783   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16784                                 GET_MODE (operands[2]),
16785                                 op0, op1);
16788 ;; Conditional addition patterns
16789 (define_expand "add<mode>cc"
16790   [(match_operand:SWI 0 "register_operand")
16791    (match_operand 1 "ordered_comparison_operator")
16792    (match_operand:SWI 2 "register_operand")
16793    (match_operand:SWI 3 "const_int_operand")]
16794   ""
16795   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16797 ;; Misc patterns (?)
16799 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16800 ;; Otherwise there will be nothing to keep
16802 ;; [(set (reg ebp) (reg esp))]
16803 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16804 ;;  (clobber (eflags)]
16805 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16807 ;; in proper program order.
16809 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16810   [(set (match_operand:P 0 "register_operand" "=r,r")
16811         (plus:P (match_operand:P 1 "register_operand" "0,r")
16812                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16813    (clobber (reg:CC FLAGS_REG))
16814    (clobber (mem:BLK (scratch)))]
16815   ""
16817   switch (get_attr_type (insn))
16818     {
16819     case TYPE_IMOV:
16820       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16822     case TYPE_ALU:
16823       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16824       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16825         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16827       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16829     default:
16830       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16831       return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16832     }
16834   [(set (attr "type")
16835         (cond [(and (eq_attr "alternative" "0")
16836                     (not (match_test "TARGET_OPT_AGU")))
16837                  (const_string "alu")
16838                (match_operand:<MODE> 2 "const0_operand")
16839                  (const_string "imov")
16840               ]
16841               (const_string "lea")))
16842    (set (attr "length_immediate")
16843         (cond [(eq_attr "type" "imov")
16844                  (const_string "0")
16845                (and (eq_attr "type" "alu")
16846                     (match_operand 2 "const128_operand"))
16847                  (const_string "1")
16848               ]
16849               (const_string "*")))
16850    (set_attr "mode" "<MODE>")])
16852 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16853   [(set (match_operand:P 0 "register_operand" "=r")
16854         (minus:P (match_operand:P 1 "register_operand" "0")
16855                  (match_operand:P 2 "register_operand" "r")))
16856    (clobber (reg:CC FLAGS_REG))
16857    (clobber (mem:BLK (scratch)))]
16858   ""
16859   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16860   [(set_attr "type" "alu")
16861    (set_attr "mode" "<MODE>")])
16863 (define_insn "allocate_stack_worker_probe_<mode>"
16864   [(set (match_operand:P 0 "register_operand" "=a")
16865         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16866                             UNSPECV_STACK_PROBE))
16867    (clobber (reg:CC FLAGS_REG))]
16868   "ix86_target_stack_probe ()"
16869   "call\t___chkstk_ms"
16870   [(set_attr "type" "multi")
16871    (set_attr "length" "5")])
16873 (define_expand "allocate_stack"
16874   [(match_operand 0 "register_operand")
16875    (match_operand 1 "general_operand")]
16876   "ix86_target_stack_probe ()"
16878   rtx x;
16880 #ifndef CHECK_STACK_LIMIT
16881 #define CHECK_STACK_LIMIT 0
16882 #endif
16884   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16885       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16886     x = operands[1];
16887   else
16888     {
16889       rtx (*insn) (rtx, rtx);
16891       x = copy_to_mode_reg (Pmode, operands[1]);
16893       insn = (TARGET_64BIT
16894               ? gen_allocate_stack_worker_probe_di
16895               : gen_allocate_stack_worker_probe_si);
16897       emit_insn (insn (x, x));
16898     }
16900   x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16901                            stack_pointer_rtx, 0, OPTAB_DIRECT);
16903   if (x != stack_pointer_rtx)
16904     emit_move_insn (stack_pointer_rtx, x);
16906   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16907   DONE;
16910 ;; Use IOR for stack probes, this is shorter.
16911 (define_expand "probe_stack"
16912   [(match_operand 0 "memory_operand")]
16913   ""
16915   rtx (*gen_ior3) (rtx, rtx, rtx);
16917   gen_ior3 = (GET_MODE (operands[0]) == DImode
16918               ? gen_iordi3 : gen_iorsi3);
16920   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16921   DONE;
16924 (define_insn "adjust_stack_and_probe<mode>"
16925   [(set (match_operand:P 0 "register_operand" "=r")
16926         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16927                             UNSPECV_PROBE_STACK_RANGE))
16928    (set (reg:P SP_REG)
16929         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16930    (clobber (reg:CC FLAGS_REG))
16931    (clobber (mem:BLK (scratch)))]
16932   ""
16933   "* return output_adjust_stack_and_probe (operands[0]);"
16934   [(set_attr "type" "multi")])
16936 (define_insn "probe_stack_range<mode>"
16937   [(set (match_operand:P 0 "register_operand" "=r")
16938         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16939                             (match_operand:P 2 "const_int_operand" "n")]
16940                             UNSPECV_PROBE_STACK_RANGE))
16941    (clobber (reg:CC FLAGS_REG))]
16942   ""
16943   "* return output_probe_stack_range (operands[0], operands[2]);"
16944   [(set_attr "type" "multi")])
16946 (define_expand "builtin_setjmp_receiver"
16947   [(label_ref (match_operand 0))]
16948   "!TARGET_64BIT && flag_pic"
16950 #if TARGET_MACHO
16951   if (TARGET_MACHO)
16952     {
16953       rtx xops[3];
16954       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16955       rtx_code_label *label_rtx = gen_label_rtx ();
16956       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16957       xops[0] = xops[1] = picreg;
16958       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16959       ix86_expand_binary_operator (MINUS, SImode, xops);
16960     }
16961   else
16962 #endif
16963     emit_insn (gen_set_got (pic_offset_table_rtx));
16964   DONE;
16967 (define_insn_and_split "nonlocal_goto_receiver"
16968   [(unspec_volatile [(const_int 0)] UNSPECV_NLGR)]
16969   "TARGET_MACHO && !TARGET_64BIT && flag_pic"
16970   "#"
16971   "&& reload_completed"
16972   [(const_int 0)]
16974   if (crtl->uses_pic_offset_table)
16975     {
16976       rtx xops[3];
16977       rtx label_rtx = gen_label_rtx ();
16978       rtx tmp;
16980       /* Get a new pic base.  */
16981       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16982       /* Correct this with the offset from the new to the old.  */
16983       xops[0] = xops[1] = pic_offset_table_rtx;
16984       label_rtx = gen_rtx_LABEL_REF (SImode, label_rtx);
16985       tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, label_rtx),
16986                             UNSPEC_MACHOPIC_OFFSET);
16987       xops[2] = gen_rtx_CONST (Pmode, tmp);
16988       ix86_expand_binary_operator (MINUS, SImode, xops);
16989     }
16990   else
16991     /* No pic reg restore needed.  */
16992     emit_note (NOTE_INSN_DELETED);
16994   DONE;
16997 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16998 ;; Do not split instructions with mask registers.
16999 (define_split
17000   [(set (match_operand 0 "general_reg_operand")
17001         (match_operator 3 "promotable_binary_operator"
17002            [(match_operand 1 "general_reg_operand")
17003             (match_operand 2 "aligned_operand")]))
17004    (clobber (reg:CC FLAGS_REG))]
17005   "! TARGET_PARTIAL_REG_STALL && reload_completed
17006    && ((GET_MODE (operands[0]) == HImode
17007         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17008             /* ??? next two lines just !satisfies_constraint_K (...) */
17009             || !CONST_INT_P (operands[2])
17010             || satisfies_constraint_K (operands[2])))
17011        || (GET_MODE (operands[0]) == QImode
17012            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17013   [(parallel [(set (match_dup 0)
17014                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17015               (clobber (reg:CC FLAGS_REG))])]
17017   operands[0] = gen_lowpart (SImode, operands[0]);
17018   operands[1] = gen_lowpart (SImode, operands[1]);
17019   if (GET_CODE (operands[3]) != ASHIFT)
17020     operands[2] = gen_lowpart (SImode, operands[2]);
17021   PUT_MODE (operands[3], SImode);
17024 ; Promote the QImode tests, as i386 has encoding of the AND
17025 ; instruction with 32-bit sign-extended immediate and thus the
17026 ; instruction size is unchanged, except in the %eax case for
17027 ; which it is increased by one byte, hence the ! optimize_size.
17028 (define_split
17029   [(set (match_operand 0 "flags_reg_operand")
17030         (match_operator 2 "compare_operator"
17031           [(and (match_operand 3 "aligned_operand")
17032                 (match_operand 4 "const_int_operand"))
17033            (const_int 0)]))
17034    (set (match_operand 1 "register_operand")
17035         (and (match_dup 3) (match_dup 4)))]
17036   "! TARGET_PARTIAL_REG_STALL && reload_completed
17037    && optimize_insn_for_speed_p ()
17038    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17039        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17040    /* Ensure that the operand will remain sign-extended immediate.  */
17041    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17042   [(parallel [(set (match_dup 0)
17043                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17044                                     (const_int 0)]))
17045               (set (match_dup 1)
17046                    (and:SI (match_dup 3) (match_dup 4)))])]
17048   operands[4]
17049     = gen_int_mode (INTVAL (operands[4])
17050                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17051   operands[1] = gen_lowpart (SImode, operands[1]);
17052   operands[3] = gen_lowpart (SImode, operands[3]);
17055 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17056 ; the TEST instruction with 32-bit sign-extended immediate and thus
17057 ; the instruction size would at least double, which is not what we
17058 ; want even with ! optimize_size.
17059 (define_split
17060   [(set (match_operand 0 "flags_reg_operand")
17061         (match_operator 1 "compare_operator"
17062           [(and (match_operand:HI 2 "aligned_operand")
17063                 (match_operand:HI 3 "const_int_operand"))
17064            (const_int 0)]))]
17065   "! TARGET_PARTIAL_REG_STALL && reload_completed
17066    && ! TARGET_FAST_PREFIX
17067    && optimize_insn_for_speed_p ()
17068    /* Ensure that the operand will remain sign-extended immediate.  */
17069    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17070   [(set (match_dup 0)
17071         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17072                          (const_int 0)]))]
17074   operands[3]
17075     = gen_int_mode (INTVAL (operands[3])
17076                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17077   operands[2] = gen_lowpart (SImode, operands[2]);
17080 (define_split
17081   [(set (match_operand 0 "register_operand")
17082         (neg (match_operand 1 "register_operand")))
17083    (clobber (reg:CC FLAGS_REG))]
17084   "! TARGET_PARTIAL_REG_STALL && reload_completed
17085    && (GET_MODE (operands[0]) == HImode
17086        || (GET_MODE (operands[0]) == QImode
17087            && (TARGET_PROMOTE_QImode
17088                || optimize_insn_for_size_p ())))"
17089   [(parallel [(set (match_dup 0)
17090                    (neg:SI (match_dup 1)))
17091               (clobber (reg:CC FLAGS_REG))])]
17093   operands[0] = gen_lowpart (SImode, operands[0]);
17094   operands[1] = gen_lowpart (SImode, operands[1]);
17097 ;; Do not split instructions with mask regs.
17098 (define_split
17099   [(set (match_operand 0 "general_reg_operand")
17100         (not (match_operand 1 "general_reg_operand")))]
17101   "! TARGET_PARTIAL_REG_STALL && reload_completed
17102    && (GET_MODE (operands[0]) == HImode
17103        || (GET_MODE (operands[0]) == QImode
17104            && (TARGET_PROMOTE_QImode
17105                || optimize_insn_for_size_p ())))"
17106   [(set (match_dup 0)
17107         (not:SI (match_dup 1)))]
17109   operands[0] = gen_lowpart (SImode, operands[0]);
17110   operands[1] = gen_lowpart (SImode, operands[1]);
17113 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
17114 ;; transform a complex memory operation into two memory to register operations.
17116 ;; Don't push memory operands
17117 (define_peephole2
17118   [(set (match_operand:SWI 0 "push_operand")
17119         (match_operand:SWI 1 "memory_operand"))
17120    (match_scratch:SWI 2 "<r>")]
17121   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17122    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17123   [(set (match_dup 2) (match_dup 1))
17124    (set (match_dup 0) (match_dup 2))])
17126 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17127 ;; SImode pushes.
17128 (define_peephole2
17129   [(set (match_operand:SF 0 "push_operand")
17130         (match_operand:SF 1 "memory_operand"))
17131    (match_scratch:SF 2 "r")]
17132   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17133    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17134   [(set (match_dup 2) (match_dup 1))
17135    (set (match_dup 0) (match_dup 2))])
17137 ;; Don't move an immediate directly to memory when the instruction
17138 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17139 (define_peephole2
17140   [(match_scratch:SWI124 1 "<r>")
17141    (set (match_operand:SWI124 0 "memory_operand")
17142         (const_int 0))]
17143   "optimize_insn_for_speed_p ()
17144    && ((<MODE>mode == HImode
17145        && TARGET_LCP_STALL)
17146        || (!TARGET_USE_MOV0
17147           && TARGET_SPLIT_LONG_MOVES
17148           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17149    && peep2_regno_dead_p (0, FLAGS_REG)"
17150   [(parallel [(set (match_dup 2) (const_int 0))
17151               (clobber (reg:CC FLAGS_REG))])
17152    (set (match_dup 0) (match_dup 1))]
17153   "operands[2] = gen_lowpart (SImode, operands[1]);")
17155 (define_peephole2
17156   [(match_scratch:SWI124 2 "<r>")
17157    (set (match_operand:SWI124 0 "memory_operand")
17158         (match_operand:SWI124 1 "immediate_operand"))]
17159   "optimize_insn_for_speed_p ()
17160    && ((<MODE>mode == HImode
17161        && TARGET_LCP_STALL)
17162        || (TARGET_SPLIT_LONG_MOVES
17163           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17164   [(set (match_dup 2) (match_dup 1))
17165    (set (match_dup 0) (match_dup 2))])
17167 ;; Don't compare memory with zero, load and use a test instead.
17168 (define_peephole2
17169   [(set (match_operand 0 "flags_reg_operand")
17170         (match_operator 1 "compare_operator"
17171           [(match_operand:SI 2 "memory_operand")
17172            (const_int 0)]))
17173    (match_scratch:SI 3 "r")]
17174   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17175   [(set (match_dup 3) (match_dup 2))
17176    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17178 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17179 ;; Don't split NOTs with a displacement operand, because resulting XOR
17180 ;; will not be pairable anyway.
17182 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17183 ;; represented using a modRM byte.  The XOR replacement is long decoded,
17184 ;; so this split helps here as well.
17186 ;; Note: Can't do this as a regular split because we can't get proper
17187 ;; lifetime information then.
17189 (define_peephole2
17190   [(set (match_operand:SWI124 0 "nonimmediate_operand")
17191         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
17192   "optimize_insn_for_speed_p ()
17193    && ((TARGET_NOT_UNPAIRABLE
17194         && (!MEM_P (operands[0])
17195             || !memory_displacement_operand (operands[0], <MODE>mode)))
17196        || (TARGET_NOT_VECTORMODE
17197            && long_memory_operand (operands[0], <MODE>mode)))
17198    && peep2_regno_dead_p (0, FLAGS_REG)"
17199   [(parallel [(set (match_dup 0)
17200                    (xor:SWI124 (match_dup 1) (const_int -1)))
17201               (clobber (reg:CC FLAGS_REG))])])
17203 ;; Non pairable "test imm, reg" instructions can be translated to
17204 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17205 ;; byte opcode instead of two, have a short form for byte operands),
17206 ;; so do it for other CPUs as well.  Given that the value was dead,
17207 ;; this should not create any new dependencies.  Pass on the sub-word
17208 ;; versions if we're concerned about partial register stalls.
17210 (define_peephole2
17211   [(set (match_operand 0 "flags_reg_operand")
17212         (match_operator 1 "compare_operator"
17213           [(and:SI (match_operand:SI 2 "register_operand")
17214                    (match_operand:SI 3 "immediate_operand"))
17215            (const_int 0)]))]
17216   "ix86_match_ccmode (insn, CCNOmode)
17217    && (true_regnum (operands[2]) != AX_REG
17218        || satisfies_constraint_K (operands[3]))
17219    && peep2_reg_dead_p (1, operands[2])"
17220   [(parallel
17221      [(set (match_dup 0)
17222            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17223                             (const_int 0)]))
17224       (set (match_dup 2)
17225            (and:SI (match_dup 2) (match_dup 3)))])])
17227 ;; We don't need to handle HImode case, because it will be promoted to SImode
17228 ;; on ! TARGET_PARTIAL_REG_STALL
17230 (define_peephole2
17231   [(set (match_operand 0 "flags_reg_operand")
17232         (match_operator 1 "compare_operator"
17233           [(and:QI (match_operand:QI 2 "register_operand")
17234                    (match_operand:QI 3 "immediate_operand"))
17235            (const_int 0)]))]
17236   "! TARGET_PARTIAL_REG_STALL
17237    && ix86_match_ccmode (insn, CCNOmode)
17238    && true_regnum (operands[2]) != AX_REG
17239    && peep2_reg_dead_p (1, operands[2])"
17240   [(parallel
17241      [(set (match_dup 0)
17242            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17243                             (const_int 0)]))
17244       (set (match_dup 2)
17245            (and:QI (match_dup 2) (match_dup 3)))])])
17247 (define_peephole2
17248   [(set (match_operand 0 "flags_reg_operand")
17249         (match_operator 1 "compare_operator"
17250           [(and:SI
17251              (zero_extract:SI
17252                (match_operand 2 "ext_register_operand")
17253                (const_int 8)
17254                (const_int 8))
17255              (match_operand 3 "const_int_operand"))
17256            (const_int 0)]))]
17257   "! TARGET_PARTIAL_REG_STALL
17258    && ix86_match_ccmode (insn, CCNOmode)
17259    && true_regnum (operands[2]) != AX_REG
17260    && peep2_reg_dead_p (1, operands[2])"
17261   [(parallel [(set (match_dup 0)
17262                    (match_op_dup 1
17263                      [(and:SI
17264                         (zero_extract:SI
17265                           (match_dup 2)
17266                           (const_int 8)
17267                           (const_int 8))
17268                         (match_dup 3))
17269                       (const_int 0)]))
17270               (set (zero_extract:SI (match_dup 2)
17271                                     (const_int 8)
17272                                     (const_int 8))
17273                    (and:SI
17274                      (zero_extract:SI
17275                        (match_dup 2)
17276                        (const_int 8)
17277                        (const_int 8))
17278                      (match_dup 3)))])])
17280 ;; Don't do logical operations with memory inputs.
17281 (define_peephole2
17282   [(match_scratch:SI 2 "r")
17283    (parallel [(set (match_operand:SI 0 "register_operand")
17284                    (match_operator:SI 3 "arith_or_logical_operator"
17285                      [(match_dup 0)
17286                       (match_operand:SI 1 "memory_operand")]))
17287               (clobber (reg:CC FLAGS_REG))])]
17288   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17289   [(set (match_dup 2) (match_dup 1))
17290    (parallel [(set (match_dup 0)
17291                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17292               (clobber (reg:CC FLAGS_REG))])])
17294 (define_peephole2
17295   [(match_scratch:SI 2 "r")
17296    (parallel [(set (match_operand:SI 0 "register_operand")
17297                    (match_operator:SI 3 "arith_or_logical_operator"
17298                      [(match_operand:SI 1 "memory_operand")
17299                       (match_dup 0)]))
17300               (clobber (reg:CC FLAGS_REG))])]
17301   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17302   [(set (match_dup 2) (match_dup 1))
17303    (parallel [(set (match_dup 0)
17304                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17305               (clobber (reg:CC FLAGS_REG))])])
17307 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17308 ;; refers to the destination of the load!
17310 (define_peephole2
17311   [(set (match_operand:SI 0 "register_operand")
17312         (match_operand:SI 1 "register_operand"))
17313    (parallel [(set (match_dup 0)
17314                    (match_operator:SI 3 "commutative_operator"
17315                      [(match_dup 0)
17316                       (match_operand:SI 2 "memory_operand")]))
17317               (clobber (reg:CC FLAGS_REG))])]
17318   "REGNO (operands[0]) != REGNO (operands[1])
17319    && GENERAL_REGNO_P (REGNO (operands[0]))
17320    && GENERAL_REGNO_P (REGNO (operands[1]))"
17321   [(set (match_dup 0) (match_dup 4))
17322    (parallel [(set (match_dup 0)
17323                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17324               (clobber (reg:CC FLAGS_REG))])]
17325   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17327 (define_peephole2
17328   [(set (match_operand 0 "register_operand")
17329         (match_operand 1 "register_operand"))
17330    (set (match_dup 0)
17331                    (match_operator 3 "commutative_operator"
17332                      [(match_dup 0)
17333                       (match_operand 2 "memory_operand")]))]
17334   "REGNO (operands[0]) != REGNO (operands[1])
17335    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
17336        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17337   [(set (match_dup 0) (match_dup 2))
17338    (set (match_dup 0)
17339         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17341 ; Don't do logical operations with memory outputs
17343 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17344 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17345 ; the same decoder scheduling characteristics as the original.
17347 (define_peephole2
17348   [(match_scratch:SI 2 "r")
17349    (parallel [(set (match_operand:SI 0 "memory_operand")
17350                    (match_operator:SI 3 "arith_or_logical_operator"
17351                      [(match_dup 0)
17352                       (match_operand:SI 1 "nonmemory_operand")]))
17353               (clobber (reg:CC FLAGS_REG))])]
17354   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17355    /* Do not split stack checking probes.  */
17356    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17357   [(set (match_dup 2) (match_dup 0))
17358    (parallel [(set (match_dup 2)
17359                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17360               (clobber (reg:CC FLAGS_REG))])
17361    (set (match_dup 0) (match_dup 2))])
17363 (define_peephole2
17364   [(match_scratch:SI 2 "r")
17365    (parallel [(set (match_operand:SI 0 "memory_operand")
17366                    (match_operator:SI 3 "arith_or_logical_operator"
17367                      [(match_operand:SI 1 "nonmemory_operand")
17368                       (match_dup 0)]))
17369               (clobber (reg:CC FLAGS_REG))])]
17370   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17371    /* Do not split stack checking probes.  */
17372    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17373   [(set (match_dup 2) (match_dup 0))
17374    (parallel [(set (match_dup 2)
17375                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17376               (clobber (reg:CC FLAGS_REG))])
17377    (set (match_dup 0) (match_dup 2))])
17379 ;; Attempt to use arith or logical operations with memory outputs with
17380 ;; setting of flags.
17381 (define_peephole2
17382   [(set (match_operand:SWI 0 "register_operand")
17383         (match_operand:SWI 1 "memory_operand"))
17384    (parallel [(set (match_dup 0)
17385                    (match_operator:SWI 3 "plusminuslogic_operator"
17386                      [(match_dup 0)
17387                       (match_operand:SWI 2 "<nonmemory_operand>")]))
17388               (clobber (reg:CC FLAGS_REG))])
17389    (set (match_dup 1) (match_dup 0))
17390    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17391   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17392    && peep2_reg_dead_p (4, operands[0])
17393    && !reg_overlap_mentioned_p (operands[0], operands[1])
17394    && !reg_overlap_mentioned_p (operands[0], operands[2])
17395    && (<MODE>mode != QImode
17396        || immediate_operand (operands[2], QImode)
17397        || q_regs_operand (operands[2], QImode))
17398    && ix86_match_ccmode (peep2_next_insn (3),
17399                          (GET_CODE (operands[3]) == PLUS
17400                           || GET_CODE (operands[3]) == MINUS)
17401                          ? CCGOCmode : CCNOmode)"
17402   [(parallel [(set (match_dup 4) (match_dup 5))
17403               (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17404                                                   (match_dup 2)]))])]
17406   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17407   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17408                                 copy_rtx (operands[1]),
17409                                 copy_rtx (operands[2]));
17410   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17411                                  operands[5], const0_rtx);
17414 (define_peephole2
17415   [(parallel [(set (match_operand:SWI 0 "register_operand")
17416                    (match_operator:SWI 2 "plusminuslogic_operator"
17417                      [(match_dup 0)
17418                       (match_operand:SWI 1 "memory_operand")]))
17419               (clobber (reg:CC FLAGS_REG))])
17420    (set (match_dup 1) (match_dup 0))
17421    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17422   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17423    && GET_CODE (operands[2]) != MINUS
17424    && peep2_reg_dead_p (3, operands[0])
17425    && !reg_overlap_mentioned_p (operands[0], operands[1])
17426    && ix86_match_ccmode (peep2_next_insn (2),
17427                          GET_CODE (operands[2]) == PLUS
17428                          ? CCGOCmode : CCNOmode)"
17429   [(parallel [(set (match_dup 3) (match_dup 4))
17430               (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17431                                                   (match_dup 0)]))])]
17433   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17434   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17435                                 copy_rtx (operands[1]),
17436                                 copy_rtx (operands[0]));
17437   operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17438                                  operands[4], const0_rtx);
17441 (define_peephole2
17442   [(set (match_operand:SWI12 0 "register_operand")
17443         (match_operand:SWI12 1 "memory_operand"))
17444    (parallel [(set (match_operand:SI 4 "register_operand")
17445                    (match_operator:SI 3 "plusminuslogic_operator"
17446                      [(match_dup 4)
17447                       (match_operand:SI 2 "nonmemory_operand")]))
17448               (clobber (reg:CC FLAGS_REG))])
17449    (set (match_dup 1) (match_dup 0))
17450    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17451   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17452    && REG_P (operands[0]) && REG_P (operands[4])
17453    && REGNO (operands[0]) == REGNO (operands[4])
17454    && peep2_reg_dead_p (4, operands[0])
17455    && (<MODE>mode != QImode
17456        || immediate_operand (operands[2], SImode)
17457        || q_regs_operand (operands[2], SImode))
17458    && !reg_overlap_mentioned_p (operands[0], operands[1])
17459    && !reg_overlap_mentioned_p (operands[0], operands[2])
17460    && ix86_match_ccmode (peep2_next_insn (3),
17461                          (GET_CODE (operands[3]) == PLUS
17462                           || GET_CODE (operands[3]) == MINUS)
17463                          ? CCGOCmode : CCNOmode)"
17464   [(parallel [(set (match_dup 4) (match_dup 5))
17465               (set (match_dup 1) (match_dup 6))])]
17467   operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17468   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17469   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17470                                 copy_rtx (operands[1]), operands[2]);
17471   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17472                                  operands[5], const0_rtx);
17473   operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17474                                 copy_rtx (operands[1]),
17475                                 copy_rtx (operands[2]));
17478 ;; Attempt to always use XOR for zeroing registers.
17479 (define_peephole2
17480   [(set (match_operand 0 "register_operand")
17481         (match_operand 1 "const0_operand"))]
17482   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17483    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17484    && GENERAL_REG_P (operands[0])
17485    && peep2_regno_dead_p (0, FLAGS_REG)"
17486   [(parallel [(set (match_dup 0) (const_int 0))
17487               (clobber (reg:CC FLAGS_REG))])]
17488   "operands[0] = gen_lowpart (word_mode, operands[0]);")
17490 (define_peephole2
17491   [(set (strict_low_part (match_operand 0 "register_operand"))
17492         (const_int 0))]
17493   "(GET_MODE (operands[0]) == QImode
17494     || GET_MODE (operands[0]) == HImode)
17495    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17496    && peep2_regno_dead_p (0, FLAGS_REG)"
17497   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17498               (clobber (reg:CC FLAGS_REG))])])
17500 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17501 (define_peephole2
17502   [(set (match_operand:SWI248 0 "register_operand")
17503         (const_int -1))]
17504   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17505    && peep2_regno_dead_p (0, FLAGS_REG)"
17506   [(parallel [(set (match_dup 0) (const_int -1))
17507               (clobber (reg:CC FLAGS_REG))])]
17509   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
17510     operands[0] = gen_lowpart (SImode, operands[0]);
17513 ;; Attempt to convert simple lea to add/shift.
17514 ;; These can be created by move expanders.
17515 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17516 ;; relevant lea instructions were already split.
17518 (define_peephole2
17519   [(set (match_operand:SWI48 0 "register_operand")
17520         (plus:SWI48 (match_dup 0)
17521                     (match_operand:SWI48 1 "<nonmemory_operand>")))]
17522   "!TARGET_OPT_AGU
17523    && peep2_regno_dead_p (0, FLAGS_REG)"
17524   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17525               (clobber (reg:CC FLAGS_REG))])])
17527 (define_peephole2
17528   [(set (match_operand:SWI48 0 "register_operand")
17529         (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17530                     (match_dup 0)))]
17531   "!TARGET_OPT_AGU
17532    && peep2_regno_dead_p (0, FLAGS_REG)"
17533   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17534               (clobber (reg:CC FLAGS_REG))])])
17536 (define_peephole2
17537   [(set (match_operand:DI 0 "register_operand")
17538         (zero_extend:DI
17539           (plus:SI (match_operand:SI 1 "register_operand")
17540                    (match_operand:SI 2 "nonmemory_operand"))))]
17541   "TARGET_64BIT && !TARGET_OPT_AGU
17542    && REGNO (operands[0]) == REGNO (operands[1])
17543    && peep2_regno_dead_p (0, FLAGS_REG)"
17544   [(parallel [(set (match_dup 0)
17545                    (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17546               (clobber (reg:CC FLAGS_REG))])])
17548 (define_peephole2
17549   [(set (match_operand:DI 0 "register_operand")
17550         (zero_extend:DI
17551           (plus:SI (match_operand:SI 1 "nonmemory_operand")
17552                    (match_operand:SI 2 "register_operand"))))]
17553   "TARGET_64BIT && !TARGET_OPT_AGU
17554    && REGNO (operands[0]) == REGNO (operands[2])
17555    && peep2_regno_dead_p (0, FLAGS_REG)"
17556   [(parallel [(set (match_dup 0)
17557                    (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17558               (clobber (reg:CC FLAGS_REG))])])
17560 (define_peephole2
17561   [(set (match_operand:SWI48 0 "register_operand")
17562         (mult:SWI48 (match_dup 0)
17563                     (match_operand:SWI48 1 "const_int_operand")))]
17564   "exact_log2 (INTVAL (operands[1])) >= 0
17565    && peep2_regno_dead_p (0, FLAGS_REG)"
17566   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17567               (clobber (reg:CC FLAGS_REG))])]
17568   "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17570 (define_peephole2
17571   [(set (match_operand:DI 0 "register_operand")
17572         (zero_extend:DI
17573           (mult:SI (match_operand:SI 1 "register_operand")
17574                    (match_operand:SI 2 "const_int_operand"))))]
17575   "TARGET_64BIT
17576    && exact_log2 (INTVAL (operands[2])) >= 0
17577    && REGNO (operands[0]) == REGNO (operands[1])
17578    && peep2_regno_dead_p (0, FLAGS_REG)"
17579   [(parallel [(set (match_dup 0)
17580                    (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
17581               (clobber (reg:CC FLAGS_REG))])]
17582   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17584 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17585 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17586 ;; On many CPUs it is also faster, since special hardware to avoid esp
17587 ;; dependencies is present.
17589 ;; While some of these conversions may be done using splitters, we use
17590 ;; peepholes in order to allow combine_stack_adjustments pass to see
17591 ;; nonobfuscated RTL.
17593 ;; Convert prologue esp subtractions to push.
17594 ;; We need register to push.  In order to keep verify_flow_info happy we have
17595 ;; two choices
17596 ;; - use scratch and clobber it in order to avoid dependencies
17597 ;; - use already live register
17598 ;; We can't use the second way right now, since there is no reliable way how to
17599 ;; verify that given register is live.  First choice will also most likely in
17600 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17601 ;; call clobbered registers are dead.  We may want to use base pointer as an
17602 ;; alternative when no register is available later.
17604 (define_peephole2
17605   [(match_scratch:W 1 "r")
17606    (parallel [(set (reg:P SP_REG)
17607                    (plus:P (reg:P SP_REG)
17608                            (match_operand:P 0 "const_int_operand")))
17609               (clobber (reg:CC FLAGS_REG))
17610               (clobber (mem:BLK (scratch)))])]
17611   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17612    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17613   [(clobber (match_dup 1))
17614    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17615               (clobber (mem:BLK (scratch)))])])
17617 (define_peephole2
17618   [(match_scratch:W 1 "r")
17619    (parallel [(set (reg:P SP_REG)
17620                    (plus:P (reg:P SP_REG)
17621                            (match_operand:P 0 "const_int_operand")))
17622               (clobber (reg:CC FLAGS_REG))
17623               (clobber (mem:BLK (scratch)))])]
17624   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17625    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17626   [(clobber (match_dup 1))
17627    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17628    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17629               (clobber (mem:BLK (scratch)))])])
17631 ;; Convert esp subtractions to push.
17632 (define_peephole2
17633   [(match_scratch:W 1 "r")
17634    (parallel [(set (reg:P SP_REG)
17635                    (plus:P (reg:P SP_REG)
17636                            (match_operand:P 0 "const_int_operand")))
17637               (clobber (reg:CC FLAGS_REG))])]
17638   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17639    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17640   [(clobber (match_dup 1))
17641    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17643 (define_peephole2
17644   [(match_scratch:W 1 "r")
17645    (parallel [(set (reg:P SP_REG)
17646                    (plus:P (reg:P SP_REG)
17647                            (match_operand:P 0 "const_int_operand")))
17648               (clobber (reg:CC FLAGS_REG))])]
17649   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17650    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17651   [(clobber (match_dup 1))
17652    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17653    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17655 ;; Convert epilogue deallocator to pop.
17656 (define_peephole2
17657   [(match_scratch:W 1 "r")
17658    (parallel [(set (reg:P SP_REG)
17659                    (plus:P (reg:P SP_REG)
17660                            (match_operand:P 0 "const_int_operand")))
17661               (clobber (reg:CC FLAGS_REG))
17662               (clobber (mem:BLK (scratch)))])]
17663   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17664    && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17665   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17666               (clobber (mem:BLK (scratch)))])])
17668 ;; Two pops case is tricky, since pop causes dependency
17669 ;; on destination register.  We use two registers if available.
17670 (define_peephole2
17671   [(match_scratch:W 1 "r")
17672    (match_scratch:W 2 "r")
17673    (parallel [(set (reg:P SP_REG)
17674                    (plus:P (reg:P SP_REG)
17675                            (match_operand:P 0 "const_int_operand")))
17676               (clobber (reg:CC FLAGS_REG))
17677               (clobber (mem:BLK (scratch)))])]
17678   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17679    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17680   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17681               (clobber (mem:BLK (scratch)))])
17682    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17684 (define_peephole2
17685   [(match_scratch:W 1 "r")
17686    (parallel [(set (reg:P SP_REG)
17687                    (plus:P (reg:P SP_REG)
17688                            (match_operand:P 0 "const_int_operand")))
17689               (clobber (reg:CC FLAGS_REG))
17690               (clobber (mem:BLK (scratch)))])]
17691   "optimize_insn_for_size_p ()
17692    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17693   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17694               (clobber (mem:BLK (scratch)))])
17695    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17697 ;; Convert esp additions to pop.
17698 (define_peephole2
17699   [(match_scratch:W 1 "r")
17700    (parallel [(set (reg:P SP_REG)
17701                    (plus:P (reg:P SP_REG)
17702                            (match_operand:P 0 "const_int_operand")))
17703               (clobber (reg:CC FLAGS_REG))])]
17704   "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17705   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17707 ;; Two pops case is tricky, since pop causes dependency
17708 ;; on destination register.  We use two registers if available.
17709 (define_peephole2
17710   [(match_scratch:W 1 "r")
17711    (match_scratch:W 2 "r")
17712    (parallel [(set (reg:P SP_REG)
17713                    (plus:P (reg:P SP_REG)
17714                            (match_operand:P 0 "const_int_operand")))
17715               (clobber (reg:CC FLAGS_REG))])]
17716   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17717   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17718    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17720 (define_peephole2
17721   [(match_scratch:W 1 "r")
17722    (parallel [(set (reg:P SP_REG)
17723                    (plus:P (reg:P SP_REG)
17724                            (match_operand:P 0 "const_int_operand")))
17725               (clobber (reg:CC FLAGS_REG))])]
17726   "optimize_insn_for_size_p ()
17727    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17728   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17729    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17731 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17732 ;; required and register dies.  Similarly for 128 to -128.
17733 (define_peephole2
17734   [(set (match_operand 0 "flags_reg_operand")
17735         (match_operator 1 "compare_operator"
17736           [(match_operand 2 "register_operand")
17737            (match_operand 3 "const_int_operand")]))]
17738   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17739      && incdec_operand (operands[3], GET_MODE (operands[3])))
17740     || (!TARGET_FUSE_CMP_AND_BRANCH
17741         && INTVAL (operands[3]) == 128))
17742    && ix86_match_ccmode (insn, CCGCmode)
17743    && peep2_reg_dead_p (1, operands[2])"
17744   [(parallel [(set (match_dup 0)
17745                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17746               (clobber (match_dup 2))])])
17748 ;; Convert imul by three, five and nine into lea
17749 (define_peephole2
17750   [(parallel
17751     [(set (match_operand:SWI48 0 "register_operand")
17752           (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17753                       (match_operand:SWI48 2 "const359_operand")))
17754      (clobber (reg:CC FLAGS_REG))])]
17755   "!TARGET_PARTIAL_REG_STALL
17756    || <MODE>mode == SImode
17757    || optimize_function_for_size_p (cfun)"
17758   [(set (match_dup 0)
17759         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17760                     (match_dup 1)))]
17761   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17763 (define_peephole2
17764   [(parallel
17765     [(set (match_operand:SWI48 0 "register_operand")
17766           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17767                       (match_operand:SWI48 2 "const359_operand")))
17768      (clobber (reg:CC FLAGS_REG))])]
17769   "optimize_insn_for_speed_p ()
17770    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17771   [(set (match_dup 0) (match_dup 1))
17772    (set (match_dup 0)
17773         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17774                     (match_dup 0)))]
17775   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17777 ;; imul $32bit_imm, mem, reg is vector decoded, while
17778 ;; imul $32bit_imm, reg, reg is direct decoded.
17779 (define_peephole2
17780   [(match_scratch:SWI48 3 "r")
17781    (parallel [(set (match_operand:SWI48 0 "register_operand")
17782                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17783                                (match_operand:SWI48 2 "immediate_operand")))
17784               (clobber (reg:CC FLAGS_REG))])]
17785   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17786    && !satisfies_constraint_K (operands[2])"
17787   [(set (match_dup 3) (match_dup 1))
17788    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17789               (clobber (reg:CC FLAGS_REG))])])
17791 (define_peephole2
17792   [(match_scratch:SI 3 "r")
17793    (parallel [(set (match_operand:DI 0 "register_operand")
17794                    (zero_extend:DI
17795                      (mult:SI (match_operand:SI 1 "memory_operand")
17796                               (match_operand:SI 2 "immediate_operand"))))
17797               (clobber (reg:CC FLAGS_REG))])]
17798   "TARGET_64BIT
17799    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17800    && !satisfies_constraint_K (operands[2])"
17801   [(set (match_dup 3) (match_dup 1))
17802    (parallel [(set (match_dup 0)
17803                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17804               (clobber (reg:CC FLAGS_REG))])])
17806 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17807 ;; Convert it into imul reg, reg
17808 ;; It would be better to force assembler to encode instruction using long
17809 ;; immediate, but there is apparently no way to do so.
17810 (define_peephole2
17811   [(parallel [(set (match_operand:SWI248 0 "register_operand")
17812                    (mult:SWI248
17813                     (match_operand:SWI248 1 "nonimmediate_operand")
17814                     (match_operand:SWI248 2 "const_int_operand")))
17815               (clobber (reg:CC FLAGS_REG))])
17816    (match_scratch:SWI248 3 "r")]
17817   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17818    && satisfies_constraint_K (operands[2])"
17819   [(set (match_dup 3) (match_dup 2))
17820    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17821               (clobber (reg:CC FLAGS_REG))])]
17823   if (!rtx_equal_p (operands[0], operands[1]))
17824     emit_move_insn (operands[0], operands[1]);
17827 ;; After splitting up read-modify operations, array accesses with memory
17828 ;; operands might end up in form:
17829 ;;  sall    $2, %eax
17830 ;;  movl    4(%esp), %edx
17831 ;;  addl    %edx, %eax
17832 ;; instead of pre-splitting:
17833 ;;  sall    $2, %eax
17834 ;;  addl    4(%esp), %eax
17835 ;; Turn it into:
17836 ;;  movl    4(%esp), %edx
17837 ;;  leal    (%edx,%eax,4), %eax
17839 (define_peephole2
17840   [(match_scratch:W 5 "r")
17841    (parallel [(set (match_operand 0 "register_operand")
17842                    (ashift (match_operand 1 "register_operand")
17843                            (match_operand 2 "const_int_operand")))
17844                (clobber (reg:CC FLAGS_REG))])
17845    (parallel [(set (match_operand 3 "register_operand")
17846                    (plus (match_dup 0)
17847                          (match_operand 4 "x86_64_general_operand")))
17848                    (clobber (reg:CC FLAGS_REG))])]
17849   "IN_RANGE (INTVAL (operands[2]), 1, 3)
17850    /* Validate MODE for lea.  */
17851    && ((!TARGET_PARTIAL_REG_STALL
17852         && (GET_MODE (operands[0]) == QImode
17853             || GET_MODE (operands[0]) == HImode))
17854        || GET_MODE (operands[0]) == SImode
17855        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17856    && (rtx_equal_p (operands[0], operands[3])
17857        || peep2_reg_dead_p (2, operands[0]))
17858    /* We reorder load and the shift.  */
17859    && !reg_overlap_mentioned_p (operands[0], operands[4])"
17860   [(set (match_dup 5) (match_dup 4))
17861    (set (match_dup 0) (match_dup 1))]
17863   machine_mode op1mode = GET_MODE (operands[1]);
17864   machine_mode mode = op1mode == DImode ? DImode : SImode;
17865   int scale = 1 << INTVAL (operands[2]);
17866   rtx index = gen_lowpart (word_mode, operands[1]);
17867   rtx base = gen_lowpart (word_mode, operands[5]);
17868   rtx dest = gen_lowpart (mode, operands[3]);
17870   operands[1] = gen_rtx_PLUS (word_mode, base,
17871                               gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17872   operands[5] = base;
17873   if (mode != word_mode)
17874     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17875   if (op1mode != word_mode)
17876     operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17877   operands[0] = dest;
17880 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17881 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17882 ;; caught for use by garbage collectors and the like.  Using an insn that
17883 ;; maps to SIGILL makes it more likely the program will rightfully die.
17884 ;; Keeping with tradition, "6" is in honor of #UD.
17885 (define_insn "trap"
17886   [(trap_if (const_int 1) (const_int 6))]
17887   ""
17889 #ifdef HAVE_AS_IX86_UD2
17890   return "ud2";
17891 #else
17892   return ASM_SHORT "0x0b0f";
17893 #endif
17895   [(set_attr "length" "2")])
17897 (define_expand "prefetch"
17898   [(prefetch (match_operand 0 "address_operand")
17899              (match_operand:SI 1 "const_int_operand")
17900              (match_operand:SI 2 "const_int_operand"))]
17901   "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
17903   bool write = INTVAL (operands[1]) != 0;
17904   int locality = INTVAL (operands[2]);
17906   gcc_assert (IN_RANGE (locality, 0, 3));
17908   /* Use 3dNOW prefetch in case we are asking for write prefetch not
17909      supported by SSE counterpart or the SSE prefetch is not available
17910      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17911      of locality.  */
17912   if (TARGET_PREFETCHWT1 && write && locality <= 2)
17913     operands[2] = const2_rtx;
17914   else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
17915     operands[2] = GEN_INT (3);
17916   else
17917     operands[1] = const0_rtx;
17920 (define_insn "*prefetch_sse"
17921   [(prefetch (match_operand 0 "address_operand" "p")
17922              (const_int 0)
17923              (match_operand:SI 1 "const_int_operand"))]
17924   "TARGET_PREFETCH_SSE"
17926   static const char * const patterns[4] = {
17927    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17928   };
17930   int locality = INTVAL (operands[1]);
17931   gcc_assert (IN_RANGE (locality, 0, 3));
17933   return patterns[locality];
17935   [(set_attr "type" "sse")
17936    (set_attr "atom_sse_attr" "prefetch")
17937    (set (attr "length_address")
17938         (symbol_ref "memory_address_length (operands[0], false)"))
17939    (set_attr "memory" "none")])
17941 (define_insn "*prefetch_3dnow"
17942   [(prefetch (match_operand 0 "address_operand" "p")
17943              (match_operand:SI 1 "const_int_operand" "n")
17944              (const_int 3))]
17945   "TARGET_PRFCHW"
17947   if (INTVAL (operands[1]) == 0)
17948     return "prefetch\t%a0";
17949   else
17950     return "prefetchw\t%a0";
17952   [(set_attr "type" "mmx")
17953    (set (attr "length_address")
17954         (symbol_ref "memory_address_length (operands[0], false)"))
17955    (set_attr "memory" "none")])
17957 (define_insn "*prefetch_prefetchwt1_<mode>"
17958   [(prefetch (match_operand:P 0 "address_operand" "p")
17959              (const_int 1)
17960              (const_int 2))]
17961   "TARGET_PREFETCHWT1"
17962   "prefetchwt1\t%a0";
17963   [(set_attr "type" "sse")
17964    (set (attr "length_address")
17965         (symbol_ref "memory_address_length (operands[0], false)"))
17966    (set_attr "memory" "none")])
17968 (define_expand "stack_protect_set"
17969   [(match_operand 0 "memory_operand")
17970    (match_operand 1 "memory_operand")]
17971   "TARGET_SSP_TLS_GUARD"
17973   rtx (*insn)(rtx, rtx);
17975 #ifdef TARGET_THREAD_SSP_OFFSET
17976   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17977   insn = (TARGET_LP64
17978           ? gen_stack_tls_protect_set_di
17979           : gen_stack_tls_protect_set_si);
17980 #else
17981   insn = (TARGET_LP64
17982           ? gen_stack_protect_set_di
17983           : gen_stack_protect_set_si);
17984 #endif
17986   emit_insn (insn (operands[0], operands[1]));
17987   DONE;
17990 (define_insn "stack_protect_set_<mode>"
17991   [(set (match_operand:PTR 0 "memory_operand" "=m")
17992         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17993                     UNSPEC_SP_SET))
17994    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17995    (clobber (reg:CC FLAGS_REG))]
17996   "TARGET_SSP_TLS_GUARD"
17997   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17998   [(set_attr "type" "multi")])
18000 (define_insn "stack_tls_protect_set_<mode>"
18001   [(set (match_operand:PTR 0 "memory_operand" "=m")
18002         (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
18003                     UNSPEC_SP_TLS_SET))
18004    (set (match_scratch:PTR 2 "=&r") (const_int 0))
18005    (clobber (reg:CC FLAGS_REG))]
18006   ""
18007   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18008   [(set_attr "type" "multi")])
18010 (define_expand "stack_protect_test"
18011   [(match_operand 0 "memory_operand")
18012    (match_operand 1 "memory_operand")
18013    (match_operand 2)]
18014   "TARGET_SSP_TLS_GUARD"
18016   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18018   rtx (*insn)(rtx, rtx, rtx);
18020 #ifdef TARGET_THREAD_SSP_OFFSET
18021   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18022   insn = (TARGET_LP64
18023           ? gen_stack_tls_protect_test_di
18024           : gen_stack_tls_protect_test_si);
18025 #else
18026   insn = (TARGET_LP64
18027           ? gen_stack_protect_test_di
18028           : gen_stack_protect_test_si);
18029 #endif
18031   emit_insn (insn (flags, operands[0], operands[1]));
18033   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18034                                   flags, const0_rtx, operands[2]));
18035   DONE;
18038 (define_insn "stack_protect_test_<mode>"
18039   [(set (match_operand:CCZ 0 "flags_reg_operand")
18040         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18041                      (match_operand:PTR 2 "memory_operand" "m")]
18042                     UNSPEC_SP_TEST))
18043    (clobber (match_scratch:PTR 3 "=&r"))]
18044   "TARGET_SSP_TLS_GUARD"
18045   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18046   [(set_attr "type" "multi")])
18048 (define_insn "stack_tls_protect_test_<mode>"
18049   [(set (match_operand:CCZ 0 "flags_reg_operand")
18050         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18051                      (match_operand:PTR 2 "const_int_operand" "i")]
18052                     UNSPEC_SP_TLS_TEST))
18053    (clobber (match_scratch:PTR 3 "=r"))]
18054   ""
18055   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
18056   [(set_attr "type" "multi")])
18058 (define_insn "sse4_2_crc32<mode>"
18059   [(set (match_operand:SI 0 "register_operand" "=r")
18060         (unspec:SI
18061           [(match_operand:SI 1 "register_operand" "0")
18062            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18063           UNSPEC_CRC32))]
18064   "TARGET_SSE4_2 || TARGET_CRC32"
18065   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18066   [(set_attr "type" "sselog1")
18067    (set_attr "prefix_rep" "1")
18068    (set_attr "prefix_extra" "1")
18069    (set (attr "prefix_data16")
18070      (if_then_else (match_operand:HI 2)
18071        (const_string "1")
18072        (const_string "*")))
18073    (set (attr "prefix_rex")
18074      (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18075        (const_string "1")
18076        (const_string "*")))
18077    (set_attr "mode" "SI")])
18079 (define_insn "sse4_2_crc32di"
18080   [(set (match_operand:DI 0 "register_operand" "=r")
18081         (unspec:DI
18082           [(match_operand:DI 1 "register_operand" "0")
18083            (match_operand:DI 2 "nonimmediate_operand" "rm")]
18084           UNSPEC_CRC32))]
18085   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18086   "crc32{q}\t{%2, %0|%0, %2}"
18087   [(set_attr "type" "sselog1")
18088    (set_attr "prefix_rep" "1")
18089    (set_attr "prefix_extra" "1")
18090    (set_attr "mode" "DI")])
18092 (define_insn "rdpmc"
18093   [(set (match_operand:DI 0 "register_operand" "=A")
18094         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18095                             UNSPECV_RDPMC))]
18096   "!TARGET_64BIT"
18097   "rdpmc"
18098   [(set_attr "type" "other")
18099    (set_attr "length" "2")])
18101 (define_insn "rdpmc_rex64"
18102   [(set (match_operand:DI 0 "register_operand" "=a")
18103         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18104                             UNSPECV_RDPMC))
18105    (set (match_operand:DI 1 "register_operand" "=d")
18106         (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18107   "TARGET_64BIT"
18108   "rdpmc"
18109   [(set_attr "type" "other")
18110    (set_attr "length" "2")])
18112 (define_insn "rdtsc"
18113   [(set (match_operand:DI 0 "register_operand" "=A")
18114         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18115   "!TARGET_64BIT"
18116   "rdtsc"
18117   [(set_attr "type" "other")
18118    (set_attr "length" "2")])
18120 (define_insn "rdtsc_rex64"
18121   [(set (match_operand:DI 0 "register_operand" "=a")
18122         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18123    (set (match_operand:DI 1 "register_operand" "=d")
18124         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18125   "TARGET_64BIT"
18126   "rdtsc"
18127   [(set_attr "type" "other")
18128    (set_attr "length" "2")])
18130 (define_insn "rdtscp"
18131   [(set (match_operand:DI 0 "register_operand" "=A")
18132         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18133    (set (match_operand:SI 1 "register_operand" "=c")
18134         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18135   "!TARGET_64BIT"
18136   "rdtscp"
18137   [(set_attr "type" "other")
18138    (set_attr "length" "3")])
18140 (define_insn "rdtscp_rex64"
18141   [(set (match_operand:DI 0 "register_operand" "=a")
18142         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18143    (set (match_operand:DI 1 "register_operand" "=d")
18144         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18145    (set (match_operand:SI 2 "register_operand" "=c")
18146         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18147   "TARGET_64BIT"
18148   "rdtscp"
18149   [(set_attr "type" "other")
18150    (set_attr "length" "3")])
18152 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18154 ;; FXSR, XSAVE and XSAVEOPT instructions
18156 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18158 (define_insn "fxsave"
18159   [(set (match_operand:BLK 0 "memory_operand" "=m")
18160         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18161   "TARGET_FXSR"
18162   "fxsave\t%0"
18163   [(set_attr "type" "other")
18164    (set_attr "memory" "store")
18165    (set (attr "length")
18166         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18168 (define_insn "fxsave64"
18169   [(set (match_operand:BLK 0 "memory_operand" "=m")
18170         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18171   "TARGET_64BIT && TARGET_FXSR"
18172   "fxsave64\t%0"
18173   [(set_attr "type" "other")
18174    (set_attr "memory" "store")
18175    (set (attr "length")
18176         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18178 (define_insn "fxrstor"
18179   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18180                     UNSPECV_FXRSTOR)]
18181   "TARGET_FXSR"
18182   "fxrstor\t%0"
18183   [(set_attr "type" "other")
18184    (set_attr "memory" "load")
18185    (set (attr "length")
18186         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18188 (define_insn "fxrstor64"
18189   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18190                     UNSPECV_FXRSTOR64)]
18191   "TARGET_64BIT && TARGET_FXSR"
18192   "fxrstor64\t%0"
18193   [(set_attr "type" "other")
18194    (set_attr "memory" "load")
18195    (set (attr "length")
18196         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18198 (define_int_iterator ANY_XSAVE
18199         [UNSPECV_XSAVE
18200          (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
18201          (UNSPECV_XSAVEC "TARGET_XSAVEC")
18202          (UNSPECV_XSAVES "TARGET_XSAVES")])
18204 (define_int_iterator ANY_XSAVE64
18205         [UNSPECV_XSAVE64
18206          (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
18207          (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
18208          (UNSPECV_XSAVES64 "TARGET_XSAVES")])
18210 (define_int_attr xsave
18211         [(UNSPECV_XSAVE "xsave")
18212          (UNSPECV_XSAVE64 "xsave64")
18213          (UNSPECV_XSAVEOPT "xsaveopt")
18214          (UNSPECV_XSAVEOPT64 "xsaveopt64")
18215          (UNSPECV_XSAVEC "xsavec")
18216          (UNSPECV_XSAVEC64 "xsavec64")
18217          (UNSPECV_XSAVES "xsaves")
18218          (UNSPECV_XSAVES64 "xsaves64")])
18220 (define_int_iterator ANY_XRSTOR
18221         [UNSPECV_XRSTOR
18222          (UNSPECV_XRSTORS "TARGET_XSAVES")])
18224 (define_int_iterator ANY_XRSTOR64
18225         [UNSPECV_XRSTOR64
18226          (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
18228 (define_int_attr xrstor
18229         [(UNSPECV_XRSTOR "xrstor")
18230          (UNSPECV_XRSTOR64 "xrstor")
18231          (UNSPECV_XRSTORS "xrstors")
18232          (UNSPECV_XRSTORS64 "xrstors")])
18234 (define_insn "<xsave>"
18235   [(set (match_operand:BLK 0 "memory_operand" "=m")
18236         (unspec_volatile:BLK
18237          [(match_operand:DI 1 "register_operand" "A")]
18238          ANY_XSAVE))]
18239   "!TARGET_64BIT && TARGET_XSAVE"
18240   "<xsave>\t%0"
18241   [(set_attr "type" "other")
18242    (set_attr "memory" "store")
18243    (set (attr "length")
18244         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18246 (define_insn "<xsave>_rex64"
18247   [(set (match_operand:BLK 0 "memory_operand" "=m")
18248         (unspec_volatile:BLK
18249          [(match_operand:SI 1 "register_operand" "a")
18250           (match_operand:SI 2 "register_operand" "d")]
18251          ANY_XSAVE))]
18252   "TARGET_64BIT && TARGET_XSAVE"
18253   "<xsave>\t%0"
18254   [(set_attr "type" "other")
18255    (set_attr "memory" "store")
18256    (set (attr "length")
18257         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18259 (define_insn "<xsave>"
18260   [(set (match_operand:BLK 0 "memory_operand" "=m")
18261         (unspec_volatile:BLK
18262          [(match_operand:SI 1 "register_operand" "a")
18263           (match_operand:SI 2 "register_operand" "d")]
18264          ANY_XSAVE64))]
18265   "TARGET_64BIT && TARGET_XSAVE"
18266   "<xsave>\t%0"
18267   [(set_attr "type" "other")
18268    (set_attr "memory" "store")
18269    (set (attr "length")
18270         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18272 (define_insn "<xrstor>"
18273    [(unspec_volatile:BLK
18274      [(match_operand:BLK 0 "memory_operand" "m")
18275       (match_operand:DI 1 "register_operand" "A")]
18276      ANY_XRSTOR)]
18277   "!TARGET_64BIT && TARGET_XSAVE"
18278   "<xrstor>\t%0"
18279   [(set_attr "type" "other")
18280    (set_attr "memory" "load")
18281    (set (attr "length")
18282         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18284 (define_insn "<xrstor>_rex64"
18285    [(unspec_volatile:BLK
18286      [(match_operand:BLK 0 "memory_operand" "m")
18287       (match_operand:SI 1 "register_operand" "a")
18288       (match_operand:SI 2 "register_operand" "d")]
18289      ANY_XRSTOR)]
18290   "TARGET_64BIT && TARGET_XSAVE"
18291   "<xrstor>\t%0"
18292   [(set_attr "type" "other")
18293    (set_attr "memory" "load")
18294    (set (attr "length")
18295         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18297 (define_insn "<xrstor>64"
18298    [(unspec_volatile:BLK
18299      [(match_operand:BLK 0 "memory_operand" "m")
18300       (match_operand:SI 1 "register_operand" "a")
18301       (match_operand:SI 2 "register_operand" "d")]
18302      ANY_XRSTOR64)]
18303   "TARGET_64BIT && TARGET_XSAVE"
18304   "<xrstor>64\t%0"
18305   [(set_attr "type" "other")
18306    (set_attr "memory" "load")
18307    (set (attr "length")
18308         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18310 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18312 ;; Floating-point instructions for atomic compound assignments
18314 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18316 ; Clobber all floating-point registers on environment save and restore
18317 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18318 (define_insn "fnstenv"
18319   [(set (match_operand:BLK 0 "memory_operand" "=m")
18320         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18321    (clobber (reg:HI FPCR_REG))
18322    (clobber (reg:XF ST0_REG))
18323    (clobber (reg:XF ST1_REG))
18324    (clobber (reg:XF ST2_REG))
18325    (clobber (reg:XF ST3_REG))
18326    (clobber (reg:XF ST4_REG))
18327    (clobber (reg:XF ST5_REG))
18328    (clobber (reg:XF ST6_REG))
18329    (clobber (reg:XF ST7_REG))]
18330   "TARGET_80387"
18331   "fnstenv\t%0"
18332   [(set_attr "type" "other")
18333    (set_attr "memory" "store")
18334    (set (attr "length")
18335         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18337 (define_insn "fldenv"
18338   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18339                     UNSPECV_FLDENV)
18340    (clobber (reg:CCFP FPSR_REG))
18341    (clobber (reg:HI FPCR_REG))
18342    (clobber (reg:XF ST0_REG))
18343    (clobber (reg:XF ST1_REG))
18344    (clobber (reg:XF ST2_REG))
18345    (clobber (reg:XF ST3_REG))
18346    (clobber (reg:XF ST4_REG))
18347    (clobber (reg:XF ST5_REG))
18348    (clobber (reg:XF ST6_REG))
18349    (clobber (reg:XF ST7_REG))]
18350   "TARGET_80387"
18351   "fldenv\t%0"
18352   [(set_attr "type" "other")
18353    (set_attr "memory" "load")
18354    (set (attr "length")
18355         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18357 (define_insn "fnstsw"
18358   [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
18359         (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18360   "TARGET_80387"
18361   "fnstsw\t%0"
18362   [(set_attr "type" "other,other")
18363    (set_attr "memory" "none,store")
18364    (set (attr "length")
18365         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18367 (define_insn "fnclex"
18368   [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
18369   "TARGET_80387"
18370   "fnclex"
18371   [(set_attr "type" "other")
18372    (set_attr "memory" "none")
18373    (set_attr "length" "2")])
18375 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18377 ;; LWP instructions
18379 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18381 (define_expand "lwp_llwpcb"
18382   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18383                     UNSPECV_LLWP_INTRINSIC)]
18384   "TARGET_LWP")
18386 (define_insn "*lwp_llwpcb<mode>1"
18387   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18388                     UNSPECV_LLWP_INTRINSIC)]
18389   "TARGET_LWP"
18390   "llwpcb\t%0"
18391   [(set_attr "type" "lwp")
18392    (set_attr "mode" "<MODE>")
18393    (set_attr "length" "5")])
18395 (define_expand "lwp_slwpcb"
18396   [(set (match_operand 0 "register_operand" "=r")
18397         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18398   "TARGET_LWP"
18400   rtx (*insn)(rtx);
18402   insn = (Pmode == DImode
18403           ? gen_lwp_slwpcbdi
18404           : gen_lwp_slwpcbsi);
18406   emit_insn (insn (operands[0]));
18407   DONE;
18410 (define_insn "lwp_slwpcb<mode>"
18411   [(set (match_operand:P 0 "register_operand" "=r")
18412         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18413   "TARGET_LWP"
18414   "slwpcb\t%0"
18415   [(set_attr "type" "lwp")
18416    (set_attr "mode" "<MODE>")
18417    (set_attr "length" "5")])
18419 (define_expand "lwp_lwpval<mode>3"
18420   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18421                      (match_operand:SI 2 "nonimmediate_operand" "rm")
18422                      (match_operand:SI 3 "const_int_operand" "i")]
18423                     UNSPECV_LWPVAL_INTRINSIC)]
18424   "TARGET_LWP"
18425   ;; Avoid unused variable warning.
18426   "(void) operands[0];")
18428 (define_insn "*lwp_lwpval<mode>3_1"
18429   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18430                      (match_operand:SI 1 "nonimmediate_operand" "rm")
18431                      (match_operand:SI 2 "const_int_operand" "i")]
18432                     UNSPECV_LWPVAL_INTRINSIC)]
18433   "TARGET_LWP"
18434   "lwpval\t{%2, %1, %0|%0, %1, %2}"
18435   [(set_attr "type" "lwp")
18436    (set_attr "mode" "<MODE>")
18437    (set (attr "length")
18438         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18440 (define_expand "lwp_lwpins<mode>3"
18441   [(set (reg:CCC FLAGS_REG)
18442         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18443                               (match_operand:SI 2 "nonimmediate_operand" "rm")
18444                               (match_operand:SI 3 "const_int_operand" "i")]
18445                              UNSPECV_LWPINS_INTRINSIC))
18446    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18447         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18448   "TARGET_LWP")
18450 (define_insn "*lwp_lwpins<mode>3_1"
18451   [(set (reg:CCC FLAGS_REG)
18452         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18453                               (match_operand:SI 1 "nonimmediate_operand" "rm")
18454                               (match_operand:SI 2 "const_int_operand" "i")]
18455                              UNSPECV_LWPINS_INTRINSIC))]
18456   "TARGET_LWP"
18457   "lwpins\t{%2, %1, %0|%0, %1, %2}"
18458   [(set_attr "type" "lwp")
18459    (set_attr "mode" "<MODE>")
18460    (set (attr "length")
18461         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18463 (define_int_iterator RDFSGSBASE
18464         [UNSPECV_RDFSBASE
18465          UNSPECV_RDGSBASE])
18467 (define_int_iterator WRFSGSBASE
18468         [UNSPECV_WRFSBASE
18469          UNSPECV_WRGSBASE])
18471 (define_int_attr fsgs
18472         [(UNSPECV_RDFSBASE "fs")
18473          (UNSPECV_RDGSBASE "gs")
18474          (UNSPECV_WRFSBASE "fs")
18475          (UNSPECV_WRGSBASE "gs")])
18477 (define_insn "rd<fsgs>base<mode>"
18478   [(set (match_operand:SWI48 0 "register_operand" "=r")
18479         (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18480   "TARGET_64BIT && TARGET_FSGSBASE"
18481   "rd<fsgs>base\t%0"
18482   [(set_attr "type" "other")
18483    (set_attr "prefix_extra" "2")])
18485 (define_insn "wr<fsgs>base<mode>"
18486   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18487                     WRFSGSBASE)]
18488   "TARGET_64BIT && TARGET_FSGSBASE"
18489   "wr<fsgs>base\t%0"
18490   [(set_attr "type" "other")
18491    (set_attr "prefix_extra" "2")])
18493 (define_insn "rdrand<mode>_1"
18494   [(set (match_operand:SWI248 0 "register_operand" "=r")
18495         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18496    (set (reg:CCC FLAGS_REG)
18497         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18498   "TARGET_RDRND"
18499   "rdrand\t%0"
18500   [(set_attr "type" "other")
18501    (set_attr "prefix_extra" "1")])
18503 (define_insn "rdseed<mode>_1"
18504   [(set (match_operand:SWI248 0 "register_operand" "=r")
18505         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18506    (set (reg:CCC FLAGS_REG)
18507         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18508   "TARGET_RDSEED"
18509   "rdseed\t%0"
18510   [(set_attr "type" "other")
18511    (set_attr "prefix_extra" "1")])
18513 (define_expand "pause"
18514   [(set (match_dup 0)
18515         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18516   ""
18518   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18519   MEM_VOLATILE_P (operands[0]) = 1;
18522 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18523 ;; They have the same encoding.
18524 (define_insn "*pause"
18525   [(set (match_operand:BLK 0)
18526         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18527   ""
18528   "rep%; nop"
18529   [(set_attr "length" "2")
18530    (set_attr "memory" "unknown")])
18532 (define_expand "xbegin"
18533   [(set (match_operand:SI 0 "register_operand")
18534         (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18535   "TARGET_RTM"
18537   rtx_code_label *label = gen_label_rtx ();
18539   /* xbegin is emitted as jump_insn, so reload won't be able
18540      to reload its operand.  Force the value into AX hard register.  */
18541   rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18542   emit_move_insn (ax_reg, constm1_rtx);
18544   emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18546   emit_label (label);
18547   LABEL_NUSES (label) = 1;
18549   emit_move_insn (operands[0], ax_reg);
18551   DONE;
18554 (define_insn "xbegin_1"
18555   [(set (pc)
18556         (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18557                           (const_int 0))
18558                       (label_ref (match_operand 1))
18559                       (pc)))
18560    (set (match_operand:SI 0 "register_operand" "+a")
18561         (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18562   "TARGET_RTM"
18563   "xbegin\t%l1"
18564   [(set_attr "type" "other")
18565    (set_attr "length" "6")])
18567 (define_insn "xend"
18568   [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18569   "TARGET_RTM"
18570   "xend"
18571   [(set_attr "type" "other")
18572    (set_attr "length" "3")])
18574 (define_insn "xabort"
18575   [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18576                     UNSPECV_XABORT)]
18577   "TARGET_RTM"
18578   "xabort\t%0"
18579   [(set_attr "type" "other")
18580    (set_attr "length" "3")])
18582 (define_expand "xtest"
18583   [(set (match_operand:QI 0 "register_operand")
18584         (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18585   "TARGET_RTM"
18587   emit_insn (gen_xtest_1 ());
18589   ix86_expand_setcc (operands[0], NE,
18590                      gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18591   DONE;
18594 (define_insn "xtest_1"
18595   [(set (reg:CCZ FLAGS_REG)
18596         (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18597   "TARGET_RTM"
18598   "xtest"
18599   [(set_attr "type" "other")
18600    (set_attr "length" "3")])
18602 (define_insn "clflushopt"
18603   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18604                    UNSPECV_CLFLUSHOPT)]
18605   "TARGET_CLFLUSHOPT"
18606   "clflushopt\t%a0"
18607   [(set_attr "type" "sse")
18608    (set_attr "atom_sse_attr" "fence")
18609    (set_attr "memory" "unknown")])
18611 (include "mmx.md")
18612 (include "sse.md")
18613 (include "sync.md")