i386: Remove TARGET_VECTORIZE_BUILTIN_CONVERSION.
[official-gcc.git] / gcc / config / i386 / i386.md
blob491037149b63290138b8dec7fff754450e4ccd73
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3.  If not see
22 ;; <http://www.gnu.org/licenses/>.  */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
35 ;;      otherwise nothing
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
43 ;;      delimiter.
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;;      %b0 would print %al if operands[0] is reg 0.
46 ;; w --  likewise, print the HImode name of the register.
47 ;; k --  likewise, print the SImode name of the register.
48 ;; q --  likewise, print the DImode name of the register.
49 ;; x --  likewise, print the V4SFmode name of the register.
50 ;; t --  likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; p -- print raw symbol name.
57 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
58 ;; & -- print some in-use local-dynamic symbol name.
59 ;; H -- print a memory address offset by 8; used for sse high-parts
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 a segment register of thread base pointer load
65 ;; UNSPEC usage:
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_REG_SAVE
86   UNSPEC_DEF_CFA
87   UNSPEC_SET_RIP
88   UNSPEC_SET_GOT_OFFSET
89   UNSPEC_MEMORY_BLOCKAGE
90   UNSPEC_STACK_CHECK
92   ;; TLS support
93   UNSPEC_TP
94   UNSPEC_TLS_GD
95   UNSPEC_TLS_LD_BASE
96   UNSPEC_TLSDESC
97   UNSPEC_TLS_IE_SUN
99   ;; Other random patterns
100   UNSPEC_SCAS
101   UNSPEC_FNSTSW
102   UNSPEC_SAHF
103   UNSPEC_PARITY
104   UNSPEC_FSTCW
105   UNSPEC_ADD_CARRY
106   UNSPEC_FLDCW
107   UNSPEC_REP
108   UNSPEC_LD_MPIC        ; load_macho_picbase
109   UNSPEC_TRUNC_NOOP
110   UNSPEC_DIV_ALREADY_SPLIT
111   UNSPEC_CALL_NEEDS_VZEROUPPER
112   UNSPEC_PAUSE
114   ;; For SSE/MMX support:
115   UNSPEC_FIX_NOTRUNC
116   UNSPEC_MASKMOV
117   UNSPEC_MOVMSK
118   UNSPEC_MOVNT
119   UNSPEC_MOVU
120   UNSPEC_RCP
121   UNSPEC_RSQRT
122   UNSPEC_SFENCE
123   UNSPEC_PFRCP
124   UNSPEC_PFRCPIT1
125   UNSPEC_PFRCPIT2
126   UNSPEC_PFRSQRT
127   UNSPEC_PFRSQIT1
128   UNSPEC_MFENCE
129   UNSPEC_LFENCE
130   UNSPEC_PSADBW
131   UNSPEC_LDDQU
132   UNSPEC_MS_TO_SYSV_CALL
134   ;; Generic math support
135   UNSPEC_COPYSIGN
136   UNSPEC_IEEE_MIN       ; not commutative
137   UNSPEC_IEEE_MAX       ; not commutative
139   ;; x87 Floating point
140   UNSPEC_SIN
141   UNSPEC_COS
142   UNSPEC_FPATAN
143   UNSPEC_FYL2X
144   UNSPEC_FYL2XP1
145   UNSPEC_FRNDINT
146   UNSPEC_FIST
147   UNSPEC_F2XM1
148   UNSPEC_TAN
149   UNSPEC_FXAM
151   ;; x87 Rounding
152   UNSPEC_FRNDINT_FLOOR
153   UNSPEC_FRNDINT_CEIL
154   UNSPEC_FRNDINT_TRUNC
155   UNSPEC_FRNDINT_MASK_PM
156   UNSPEC_FIST_FLOOR
157   UNSPEC_FIST_CEIL
159   ;; x87 Double output FP
160   UNSPEC_SINCOS_COS
161   UNSPEC_SINCOS_SIN
162   UNSPEC_XTRACT_FRACT
163   UNSPEC_XTRACT_EXP
164   UNSPEC_FSCALE_FRACT
165   UNSPEC_FSCALE_EXP
166   UNSPEC_FPREM_F
167   UNSPEC_FPREM_U
168   UNSPEC_FPREM1_F
169   UNSPEC_FPREM1_U
171   UNSPEC_C2_FLAG
172   UNSPEC_FXAM_MEM
174   ;; SSP patterns
175   UNSPEC_SP_SET
176   UNSPEC_SP_TEST
177   UNSPEC_SP_TLS_SET
178   UNSPEC_SP_TLS_TEST
180   ;; SSSE3
181   UNSPEC_PSHUFB
182   UNSPEC_PSIGN
183   UNSPEC_PALIGNR
185   ;; For SSE4A support
186   UNSPEC_EXTRQI
187   UNSPEC_EXTRQ
188   UNSPEC_INSERTQI
189   UNSPEC_INSERTQ
191   ;; For SSE4.1 support
192   UNSPEC_BLENDV
193   UNSPEC_INSERTPS
194   UNSPEC_DP
195   UNSPEC_MOVNTDQA
196   UNSPEC_MPSADBW
197   UNSPEC_PHMINPOSUW
198   UNSPEC_PTEST
199   UNSPEC_ROUND
201   ;; For SSE4.2 support
202   UNSPEC_CRC32
203   UNSPEC_PCMPESTR
204   UNSPEC_PCMPISTR
206   ;; For FMA4 support
207   UNSPEC_FMADDSUB
208   UNSPEC_XOP_UNSIGNED_CMP
209   UNSPEC_XOP_TRUEFALSE
210   UNSPEC_XOP_PERMUTE
211   UNSPEC_FRCZ
213   ;; For AES support
214   UNSPEC_AESENC
215   UNSPEC_AESENCLAST
216   UNSPEC_AESDEC
217   UNSPEC_AESDECLAST
218   UNSPEC_AESIMC
219   UNSPEC_AESKEYGENASSIST
221   ;; For PCLMUL support
222   UNSPEC_PCLMUL
224   ;; For AVX support
225   UNSPEC_PCMP
226   UNSPEC_VPERMIL
227   UNSPEC_VPERMIL2
228   UNSPEC_VPERMIL2F128
229   UNSPEC_CAST
230   UNSPEC_VTESTP
231   UNSPEC_VCVTPH2PS
232   UNSPEC_VCVTPS2PH
234   ;; For AVX2 support
235   UNSPEC_VPERMSI
236   UNSPEC_VPERMDF
237   UNSPEC_VPERMSF
238   UNSPEC_VPERMTI
239   UNSPEC_GATHER
240   UNSPEC_VSIBADDR
242   ;; For BMI support
243   UNSPEC_BEXTR
245   ;; For RDRAND support
246   UNSPEC_RDRAND
248   ;; For BMI2 support
249   UNSPEC_PDEP
250   UNSPEC_PEXT
253 (define_c_enum "unspecv" [
254   UNSPECV_BLOCKAGE
255   UNSPECV_STACK_PROBE
256   UNSPECV_PROBE_STACK_RANGE
257   UNSPECV_EMMS
258   UNSPECV_LDMXCSR
259   UNSPECV_STMXCSR
260   UNSPECV_FEMMS
261   UNSPECV_CLFLUSH
262   UNSPECV_ALIGN
263   UNSPECV_MONITOR
264   UNSPECV_MWAIT
265   UNSPECV_CMPXCHG
266   UNSPECV_XCHG
267   UNSPECV_LOCK
268   UNSPECV_PROLOGUE_USE
269   UNSPECV_CLD
270   UNSPECV_NOPS
271   UNSPECV_VZEROALL
272   UNSPECV_VZEROUPPER
273   UNSPECV_RDTSC
274   UNSPECV_RDTSCP
275   UNSPECV_RDPMC
276   UNSPECV_LLWP_INTRINSIC
277   UNSPECV_SLWP_INTRINSIC
278   UNSPECV_LWPVAL_INTRINSIC
279   UNSPECV_LWPINS_INTRINSIC
280   UNSPECV_RDFSBASE
281   UNSPECV_RDGSBASE
282   UNSPECV_WRFSBASE
283   UNSPECV_WRGSBASE
284   UNSPECV_SPLIT_STACK_RETURN
287 ;; Constants to represent rounding modes in the ROUND instruction
288 (define_constants
289   [(ROUND_FLOOR                 0x1)
290    (ROUND_CEIL                  0x2)
291    (ROUND_TRUNC                 0x3)
292    (ROUND_MXCSR                 0x4)
293    (ROUND_NO_EXC                0x8)
294   ])
296 ;; Constants to represent pcomtrue/pcomfalse variants
297 (define_constants
298   [(PCOM_FALSE                  0)
299    (PCOM_TRUE                   1)
300    (COM_FALSE_S                 2)
301    (COM_FALSE_P                 3)
302    (COM_TRUE_S                  4)
303    (COM_TRUE_P                  5)
304   ])
306 ;; Constants used in the XOP pperm instruction
307 (define_constants
308   [(PPERM_SRC                   0x00)   /* copy source */
309    (PPERM_INVERT                0x20)   /* invert source */
310    (PPERM_REVERSE               0x40)   /* bit reverse source */
311    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
312    (PPERM_ZERO                  0x80)   /* all 0's */
313    (PPERM_ONES                  0xa0)   /* all 1's */
314    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
315    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
316    (PPERM_SRC1                  0x00)   /* use first source byte */
317    (PPERM_SRC2                  0x10)   /* use second source byte */
318    ])
320 ;; Registers by name.
321 (define_constants
322   [(AX_REG                       0)
323    (DX_REG                       1)
324    (CX_REG                       2)
325    (BX_REG                       3)
326    (SI_REG                       4)
327    (DI_REG                       5)
328    (BP_REG                       6)
329    (SP_REG                       7)
330    (ST0_REG                      8)
331    (ST1_REG                      9)
332    (ST2_REG                     10)
333    (ST3_REG                     11)
334    (ST4_REG                     12)
335    (ST5_REG                     13)
336    (ST6_REG                     14)
337    (ST7_REG                     15)
338    (FLAGS_REG                   17)
339    (FPSR_REG                    18)
340    (FPCR_REG                    19)
341    (XMM0_REG                    21)
342    (XMM1_REG                    22)
343    (XMM2_REG                    23)
344    (XMM3_REG                    24)
345    (XMM4_REG                    25)
346    (XMM5_REG                    26)
347    (XMM6_REG                    27)
348    (XMM7_REG                    28)
349    (MM0_REG                     29)
350    (MM1_REG                     30)
351    (MM2_REG                     31)
352    (MM3_REG                     32)
353    (MM4_REG                     33)
354    (MM5_REG                     34)
355    (MM6_REG                     35)
356    (MM7_REG                     36)
357    (R8_REG                      37)
358    (R9_REG                      38)
359    (R10_REG                     39)
360    (R11_REG                     40)
361    (R12_REG                     41)
362    (R13_REG                     42)
363    (XMM8_REG                    45)
364    (XMM9_REG                    46)
365    (XMM10_REG                   47)
366    (XMM11_REG                   48)
367    (XMM12_REG                   49)
368    (XMM13_REG                   50)
369    (XMM14_REG                   51)
370    (XMM15_REG                   52)
371   ])
373 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
374 ;; from i386.c.
376 ;; In C guard expressions, put expressions which may be compile-time
377 ;; constants first.  This allows for better optimization.  For
378 ;; example, write "TARGET_64BIT && reload_completed", not
379 ;; "reload_completed && TARGET_64BIT".
382 ;; Processor type.
383 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
384                     atom,generic64,amdfam10,bdver1,bdver2,btver1"
385   (const (symbol_ref "ix86_schedule")))
387 ;; A basic instruction type.  Refinements due to arguments to be
388 ;; provided in other attributes.
389 (define_attr "type"
390   "other,multi,
391    alu,alu1,negnot,imov,imovx,lea,
392    incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
393    icmp,test,ibr,setcc,icmov,
394    push,pop,call,callv,leave,
395    str,bitmanip,
396    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
397    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
398    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
399    ssemuladd,sse4arg,lwp,
400    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
401   (const_string "other"))
403 ;; Main data type used by the insn
404 (define_attr "mode"
405   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
406   (const_string "unknown"))
408 ;; The CPU unit operations uses.
409 (define_attr "unit" "integer,i387,sse,mmx,unknown"
410   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
411            (const_string "i387")
412          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
413                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
414                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
415            (const_string "sse")
416          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
417            (const_string "mmx")
418          (eq_attr "type" "other")
419            (const_string "unknown")]
420          (const_string "integer")))
422 ;; The (bounding maximum) length of an instruction immediate.
423 (define_attr "length_immediate" ""
424   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
425                           bitmanip,imulx")
426            (const_int 0)
427          (eq_attr "unit" "i387,sse,mmx")
428            (const_int 0)
429          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
430                           rotate,rotatex,rotate1,imul,icmp,push,pop")
431            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
432          (eq_attr "type" "imov,test")
433            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
434          (eq_attr "type" "call")
435            (if_then_else (match_operand 0 "constant_call_address_operand" "")
436              (const_int 4)
437              (const_int 0))
438          (eq_attr "type" "callv")
439            (if_then_else (match_operand 1 "constant_call_address_operand" "")
440              (const_int 4)
441              (const_int 0))
442          ;; We don't know the size before shorten_branches.  Expect
443          ;; the instruction to fit for better scheduling.
444          (eq_attr "type" "ibr")
445            (const_int 1)
446          ]
447          (symbol_ref "/* Update immediate_length and other attributes! */
448                       gcc_unreachable (),1")))
450 ;; The (bounding maximum) length of an instruction address.
451 (define_attr "length_address" ""
452   (cond [(eq_attr "type" "str,other,multi,fxch")
453            (const_int 0)
454          (and (eq_attr "type" "call")
455               (match_operand 0 "constant_call_address_operand" ""))
456              (const_int 0)
457          (and (eq_attr "type" "callv")
458               (match_operand 1 "constant_call_address_operand" ""))
459              (const_int 0)
460          ]
461          (symbol_ref "ix86_attr_length_address_default (insn)")))
463 ;; Set when length prefix is used.
464 (define_attr "prefix_data16" ""
465   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
466            (const_int 0)
467          (eq_attr "mode" "HI")
468            (const_int 1)
469          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
470            (const_int 1)
471         ]
472         (const_int 0)))
474 ;; Set when string REP prefix is used.
475 (define_attr "prefix_rep" ""
476   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
477            (const_int 0)
478          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
479            (const_int 1)
480         ]
481         (const_int 0)))
483 ;; Set when 0f opcode prefix is used.
484 (define_attr "prefix_0f" ""
485   (if_then_else
486     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
487          (eq_attr "unit" "sse,mmx"))
488     (const_int 1)
489     (const_int 0)))
491 ;; Set when REX opcode prefix is used.
492 (define_attr "prefix_rex" ""
493   (cond [(not (match_test "TARGET_64BIT"))
494            (const_int 0)
495          (and (eq_attr "mode" "DI")
496               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
497                    (eq_attr "unit" "!mmx")))
498            (const_int 1)
499          (and (eq_attr "mode" "QI")
500               (match_test "x86_extended_QIreg_mentioned_p (insn)"))
501            (const_int 1)
502          (match_test "x86_extended_reg_mentioned_p (insn)")
503            (const_int 1)
504          (and (eq_attr "type" "imovx")
505               (match_operand:QI 1 "ext_QIreg_operand" ""))
506            (const_int 1)
507         ]
508         (const_int 0)))
510 ;; There are also additional prefixes in 3DNOW, SSSE3.
511 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
512 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
513 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
514 (define_attr "prefix_extra" ""
515   (cond [(eq_attr "type" "ssemuladd,sse4arg")
516            (const_int 2)
517          (eq_attr "type" "sseiadd1,ssecvt1")
518            (const_int 1)
519         ]
520         (const_int 0)))
522 ;; Prefix used: original, VEX or maybe VEX.
523 (define_attr "prefix" "orig,vex,maybe_vex"
524   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
525     (const_string "vex")
526     (const_string "orig")))
528 ;; VEX W bit is used.
529 (define_attr "prefix_vex_w" "" (const_int 0))
531 ;; The length of VEX prefix
532 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
533 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
534 ;; still prefix_0f 1, with prefix_extra 1.
535 (define_attr "length_vex" ""
536   (if_then_else (and (eq_attr "prefix_0f" "1")
537                      (eq_attr "prefix_extra" "0"))
538     (if_then_else (eq_attr "prefix_vex_w" "1")
539       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
540       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
541     (if_then_else (eq_attr "prefix_vex_w" "1")
542       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
543       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
545 ;; Set when modrm byte is used.
546 (define_attr "modrm" ""
547   (cond [(eq_attr "type" "str,leave")
548            (const_int 0)
549          (eq_attr "unit" "i387")
550            (const_int 0)
551          (and (eq_attr "type" "incdec")
552               (and (not (match_test "TARGET_64BIT"))
553                    (ior (match_operand:SI 1 "register_operand" "")
554                         (match_operand:HI 1 "register_operand" ""))))
555            (const_int 0)
556          (and (eq_attr "type" "push")
557               (not (match_operand 1 "memory_operand" "")))
558            (const_int 0)
559          (and (eq_attr "type" "pop")
560               (not (match_operand 0 "memory_operand" "")))
561            (const_int 0)
562          (and (eq_attr "type" "imov")
563               (and (not (eq_attr "mode" "DI"))
564                    (ior (and (match_operand 0 "register_operand" "")
565                              (match_operand 1 "immediate_operand" ""))
566                         (ior (and (match_operand 0 "ax_reg_operand" "")
567                                   (match_operand 1 "memory_displacement_only_operand" ""))
568                              (and (match_operand 0 "memory_displacement_only_operand" "")
569                                   (match_operand 1 "ax_reg_operand" ""))))))
570            (const_int 0)
571          (and (eq_attr "type" "call")
572               (match_operand 0 "constant_call_address_operand" ""))
573              (const_int 0)
574          (and (eq_attr "type" "callv")
575               (match_operand 1 "constant_call_address_operand" ""))
576              (const_int 0)
577          (and (eq_attr "type" "alu,alu1,icmp,test")
578               (match_operand 0 "ax_reg_operand" ""))
579              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
580          ]
581          (const_int 1)))
583 ;; The (bounding maximum) length of an instruction in bytes.
584 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
585 ;; Later we may want to split them and compute proper length as for
586 ;; other insns.
587 (define_attr "length" ""
588   (cond [(eq_attr "type" "other,multi,fistp,frndint")
589            (const_int 16)
590          (eq_attr "type" "fcmp")
591            (const_int 4)
592          (eq_attr "unit" "i387")
593            (plus (const_int 2)
594                  (plus (attr "prefix_data16")
595                        (attr "length_address")))
596          (ior (eq_attr "prefix" "vex")
597               (and (eq_attr "prefix" "maybe_vex")
598                    (match_test "TARGET_AVX")))
599            (plus (attr "length_vex")
600                  (plus (attr "length_immediate")
601                        (plus (attr "modrm")
602                              (attr "length_address"))))]
603          (plus (plus (attr "modrm")
604                      (plus (attr "prefix_0f")
605                            (plus (attr "prefix_rex")
606                                  (plus (attr "prefix_extra")
607                                        (const_int 1)))))
608                (plus (attr "prefix_rep")
609                      (plus (attr "prefix_data16")
610                            (plus (attr "length_immediate")
611                                  (attr "length_address")))))))
613 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
614 ;; `store' if there is a simple memory reference therein, or `unknown'
615 ;; if the instruction is complex.
617 (define_attr "memory" "none,load,store,both,unknown"
618   (cond [(eq_attr "type" "other,multi,str,lwp")
619            (const_string "unknown")
620          (eq_attr "type" "lea,fcmov,fpspc")
621            (const_string "none")
622          (eq_attr "type" "fistp,leave")
623            (const_string "both")
624          (eq_attr "type" "frndint")
625            (const_string "load")
626          (eq_attr "type" "push")
627            (if_then_else (match_operand 1 "memory_operand" "")
628              (const_string "both")
629              (const_string "store"))
630          (eq_attr "type" "pop")
631            (if_then_else (match_operand 0 "memory_operand" "")
632              (const_string "both")
633              (const_string "load"))
634          (eq_attr "type" "setcc")
635            (if_then_else (match_operand 0 "memory_operand" "")
636              (const_string "store")
637              (const_string "none"))
638          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
639            (if_then_else (ior (match_operand 0 "memory_operand" "")
640                               (match_operand 1 "memory_operand" ""))
641              (const_string "load")
642              (const_string "none"))
643          (eq_attr "type" "ibr")
644            (if_then_else (match_operand 0 "memory_operand" "")
645              (const_string "load")
646              (const_string "none"))
647          (eq_attr "type" "call")
648            (if_then_else (match_operand 0 "constant_call_address_operand" "")
649              (const_string "none")
650              (const_string "load"))
651          (eq_attr "type" "callv")
652            (if_then_else (match_operand 1 "constant_call_address_operand" "")
653              (const_string "none")
654              (const_string "load"))
655          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
656               (match_operand 1 "memory_operand" ""))
657            (const_string "both")
658          (and (match_operand 0 "memory_operand" "")
659               (match_operand 1 "memory_operand" ""))
660            (const_string "both")
661          (match_operand 0 "memory_operand" "")
662            (const_string "store")
663          (match_operand 1 "memory_operand" "")
664            (const_string "load")
665          (and (eq_attr "type"
666                  "!alu1,negnot,ishift1,
667                    imov,imovx,icmp,test,bitmanip,
668                    fmov,fcmp,fsgn,
669                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
670                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
671               (match_operand 2 "memory_operand" ""))
672            (const_string "load")
673          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
674               (match_operand 3 "memory_operand" ""))
675            (const_string "load")
676         ]
677         (const_string "none")))
679 ;; Indicates if an instruction has both an immediate and a displacement.
681 (define_attr "imm_disp" "false,true,unknown"
682   (cond [(eq_attr "type" "other,multi")
683            (const_string "unknown")
684          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
685               (and (match_operand 0 "memory_displacement_operand" "")
686                    (match_operand 1 "immediate_operand" "")))
687            (const_string "true")
688          (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
689               (and (match_operand 0 "memory_displacement_operand" "")
690                    (match_operand 2 "immediate_operand" "")))
691            (const_string "true")
692         ]
693         (const_string "false")))
695 ;; Indicates if an FP operation has an integer source.
697 (define_attr "fp_int_src" "false,true"
698   (const_string "false"))
700 ;; Defines rounding mode of an FP operation.
702 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
703   (const_string "any"))
705 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
706 (define_attr "use_carry" "0,1" (const_string "0"))
708 ;; Define attribute to indicate unaligned ssemov insns
709 (define_attr "movu" "0,1" (const_string "0"))
711 ;; Used to control the "enabled" attribute on a per-instruction basis.
712 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,bmi2"
713   (const_string "base"))
715 (define_attr "enabled" ""
716   (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
717          (eq_attr "isa" "sse2_noavx")
718            (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
719          (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
720          (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
721          (eq_attr "isa" "sse4_noavx")
722            (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
723          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
724          (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
725          (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
726         ]
727         (const_int 1)))
729 ;; Describe a user's asm statement.
730 (define_asm_attributes
731   [(set_attr "length" "128")
732    (set_attr "type" "multi")])
734 (define_code_iterator plusminus [plus minus])
736 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
738 ;; Base name for define_insn
739 (define_code_attr plusminus_insn
740   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
741    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
743 ;; Base name for insn mnemonic.
744 (define_code_attr plusminus_mnemonic
745   [(plus "add") (ss_plus "adds") (us_plus "addus")
746    (minus "sub") (ss_minus "subs") (us_minus "subus")])
747 (define_code_attr plusminus_carry_mnemonic
748   [(plus "adc") (minus "sbb")])
750 ;; Mark commutative operators as such in constraints.
751 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
752                         (minus "") (ss_minus "") (us_minus "")])
754 ;; Mapping of max and min
755 (define_code_iterator maxmin [smax smin umax umin])
757 ;; Mapping of signed max and min
758 (define_code_iterator smaxmin [smax smin])
760 ;; Mapping of unsigned max and min
761 (define_code_iterator umaxmin [umax umin])
763 ;; Base name for integer and FP insn mnemonic
764 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
765                               (umax "maxu") (umin "minu")])
766 (define_code_attr maxmin_float [(smax "max") (smin "min")])
768 ;; Mapping of logic operators
769 (define_code_iterator any_logic [and ior xor])
770 (define_code_iterator any_or [ior xor])
772 ;; Base name for insn mnemonic.
773 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
775 ;; Mapping of logic-shift operators
776 (define_code_iterator any_lshift [ashift lshiftrt])
778 ;; Mapping of shift-right operators
779 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
781 ;; Base name for define_insn
782 (define_code_attr shift_insn
783   [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
785 ;; Base name for insn mnemonic.
786 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
787 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
789 ;; Mapping of rotate operators
790 (define_code_iterator any_rotate [rotate rotatert])
792 ;; Base name for define_insn
793 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
795 ;; Base name for insn mnemonic.
796 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
798 ;; Mapping of abs neg operators
799 (define_code_iterator absneg [abs neg])
801 ;; Base name for x87 insn mnemonic.
802 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
804 ;; Used in signed and unsigned widening multiplications.
805 (define_code_iterator any_extend [sign_extend zero_extend])
807 ;; Prefix for insn menmonic.
808 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
810 ;; Prefix for define_insn
811 (define_code_attr u [(sign_extend "") (zero_extend "u")])
812 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
814 ;; All integer modes.
815 (define_mode_iterator SWI1248x [QI HI SI DI])
817 ;; All integer modes without QImode.
818 (define_mode_iterator SWI248x [HI SI DI])
820 ;; All integer modes without QImode and HImode.
821 (define_mode_iterator SWI48x [SI DI])
823 ;; All integer modes without SImode and DImode.
824 (define_mode_iterator SWI12 [QI HI])
826 ;; All integer modes without DImode.
827 (define_mode_iterator SWI124 [QI HI SI])
829 ;; All integer modes without QImode and DImode.
830 (define_mode_iterator SWI24 [HI SI])
832 ;; Single word integer modes.
833 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
835 ;; Single word integer modes without QImode.
836 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
838 ;; Single word integer modes without QImode and HImode.
839 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
841 ;; All math-dependant single and double word integer modes.
842 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
843                              (HI "TARGET_HIMODE_MATH")
844                              SI DI (TI "TARGET_64BIT")])
846 ;; Math-dependant single word integer modes.
847 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
848                             (HI "TARGET_HIMODE_MATH")
849                             SI (DI "TARGET_64BIT")])
851 ;; Math-dependant integer modes without DImode.
852 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
853                                (HI "TARGET_HIMODE_MATH")
854                                SI])
856 ;; Math-dependant single word integer modes without QImode.
857 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
858                                SI (DI "TARGET_64BIT")])
860 ;; Double word integer modes.
861 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
862                            (TI "TARGET_64BIT")])
864 ;; Double word integer modes as mode attribute.
865 (define_mode_attr DWI [(SI "DI") (DI "TI")])
866 (define_mode_attr dwi [(SI "di") (DI "ti")])
868 ;; Half mode for double word integer modes.
869 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
870                             (DI "TARGET_64BIT")])
872 ;; Instruction suffix for integer modes.
873 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
875 ;; Pointer size prefix for integer modes (Intel asm dialect)
876 (define_mode_attr iptrsize [(QI "BYTE")
877                             (HI "WORD")
878                             (SI "DWORD")
879                             (DI "QWORD")])
881 ;; Register class for integer modes.
882 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
884 ;; Immediate operand constraint for integer modes.
885 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
887 ;; General operand constraint for word modes.
888 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
890 ;; Immediate operand constraint for double integer modes.
891 (define_mode_attr di [(SI "nF") (DI "e")])
893 ;; Immediate operand constraint for shifts.
894 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
896 ;; General operand predicate for integer modes.
897 (define_mode_attr general_operand
898         [(QI "general_operand")
899          (HI "general_operand")
900          (SI "x86_64_general_operand")
901          (DI "x86_64_general_operand")
902          (TI "x86_64_general_operand")])
904 ;; General sign/zero extend operand predicate for integer modes.
905 (define_mode_attr general_szext_operand
906         [(QI "general_operand")
907          (HI "general_operand")
908          (SI "x86_64_szext_general_operand")
909          (DI "x86_64_szext_general_operand")])
911 ;; Immediate operand predicate for integer modes.
912 (define_mode_attr immediate_operand
913         [(QI "immediate_operand")
914          (HI "immediate_operand")
915          (SI "x86_64_immediate_operand")
916          (DI "x86_64_immediate_operand")])
918 ;; Nonmemory operand predicate for integer modes.
919 (define_mode_attr nonmemory_operand
920         [(QI "nonmemory_operand")
921          (HI "nonmemory_operand")
922          (SI "x86_64_nonmemory_operand")
923          (DI "x86_64_nonmemory_operand")])
925 ;; Operand predicate for shifts.
926 (define_mode_attr shift_operand
927         [(QI "nonimmediate_operand")
928          (HI "nonimmediate_operand")
929          (SI "nonimmediate_operand")
930          (DI "shiftdi_operand")
931          (TI "register_operand")])
933 ;; Operand predicate for shift argument.
934 (define_mode_attr shift_immediate_operand
935         [(QI "const_1_to_31_operand")
936          (HI "const_1_to_31_operand")
937          (SI "const_1_to_31_operand")
938          (DI "const_1_to_63_operand")])
940 ;; Input operand predicate for arithmetic left shifts.
941 (define_mode_attr ashl_input_operand
942         [(QI "nonimmediate_operand")
943          (HI "nonimmediate_operand")
944          (SI "nonimmediate_operand")
945          (DI "ashldi_input_operand")
946          (TI "reg_or_pm1_operand")])
948 ;; SSE and x87 SFmode and DFmode floating point modes
949 (define_mode_iterator MODEF [SF DF])
951 ;; All x87 floating point modes
952 (define_mode_iterator X87MODEF [SF DF XF])
954 ;; SSE instruction suffix for various modes
955 (define_mode_attr ssemodesuffix
956   [(SF "ss") (DF "sd")
957    (V8SF "ps") (V4DF "pd")
958    (V4SF "ps") (V2DF "pd")
959    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
960    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
962 ;; SSE vector suffix for floating point modes
963 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
965 ;; SSE vector mode corresponding to a scalar mode
966 (define_mode_attr ssevecmode
967   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
969 ;; Instruction suffix for REX 64bit operators.
970 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
972 ;; This mode iterator allows :P to be used for patterns that operate on
973 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
974 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
976 ;; This mode iterator allows :PTR to be used for patterns that operate on
977 ;; ptr_mode sized quantities.
978 (define_mode_iterator PTR
979   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
981 ;; Scheduling descriptions
983 (include "pentium.md")
984 (include "ppro.md")
985 (include "k6.md")
986 (include "athlon.md")
987 (include "bdver1.md")
988 (include "geode.md")
989 (include "atom.md")
990 (include "core2.md")
993 ;; Operand and operator predicates and constraints
995 (include "predicates.md")
996 (include "constraints.md")
999 ;; Compare and branch/compare and store instructions.
1001 (define_expand "cbranch<mode>4"
1002   [(set (reg:CC FLAGS_REG)
1003         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
1004                     (match_operand:SDWIM 2 "<general_operand>" "")))
1005    (set (pc) (if_then_else
1006                (match_operator 0 "ordered_comparison_operator"
1007                 [(reg:CC FLAGS_REG) (const_int 0)])
1008                (label_ref (match_operand 3 "" ""))
1009                (pc)))]
1010   ""
1012   if (MEM_P (operands[1]) && MEM_P (operands[2]))
1013     operands[1] = force_reg (<MODE>mode, operands[1]);
1014   ix86_expand_branch (GET_CODE (operands[0]),
1015                       operands[1], operands[2], operands[3]);
1016   DONE;
1019 (define_expand "cstore<mode>4"
1020   [(set (reg:CC FLAGS_REG)
1021         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
1022                     (match_operand:SWIM 3 "<general_operand>" "")))
1023    (set (match_operand:QI 0 "register_operand" "")
1024         (match_operator 1 "ordered_comparison_operator"
1025           [(reg:CC FLAGS_REG) (const_int 0)]))]
1026   ""
1028   if (MEM_P (operands[2]) && MEM_P (operands[3]))
1029     operands[2] = force_reg (<MODE>mode, operands[2]);
1030   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1031                      operands[2], operands[3]);
1032   DONE;
1035 (define_expand "cmp<mode>_1"
1036   [(set (reg:CC FLAGS_REG)
1037         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
1038                     (match_operand:SWI48 1 "<general_operand>" "")))])
1040 (define_insn "*cmp<mode>_ccno_1"
1041   [(set (reg FLAGS_REG)
1042         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1043                  (match_operand:SWI 1 "const0_operand" "")))]
1044   "ix86_match_ccmode (insn, CCNOmode)"
1045   "@
1046    test{<imodesuffix>}\t%0, %0
1047    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1048   [(set_attr "type" "test,icmp")
1049    (set_attr "length_immediate" "0,1")
1050    (set_attr "mode" "<MODE>")])
1052 (define_insn "*cmp<mode>_1"
1053   [(set (reg FLAGS_REG)
1054         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1055                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1056   "ix86_match_ccmode (insn, CCmode)"
1057   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1058   [(set_attr "type" "icmp")
1059    (set_attr "mode" "<MODE>")])
1061 (define_insn "*cmp<mode>_minus_1"
1062   [(set (reg FLAGS_REG)
1063         (compare
1064           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1065                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1066           (const_int 0)))]
1067   "ix86_match_ccmode (insn, CCGOCmode)"
1068   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1069   [(set_attr "type" "icmp")
1070    (set_attr "mode" "<MODE>")])
1072 (define_insn "*cmpqi_ext_1"
1073   [(set (reg FLAGS_REG)
1074         (compare
1075           (match_operand:QI 0 "general_operand" "Qm")
1076           (subreg:QI
1077             (zero_extract:SI
1078               (match_operand 1 "ext_register_operand" "Q")
1079               (const_int 8)
1080               (const_int 8)) 0)))]
1081   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1082   "cmp{b}\t{%h1, %0|%0, %h1}"
1083   [(set_attr "type" "icmp")
1084    (set_attr "mode" "QI")])
1086 (define_insn "*cmpqi_ext_1_rex64"
1087   [(set (reg FLAGS_REG)
1088         (compare
1089           (match_operand:QI 0 "register_operand" "Q")
1090           (subreg:QI
1091             (zero_extract:SI
1092               (match_operand 1 "ext_register_operand" "Q")
1093               (const_int 8)
1094               (const_int 8)) 0)))]
1095   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1096   "cmp{b}\t{%h1, %0|%0, %h1}"
1097   [(set_attr "type" "icmp")
1098    (set_attr "mode" "QI")])
1100 (define_insn "*cmpqi_ext_2"
1101   [(set (reg FLAGS_REG)
1102         (compare
1103           (subreg:QI
1104             (zero_extract:SI
1105               (match_operand 0 "ext_register_operand" "Q")
1106               (const_int 8)
1107               (const_int 8)) 0)
1108           (match_operand:QI 1 "const0_operand" "")))]
1109   "ix86_match_ccmode (insn, CCNOmode)"
1110   "test{b}\t%h0, %h0"
1111   [(set_attr "type" "test")
1112    (set_attr "length_immediate" "0")
1113    (set_attr "mode" "QI")])
1115 (define_expand "cmpqi_ext_3"
1116   [(set (reg:CC FLAGS_REG)
1117         (compare:CC
1118           (subreg:QI
1119             (zero_extract:SI
1120               (match_operand 0 "ext_register_operand" "")
1121               (const_int 8)
1122               (const_int 8)) 0)
1123           (match_operand:QI 1 "immediate_operand" "")))])
1125 (define_insn "*cmpqi_ext_3_insn"
1126   [(set (reg FLAGS_REG)
1127         (compare
1128           (subreg:QI
1129             (zero_extract:SI
1130               (match_operand 0 "ext_register_operand" "Q")
1131               (const_int 8)
1132               (const_int 8)) 0)
1133           (match_operand:QI 1 "general_operand" "Qmn")))]
1134   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1135   "cmp{b}\t{%1, %h0|%h0, %1}"
1136   [(set_attr "type" "icmp")
1137    (set_attr "modrm" "1")
1138    (set_attr "mode" "QI")])
1140 (define_insn "*cmpqi_ext_3_insn_rex64"
1141   [(set (reg FLAGS_REG)
1142         (compare
1143           (subreg:QI
1144             (zero_extract:SI
1145               (match_operand 0 "ext_register_operand" "Q")
1146               (const_int 8)
1147               (const_int 8)) 0)
1148           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1149   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1150   "cmp{b}\t{%1, %h0|%h0, %1}"
1151   [(set_attr "type" "icmp")
1152    (set_attr "modrm" "1")
1153    (set_attr "mode" "QI")])
1155 (define_insn "*cmpqi_ext_4"
1156   [(set (reg FLAGS_REG)
1157         (compare
1158           (subreg:QI
1159             (zero_extract:SI
1160               (match_operand 0 "ext_register_operand" "Q")
1161               (const_int 8)
1162               (const_int 8)) 0)
1163           (subreg:QI
1164             (zero_extract:SI
1165               (match_operand 1 "ext_register_operand" "Q")
1166               (const_int 8)
1167               (const_int 8)) 0)))]
1168   "ix86_match_ccmode (insn, CCmode)"
1169   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1170   [(set_attr "type" "icmp")
1171    (set_attr "mode" "QI")])
1173 ;; These implement float point compares.
1174 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1175 ;; which would allow mix and match FP modes on the compares.  Which is what
1176 ;; the old patterns did, but with many more of them.
1178 (define_expand "cbranchxf4"
1179   [(set (reg:CC FLAGS_REG)
1180         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1181                     (match_operand:XF 2 "nonmemory_operand" "")))
1182    (set (pc) (if_then_else
1183               (match_operator 0 "ix86_fp_comparison_operator"
1184                [(reg:CC FLAGS_REG)
1185                 (const_int 0)])
1186               (label_ref (match_operand 3 "" ""))
1187               (pc)))]
1188   "TARGET_80387"
1190   ix86_expand_branch (GET_CODE (operands[0]),
1191                       operands[1], operands[2], operands[3]);
1192   DONE;
1195 (define_expand "cstorexf4"
1196   [(set (reg:CC FLAGS_REG)
1197         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1198                     (match_operand:XF 3 "nonmemory_operand" "")))
1199    (set (match_operand:QI 0 "register_operand" "")
1200               (match_operator 1 "ix86_fp_comparison_operator"
1201                [(reg:CC FLAGS_REG)
1202                 (const_int 0)]))]
1203   "TARGET_80387"
1205   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1206                      operands[2], operands[3]);
1207   DONE;
1210 (define_expand "cbranch<mode>4"
1211   [(set (reg:CC FLAGS_REG)
1212         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1213                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1214    (set (pc) (if_then_else
1215               (match_operator 0 "ix86_fp_comparison_operator"
1216                [(reg:CC FLAGS_REG)
1217                 (const_int 0)])
1218               (label_ref (match_operand 3 "" ""))
1219               (pc)))]
1220   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1222   ix86_expand_branch (GET_CODE (operands[0]),
1223                       operands[1], operands[2], operands[3]);
1224   DONE;
1227 (define_expand "cstore<mode>4"
1228   [(set (reg:CC FLAGS_REG)
1229         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1230                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1231    (set (match_operand:QI 0 "register_operand" "")
1232               (match_operator 1 "ix86_fp_comparison_operator"
1233                [(reg:CC FLAGS_REG)
1234                 (const_int 0)]))]
1235   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1237   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1238                      operands[2], operands[3]);
1239   DONE;
1242 (define_expand "cbranchcc4"
1243   [(set (pc) (if_then_else
1244               (match_operator 0 "comparison_operator"
1245                [(match_operand 1 "flags_reg_operand" "")
1246                 (match_operand 2 "const0_operand" "")])
1247               (label_ref (match_operand 3 "" ""))
1248               (pc)))]
1249   ""
1251   ix86_expand_branch (GET_CODE (operands[0]),
1252                       operands[1], operands[2], operands[3]);
1253   DONE;
1256 (define_expand "cstorecc4"
1257   [(set (match_operand:QI 0 "register_operand" "")
1258               (match_operator 1 "comparison_operator"
1259                [(match_operand 2 "flags_reg_operand" "")
1260                 (match_operand 3 "const0_operand" "")]))]
1261   ""
1263   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1264                      operands[2], operands[3]);
1265   DONE;
1269 ;; FP compares, step 1:
1270 ;; Set the FP condition codes.
1272 ;; CCFPmode     compare with exceptions
1273 ;; CCFPUmode    compare with no exceptions
1275 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1276 ;; used to manage the reg stack popping would not be preserved.
1278 (define_insn "*cmpfp_0"
1279   [(set (match_operand:HI 0 "register_operand" "=a")
1280         (unspec:HI
1281           [(compare:CCFP
1282              (match_operand 1 "register_operand" "f")
1283              (match_operand 2 "const0_operand" ""))]
1284         UNSPEC_FNSTSW))]
1285   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1286    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1287   "* return output_fp_compare (insn, operands, false, false);"
1288   [(set_attr "type" "multi")
1289    (set_attr "unit" "i387")
1290    (set (attr "mode")
1291      (cond [(match_operand:SF 1 "" "")
1292               (const_string "SF")
1293             (match_operand:DF 1 "" "")
1294               (const_string "DF")
1295            ]
1296            (const_string "XF")))])
1298 (define_insn_and_split "*cmpfp_0_cc"
1299   [(set (reg:CCFP FLAGS_REG)
1300         (compare:CCFP
1301           (match_operand 1 "register_operand" "f")
1302           (match_operand 2 "const0_operand" "")))
1303    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1304   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1305    && TARGET_SAHF && !TARGET_CMOVE
1306    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1307   "#"
1308   "&& reload_completed"
1309   [(set (match_dup 0)
1310         (unspec:HI
1311           [(compare:CCFP (match_dup 1)(match_dup 2))]
1312         UNSPEC_FNSTSW))
1313    (set (reg:CC FLAGS_REG)
1314         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1315   ""
1316   [(set_attr "type" "multi")
1317    (set_attr "unit" "i387")
1318    (set (attr "mode")
1319      (cond [(match_operand:SF 1 "" "")
1320               (const_string "SF")
1321             (match_operand:DF 1 "" "")
1322               (const_string "DF")
1323            ]
1324            (const_string "XF")))])
1326 (define_insn "*cmpfp_xf"
1327   [(set (match_operand:HI 0 "register_operand" "=a")
1328         (unspec:HI
1329           [(compare:CCFP
1330              (match_operand:XF 1 "register_operand" "f")
1331              (match_operand:XF 2 "register_operand" "f"))]
1332           UNSPEC_FNSTSW))]
1333   "TARGET_80387"
1334   "* return output_fp_compare (insn, operands, false, false);"
1335   [(set_attr "type" "multi")
1336    (set_attr "unit" "i387")
1337    (set_attr "mode" "XF")])
1339 (define_insn_and_split "*cmpfp_xf_cc"
1340   [(set (reg:CCFP FLAGS_REG)
1341         (compare:CCFP
1342           (match_operand:XF 1 "register_operand" "f")
1343           (match_operand:XF 2 "register_operand" "f")))
1344    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1345   "TARGET_80387
1346    && TARGET_SAHF && !TARGET_CMOVE"
1347   "#"
1348   "&& reload_completed"
1349   [(set (match_dup 0)
1350         (unspec:HI
1351           [(compare:CCFP (match_dup 1)(match_dup 2))]
1352         UNSPEC_FNSTSW))
1353    (set (reg:CC FLAGS_REG)
1354         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1355   ""
1356   [(set_attr "type" "multi")
1357    (set_attr "unit" "i387")
1358    (set_attr "mode" "XF")])
1360 (define_insn "*cmpfp_<mode>"
1361   [(set (match_operand:HI 0 "register_operand" "=a")
1362         (unspec:HI
1363           [(compare:CCFP
1364              (match_operand:MODEF 1 "register_operand" "f")
1365              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1366           UNSPEC_FNSTSW))]
1367   "TARGET_80387"
1368   "* return output_fp_compare (insn, operands, false, false);"
1369   [(set_attr "type" "multi")
1370    (set_attr "unit" "i387")
1371    (set_attr "mode" "<MODE>")])
1373 (define_insn_and_split "*cmpfp_<mode>_cc"
1374   [(set (reg:CCFP FLAGS_REG)
1375         (compare:CCFP
1376           (match_operand:MODEF 1 "register_operand" "f")
1377           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1378    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1379   "TARGET_80387
1380    && TARGET_SAHF && !TARGET_CMOVE"
1381   "#"
1382   "&& reload_completed"
1383   [(set (match_dup 0)
1384         (unspec:HI
1385           [(compare:CCFP (match_dup 1)(match_dup 2))]
1386         UNSPEC_FNSTSW))
1387    (set (reg:CC FLAGS_REG)
1388         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1389   ""
1390   [(set_attr "type" "multi")
1391    (set_attr "unit" "i387")
1392    (set_attr "mode" "<MODE>")])
1394 (define_insn "*cmpfp_u"
1395   [(set (match_operand:HI 0 "register_operand" "=a")
1396         (unspec:HI
1397           [(compare:CCFPU
1398              (match_operand 1 "register_operand" "f")
1399              (match_operand 2 "register_operand" "f"))]
1400           UNSPEC_FNSTSW))]
1401   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1402    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1403   "* return output_fp_compare (insn, operands, false, true);"
1404   [(set_attr "type" "multi")
1405    (set_attr "unit" "i387")
1406    (set (attr "mode")
1407      (cond [(match_operand:SF 1 "" "")
1408               (const_string "SF")
1409             (match_operand:DF 1 "" "")
1410               (const_string "DF")
1411            ]
1412            (const_string "XF")))])
1414 (define_insn_and_split "*cmpfp_u_cc"
1415   [(set (reg:CCFPU FLAGS_REG)
1416         (compare:CCFPU
1417           (match_operand 1 "register_operand" "f")
1418           (match_operand 2 "register_operand" "f")))
1419    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1420   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1421    && TARGET_SAHF && !TARGET_CMOVE
1422    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1423   "#"
1424   "&& reload_completed"
1425   [(set (match_dup 0)
1426         (unspec:HI
1427           [(compare:CCFPU (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")
1435      (cond [(match_operand:SF 1 "" "")
1436               (const_string "SF")
1437             (match_operand:DF 1 "" "")
1438               (const_string "DF")
1439            ]
1440            (const_string "XF")))])
1442 (define_insn "*cmpfp_<mode>"
1443   [(set (match_operand:HI 0 "register_operand" "=a")
1444         (unspec:HI
1445           [(compare:CCFP
1446              (match_operand 1 "register_operand" "f")
1447              (match_operator 3 "float_operator"
1448                [(match_operand:SWI24 2 "memory_operand" "m")]))]
1449           UNSPEC_FNSTSW))]
1450   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1451    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1452    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1453   "* return output_fp_compare (insn, operands, false, false);"
1454   [(set_attr "type" "multi")
1455    (set_attr "unit" "i387")
1456    (set_attr "fp_int_src" "true")
1457    (set_attr "mode" "<MODE>")])
1459 (define_insn_and_split "*cmpfp_<mode>_cc"
1460   [(set (reg:CCFP FLAGS_REG)
1461         (compare:CCFP
1462           (match_operand 1 "register_operand" "f")
1463           (match_operator 3 "float_operator"
1464             [(match_operand:SWI24 2 "memory_operand" "m")])))
1465    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1466   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1467    && TARGET_SAHF && !TARGET_CMOVE
1468    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1469    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1470   "#"
1471   "&& reload_completed"
1472   [(set (match_dup 0)
1473         (unspec:HI
1474           [(compare:CCFP
1475              (match_dup 1)
1476              (match_op_dup 3 [(match_dup 2)]))]
1477         UNSPEC_FNSTSW))
1478    (set (reg:CC FLAGS_REG)
1479         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1480   ""
1481   [(set_attr "type" "multi")
1482    (set_attr "unit" "i387")
1483    (set_attr "fp_int_src" "true")
1484    (set_attr "mode" "<MODE>")])
1486 ;; FP compares, step 2
1487 ;; Move the fpsw to ax.
1489 (define_insn "x86_fnstsw_1"
1490   [(set (match_operand:HI 0 "register_operand" "=a")
1491         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1492   "TARGET_80387"
1493   "fnstsw\t%0"
1494   [(set (attr "length")
1495         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1496    (set_attr "mode" "SI")
1497    (set_attr "unit" "i387")])
1499 ;; FP compares, step 3
1500 ;; Get ax into flags, general case.
1502 (define_insn "x86_sahf_1"
1503   [(set (reg:CC FLAGS_REG)
1504         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1505                    UNSPEC_SAHF))]
1506   "TARGET_SAHF"
1508 #ifndef HAVE_AS_IX86_SAHF
1509   if (TARGET_64BIT)
1510     return ASM_BYTE "0x9e";
1511   else
1512 #endif
1513   return "sahf";
1515   [(set_attr "length" "1")
1516    (set_attr "athlon_decode" "vector")
1517    (set_attr "amdfam10_decode" "direct")
1518    (set_attr "bdver1_decode" "direct")
1519    (set_attr "mode" "SI")])
1521 ;; Pentium Pro can do steps 1 through 3 in one go.
1522 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1523 ;; (these i387 instructions set flags directly)
1524 (define_insn "*cmpfp_i_mixed"
1525   [(set (reg:CCFP FLAGS_REG)
1526         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1527                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1528   "TARGET_MIX_SSE_I387
1529    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1530    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1531   "* return output_fp_compare (insn, operands, true, false);"
1532   [(set_attr "type" "fcmp,ssecomi")
1533    (set_attr "prefix" "orig,maybe_vex")
1534    (set (attr "mode")
1535      (if_then_else (match_operand:SF 1 "" "")
1536         (const_string "SF")
1537         (const_string "DF")))
1538    (set (attr "prefix_rep")
1539         (if_then_else (eq_attr "type" "ssecomi")
1540                       (const_string "0")
1541                       (const_string "*")))
1542    (set (attr "prefix_data16")
1543         (cond [(eq_attr "type" "fcmp")
1544                  (const_string "*")
1545                (eq_attr "mode" "DF")
1546                  (const_string "1")
1547               ]
1548               (const_string "0")))
1549    (set_attr "athlon_decode" "vector")
1550    (set_attr "amdfam10_decode" "direct")
1551    (set_attr "bdver1_decode" "double")])
1553 (define_insn "*cmpfp_i_sse"
1554   [(set (reg:CCFP FLAGS_REG)
1555         (compare:CCFP (match_operand 0 "register_operand" "x")
1556                       (match_operand 1 "nonimmediate_operand" "xm")))]
1557   "TARGET_SSE_MATH
1558    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1559    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1560   "* return output_fp_compare (insn, operands, true, false);"
1561   [(set_attr "type" "ssecomi")
1562    (set_attr "prefix" "maybe_vex")
1563    (set (attr "mode")
1564      (if_then_else (match_operand:SF 1 "" "")
1565         (const_string "SF")
1566         (const_string "DF")))
1567    (set_attr "prefix_rep" "0")
1568    (set (attr "prefix_data16")
1569         (if_then_else (eq_attr "mode" "DF")
1570                       (const_string "1")
1571                       (const_string "0")))
1572    (set_attr "athlon_decode" "vector")
1573    (set_attr "amdfam10_decode" "direct")
1574    (set_attr "bdver1_decode" "double")])
1576 (define_insn "*cmpfp_i_i387"
1577   [(set (reg:CCFP FLAGS_REG)
1578         (compare:CCFP (match_operand 0 "register_operand" "f")
1579                       (match_operand 1 "register_operand" "f")))]
1580   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1581    && TARGET_CMOVE
1582    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1583    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1584   "* return output_fp_compare (insn, operands, true, false);"
1585   [(set_attr "type" "fcmp")
1586    (set (attr "mode")
1587      (cond [(match_operand:SF 1 "" "")
1588               (const_string "SF")
1589             (match_operand:DF 1 "" "")
1590               (const_string "DF")
1591            ]
1592            (const_string "XF")))
1593    (set_attr "athlon_decode" "vector")
1594    (set_attr "amdfam10_decode" "direct")
1595    (set_attr "bdver1_decode" "double")])
1597 (define_insn "*cmpfp_iu_mixed"
1598   [(set (reg:CCFPU FLAGS_REG)
1599         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1600                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1601   "TARGET_MIX_SSE_I387
1602    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1603    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1604   "* return output_fp_compare (insn, operands, true, true);"
1605   [(set_attr "type" "fcmp,ssecomi")
1606    (set_attr "prefix" "orig,maybe_vex")
1607    (set (attr "mode")
1608      (if_then_else (match_operand:SF 1 "" "")
1609         (const_string "SF")
1610         (const_string "DF")))
1611    (set (attr "prefix_rep")
1612         (if_then_else (eq_attr "type" "ssecomi")
1613                       (const_string "0")
1614                       (const_string "*")))
1615    (set (attr "prefix_data16")
1616         (cond [(eq_attr "type" "fcmp")
1617                  (const_string "*")
1618                (eq_attr "mode" "DF")
1619                  (const_string "1")
1620               ]
1621               (const_string "0")))
1622    (set_attr "athlon_decode" "vector")
1623    (set_attr "amdfam10_decode" "direct")
1624    (set_attr "bdver1_decode" "double")])
1626 (define_insn "*cmpfp_iu_sse"
1627   [(set (reg:CCFPU FLAGS_REG)
1628         (compare:CCFPU (match_operand 0 "register_operand" "x")
1629                        (match_operand 1 "nonimmediate_operand" "xm")))]
1630   "TARGET_SSE_MATH
1631    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1632    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1633   "* return output_fp_compare (insn, operands, true, true);"
1634   [(set_attr "type" "ssecomi")
1635    (set_attr "prefix" "maybe_vex")
1636    (set (attr "mode")
1637      (if_then_else (match_operand:SF 1 "" "")
1638         (const_string "SF")
1639         (const_string "DF")))
1640    (set_attr "prefix_rep" "0")
1641    (set (attr "prefix_data16")
1642         (if_then_else (eq_attr "mode" "DF")
1643                       (const_string "1")
1644                       (const_string "0")))
1645    (set_attr "athlon_decode" "vector")
1646    (set_attr "amdfam10_decode" "direct")
1647    (set_attr "bdver1_decode" "double")])
1649 (define_insn "*cmpfp_iu_387"
1650   [(set (reg:CCFPU FLAGS_REG)
1651         (compare:CCFPU (match_operand 0 "register_operand" "f")
1652                        (match_operand 1 "register_operand" "f")))]
1653   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1654    && TARGET_CMOVE
1655    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1656    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1657   "* return output_fp_compare (insn, operands, true, true);"
1658   [(set_attr "type" "fcmp")
1659    (set (attr "mode")
1660      (cond [(match_operand:SF 1 "" "")
1661               (const_string "SF")
1662             (match_operand:DF 1 "" "")
1663               (const_string "DF")
1664            ]
1665            (const_string "XF")))
1666    (set_attr "athlon_decode" "vector")
1667    (set_attr "amdfam10_decode" "direct")
1668    (set_attr "bdver1_decode" "direct")])
1670 ;; Push/pop instructions.
1672 (define_insn "*push<mode>2"
1673   [(set (match_operand:DWI 0 "push_operand" "=<")
1674         (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1675   ""
1676   "#"
1677   [(set_attr "type" "multi")
1678    (set_attr "mode" "<MODE>")])
1680 (define_split
1681   [(set (match_operand:TI 0 "push_operand" "")
1682         (match_operand:TI 1 "general_operand" ""))]
1683   "TARGET_64BIT && reload_completed
1684    && !SSE_REG_P (operands[1])"
1685   [(const_int 0)]
1686   "ix86_split_long_move (operands); DONE;")
1688 (define_insn "*pushdi2_rex64"
1689   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1690         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1691   "TARGET_64BIT"
1692   "@
1693    push{q}\t%1
1694    #"
1695   [(set_attr "type" "push,multi")
1696    (set_attr "mode" "DI")])
1698 ;; Convert impossible pushes of immediate to existing instructions.
1699 ;; First try to get scratch register and go through it.  In case this
1700 ;; fails, push sign extended lower part first and then overwrite
1701 ;; upper part by 32bit move.
1702 (define_peephole2
1703   [(match_scratch:DI 2 "r")
1704    (set (match_operand:DI 0 "push_operand" "")
1705         (match_operand:DI 1 "immediate_operand" ""))]
1706   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1707    && !x86_64_immediate_operand (operands[1], DImode)"
1708   [(set (match_dup 2) (match_dup 1))
1709    (set (match_dup 0) (match_dup 2))])
1711 ;; We need to define this as both peepholer and splitter for case
1712 ;; peephole2 pass is not run.
1713 ;; "&& 1" is needed to keep it from matching the previous pattern.
1714 (define_peephole2
1715   [(set (match_operand:DI 0 "push_operand" "")
1716         (match_operand:DI 1 "immediate_operand" ""))]
1717   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1718    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1719   [(set (match_dup 0) (match_dup 1))
1720    (set (match_dup 2) (match_dup 3))]
1722   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1724   operands[1] = gen_lowpart (DImode, operands[2]);
1725   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1726                                                    GEN_INT (4)));
1729 (define_split
1730   [(set (match_operand:DI 0 "push_operand" "")
1731         (match_operand:DI 1 "immediate_operand" ""))]
1732   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1733                     ? epilogue_completed : reload_completed)
1734    && !symbolic_operand (operands[1], DImode)
1735    && !x86_64_immediate_operand (operands[1], DImode)"
1736   [(set (match_dup 0) (match_dup 1))
1737    (set (match_dup 2) (match_dup 3))]
1739   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1741   operands[1] = gen_lowpart (DImode, operands[2]);
1742   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1743                                                    GEN_INT (4)));
1746 (define_split
1747   [(set (match_operand:DI 0 "push_operand" "")
1748         (match_operand:DI 1 "general_operand" ""))]
1749   "!TARGET_64BIT && reload_completed
1750    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1751   [(const_int 0)]
1752   "ix86_split_long_move (operands); DONE;")
1754 (define_insn "*pushsi2"
1755   [(set (match_operand:SI 0 "push_operand" "=<")
1756         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1757   "!TARGET_64BIT"
1758   "push{l}\t%1"
1759   [(set_attr "type" "push")
1760    (set_attr "mode" "SI")])
1762 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1763 ;; "push a byte/word".  But actually we use pushl, which has the effect
1764 ;; of rounding the amount pushed up to a word.
1766 ;; For TARGET_64BIT we always round up to 8 bytes.
1767 (define_insn "*push<mode>2_rex64"
1768   [(set (match_operand:SWI124 0 "push_operand" "=X")
1769         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1770   "TARGET_64BIT"
1771   "push{q}\t%q1"
1772   [(set_attr "type" "push")
1773    (set_attr "mode" "DI")])
1775 (define_insn "*push<mode>2"
1776   [(set (match_operand:SWI12 0 "push_operand" "=X")
1777         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1778   "!TARGET_64BIT"
1779   "push{l}\t%k1"
1780   [(set_attr "type" "push")
1781    (set_attr "mode" "SI")])
1783 (define_insn "*push<mode>2_prologue"
1784   [(set (match_operand:P 0 "push_operand" "=<")
1785         (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1786    (clobber (mem:BLK (scratch)))]
1787   ""
1788   "push{<imodesuffix>}\t%1"
1789   [(set_attr "type" "push")
1790    (set_attr "mode" "<MODE>")])
1792 (define_insn "*pop<mode>1"
1793   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1794         (match_operand:P 1 "pop_operand" ">"))]
1795   ""
1796   "pop{<imodesuffix>}\t%0"
1797   [(set_attr "type" "pop")
1798    (set_attr "mode" "<MODE>")])
1800 (define_insn "*pop<mode>1_epilogue"
1801   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1802         (match_operand:P 1 "pop_operand" ">"))
1803    (clobber (mem:BLK (scratch)))]
1804   ""
1805   "pop{<imodesuffix>}\t%0"
1806   [(set_attr "type" "pop")
1807    (set_attr "mode" "<MODE>")])
1809 ;; Move instructions.
1811 (define_expand "movoi"
1812   [(set (match_operand:OI 0 "nonimmediate_operand" "")
1813         (match_operand:OI 1 "general_operand" ""))]
1814   "TARGET_AVX"
1815   "ix86_expand_move (OImode, operands); DONE;")
1817 (define_expand "movti"
1818   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1819         (match_operand:TI 1 "nonimmediate_operand" ""))]
1820   "TARGET_64BIT || TARGET_SSE"
1822   if (TARGET_64BIT)
1823     ix86_expand_move (TImode, operands);
1824   else if (push_operand (operands[0], TImode))
1825     ix86_expand_push (TImode, operands[1]);
1826   else
1827     ix86_expand_vector_move (TImode, operands);
1828   DONE;
1831 ;; This expands to what emit_move_complex would generate if we didn't
1832 ;; have a movti pattern.  Having this avoids problems with reload on
1833 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1834 ;; to have around all the time.
1835 (define_expand "movcdi"
1836   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1837         (match_operand:CDI 1 "general_operand" ""))]
1838   ""
1840   if (push_operand (operands[0], CDImode))
1841     emit_move_complex_push (CDImode, operands[0], operands[1]);
1842   else
1843     emit_move_complex_parts (operands[0], operands[1]);
1844   DONE;
1847 (define_expand "mov<mode>"
1848   [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1849         (match_operand:SWI1248x 1 "general_operand" ""))]
1850   ""
1851   "ix86_expand_move (<MODE>mode, operands); DONE;")
1853 (define_insn "*mov<mode>_xor"
1854   [(set (match_operand:SWI48 0 "register_operand" "=r")
1855         (match_operand:SWI48 1 "const0_operand" ""))
1856    (clobber (reg:CC FLAGS_REG))]
1857   "reload_completed"
1858   "xor{l}\t%k0, %k0"
1859   [(set_attr "type" "alu1")
1860    (set_attr "mode" "SI")
1861    (set_attr "length_immediate" "0")])
1863 (define_insn "*mov<mode>_or"
1864   [(set (match_operand:SWI48 0 "register_operand" "=r")
1865         (match_operand:SWI48 1 "const_int_operand" ""))
1866    (clobber (reg:CC FLAGS_REG))]
1867   "reload_completed
1868    && operands[1] == constm1_rtx"
1869   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1870   [(set_attr "type" "alu1")
1871    (set_attr "mode" "<MODE>")
1872    (set_attr "length_immediate" "1")])
1874 (define_insn "*movoi_internal_avx"
1875   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1876         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1877   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1879   switch (which_alternative)
1880     {
1881     case 0:
1882       return standard_sse_constant_opcode (insn, operands[1]);
1883     case 1:
1884     case 2:
1885       if (misaligned_operand (operands[0], OImode)
1886           || misaligned_operand (operands[1], OImode))
1887         return "vmovdqu\t{%1, %0|%0, %1}";
1888       else
1889         return "vmovdqa\t{%1, %0|%0, %1}";
1890     default:
1891       gcc_unreachable ();
1892     }
1894   [(set_attr "type" "sselog1,ssemov,ssemov")
1895    (set_attr "prefix" "vex")
1896    (set_attr "mode" "OI")])
1898 (define_insn "*movti_internal_rex64"
1899   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1900         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1901   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1903   switch (which_alternative)
1904     {
1905     case 0:
1906     case 1:
1907       return "#";
1908     case 2:
1909       return standard_sse_constant_opcode (insn, operands[1]);
1910     case 3:
1911     case 4:
1912       /* TDmode values are passed as TImode on the stack.  Moving them
1913          to stack may result in unaligned memory access.  */
1914       if (misaligned_operand (operands[0], TImode)
1915           || misaligned_operand (operands[1], TImode))
1916         {
1917           if (get_attr_mode (insn) == MODE_V4SF)
1918             return "%vmovups\t{%1, %0|%0, %1}";
1919           else
1920             return "%vmovdqu\t{%1, %0|%0, %1}";
1921         }
1922       else
1923         {
1924           if (get_attr_mode (insn) == MODE_V4SF)
1925             return "%vmovaps\t{%1, %0|%0, %1}";
1926           else
1927             return "%vmovdqa\t{%1, %0|%0, %1}";
1928         }
1929     default:
1930       gcc_unreachable ();
1931     }
1933   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1934    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1935    (set (attr "mode")
1936         (cond [(eq_attr "alternative" "2,3")
1937                  (if_then_else
1938                    (match_test "optimize_function_for_size_p (cfun)")
1939                    (const_string "V4SF")
1940                    (const_string "TI"))
1941                (eq_attr "alternative" "4")
1942                  (if_then_else
1943                    (ior (match_test "TARGET_SSE_TYPELESS_STORES")
1944                         (match_test "optimize_function_for_size_p (cfun)"))
1945                    (const_string "V4SF")
1946                    (const_string "TI"))]
1947                (const_string "DI")))])
1949 (define_split
1950   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1951         (match_operand:TI 1 "general_operand" ""))]
1952   "reload_completed
1953    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1954   [(const_int 0)]
1955   "ix86_split_long_move (operands); DONE;")
1957 (define_insn "*movti_internal_sse"
1958   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1959         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1960   "TARGET_SSE && !TARGET_64BIT
1961    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1963   switch (which_alternative)
1964     {
1965     case 0:
1966       return standard_sse_constant_opcode (insn, operands[1]);
1967     case 1:
1968     case 2:
1969       /* TDmode values are passed as TImode on the stack.  Moving them
1970          to stack may result in unaligned memory access.  */
1971       if (misaligned_operand (operands[0], TImode)
1972           || misaligned_operand (operands[1], TImode))
1973         {
1974           if (get_attr_mode (insn) == MODE_V4SF)
1975             return "%vmovups\t{%1, %0|%0, %1}";
1976           else
1977             return "%vmovdqu\t{%1, %0|%0, %1}";
1978         }
1979       else
1980         {
1981           if (get_attr_mode (insn) == MODE_V4SF)
1982             return "%vmovaps\t{%1, %0|%0, %1}";
1983           else
1984             return "%vmovdqa\t{%1, %0|%0, %1}";
1985         }
1986     default:
1987       gcc_unreachable ();
1988     }
1990   [(set_attr "type" "sselog1,ssemov,ssemov")
1991    (set_attr "prefix" "maybe_vex")
1992    (set (attr "mode")
1993         (cond [(ior (not (match_test "TARGET_SSE2"))
1994                     (match_test "optimize_function_for_size_p (cfun)"))
1995                  (const_string "V4SF")
1996                (and (eq_attr "alternative" "2")
1997                     (match_test "TARGET_SSE_TYPELESS_STORES"))
1998                  (const_string "V4SF")]
1999               (const_string "TI")))])
2001 (define_insn "*movdi_internal_rex64"
2002   [(set (match_operand:DI 0 "nonimmediate_operand"
2003           "=r,r  ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
2004         (match_operand:DI 1 "general_operand"
2005           "Z ,rem,i,re,n ,C ,*y ,m  ,*Ym,r   ,C ,*x,*x,m ,*Yi,r   ,*Ym,*x"))]
2006   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2008   switch (get_attr_type (insn))
2009     {
2010     case TYPE_SSECVT:
2011       if (SSE_REG_P (operands[0]))
2012         return "movq2dq\t{%1, %0|%0, %1}";
2013       else
2014         return "movdq2q\t{%1, %0|%0, %1}";
2016     case TYPE_SSEMOV:
2017       if (get_attr_mode (insn) == MODE_TI)
2018         return "%vmovdqa\t{%1, %0|%0, %1}";
2019       /* Handle broken assemblers that require movd instead of movq.  */
2020       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2021         return "%vmovd\t{%1, %0|%0, %1}";
2022       else
2023         return "%vmovq\t{%1, %0|%0, %1}";
2025     case TYPE_MMXMOV:
2026       /* Handle broken assemblers that require movd instead of movq.  */
2027       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2028         return "movd\t{%1, %0|%0, %1}";
2029       else
2030         return "movq\t{%1, %0|%0, %1}";
2032     case TYPE_SSELOG1:
2033       return standard_sse_constant_opcode (insn, operands[1]);
2035     case TYPE_MMX:
2036       return "pxor\t%0, %0";
2038     case TYPE_MULTI:
2039       return "#";
2041     case TYPE_LEA:
2042       return "lea{q}\t{%a1, %0|%0, %a1}";
2044     default:
2045       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2046       if (get_attr_mode (insn) == MODE_SI)
2047         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2048       else if (which_alternative == 2)
2049         return "movabs{q}\t{%1, %0|%0, %1}";
2050       else
2051         return "mov{q}\t{%1, %0|%0, %1}";
2052     }
2054   [(set (attr "type")
2055      (cond [(eq_attr "alternative" "4")
2056               (const_string "multi")
2057             (eq_attr "alternative" "5")
2058               (const_string "mmx")
2059             (eq_attr "alternative" "6,7,8,9")
2060               (const_string "mmxmov")
2061             (eq_attr "alternative" "10")
2062               (const_string "sselog1")
2063             (eq_attr "alternative" "11,12,13,14,15")
2064               (const_string "ssemov")
2065             (eq_attr "alternative" "16,17")
2066               (const_string "ssecvt")
2067             (match_operand 1 "pic_32bit_operand" "")
2068               (const_string "lea")
2069            ]
2070            (const_string "imov")))
2071    (set (attr "modrm")
2072      (if_then_else
2073        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2074          (const_string "0")
2075          (const_string "*")))
2076    (set (attr "length_immediate")
2077      (if_then_else
2078        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2079          (const_string "8")
2080          (const_string "*")))
2081    (set (attr "prefix_rex")
2082      (if_then_else (eq_attr "alternative" "8,9")
2083        (const_string "1")
2084        (const_string "*")))
2085    (set (attr "prefix_data16")
2086      (if_then_else (eq_attr "alternative" "11")
2087        (const_string "1")
2088        (const_string "*")))
2089    (set (attr "prefix")
2090      (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2091        (const_string "maybe_vex")
2092        (const_string "orig")))
2093    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2095 ;; Reload patterns to support multi-word load/store
2096 ;; with non-offsetable address.
2097 (define_expand "reload_noff_store"
2098   [(parallel [(match_operand 0 "memory_operand" "=m")
2099               (match_operand 1 "register_operand" "r")
2100               (match_operand:DI 2 "register_operand" "=&r")])]
2101   "TARGET_64BIT"
2103   rtx mem = operands[0];
2104   rtx addr = XEXP (mem, 0);
2106   emit_move_insn (operands[2], addr);
2107   mem = replace_equiv_address_nv (mem, operands[2]);
2109   emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2110   DONE;
2113 (define_expand "reload_noff_load"
2114   [(parallel [(match_operand 0 "register_operand" "=r")
2115               (match_operand 1 "memory_operand" "m")
2116               (match_operand:DI 2 "register_operand" "=r")])]
2117   "TARGET_64BIT"
2119   rtx mem = operands[1];
2120   rtx addr = XEXP (mem, 0);
2122   emit_move_insn (operands[2], addr);
2123   mem = replace_equiv_address_nv (mem, operands[2]);
2125   emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2126   DONE;
2129 ;; Convert impossible stores of immediate to existing instructions.
2130 ;; First try to get scratch register and go through it.  In case this
2131 ;; fails, move by 32bit parts.
2132 (define_peephole2
2133   [(match_scratch:DI 2 "r")
2134    (set (match_operand:DI 0 "memory_operand" "")
2135         (match_operand:DI 1 "immediate_operand" ""))]
2136   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2137    && !x86_64_immediate_operand (operands[1], DImode)"
2138   [(set (match_dup 2) (match_dup 1))
2139    (set (match_dup 0) (match_dup 2))])
2141 ;; We need to define this as both peepholer and splitter for case
2142 ;; peephole2 pass is not run.
2143 ;; "&& 1" is needed to keep it from matching the previous pattern.
2144 (define_peephole2
2145   [(set (match_operand:DI 0 "memory_operand" "")
2146         (match_operand:DI 1 "immediate_operand" ""))]
2147   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2148    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2149   [(set (match_dup 2) (match_dup 3))
2150    (set (match_dup 4) (match_dup 5))]
2151   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2153 (define_split
2154   [(set (match_operand:DI 0 "memory_operand" "")
2155         (match_operand:DI 1 "immediate_operand" ""))]
2156   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2157                     ? epilogue_completed : reload_completed)
2158    && !symbolic_operand (operands[1], DImode)
2159    && !x86_64_immediate_operand (operands[1], DImode)"
2160   [(set (match_dup 2) (match_dup 3))
2161    (set (match_dup 4) (match_dup 5))]
2162   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2164 (define_insn "*movdi_internal"
2165   [(set (match_operand:DI 0 "nonimmediate_operand"
2166           "=r  ,o  ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2167         (match_operand:DI 1 "general_operand"
2168           "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2169   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2171   switch (get_attr_type (insn))
2172     {
2173     case TYPE_SSECVT:
2174       if (SSE_REG_P (operands[0]))
2175         return "movq2dq\t{%1, %0|%0, %1}";
2176       else
2177         return "movdq2q\t{%1, %0|%0, %1}";
2179     case TYPE_SSEMOV:
2180       switch (get_attr_mode (insn))
2181         {
2182         case MODE_TI:
2183           return "%vmovdqa\t{%1, %0|%0, %1}";
2184         case MODE_DI:
2185            return "%vmovq\t{%1, %0|%0, %1}";
2186         case MODE_V4SF:
2187           return "movaps\t{%1, %0|%0, %1}";
2188         case MODE_V2SF:
2189           return "movlps\t{%1, %0|%0, %1}";
2190         default:
2191           gcc_unreachable ();
2192         }
2194     case TYPE_MMXMOV:
2195       return "movq\t{%1, %0|%0, %1}";
2197     case TYPE_SSELOG1:
2198       return standard_sse_constant_opcode (insn, operands[1]);
2200     case TYPE_MMX:
2201       return "pxor\t%0, %0";
2203     case TYPE_MULTI:
2204       return "#";
2206     default:
2207       gcc_unreachable ();
2208     }
2210   [(set (attr "isa")
2211      (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2212               (const_string "sse2")
2213             (eq_attr "alternative" "9,10,11,12")
2214               (const_string "noavx")
2215            ]
2216            (const_string "*")))
2217    (set (attr "type")
2218      (cond [(eq_attr "alternative" "0,1")
2219               (const_string "multi")
2220             (eq_attr "alternative" "2")
2221               (const_string "mmx")
2222             (eq_attr "alternative" "3,4")
2223               (const_string "mmxmov")
2224             (eq_attr "alternative" "5,9")
2225               (const_string "sselog1")
2226             (eq_attr "alternative" "13,14")
2227               (const_string "ssecvt")
2228            ]
2229            (const_string "ssemov")))
2230    (set (attr "prefix")
2231      (if_then_else (eq_attr "alternative" "5,6,7,8")
2232        (const_string "maybe_vex")
2233        (const_string "orig")))
2234    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2236 (define_split
2237   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2238         (match_operand:DI 1 "general_operand" ""))]
2239   "!TARGET_64BIT && reload_completed
2240    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2241    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2242   [(const_int 0)]
2243   "ix86_split_long_move (operands); DONE;")
2245 (define_insn "*movsi_internal"
2246   [(set (match_operand:SI 0 "nonimmediate_operand"
2247                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2248         (match_operand:SI 1 "general_operand"
2249                         "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
2250   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2252   switch (get_attr_type (insn))
2253     {
2254     case TYPE_SSELOG1:
2255       return standard_sse_constant_opcode (insn, operands[1]);
2257     case TYPE_SSEMOV:
2258       switch (get_attr_mode (insn))
2259         {
2260         case MODE_TI:
2261           return "%vmovdqa\t{%1, %0|%0, %1}";
2262         case MODE_V4SF:
2263           return "%vmovaps\t{%1, %0|%0, %1}";
2264         case MODE_SI:
2265           return "%vmovd\t{%1, %0|%0, %1}";
2266         case MODE_SF:
2267           return "%vmovss\t{%1, %0|%0, %1}";
2268         default:
2269           gcc_unreachable ();
2270         }
2272     case TYPE_MMX:
2273       return "pxor\t%0, %0";
2275     case TYPE_MMXMOV:
2276       if (get_attr_mode (insn) == MODE_DI)
2277         return "movq\t{%1, %0|%0, %1}";
2278       return "movd\t{%1, %0|%0, %1}";
2280     case TYPE_LEA:
2281       return "lea{l}\t{%a1, %0|%0, %a1}";
2283     default:
2284       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2285       return "mov{l}\t{%1, %0|%0, %1}";
2286     }
2288   [(set (attr "type")
2289      (cond [(eq_attr "alternative" "2")
2290               (const_string "mmx")
2291             (eq_attr "alternative" "3,4,5")
2292               (const_string "mmxmov")
2293             (eq_attr "alternative" "6")
2294               (const_string "sselog1")
2295             (eq_attr "alternative" "7,8,9,10,11")
2296               (const_string "ssemov")
2297             (match_operand 1 "pic_32bit_operand" "")
2298               (const_string "lea")
2299            ]
2300            (const_string "imov")))
2301    (set (attr "prefix")
2302      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2303        (const_string "orig")
2304        (const_string "maybe_vex")))
2305    (set (attr "prefix_data16")
2306      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2307        (const_string "1")
2308        (const_string "*")))
2309    (set (attr "mode")
2310      (cond [(eq_attr "alternative" "2,3")
2311               (const_string "DI")
2312             (eq_attr "alternative" "6,7")
2313               (if_then_else
2314                 (not (match_test "TARGET_SSE2"))
2315                 (const_string "V4SF")
2316                 (const_string "TI"))
2317             (and (eq_attr "alternative" "8,9,10,11")
2318                  (not (match_test "TARGET_SSE2")))
2319               (const_string "SF")
2320            ]
2321            (const_string "SI")))])
2323 (define_insn "*movhi_internal"
2324   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2325         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2326   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2328   switch (get_attr_type (insn))
2329     {
2330     case TYPE_IMOVX:
2331       /* movzwl is faster than movw on p2 due to partial word stalls,
2332          though not as fast as an aligned movl.  */
2333       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2334     default:
2335       if (get_attr_mode (insn) == MODE_SI)
2336         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2337       else
2338         return "mov{w}\t{%1, %0|%0, %1}";
2339     }
2341   [(set (attr "type")
2342      (cond [(match_test "optimize_function_for_size_p (cfun)")
2343               (const_string "imov")
2344             (and (eq_attr "alternative" "0")
2345                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2346                       (not (match_test "TARGET_HIMODE_MATH"))))
2347               (const_string "imov")
2348             (and (eq_attr "alternative" "1,2")
2349                  (match_operand:HI 1 "aligned_operand" ""))
2350               (const_string "imov")
2351             (and (match_test "TARGET_MOVX")
2352                  (eq_attr "alternative" "0,2"))
2353               (const_string "imovx")
2354            ]
2355            (const_string "imov")))
2356     (set (attr "mode")
2357       (cond [(eq_attr "type" "imovx")
2358                (const_string "SI")
2359              (and (eq_attr "alternative" "1,2")
2360                   (match_operand:HI 1 "aligned_operand" ""))
2361                (const_string "SI")
2362              (and (eq_attr "alternative" "0")
2363                   (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2364                        (not (match_test "TARGET_HIMODE_MATH"))))
2365                (const_string "SI")
2366             ]
2367             (const_string "HI")))])
2369 ;; Situation is quite tricky about when to choose full sized (SImode) move
2370 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2371 ;; partial register dependency machines (such as AMD Athlon), where QImode
2372 ;; moves issue extra dependency and for partial register stalls machines
2373 ;; that don't use QImode patterns (and QImode move cause stall on the next
2374 ;; instruction).
2376 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2377 ;; register stall machines with, where we use QImode instructions, since
2378 ;; partial register stall can be caused there.  Then we use movzx.
2379 (define_insn "*movqi_internal"
2380   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2381         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2382   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2384   switch (get_attr_type (insn))
2385     {
2386     case TYPE_IMOVX:
2387       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2388       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2389     default:
2390       if (get_attr_mode (insn) == MODE_SI)
2391         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2392       else
2393         return "mov{b}\t{%1, %0|%0, %1}";
2394     }
2396   [(set (attr "type")
2397      (cond [(and (eq_attr "alternative" "5")
2398                  (not (match_operand:QI 1 "aligned_operand" "")))
2399               (const_string "imovx")
2400             (match_test "optimize_function_for_size_p (cfun)")
2401               (const_string "imov")
2402             (and (eq_attr "alternative" "3")
2403                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2404                       (not (match_test "TARGET_QIMODE_MATH"))))
2405               (const_string "imov")
2406             (eq_attr "alternative" "3,5")
2407               (const_string "imovx")
2408             (and (match_test "TARGET_MOVX")
2409                  (eq_attr "alternative" "2"))
2410               (const_string "imovx")
2411            ]
2412            (const_string "imov")))
2413    (set (attr "mode")
2414       (cond [(eq_attr "alternative" "3,4,5")
2415                (const_string "SI")
2416              (eq_attr "alternative" "6")
2417                (const_string "QI")
2418              (eq_attr "type" "imovx")
2419                (const_string "SI")
2420              (and (eq_attr "type" "imov")
2421                   (and (eq_attr "alternative" "0,1")
2422                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2423                             (and (not (match_test "optimize_function_for_size_p (cfun)"))
2424                                  (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2425                (const_string "SI")
2426              ;; Avoid partial register stalls when not using QImode arithmetic
2427              (and (eq_attr "type" "imov")
2428                   (and (eq_attr "alternative" "0,1")
2429                        (and (match_test "TARGET_PARTIAL_REG_STALL")
2430                             (not (match_test "TARGET_QIMODE_MATH")))))
2431                (const_string "SI")
2432            ]
2433            (const_string "QI")))])
2435 ;; Stores and loads of ax to arbitrary constant address.
2436 ;; We fake an second form of instruction to force reload to load address
2437 ;; into register when rax is not available
2438 (define_insn "*movabs<mode>_1"
2439   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2440         (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2441   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2442   "@
2443    movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2444    mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2445   [(set_attr "type" "imov")
2446    (set_attr "modrm" "0,*")
2447    (set_attr "length_address" "8,0")
2448    (set_attr "length_immediate" "0,*")
2449    (set_attr "memory" "store")
2450    (set_attr "mode" "<MODE>")])
2452 (define_insn "*movabs<mode>_2"
2453   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2454         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2455   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2456   "@
2457    movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2458    mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2459   [(set_attr "type" "imov")
2460    (set_attr "modrm" "0,*")
2461    (set_attr "length_address" "8,0")
2462    (set_attr "length_immediate" "0")
2463    (set_attr "memory" "load")
2464    (set_attr "mode" "<MODE>")])
2466 (define_insn "*swap<mode>"
2467   [(set (match_operand:SWI48 0 "register_operand" "+r")
2468         (match_operand:SWI48 1 "register_operand" "+r"))
2469    (set (match_dup 1)
2470         (match_dup 0))]
2471   ""
2472   "xchg{<imodesuffix>}\t%1, %0"
2473   [(set_attr "type" "imov")
2474    (set_attr "mode" "<MODE>")
2475    (set_attr "pent_pair" "np")
2476    (set_attr "athlon_decode" "vector")
2477    (set_attr "amdfam10_decode" "double")
2478    (set_attr "bdver1_decode" "double")])
2480 (define_insn "*swap<mode>_1"
2481   [(set (match_operand:SWI12 0 "register_operand" "+r")
2482         (match_operand:SWI12 1 "register_operand" "+r"))
2483    (set (match_dup 1)
2484         (match_dup 0))]
2485   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2486   "xchg{l}\t%k1, %k0"
2487   [(set_attr "type" "imov")
2488    (set_attr "mode" "SI")
2489    (set_attr "pent_pair" "np")
2490    (set_attr "athlon_decode" "vector")
2491    (set_attr "amdfam10_decode" "double")
2492    (set_attr "bdver1_decode" "double")])
2494 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2495 ;; is disabled for AMDFAM10
2496 (define_insn "*swap<mode>_2"
2497   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2498         (match_operand:SWI12 1 "register_operand" "+<r>"))
2499    (set (match_dup 1)
2500         (match_dup 0))]
2501   "TARGET_PARTIAL_REG_STALL"
2502   "xchg{<imodesuffix>}\t%1, %0"
2503   [(set_attr "type" "imov")
2504    (set_attr "mode" "<MODE>")
2505    (set_attr "pent_pair" "np")
2506    (set_attr "athlon_decode" "vector")])
2508 (define_expand "movstrict<mode>"
2509   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2510         (match_operand:SWI12 1 "general_operand" ""))]
2511   ""
2513   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2514     FAIL;
2515   if (GET_CODE (operands[0]) == SUBREG
2516       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2517     FAIL;
2518   /* Don't generate memory->memory moves, go through a register */
2519   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2520     operands[1] = force_reg (<MODE>mode, operands[1]);
2523 (define_insn "*movstrict<mode>_1"
2524   [(set (strict_low_part
2525           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2526         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2527   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2528    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2529   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2530   [(set_attr "type" "imov")
2531    (set_attr "mode" "<MODE>")])
2533 (define_insn "*movstrict<mode>_xor"
2534   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2535         (match_operand:SWI12 1 "const0_operand" ""))
2536    (clobber (reg:CC FLAGS_REG))]
2537   "reload_completed"
2538   "xor{<imodesuffix>}\t%0, %0"
2539   [(set_attr "type" "alu1")
2540    (set_attr "mode" "<MODE>")
2541    (set_attr "length_immediate" "0")])
2543 (define_insn "*mov<mode>_extv_1"
2544   [(set (match_operand:SWI24 0 "register_operand" "=R")
2545         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2546                             (const_int 8)
2547                             (const_int 8)))]
2548   ""
2549   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2550   [(set_attr "type" "imovx")
2551    (set_attr "mode" "SI")])
2553 (define_insn "*movqi_extv_1_rex64"
2554   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2555         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2556                          (const_int 8)
2557                          (const_int 8)))]
2558   "TARGET_64BIT"
2560   switch (get_attr_type (insn))
2561     {
2562     case TYPE_IMOVX:
2563       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2564     default:
2565       return "mov{b}\t{%h1, %0|%0, %h1}";
2566     }
2568   [(set (attr "type")
2569      (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2570                         (match_test "TARGET_MOVX"))
2571         (const_string "imovx")
2572         (const_string "imov")))
2573    (set (attr "mode")
2574      (if_then_else (eq_attr "type" "imovx")
2575         (const_string "SI")
2576         (const_string "QI")))])
2578 (define_insn "*movqi_extv_1"
2579   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2580         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2581                          (const_int 8)
2582                          (const_int 8)))]
2583   "!TARGET_64BIT"
2585   switch (get_attr_type (insn))
2586     {
2587     case TYPE_IMOVX:
2588       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2589     default:
2590       return "mov{b}\t{%h1, %0|%0, %h1}";
2591     }
2593   [(set (attr "type")
2594      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2595                         (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2596                              (match_test "TARGET_MOVX")))
2597         (const_string "imovx")
2598         (const_string "imov")))
2599    (set (attr "mode")
2600      (if_then_else (eq_attr "type" "imovx")
2601         (const_string "SI")
2602         (const_string "QI")))])
2604 (define_insn "*mov<mode>_extzv_1"
2605   [(set (match_operand:SWI48 0 "register_operand" "=R")
2606         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2607                             (const_int 8)
2608                             (const_int 8)))]
2609   ""
2610   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2611   [(set_attr "type" "imovx")
2612    (set_attr "mode" "SI")])
2614 (define_insn "*movqi_extzv_2_rex64"
2615   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2616         (subreg:QI
2617           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2618                            (const_int 8)
2619                            (const_int 8)) 0))]
2620   "TARGET_64BIT"
2622   switch (get_attr_type (insn))
2623     {
2624     case TYPE_IMOVX:
2625       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2626     default:
2627       return "mov{b}\t{%h1, %0|%0, %h1}";
2628     }
2630   [(set (attr "type")
2631      (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2632                         (match_test "TARGET_MOVX"))
2633         (const_string "imovx")
2634         (const_string "imov")))
2635    (set (attr "mode")
2636      (if_then_else (eq_attr "type" "imovx")
2637         (const_string "SI")
2638         (const_string "QI")))])
2640 (define_insn "*movqi_extzv_2"
2641   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2642         (subreg:QI
2643           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2644                            (const_int 8)
2645                            (const_int 8)) 0))]
2646   "!TARGET_64BIT"
2648   switch (get_attr_type (insn))
2649     {
2650     case TYPE_IMOVX:
2651       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2652     default:
2653       return "mov{b}\t{%h1, %0|%0, %h1}";
2654     }
2656   [(set (attr "type")
2657      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2658                         (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2659                              (match_test "TARGET_MOVX")))
2660         (const_string "imovx")
2661         (const_string "imov")))
2662    (set (attr "mode")
2663      (if_then_else (eq_attr "type" "imovx")
2664         (const_string "SI")
2665         (const_string "QI")))])
2667 (define_expand "mov<mode>_insv_1"
2668   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2669                             (const_int 8)
2670                             (const_int 8))
2671         (match_operand:SWI48 1 "nonmemory_operand" ""))])
2673 (define_insn "*mov<mode>_insv_1_rex64"
2674   [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2675                              (const_int 8)
2676                              (const_int 8))
2677         (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2678   "TARGET_64BIT"
2679   "mov{b}\t{%b1, %h0|%h0, %b1}"
2680   [(set_attr "type" "imov")
2681    (set_attr "mode" "QI")])
2683 (define_insn "*movsi_insv_1"
2684   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2685                          (const_int 8)
2686                          (const_int 8))
2687         (match_operand:SI 1 "general_operand" "Qmn"))]
2688   "!TARGET_64BIT"
2689   "mov{b}\t{%b1, %h0|%h0, %b1}"
2690   [(set_attr "type" "imov")
2691    (set_attr "mode" "QI")])
2693 (define_insn "*movqi_insv_2"
2694   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2695                          (const_int 8)
2696                          (const_int 8))
2697         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2698                      (const_int 8)))]
2699   ""
2700   "mov{b}\t{%h1, %h0|%h0, %h1}"
2701   [(set_attr "type" "imov")
2702    (set_attr "mode" "QI")])
2704 ;; Floating point push instructions.
2706 (define_insn "*pushtf"
2707   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2708         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2709   "TARGET_SSE2"
2711   /* This insn should be already split before reg-stack.  */
2712   gcc_unreachable ();
2714   [(set_attr "type" "multi")
2715    (set_attr "unit" "sse,*,*")
2716    (set_attr "mode" "TF,SI,SI")])
2718 ;; %%% Kill this when call knows how to work this out.
2719 (define_split
2720   [(set (match_operand:TF 0 "push_operand" "")
2721         (match_operand:TF 1 "sse_reg_operand" ""))]
2722   "TARGET_SSE2 && reload_completed"
2723   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2724    (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2726 (define_insn "*pushxf"
2727   [(set (match_operand:XF 0 "push_operand" "=<,<")
2728         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2729   "optimize_function_for_speed_p (cfun)"
2731   /* This insn should be already split before reg-stack.  */
2732   gcc_unreachable ();
2734   [(set_attr "type" "multi")
2735    (set_attr "unit" "i387,*")
2736    (set_attr "mode" "XF,SI")])
2738 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2739 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2740 ;; Pushing using integer instructions is longer except for constants
2741 ;; and direct memory references (assuming that any given constant is pushed
2742 ;; only once, but this ought to be handled elsewhere).
2744 (define_insn "*pushxf_nointeger"
2745   [(set (match_operand:XF 0 "push_operand" "=<,<")
2746         (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2747   "optimize_function_for_size_p (cfun)"
2749   /* This insn should be already split before reg-stack.  */
2750   gcc_unreachable ();
2752   [(set_attr "type" "multi")
2753    (set_attr "unit" "i387,*")
2754    (set_attr "mode" "XF,SI")])
2756 ;; %%% Kill this when call knows how to work this out.
2757 (define_split
2758   [(set (match_operand:XF 0 "push_operand" "")
2759         (match_operand:XF 1 "fp_register_operand" ""))]
2760   "reload_completed"
2761   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2762    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2763   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2765 (define_insn "*pushdf_rex64"
2766   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2767         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2768   "TARGET_64BIT"
2770   /* This insn should be already split before reg-stack.  */
2771   gcc_unreachable ();
2773   [(set_attr "type" "multi")
2774    (set_attr "unit" "i387,*,*")
2775    (set_attr "mode" "DF,DI,DF")])
2777 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2778 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2779 ;; On the average, pushdf using integers can be still shorter.
2781 (define_insn "*pushdf"
2782   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2783         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2784   "!TARGET_64BIT"
2786   /* This insn should be already split before reg-stack.  */
2787   gcc_unreachable ();
2789   [(set_attr "isa" "*,*,sse2")
2790    (set_attr "type" "multi")
2791    (set_attr "unit" "i387,*,*")
2792    (set_attr "mode" "DF,DI,DF")])
2794 ;; %%% Kill this when call knows how to work this out.
2795 (define_split
2796   [(set (match_operand:DF 0 "push_operand" "")
2797         (match_operand:DF 1 "any_fp_register_operand" ""))]
2798   "reload_completed"
2799   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2800    (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2802 (define_insn "*pushsf_rex64"
2803   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2804         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2805   "TARGET_64BIT"
2807   /* Anything else should be already split before reg-stack.  */
2808   gcc_assert (which_alternative == 1);
2809   return "push{q}\t%q1";
2811   [(set_attr "type" "multi,push,multi")
2812    (set_attr "unit" "i387,*,*")
2813    (set_attr "mode" "SF,DI,SF")])
2815 (define_insn "*pushsf"
2816   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2817         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2818   "!TARGET_64BIT"
2820   /* Anything else should be already split before reg-stack.  */
2821   gcc_assert (which_alternative == 1);
2822   return "push{l}\t%1";
2824   [(set_attr "type" "multi,push,multi")
2825    (set_attr "unit" "i387,*,*")
2826    (set_attr "mode" "SF,SI,SF")])
2828 ;; %%% Kill this when call knows how to work this out.
2829 (define_split
2830   [(set (match_operand:SF 0 "push_operand" "")
2831         (match_operand:SF 1 "any_fp_register_operand" ""))]
2832   "reload_completed"
2833   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2834    (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2835   "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2837 (define_split
2838   [(set (match_operand:SF 0 "push_operand" "")
2839         (match_operand:SF 1 "memory_operand" ""))]
2840   "reload_completed
2841    && (operands[2] = find_constant_src (insn))"
2842   [(set (match_dup 0) (match_dup 2))])
2844 (define_split
2845   [(set (match_operand 0 "push_operand" "")
2846         (match_operand 1 "general_operand" ""))]
2847   "reload_completed
2848    && (GET_MODE (operands[0]) == TFmode
2849        || GET_MODE (operands[0]) == XFmode
2850        || GET_MODE (operands[0]) == DFmode)
2851    && !ANY_FP_REG_P (operands[1])"
2852   [(const_int 0)]
2853   "ix86_split_long_move (operands); DONE;")
2855 ;; Floating point move instructions.
2857 (define_expand "movtf"
2858   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2859         (match_operand:TF 1 "nonimmediate_operand" ""))]
2860   "TARGET_SSE2"
2862   ix86_expand_move (TFmode, operands);
2863   DONE;
2866 (define_expand "mov<mode>"
2867   [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2868         (match_operand:X87MODEF 1 "general_operand" ""))]
2869   ""
2870   "ix86_expand_move (<MODE>mode, operands); DONE;")
2872 (define_insn "*movtf_internal"
2873   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2874         (match_operand:TF 1 "general_operand"      "xm,x,C,*roF,F*r"))]
2875   "TARGET_SSE2
2876    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2877    && (!can_create_pseudo_p ()
2878        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2879        || GET_CODE (operands[1]) != CONST_DOUBLE
2880        || (optimize_function_for_size_p (cfun)
2881            && standard_sse_constant_p (operands[1])
2882            && !memory_operand (operands[0], TFmode))
2883        || (!TARGET_MEMORY_MISMATCH_STALL
2884            && memory_operand (operands[0], TFmode)))"
2886   switch (which_alternative)
2887     {
2888     case 0:
2889     case 1:
2890       /* Handle misaligned load/store since we
2891          don't have movmisaligntf pattern. */
2892       if (misaligned_operand (operands[0], TFmode)
2893           || misaligned_operand (operands[1], TFmode))
2894         {
2895           if (get_attr_mode (insn) == MODE_V4SF)
2896             return "%vmovups\t{%1, %0|%0, %1}";
2897           else
2898             return "%vmovdqu\t{%1, %0|%0, %1}";
2899         }
2900       else
2901         {
2902           if (get_attr_mode (insn) == MODE_V4SF)
2903             return "%vmovaps\t{%1, %0|%0, %1}";
2904           else
2905             return "%vmovdqa\t{%1, %0|%0, %1}";
2906         }
2908     case 2:
2909       return standard_sse_constant_opcode (insn, operands[1]);
2911     case 3:
2912     case 4:
2913         return "#";
2915     default:
2916       gcc_unreachable ();
2917     }
2919   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2920    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2921    (set (attr "mode")
2922         (cond [(eq_attr "alternative" "0,2")
2923                  (if_then_else
2924                    (match_test "optimize_function_for_size_p (cfun)")
2925                    (const_string "V4SF")
2926                    (const_string "TI"))
2927                (eq_attr "alternative" "1")
2928                  (if_then_else
2929                    (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2930                         (match_test "optimize_function_for_size_p (cfun)"))
2931                    (const_string "V4SF")
2932                    (const_string "TI"))]
2933                (const_string "DI")))])
2935 ;; Possible store forwarding (partial memory) stall in alternative 4.
2936 (define_insn "*movxf_internal"
2937   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2938         (match_operand:XF 1 "general_operand"      "fm,f,G,Yx*roF,FYx*r"))]
2939   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2940    && (!can_create_pseudo_p ()
2941        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2942        || GET_CODE (operands[1]) != CONST_DOUBLE
2943        || (optimize_function_for_size_p (cfun)
2944            && standard_80387_constant_p (operands[1]) > 0
2945            && !memory_operand (operands[0], XFmode))
2946        || (!TARGET_MEMORY_MISMATCH_STALL
2947            && memory_operand (operands[0], XFmode)))"
2949   switch (which_alternative)
2950     {
2951     case 0:
2952     case 1:
2953       return output_387_reg_move (insn, operands);
2955     case 2:
2956       return standard_80387_constant_opcode (operands[1]);
2958     case 3:
2959     case 4:
2960       return "#";
2962     default:
2963       gcc_unreachable ();
2964     }
2966   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2967    (set_attr "mode" "XF,XF,XF,SI,SI")])
2969 (define_insn "*movdf_internal_rex64"
2970   [(set (match_operand:DF 0 "nonimmediate_operand"
2971                 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2972         (match_operand:DF 1 "general_operand"
2973                 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2974   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2975    && (!can_create_pseudo_p ()
2976        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2977        || GET_CODE (operands[1]) != CONST_DOUBLE
2978        || (optimize_function_for_size_p (cfun)
2979            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2980                 && standard_80387_constant_p (operands[1]) > 0)
2981                || (TARGET_SSE2 && TARGET_SSE_MATH
2982                    && standard_sse_constant_p (operands[1]))))
2983        || memory_operand (operands[0], DFmode))"
2985   switch (which_alternative)
2986     {
2987     case 0:
2988     case 1:
2989       return output_387_reg_move (insn, operands);
2991     case 2:
2992       return standard_80387_constant_opcode (operands[1]);
2994     case 3:
2995     case 4:
2996       return "mov{q}\t{%1, %0|%0, %1}";
2998     case 5:
2999       return "movabs{q}\t{%1, %0|%0, %1}";
3001     case 6:
3002       return "#";
3004     case 7:
3005       return standard_sse_constant_opcode (insn, operands[1]);
3007     case 8:
3008     case 9:
3009     case 10:
3010       switch (get_attr_mode (insn))
3011         {
3012         case MODE_V2DF:
3013           if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3014             return "%vmovapd\t{%1, %0|%0, %1}";
3015         case MODE_V4SF:
3016           return "%vmovaps\t{%1, %0|%0, %1}";
3018         case MODE_DI:
3019           return "%vmovq\t{%1, %0|%0, %1}";
3020         case MODE_DF:
3021           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3022             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3023           return "%vmovsd\t{%1, %0|%0, %1}";
3024         case MODE_V1DF:
3025           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3026         case MODE_V2SF:
3027           return "%vmovlps\t{%1, %d0|%d0, %1}";
3028         default:
3029           gcc_unreachable ();
3030         }
3032     case 11:
3033     case 12:
3034       /* Handle broken assemblers that require movd instead of movq.  */
3035       return "%vmovd\t{%1, %0|%0, %1}";
3037     default:
3038       gcc_unreachable();
3039     }
3041   [(set (attr "type")
3042         (cond [(eq_attr "alternative" "0,1,2")
3043                  (const_string "fmov")
3044                (eq_attr "alternative" "3,4,5")
3045                  (const_string "imov")
3046                (eq_attr "alternative" "6")
3047                  (const_string "multi")
3048                (eq_attr "alternative" "7")
3049                  (const_string "sselog1")
3050               ]
3051               (const_string "ssemov")))
3052    (set (attr "modrm")
3053      (if_then_else
3054        (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3055          (const_string "0")
3056          (const_string "*")))
3057    (set (attr "length_immediate")
3058      (if_then_else
3059        (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3060          (const_string "8")
3061          (const_string "*")))
3062    (set (attr "prefix")
3063      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3064        (const_string "orig")
3065        (const_string "maybe_vex")))
3066    (set (attr "prefix_data16")
3067      (if_then_else (eq_attr "mode" "V1DF")
3068        (const_string "1")
3069        (const_string "*")))
3070    (set (attr "mode")
3071         (cond [(eq_attr "alternative" "0,1,2")
3072                  (const_string "DF")
3073                (eq_attr "alternative" "3,4,5,6,11,12")
3074                  (const_string "DI")
3076                /* xorps is one byte shorter.  */
3077                (eq_attr "alternative" "7")
3078                  (cond [(match_test "optimize_function_for_size_p (cfun)")
3079                           (const_string "V4SF")
3080                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3081                           (const_string "TI")
3082                        ]
3083                        (const_string "V2DF"))
3085                /* For architectures resolving dependencies on
3086                   whole SSE registers use APD move to break dependency
3087                   chains, otherwise use short move to avoid extra work.
3089                   movaps encodes one byte shorter.  */
3090                (eq_attr "alternative" "8")
3091                  (cond
3092                    [(match_test "optimize_function_for_size_p (cfun)")
3093                       (const_string "V4SF")
3094                     (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3095                       (const_string "V2DF")
3096                    ]
3097                    (const_string "DF"))
3098                /* For architectures resolving dependencies on register
3099                   parts we may avoid extra work to zero out upper part
3100                   of register.  */
3101                (eq_attr "alternative" "9")
3102                  (if_then_else
3103                    (match_test "TARGET_SSE_SPLIT_REGS")
3104                    (const_string "V1DF")
3105                    (const_string "DF"))
3106               ]
3107               (const_string "DF")))])
3109 ;; Possible store forwarding (partial memory) stall in alternative 4.
3110 (define_insn "*movdf_internal"
3111   [(set (match_operand:DF 0 "nonimmediate_operand"
3112                 "=f,m,f,?Yd*r ,!o   ,x,x,x,m,*x,*x,*x,m")
3113         (match_operand:DF 1 "general_operand"
3114                 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3115   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3116    && (!can_create_pseudo_p ()
3117        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3118        || GET_CODE (operands[1]) != CONST_DOUBLE
3119        || (optimize_function_for_size_p (cfun)
3120            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3121                 && standard_80387_constant_p (operands[1]) > 0)
3122                || (TARGET_SSE2 && TARGET_SSE_MATH
3123                    && standard_sse_constant_p (operands[1])))
3124            && !memory_operand (operands[0], DFmode))
3125        || (!TARGET_MEMORY_MISMATCH_STALL
3126            && memory_operand (operands[0], DFmode)))"
3128   switch (which_alternative)
3129     {
3130     case 0:
3131     case 1:
3132       return output_387_reg_move (insn, operands);
3134     case 2:
3135       return standard_80387_constant_opcode (operands[1]);
3137     case 3:
3138     case 4:
3139       return "#";
3141     case 5:
3142     case 9:
3143       return standard_sse_constant_opcode (insn, operands[1]);
3145     case 6:
3146     case 7:
3147     case 8:
3148     case 10:
3149     case 11:
3150     case 12:
3151       switch (get_attr_mode (insn))
3152         {
3153         case MODE_V2DF:
3154           if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3155             return "%vmovapd\t{%1, %0|%0, %1}";
3156         case MODE_V4SF:
3157           return "%vmovaps\t{%1, %0|%0, %1}";
3159         case MODE_DI:
3160           return "%vmovq\t{%1, %0|%0, %1}";
3161         case MODE_DF:
3162           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3163             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3164           return "%vmovsd\t{%1, %0|%0, %1}";
3165         case MODE_V1DF:
3166           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3167         case MODE_V2SF:
3168           return "%vmovlps\t{%1, %d0|%d0, %1}";
3169         default:
3170           gcc_unreachable ();
3171         }
3173     default:
3174       gcc_unreachable ();
3175     }
3177   [(set (attr "isa")
3178      (if_then_else (eq_attr "alternative" "5,6,7,8")
3179        (const_string "sse2")
3180        (const_string "*")))
3181    (set (attr "type")
3182         (cond [(eq_attr "alternative" "0,1,2")
3183                  (const_string "fmov")
3184                (eq_attr "alternative" "3,4")
3185                  (const_string "multi")
3186                (eq_attr "alternative" "5,9")
3187                  (const_string "sselog1")
3188               ]
3189               (const_string "ssemov")))
3190    (set (attr "prefix")
3191      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3192        (const_string "orig")
3193        (const_string "maybe_vex")))
3194    (set (attr "prefix_data16")
3195      (if_then_else (eq_attr "mode" "V1DF")
3196        (const_string "1")
3197        (const_string "*")))
3198    (set (attr "mode")
3199         (cond [(eq_attr "alternative" "0,1,2")
3200                  (const_string "DF")
3201                (eq_attr "alternative" "3,4")
3202                  (const_string "SI")
3204                /* For SSE1, we have many fewer alternatives.  */
3205                (not (match_test "TARGET_SSE2"))
3206                  (if_then_else
3207                    (eq_attr "alternative" "5,6,9,10")
3208                    (const_string "V4SF")
3209                    (const_string "V2SF"))
3211                /* xorps is one byte shorter.  */
3212                (eq_attr "alternative" "5,9")
3213                  (cond [(match_test "optimize_function_for_size_p (cfun)")
3214                           (const_string "V4SF")
3215                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3216                           (const_string "TI")
3217                        ]
3218                        (const_string "V2DF"))
3220                /* For architectures resolving dependencies on
3221                   whole SSE registers use APD move to break dependency
3222                   chains, otherwise use short move to avoid extra work.
3224                   movaps encodes one byte shorter.  */
3225                (eq_attr "alternative" "6,10")
3226                  (cond
3227                    [(match_test "optimize_function_for_size_p (cfun)")
3228                       (const_string "V4SF")
3229                     (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3230                       (const_string "V2DF")
3231                    ]
3232                    (const_string "DF"))
3233                /* For architectures resolving dependencies on register
3234                   parts we may avoid extra work to zero out upper part
3235                   of register.  */
3236                (eq_attr "alternative" "7,11")
3237                  (if_then_else
3238                    (match_test "TARGET_SSE_SPLIT_REGS")
3239                    (const_string "V1DF")
3240                    (const_string "DF"))
3241               ]
3242               (const_string "DF")))])
3244 (define_insn "*movsf_internal"
3245   [(set (match_operand:SF 0 "nonimmediate_operand"
3246           "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3247         (match_operand:SF 1 "general_operand"
3248           "fm,f,G,rmF,Fr,C,x,m,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
3249   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3250    && (!can_create_pseudo_p ()
3251        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3252        || GET_CODE (operands[1]) != CONST_DOUBLE
3253        || (optimize_function_for_size_p (cfun)
3254            && ((!TARGET_SSE_MATH
3255                 && standard_80387_constant_p (operands[1]) > 0)
3256                || (TARGET_SSE_MATH
3257                    && standard_sse_constant_p (operands[1]))))
3258        || memory_operand (operands[0], SFmode))"
3260   switch (which_alternative)
3261     {
3262     case 0:
3263     case 1:
3264       return output_387_reg_move (insn, operands);
3266     case 2:
3267       return standard_80387_constant_opcode (operands[1]);
3269     case 3:
3270     case 4:
3271       return "mov{l}\t{%1, %0|%0, %1}";
3273     case 5:
3274       return standard_sse_constant_opcode (insn, operands[1]);
3276     case 6:
3277       if (get_attr_mode (insn) == MODE_V4SF)
3278         return "%vmovaps\t{%1, %0|%0, %1}";
3279       if (TARGET_AVX)
3280         return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3282     case 7:
3283     case 8:
3284       return "%vmovss\t{%1, %0|%0, %1}";
3286     case 9:
3287     case 10:
3288     case 14:
3289     case 15:
3290       return "movd\t{%1, %0|%0, %1}";
3292     case 11:
3293       return "movq\t{%1, %0|%0, %1}";
3295     case 12:
3296     case 13:
3297       return "%vmovd\t{%1, %0|%0, %1}";
3299     default:
3300       gcc_unreachable ();
3301     }
3303   [(set (attr "type")
3304         (cond [(eq_attr "alternative" "0,1,2")
3305                  (const_string "fmov")
3306                (eq_attr "alternative" "3,4")
3307                  (const_string "multi")
3308                (eq_attr "alternative" "5")
3309                  (const_string "sselog1")
3310                (eq_attr "alternative" "9,10,11,14,15")
3311                  (const_string "mmxmov")
3312               ]
3313               (const_string "ssemov")))
3314    (set (attr "prefix")
3315      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3316        (const_string "maybe_vex")
3317        (const_string "orig")))
3318    (set (attr "mode")
3319         (cond [(eq_attr "alternative" "3,4,9,10")
3320                  (const_string "SI")
3321                (eq_attr "alternative" "5")
3322                  (if_then_else
3323                    (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3324                              (match_test "TARGET_SSE2"))
3325                         (not (match_test "optimize_function_for_size_p (cfun)")))
3326                    (const_string "TI")
3327                    (const_string "V4SF"))
3328                /* For architectures resolving dependencies on
3329                   whole SSE registers use APS move to break dependency
3330                   chains, otherwise use short move to avoid extra work.
3332                   Do the same for architectures resolving dependencies on
3333                   the parts.  While in DF mode it is better to always handle
3334                   just register parts, the SF mode is different due to lack
3335                   of instructions to load just part of the register.  It is
3336                   better to maintain the whole registers in single format
3337                   to avoid problems on using packed logical operations.  */
3338                (eq_attr "alternative" "6")
3339                  (if_then_else
3340                    (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3341                         (match_test "TARGET_SSE_SPLIT_REGS"))
3342                    (const_string "V4SF")
3343                    (const_string "SF"))
3344                (eq_attr "alternative" "11")
3345                  (const_string "DI")]
3346                (const_string "SF")))])
3348 (define_split
3349   [(set (match_operand 0 "any_fp_register_operand" "")
3350         (match_operand 1 "memory_operand" ""))]
3351   "reload_completed
3352    && (GET_MODE (operands[0]) == TFmode
3353        || GET_MODE (operands[0]) == XFmode
3354        || GET_MODE (operands[0]) == DFmode
3355        || GET_MODE (operands[0]) == SFmode)
3356    && (operands[2] = find_constant_src (insn))"
3357   [(set (match_dup 0) (match_dup 2))]
3359   rtx c = operands[2];
3360   int r = REGNO (operands[0]);
3362   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3363       || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3364     FAIL;
3367 (define_split
3368   [(set (match_operand 0 "any_fp_register_operand" "")
3369         (float_extend (match_operand 1 "memory_operand" "")))]
3370   "reload_completed
3371    && (GET_MODE (operands[0]) == TFmode
3372        || GET_MODE (operands[0]) == XFmode
3373        || GET_MODE (operands[0]) == DFmode)
3374    && (operands[2] = find_constant_src (insn))"
3375   [(set (match_dup 0) (match_dup 2))]
3377   rtx c = operands[2];
3378   int r = REGNO (operands[0]);
3380   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3381       || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3382     FAIL;
3385 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3386 (define_split
3387   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3388         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3389   "reload_completed
3390    && (standard_80387_constant_p (operands[1]) == 8
3391        || standard_80387_constant_p (operands[1]) == 9)"
3392   [(set (match_dup 0)(match_dup 1))
3393    (set (match_dup 0)
3394         (neg:X87MODEF (match_dup 0)))]
3396   REAL_VALUE_TYPE r;
3398   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3399   if (real_isnegzero (&r))
3400     operands[1] = CONST0_RTX (<MODE>mode);
3401   else
3402     operands[1] = CONST1_RTX (<MODE>mode);
3405 (define_split
3406   [(set (match_operand 0 "nonimmediate_operand" "")
3407         (match_operand 1 "general_operand" ""))]
3408   "reload_completed
3409    && (GET_MODE (operands[0]) == TFmode
3410        || GET_MODE (operands[0]) == XFmode
3411        || GET_MODE (operands[0]) == DFmode)
3412    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3413   [(const_int 0)]
3414   "ix86_split_long_move (operands); DONE;")
3416 (define_insn "swapxf"
3417   [(set (match_operand:XF 0 "register_operand" "+f")
3418         (match_operand:XF 1 "register_operand" "+f"))
3419    (set (match_dup 1)
3420         (match_dup 0))]
3421   "TARGET_80387"
3423   if (STACK_TOP_P (operands[0]))
3424     return "fxch\t%1";
3425   else
3426     return "fxch\t%0";
3428   [(set_attr "type" "fxch")
3429    (set_attr "mode" "XF")])
3431 (define_insn "*swap<mode>"
3432   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3433         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3434    (set (match_dup 1)
3435         (match_dup 0))]
3436   "TARGET_80387 || reload_completed"
3438   if (STACK_TOP_P (operands[0]))
3439     return "fxch\t%1";
3440   else
3441     return "fxch\t%0";
3443   [(set_attr "type" "fxch")
3444    (set_attr "mode" "<MODE>")])
3446 ;; Zero extension instructions
3448 (define_expand "zero_extendsidi2"
3449   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3450         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3451   ""
3453   if (!TARGET_64BIT)
3454     {
3455       emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3456       DONE;
3457     }
3460 (define_insn "*zero_extendsidi2_rex64"
3461   [(set (match_operand:DI 0 "nonimmediate_operand"  "=r,o,?*Ym,?*y,?*Yi,*x")
3462         (zero_extend:DI
3463          (match_operand:SI 1 "nonimmediate_operand" "rm,0,r   ,m  ,r   ,m")))]
3464   "TARGET_64BIT"
3465   "@
3466    mov\t{%k1, %k0|%k0, %k1}
3467    #
3468    movd\t{%1, %0|%0, %1}
3469    movd\t{%1, %0|%0, %1}
3470    %vmovd\t{%1, %0|%0, %1}
3471    %vmovd\t{%1, %0|%0, %1}"
3472   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3473    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3474    (set_attr "prefix_0f" "0,*,*,*,*,*")
3475    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3477 (define_split
3478   [(set (match_operand:DI 0 "memory_operand" "")
3479         (zero_extend:DI (match_dup 0)))]
3480   "TARGET_64BIT"
3481   [(set (match_dup 4) (const_int 0))]
3482   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3484 ;; %%% Kill me once multi-word ops are sane.
3485 (define_insn "zero_extendsidi2_1"
3486   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*x")
3487         (zero_extend:DI
3488          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3489    (clobber (reg:CC FLAGS_REG))]
3490   "!TARGET_64BIT"
3491   "@
3492    #
3493    #
3494    #
3495    movd\t{%1, %0|%0, %1}
3496    movd\t{%1, %0|%0, %1}
3497    %vmovd\t{%1, %0|%0, %1}
3498    %vmovd\t{%1, %0|%0, %1}"
3499   [(set_attr "isa" "*,*,*,*,*,*,sse2")
3500    (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3501    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3502    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3504 (define_split
3505   [(set (match_operand:DI 0 "register_operand" "")
3506         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3507    (clobber (reg:CC FLAGS_REG))]
3508   "!TARGET_64BIT && reload_completed
3509    && true_regnum (operands[0]) == true_regnum (operands[1])"
3510   [(set (match_dup 4) (const_int 0))]
3511   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3513 (define_split
3514   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3515         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3516    (clobber (reg:CC FLAGS_REG))]
3517   "!TARGET_64BIT && reload_completed
3518    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3519   [(set (match_dup 3) (match_dup 1))
3520    (set (match_dup 4) (const_int 0))]
3521   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3523 (define_insn "zero_extend<mode>di2"
3524   [(set (match_operand:DI 0 "register_operand" "=r")
3525         (zero_extend:DI
3526          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3527   "TARGET_64BIT"
3528   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3529   [(set_attr "type" "imovx")
3530    (set_attr "mode" "SI")])
3532 (define_expand "zero_extendhisi2"
3533   [(set (match_operand:SI 0 "register_operand" "")
3534         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3535   ""
3537   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3538     {
3539       operands[1] = force_reg (HImode, operands[1]);
3540       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3541       DONE;
3542     }
3545 (define_insn_and_split "zero_extendhisi2_and"
3546   [(set (match_operand:SI 0 "register_operand" "=r")
3547         (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3548    (clobber (reg:CC FLAGS_REG))]
3549   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3550   "#"
3551   "&& reload_completed"
3552   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3553               (clobber (reg:CC FLAGS_REG))])]
3554   ""
3555   [(set_attr "type" "alu1")
3556    (set_attr "mode" "SI")])
3558 (define_insn "*zero_extendhisi2_movzwl"
3559   [(set (match_operand:SI 0 "register_operand" "=r")
3560         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3561   "!TARGET_ZERO_EXTEND_WITH_AND
3562    || optimize_function_for_size_p (cfun)"
3563   "movz{wl|x}\t{%1, %0|%0, %1}"
3564   [(set_attr "type" "imovx")
3565    (set_attr "mode" "SI")])
3567 (define_expand "zero_extendqi<mode>2"
3568   [(parallel
3569     [(set (match_operand:SWI24 0 "register_operand" "")
3570           (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3571      (clobber (reg:CC FLAGS_REG))])])
3573 (define_insn "*zero_extendqi<mode>2_and"
3574   [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3575         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3576    (clobber (reg:CC FLAGS_REG))]
3577   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3578   "#"
3579   [(set_attr "type" "alu1")
3580    (set_attr "mode" "<MODE>")])
3582 ;; When source and destination does not overlap, clear destination
3583 ;; first and then do the movb
3584 (define_split
3585   [(set (match_operand:SWI24 0 "register_operand" "")
3586         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3587    (clobber (reg:CC FLAGS_REG))]
3588   "reload_completed
3589    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3590    && ANY_QI_REG_P (operands[0])
3591    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3592    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3593   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3595   operands[2] = gen_lowpart (QImode, operands[0]);
3596   ix86_expand_clear (operands[0]);
3599 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3600   [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3601         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3602    (clobber (reg:CC FLAGS_REG))]
3603   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3604   "#"
3605   [(set_attr "type" "imovx,alu1")
3606    (set_attr "mode" "<MODE>")])
3608 ;; For the movzbl case strip only the clobber
3609 (define_split
3610   [(set (match_operand:SWI24 0 "register_operand" "")
3611         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3612    (clobber (reg:CC FLAGS_REG))]
3613   "reload_completed
3614    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3615    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3616   [(set (match_dup 0)
3617         (zero_extend:SWI24 (match_dup 1)))])
3619 ; zero extend to SImode to avoid partial register stalls
3620 (define_insn "*zero_extendqi<mode>2_movzbl"
3621   [(set (match_operand:SWI24 0 "register_operand" "=r")
3622         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3623   "reload_completed
3624    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3625   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3626   [(set_attr "type" "imovx")
3627    (set_attr "mode" "SI")])
3629 ;; Rest is handled by single and.
3630 (define_split
3631   [(set (match_operand:SWI24 0 "register_operand" "")
3632         (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3633    (clobber (reg:CC FLAGS_REG))]
3634   "reload_completed
3635    && true_regnum (operands[0]) == true_regnum (operands[1])"
3636   [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3637               (clobber (reg:CC FLAGS_REG))])])
3639 ;; Sign extension instructions
3641 (define_expand "extendsidi2"
3642   [(set (match_operand:DI 0 "register_operand" "")
3643         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3644   ""
3646   if (!TARGET_64BIT)
3647     {
3648       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3649       DONE;
3650     }
3653 (define_insn "*extendsidi2_rex64"
3654   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3655         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3656   "TARGET_64BIT"
3657   "@
3658    {cltq|cdqe}
3659    movs{lq|x}\t{%1, %0|%0, %1}"
3660   [(set_attr "type" "imovx")
3661    (set_attr "mode" "DI")
3662    (set_attr "prefix_0f" "0")
3663    (set_attr "modrm" "0,1")])
3665 (define_insn "extendsidi2_1"
3666   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3667         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3668    (clobber (reg:CC FLAGS_REG))
3669    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3670   "!TARGET_64BIT"
3671   "#")
3673 ;; Extend to memory case when source register does die.
3674 (define_split
3675   [(set (match_operand:DI 0 "memory_operand" "")
3676         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3677    (clobber (reg:CC FLAGS_REG))
3678    (clobber (match_operand:SI 2 "register_operand" ""))]
3679   "(reload_completed
3680     && dead_or_set_p (insn, operands[1])
3681     && !reg_mentioned_p (operands[1], operands[0]))"
3682   [(set (match_dup 3) (match_dup 1))
3683    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3684               (clobber (reg:CC FLAGS_REG))])
3685    (set (match_dup 4) (match_dup 1))]
3686   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3688 ;; Extend to memory case when source register does not die.
3689 (define_split
3690   [(set (match_operand:DI 0 "memory_operand" "")
3691         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3692    (clobber (reg:CC FLAGS_REG))
3693    (clobber (match_operand:SI 2 "register_operand" ""))]
3694   "reload_completed"
3695   [(const_int 0)]
3697   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3699   emit_move_insn (operands[3], operands[1]);
3701   /* Generate a cltd if possible and doing so it profitable.  */
3702   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3703       && true_regnum (operands[1]) == AX_REG
3704       && true_regnum (operands[2]) == DX_REG)
3705     {
3706       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3707     }
3708   else
3709     {
3710       emit_move_insn (operands[2], operands[1]);
3711       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3712     }
3713   emit_move_insn (operands[4], operands[2]);
3714   DONE;
3717 ;; Extend to register case.  Optimize case where source and destination
3718 ;; registers match and cases where we can use cltd.
3719 (define_split
3720   [(set (match_operand:DI 0 "register_operand" "")
3721         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3722    (clobber (reg:CC FLAGS_REG))
3723    (clobber (match_scratch:SI 2 ""))]
3724   "reload_completed"
3725   [(const_int 0)]
3727   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3729   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3730     emit_move_insn (operands[3], operands[1]);
3732   /* Generate a cltd if possible and doing so it profitable.  */
3733   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3734       && true_regnum (operands[3]) == AX_REG
3735       && true_regnum (operands[4]) == DX_REG)
3736     {
3737       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3738       DONE;
3739     }
3741   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3742     emit_move_insn (operands[4], operands[1]);
3744   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3745   DONE;
3748 (define_insn "extend<mode>di2"
3749   [(set (match_operand:DI 0 "register_operand" "=r")
3750         (sign_extend:DI
3751          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3752   "TARGET_64BIT"
3753   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3754   [(set_attr "type" "imovx")
3755    (set_attr "mode" "DI")])
3757 (define_insn "extendhisi2"
3758   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3759         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3760   ""
3762   switch (get_attr_prefix_0f (insn))
3763     {
3764     case 0:
3765       return "{cwtl|cwde}";
3766     default:
3767       return "movs{wl|x}\t{%1, %0|%0, %1}";
3768     }
3770   [(set_attr "type" "imovx")
3771    (set_attr "mode" "SI")
3772    (set (attr "prefix_0f")
3773      ;; movsx is short decodable while cwtl is vector decoded.
3774      (if_then_else (and (eq_attr "cpu" "!k6")
3775                         (eq_attr "alternative" "0"))
3776         (const_string "0")
3777         (const_string "1")))
3778    (set (attr "modrm")
3779      (if_then_else (eq_attr "prefix_0f" "0")
3780         (const_string "0")
3781         (const_string "1")))])
3783 (define_insn "*extendhisi2_zext"
3784   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3785         (zero_extend:DI
3786          (sign_extend:SI
3787           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3788   "TARGET_64BIT"
3790   switch (get_attr_prefix_0f (insn))
3791     {
3792     case 0:
3793       return "{cwtl|cwde}";
3794     default:
3795       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3796     }
3798   [(set_attr "type" "imovx")
3799    (set_attr "mode" "SI")
3800    (set (attr "prefix_0f")
3801      ;; movsx is short decodable while cwtl is vector decoded.
3802      (if_then_else (and (eq_attr "cpu" "!k6")
3803                         (eq_attr "alternative" "0"))
3804         (const_string "0")
3805         (const_string "1")))
3806    (set (attr "modrm")
3807      (if_then_else (eq_attr "prefix_0f" "0")
3808         (const_string "0")
3809         (const_string "1")))])
3811 (define_insn "extendqisi2"
3812   [(set (match_operand:SI 0 "register_operand" "=r")
3813         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3814   ""
3815   "movs{bl|x}\t{%1, %0|%0, %1}"
3816    [(set_attr "type" "imovx")
3817     (set_attr "mode" "SI")])
3819 (define_insn "*extendqisi2_zext"
3820   [(set (match_operand:DI 0 "register_operand" "=r")
3821         (zero_extend:DI
3822           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3823   "TARGET_64BIT"
3824   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3825    [(set_attr "type" "imovx")
3826     (set_attr "mode" "SI")])
3828 (define_insn "extendqihi2"
3829   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3830         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3831   ""
3833   switch (get_attr_prefix_0f (insn))
3834     {
3835     case 0:
3836       return "{cbtw|cbw}";
3837     default:
3838       return "movs{bw|x}\t{%1, %0|%0, %1}";
3839     }
3841   [(set_attr "type" "imovx")
3842    (set_attr "mode" "HI")
3843    (set (attr "prefix_0f")
3844      ;; movsx is short decodable while cwtl is vector decoded.
3845      (if_then_else (and (eq_attr "cpu" "!k6")
3846                         (eq_attr "alternative" "0"))
3847         (const_string "0")
3848         (const_string "1")))
3849    (set (attr "modrm")
3850      (if_then_else (eq_attr "prefix_0f" "0")
3851         (const_string "0")
3852         (const_string "1")))])
3854 ;; Conversions between float and double.
3856 ;; These are all no-ops in the model used for the 80387.
3857 ;; So just emit moves.
3859 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3860 (define_split
3861   [(set (match_operand:DF 0 "push_operand" "")
3862         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3863   "reload_completed"
3864   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3865    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3867 (define_split
3868   [(set (match_operand:XF 0 "push_operand" "")
3869         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3870   "reload_completed"
3871   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3872    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3873   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3875 (define_expand "extendsfdf2"
3876   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3877         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3878   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3880   /* ??? Needed for compress_float_constant since all fp constants
3881      are TARGET_LEGITIMATE_CONSTANT_P.  */
3882   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3883     {
3884       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3885           && standard_80387_constant_p (operands[1]) > 0)
3886         {
3887           operands[1] = simplify_const_unary_operation
3888             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3889           emit_move_insn_1 (operands[0], operands[1]);
3890           DONE;
3891         }
3892       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3893     }
3896 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3897    cvtss2sd:
3898       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3899       cvtps2pd xmm2,xmm1
3900    We do the conversion post reload to avoid producing of 128bit spills
3901    that might lead to ICE on 32bit target.  The sequence unlikely combine
3902    anyway.  */
3903 (define_split
3904   [(set (match_operand:DF 0 "register_operand" "")
3905         (float_extend:DF
3906           (match_operand:SF 1 "nonimmediate_operand" "")))]
3907   "TARGET_USE_VECTOR_FP_CONVERTS
3908    && optimize_insn_for_speed_p ()
3909    && reload_completed && SSE_REG_P (operands[0])"
3910    [(set (match_dup 2)
3911          (float_extend:V2DF
3912            (vec_select:V2SF
3913              (match_dup 3)
3914              (parallel [(const_int 0) (const_int 1)]))))]
3916   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3917   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3918   /* Use movss for loading from memory, unpcklps reg, reg for registers.
3919      Try to avoid move when unpacking can be done in source.  */
3920   if (REG_P (operands[1]))
3921     {
3922       /* If it is unsafe to overwrite upper half of source, we need
3923          to move to destination and unpack there.  */
3924       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3925            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3926           && true_regnum (operands[0]) != true_regnum (operands[1]))
3927         {
3928           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3929           emit_move_insn (tmp, operands[1]);
3930         }
3931       else
3932         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3933       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3934                                              operands[3]));
3935     }
3936   else
3937     emit_insn (gen_vec_setv4sf_0 (operands[3],
3938                                   CONST0_RTX (V4SFmode), operands[1]));
3941 (define_insn "*extendsfdf2_mixed"
3942   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3943         (float_extend:DF
3944           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3945   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3947   switch (which_alternative)
3948     {
3949     case 0:
3950     case 1:
3951       return output_387_reg_move (insn, operands);
3953     case 2:
3954       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3956     default:
3957       gcc_unreachable ();
3958     }
3960   [(set_attr "type" "fmov,fmov,ssecvt")
3961    (set_attr "prefix" "orig,orig,maybe_vex")
3962    (set_attr "mode" "SF,XF,DF")])
3964 (define_insn "*extendsfdf2_sse"
3965   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3966         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3967   "TARGET_SSE2 && TARGET_SSE_MATH"
3968   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3969   [(set_attr "type" "ssecvt")
3970    (set_attr "prefix" "maybe_vex")
3971    (set_attr "mode" "DF")])
3973 (define_insn "*extendsfdf2_i387"
3974   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3975         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3976   "TARGET_80387"
3977   "* return output_387_reg_move (insn, operands);"
3978   [(set_attr "type" "fmov")
3979    (set_attr "mode" "SF,XF")])
3981 (define_expand "extend<mode>xf2"
3982   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3983         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3984   "TARGET_80387"
3986   /* ??? Needed for compress_float_constant since all fp constants
3987      are TARGET_LEGITIMATE_CONSTANT_P.  */
3988   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3989     {
3990       if (standard_80387_constant_p (operands[1]) > 0)
3991         {
3992           operands[1] = simplify_const_unary_operation
3993             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3994           emit_move_insn_1 (operands[0], operands[1]);
3995           DONE;
3996         }
3997       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3998     }
4001 (define_insn "*extend<mode>xf2_i387"
4002   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4003         (float_extend:XF
4004           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4005   "TARGET_80387"
4006   "* return output_387_reg_move (insn, operands);"
4007   [(set_attr "type" "fmov")
4008    (set_attr "mode" "<MODE>,XF")])
4010 ;; %%% This seems bad bad news.
4011 ;; This cannot output into an f-reg because there is no way to be sure
4012 ;; of truncating in that case.  Otherwise this is just like a simple move
4013 ;; insn.  So we pretend we can output to a reg in order to get better
4014 ;; register preferencing, but we really use a stack slot.
4016 ;; Conversion from DFmode to SFmode.
4018 (define_expand "truncdfsf2"
4019   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4020         (float_truncate:SF
4021           (match_operand:DF 1 "nonimmediate_operand" "")))]
4022   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4024   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4025     ;
4026   else if (flag_unsafe_math_optimizations)
4027     ;
4028   else
4029     {
4030       enum ix86_stack_slot slot = (virtuals_instantiated
4031                                    ? SLOT_TEMP
4032                                    : SLOT_VIRTUAL);
4033       rtx temp = assign_386_stack_local (SFmode, slot);
4034       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4035       DONE;
4036     }
4039 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4040    cvtsd2ss:
4041       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4042       cvtpd2ps xmm2,xmm1
4043    We do the conversion post reload to avoid producing of 128bit spills
4044    that might lead to ICE on 32bit target.  The sequence unlikely combine
4045    anyway.  */
4046 (define_split
4047   [(set (match_operand:SF 0 "register_operand" "")
4048         (float_truncate:SF
4049           (match_operand:DF 1 "nonimmediate_operand" "")))]
4050   "TARGET_USE_VECTOR_FP_CONVERTS
4051    && optimize_insn_for_speed_p ()
4052    && reload_completed && SSE_REG_P (operands[0])"
4053    [(set (match_dup 2)
4054          (vec_concat:V4SF
4055            (float_truncate:V2SF
4056              (match_dup 4))
4057            (match_dup 3)))]
4059   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4060   operands[3] = CONST0_RTX (V2SFmode);
4061   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4062   /* Use movsd for loading from memory, unpcklpd for registers.
4063      Try to avoid move when unpacking can be done in source, or SSE3
4064      movddup is available.  */
4065   if (REG_P (operands[1]))
4066     {
4067       if (!TARGET_SSE3
4068           && true_regnum (operands[0]) != true_regnum (operands[1])
4069           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4070               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4071         {
4072           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4073           emit_move_insn (tmp, operands[1]);
4074           operands[1] = tmp;
4075         }
4076       else if (!TARGET_SSE3)
4077         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4078       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4079     }
4080   else
4081     emit_insn (gen_sse2_loadlpd (operands[4],
4082                                  CONST0_RTX (V2DFmode), operands[1]));
4085 (define_expand "truncdfsf2_with_temp"
4086   [(parallel [(set (match_operand:SF 0 "" "")
4087                    (float_truncate:SF (match_operand:DF 1 "" "")))
4088               (clobber (match_operand:SF 2 "" ""))])])
4090 (define_insn "*truncdfsf_fast_mixed"
4091   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4092         (float_truncate:SF
4093           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4094   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4096   switch (which_alternative)
4097     {
4098     case 0:
4099       return output_387_reg_move (insn, operands);
4100     case 1:
4101       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4102     default:
4103       gcc_unreachable ();
4104     }
4106   [(set_attr "type" "fmov,ssecvt")
4107    (set_attr "prefix" "orig,maybe_vex")
4108    (set_attr "mode" "SF")])
4110 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4111 ;; because nothing we do here is unsafe.
4112 (define_insn "*truncdfsf_fast_sse"
4113   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4114         (float_truncate:SF
4115           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4116   "TARGET_SSE2 && TARGET_SSE_MATH"
4117   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4118   [(set_attr "type" "ssecvt")
4119    (set_attr "prefix" "maybe_vex")
4120    (set_attr "mode" "SF")])
4122 (define_insn "*truncdfsf_fast_i387"
4123   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4124         (float_truncate:SF
4125           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4126   "TARGET_80387 && flag_unsafe_math_optimizations"
4127   "* return output_387_reg_move (insn, operands);"
4128   [(set_attr "type" "fmov")
4129    (set_attr "mode" "SF")])
4131 (define_insn "*truncdfsf_mixed"
4132   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,x ,?f,?x,?*r")
4133         (float_truncate:SF
4134           (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4135    (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
4136   "TARGET_MIX_SSE_I387"
4138   switch (which_alternative)
4139     {
4140     case 0:
4141       return output_387_reg_move (insn, operands);
4142     case 1:
4143       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4145     default:
4146       return "#";
4147     }
4149   [(set_attr "isa" "*,sse2,*,*,*")
4150    (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4151    (set_attr "unit" "*,*,i387,i387,i387")
4152    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4153    (set_attr "mode" "SF")])
4155 (define_insn "*truncdfsf_i387"
4156   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4157         (float_truncate:SF
4158           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4159    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4160   "TARGET_80387"
4162   switch (which_alternative)
4163     {
4164     case 0:
4165       return output_387_reg_move (insn, operands);
4167     default:
4168       return "#";
4169     }
4171   [(set_attr "type" "fmov,multi,multi,multi")
4172    (set_attr "unit" "*,i387,i387,i387")
4173    (set_attr "mode" "SF")])
4175 (define_insn "*truncdfsf2_i387_1"
4176   [(set (match_operand:SF 0 "memory_operand" "=m")
4177         (float_truncate:SF
4178           (match_operand:DF 1 "register_operand" "f")))]
4179   "TARGET_80387
4180    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4181    && !TARGET_MIX_SSE_I387"
4182   "* return output_387_reg_move (insn, operands);"
4183   [(set_attr "type" "fmov")
4184    (set_attr "mode" "SF")])
4186 (define_split
4187   [(set (match_operand:SF 0 "register_operand" "")
4188         (float_truncate:SF
4189          (match_operand:DF 1 "fp_register_operand" "")))
4190    (clobber (match_operand 2 "" ""))]
4191   "reload_completed"
4192   [(set (match_dup 2) (match_dup 1))
4193    (set (match_dup 0) (match_dup 2))]
4194   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4196 ;; Conversion from XFmode to {SF,DF}mode
4198 (define_expand "truncxf<mode>2"
4199   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4200                    (float_truncate:MODEF
4201                      (match_operand:XF 1 "register_operand" "")))
4202               (clobber (match_dup 2))])]
4203   "TARGET_80387"
4205   if (flag_unsafe_math_optimizations)
4206     {
4207       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4208       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4209       if (reg != operands[0])
4210         emit_move_insn (operands[0], reg);
4211       DONE;
4212     }
4213   else
4214     {
4215       enum ix86_stack_slot slot = (virtuals_instantiated
4216                                    ? SLOT_TEMP
4217                                    : SLOT_VIRTUAL);
4218       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4219     }
4222 (define_insn "*truncxfsf2_mixed"
4223   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4224         (float_truncate:SF
4225           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4226    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4227   "TARGET_80387"
4229   gcc_assert (!which_alternative);
4230   return output_387_reg_move (insn, operands);
4232   [(set_attr "type" "fmov,multi,multi,multi")
4233    (set_attr "unit" "*,i387,i387,i387")
4234    (set_attr "mode" "SF")])
4236 (define_insn "*truncxfdf2_mixed"
4237   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4238         (float_truncate:DF
4239           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4240    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4241   "TARGET_80387"
4243   gcc_assert (!which_alternative);
4244   return output_387_reg_move (insn, operands);
4246   [(set_attr "isa" "*,*,sse2,*")
4247    (set_attr "type" "fmov,multi,multi,multi")
4248    (set_attr "unit" "*,i387,i387,i387")
4249    (set_attr "mode" "DF")])
4251 (define_insn "truncxf<mode>2_i387_noop"
4252   [(set (match_operand:MODEF 0 "register_operand" "=f")
4253         (float_truncate:MODEF
4254           (match_operand:XF 1 "register_operand" "f")))]
4255   "TARGET_80387 && flag_unsafe_math_optimizations"
4256   "* return output_387_reg_move (insn, operands);"
4257   [(set_attr "type" "fmov")
4258    (set_attr "mode" "<MODE>")])
4260 (define_insn "*truncxf<mode>2_i387"
4261   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4262         (float_truncate:MODEF
4263           (match_operand:XF 1 "register_operand" "f")))]
4264   "TARGET_80387"
4265   "* return output_387_reg_move (insn, operands);"
4266   [(set_attr "type" "fmov")
4267    (set_attr "mode" "<MODE>")])
4269 (define_split
4270   [(set (match_operand:MODEF 0 "register_operand" "")
4271         (float_truncate:MODEF
4272           (match_operand:XF 1 "register_operand" "")))
4273    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4274   "TARGET_80387 && reload_completed"
4275   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4276    (set (match_dup 0) (match_dup 2))])
4278 (define_split
4279   [(set (match_operand:MODEF 0 "memory_operand" "")
4280         (float_truncate:MODEF
4281           (match_operand:XF 1 "register_operand" "")))
4282    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4283   "TARGET_80387"
4284   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4286 ;; Signed conversion to DImode.
4288 (define_expand "fix_truncxfdi2"
4289   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4290                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4291               (clobber (reg:CC FLAGS_REG))])]
4292   "TARGET_80387"
4294   if (TARGET_FISTTP)
4295    {
4296      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4297      DONE;
4298    }
4301 (define_expand "fix_trunc<mode>di2"
4302   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4303                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4304               (clobber (reg:CC FLAGS_REG))])]
4305   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4307   if (TARGET_FISTTP
4308       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4309    {
4310      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4311      DONE;
4312    }
4313   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4314    {
4315      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4316      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4317      if (out != operands[0])
4318         emit_move_insn (operands[0], out);
4319      DONE;
4320    }
4323 ;; Signed conversion to SImode.
4325 (define_expand "fix_truncxfsi2"
4326   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4327                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4328               (clobber (reg:CC FLAGS_REG))])]
4329   "TARGET_80387"
4331   if (TARGET_FISTTP)
4332    {
4333      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4334      DONE;
4335    }
4338 (define_expand "fix_trunc<mode>si2"
4339   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4340                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4341               (clobber (reg:CC FLAGS_REG))])]
4342   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4344   if (TARGET_FISTTP
4345       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4346    {
4347      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4348      DONE;
4349    }
4350   if (SSE_FLOAT_MODE_P (<MODE>mode))
4351    {
4352      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4353      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4354      if (out != operands[0])
4355         emit_move_insn (operands[0], out);
4356      DONE;
4357    }
4360 ;; Signed conversion to HImode.
4362 (define_expand "fix_trunc<mode>hi2"
4363   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4364                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4365               (clobber (reg:CC FLAGS_REG))])]
4366   "TARGET_80387
4367    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4369   if (TARGET_FISTTP)
4370    {
4371      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4372      DONE;
4373    }
4376 ;; Unsigned conversion to SImode.
4378 (define_expand "fixuns_trunc<mode>si2"
4379   [(parallel
4380     [(set (match_operand:SI 0 "register_operand" "")
4381           (unsigned_fix:SI
4382             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4383      (use (match_dup 2))
4384      (clobber (match_scratch:<ssevecmode> 3 ""))
4385      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4386   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4388   enum machine_mode mode = <MODE>mode;
4389   enum machine_mode vecmode = <ssevecmode>mode;
4390   REAL_VALUE_TYPE TWO31r;
4391   rtx two31;
4393   if (optimize_insn_for_size_p ())
4394     FAIL;
4396   real_ldexp (&TWO31r, &dconst1, 31);
4397   two31 = const_double_from_real_value (TWO31r, mode);
4398   two31 = ix86_build_const_vector (vecmode, true, two31);
4399   operands[2] = force_reg (vecmode, two31);
4402 (define_insn_and_split "*fixuns_trunc<mode>_1"
4403   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4404         (unsigned_fix:SI
4405           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4406    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4407    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4408    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4409   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4410    && optimize_function_for_speed_p (cfun)"
4411   "#"
4412   "&& reload_completed"
4413   [(const_int 0)]
4415   ix86_split_convert_uns_si_sse (operands);
4416   DONE;
4419 ;; Unsigned conversion to HImode.
4420 ;; Without these patterns, we'll try the unsigned SI conversion which
4421 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4423 (define_expand "fixuns_trunc<mode>hi2"
4424   [(set (match_dup 2)
4425         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4426    (set (match_operand:HI 0 "nonimmediate_operand" "")
4427         (subreg:HI (match_dup 2) 0))]
4428   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4429   "operands[2] = gen_reg_rtx (SImode);")
4431 ;; When SSE is available, it is always faster to use it!
4432 (define_insn "fix_trunc<mode>di_sse"
4433   [(set (match_operand:DI 0 "register_operand" "=r,r")
4434         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4435   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4436    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4437   "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4438   [(set_attr "type" "sseicvt")
4439    (set_attr "prefix" "maybe_vex")
4440    (set_attr "prefix_rex" "1")
4441    (set_attr "mode" "<MODE>")
4442    (set_attr "athlon_decode" "double,vector")
4443    (set_attr "amdfam10_decode" "double,double")
4444    (set_attr "bdver1_decode" "double,double")])
4446 (define_insn "fix_trunc<mode>si_sse"
4447   [(set (match_operand:SI 0 "register_operand" "=r,r")
4448         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4449   "SSE_FLOAT_MODE_P (<MODE>mode)
4450    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4451   "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4452   [(set_attr "type" "sseicvt")
4453    (set_attr "prefix" "maybe_vex")
4454    (set_attr "mode" "<MODE>")
4455    (set_attr "athlon_decode" "double,vector")
4456    (set_attr "amdfam10_decode" "double,double")
4457    (set_attr "bdver1_decode" "double,double")])
4459 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4460 (define_peephole2
4461   [(set (match_operand:MODEF 0 "register_operand" "")
4462         (match_operand:MODEF 1 "memory_operand" ""))
4463    (set (match_operand:SWI48x 2 "register_operand" "")
4464         (fix:SWI48x (match_dup 0)))]
4465   "TARGET_SHORTEN_X87_SSE
4466    && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4467    && peep2_reg_dead_p (2, operands[0])"
4468   [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4470 ;; Avoid vector decoded forms of the instruction.
4471 (define_peephole2
4472   [(match_scratch:DF 2 "x")
4473    (set (match_operand:SWI48x 0 "register_operand" "")
4474         (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4475   "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4476   [(set (match_dup 2) (match_dup 1))
4477    (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4479 (define_peephole2
4480   [(match_scratch:SF 2 "x")
4481    (set (match_operand:SWI48x 0 "register_operand" "")
4482         (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4483   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4484   [(set (match_dup 2) (match_dup 1))
4485    (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4487 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4488   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4489         (fix:SWI248x (match_operand 1 "register_operand" "")))]
4490   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4491    && TARGET_FISTTP
4492    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4493          && (TARGET_64BIT || <MODE>mode != DImode))
4494         && TARGET_SSE_MATH)
4495    && can_create_pseudo_p ()"
4496   "#"
4497   "&& 1"
4498   [(const_int 0)]
4500   if (memory_operand (operands[0], VOIDmode))
4501     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4502   else
4503     {
4504       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4505       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4506                                                             operands[1],
4507                                                             operands[2]));
4508     }
4509   DONE;
4511   [(set_attr "type" "fisttp")
4512    (set_attr "mode" "<MODE>")])
4514 (define_insn "fix_trunc<mode>_i387_fisttp"
4515   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4516         (fix:SWI248x (match_operand 1 "register_operand" "f")))
4517    (clobber (match_scratch:XF 2 "=&1f"))]
4518   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4519    && TARGET_FISTTP
4520    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4521          && (TARGET_64BIT || <MODE>mode != DImode))
4522         && TARGET_SSE_MATH)"
4523   "* return output_fix_trunc (insn, operands, true);"
4524   [(set_attr "type" "fisttp")
4525    (set_attr "mode" "<MODE>")])
4527 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4528   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4529         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4530    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4531    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4532   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4533    && TARGET_FISTTP
4534    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4535         && (TARGET_64BIT || <MODE>mode != DImode))
4536         && TARGET_SSE_MATH)"
4537   "#"
4538   [(set_attr "type" "fisttp")
4539    (set_attr "mode" "<MODE>")])
4541 (define_split
4542   [(set (match_operand:SWI248x 0 "register_operand" "")
4543         (fix:SWI248x (match_operand 1 "register_operand" "")))
4544    (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4545    (clobber (match_scratch 3 ""))]
4546   "reload_completed"
4547   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4548               (clobber (match_dup 3))])
4549    (set (match_dup 0) (match_dup 2))])
4551 (define_split
4552   [(set (match_operand:SWI248x 0 "memory_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 0) (fix:SWI248x (match_dup 1)))
4558               (clobber (match_dup 3))])])
4560 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4561 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4562 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4563 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4564 ;; function in i386.c.
4565 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4566   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4567         (fix:SWI248x (match_operand 1 "register_operand" "")))
4568    (clobber (reg:CC FLAGS_REG))]
4569   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4570    && !TARGET_FISTTP
4571    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4572          && (TARGET_64BIT || <MODE>mode != DImode))
4573    && can_create_pseudo_p ()"
4574   "#"
4575   "&& 1"
4576   [(const_int 0)]
4578   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4580   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4581   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4582   if (memory_operand (operands[0], VOIDmode))
4583     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4584                                          operands[2], operands[3]));
4585   else
4586     {
4587       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4588       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4589                                                      operands[2], operands[3],
4590                                                      operands[4]));
4591     }
4592   DONE;
4594   [(set_attr "type" "fistp")
4595    (set_attr "i387_cw" "trunc")
4596    (set_attr "mode" "<MODE>")])
4598 (define_insn "fix_truncdi_i387"
4599   [(set (match_operand:DI 0 "memory_operand" "=m")
4600         (fix:DI (match_operand 1 "register_operand" "f")))
4601    (use (match_operand:HI 2 "memory_operand" "m"))
4602    (use (match_operand:HI 3 "memory_operand" "m"))
4603    (clobber (match_scratch:XF 4 "=&1f"))]
4604   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4605    && !TARGET_FISTTP
4606    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4607   "* return output_fix_trunc (insn, operands, false);"
4608   [(set_attr "type" "fistp")
4609    (set_attr "i387_cw" "trunc")
4610    (set_attr "mode" "DI")])
4612 (define_insn "fix_truncdi_i387_with_temp"
4613   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4614         (fix:DI (match_operand 1 "register_operand" "f,f")))
4615    (use (match_operand:HI 2 "memory_operand" "m,m"))
4616    (use (match_operand:HI 3 "memory_operand" "m,m"))
4617    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4618    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4619   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4620    && !TARGET_FISTTP
4621    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4622   "#"
4623   [(set_attr "type" "fistp")
4624    (set_attr "i387_cw" "trunc")
4625    (set_attr "mode" "DI")])
4627 (define_split
4628   [(set (match_operand:DI 0 "register_operand" "")
4629         (fix:DI (match_operand 1 "register_operand" "")))
4630    (use (match_operand:HI 2 "memory_operand" ""))
4631    (use (match_operand:HI 3 "memory_operand" ""))
4632    (clobber (match_operand:DI 4 "memory_operand" ""))
4633    (clobber (match_scratch 5 ""))]
4634   "reload_completed"
4635   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4636               (use (match_dup 2))
4637               (use (match_dup 3))
4638               (clobber (match_dup 5))])
4639    (set (match_dup 0) (match_dup 4))])
4641 (define_split
4642   [(set (match_operand:DI 0 "memory_operand" "")
4643         (fix:DI (match_operand 1 "register_operand" "")))
4644    (use (match_operand:HI 2 "memory_operand" ""))
4645    (use (match_operand:HI 3 "memory_operand" ""))
4646    (clobber (match_operand:DI 4 "memory_operand" ""))
4647    (clobber (match_scratch 5 ""))]
4648   "reload_completed"
4649   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4650               (use (match_dup 2))
4651               (use (match_dup 3))
4652               (clobber (match_dup 5))])])
4654 (define_insn "fix_trunc<mode>_i387"
4655   [(set (match_operand:SWI24 0 "memory_operand" "=m")
4656         (fix:SWI24 (match_operand 1 "register_operand" "f")))
4657    (use (match_operand:HI 2 "memory_operand" "m"))
4658    (use (match_operand:HI 3 "memory_operand" "m"))]
4659   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4660    && !TARGET_FISTTP
4661    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4662   "* return output_fix_trunc (insn, operands, false);"
4663   [(set_attr "type" "fistp")
4664    (set_attr "i387_cw" "trunc")
4665    (set_attr "mode" "<MODE>")])
4667 (define_insn "fix_trunc<mode>_i387_with_temp"
4668   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4669         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4670    (use (match_operand:HI 2 "memory_operand" "m,m"))
4671    (use (match_operand:HI 3 "memory_operand" "m,m"))
4672    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4673   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4674    && !TARGET_FISTTP
4675    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4676   "#"
4677   [(set_attr "type" "fistp")
4678    (set_attr "i387_cw" "trunc")
4679    (set_attr "mode" "<MODE>")])
4681 (define_split
4682   [(set (match_operand:SWI24 0 "register_operand" "")
4683         (fix:SWI24 (match_operand 1 "register_operand" "")))
4684    (use (match_operand:HI 2 "memory_operand" ""))
4685    (use (match_operand:HI 3 "memory_operand" ""))
4686    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4687   "reload_completed"
4688   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4689               (use (match_dup 2))
4690               (use (match_dup 3))])
4691    (set (match_dup 0) (match_dup 4))])
4693 (define_split
4694   [(set (match_operand:SWI24 0 "memory_operand" "")
4695         (fix:SWI24 (match_operand 1 "register_operand" "")))
4696    (use (match_operand:HI 2 "memory_operand" ""))
4697    (use (match_operand:HI 3 "memory_operand" ""))
4698    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4699   "reload_completed"
4700   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4701               (use (match_dup 2))
4702               (use (match_dup 3))])])
4704 (define_insn "x86_fnstcw_1"
4705   [(set (match_operand:HI 0 "memory_operand" "=m")
4706         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4707   "TARGET_80387"
4708   "fnstcw\t%0"
4709   [(set (attr "length")
4710         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4711    (set_attr "mode" "HI")
4712    (set_attr "unit" "i387")
4713    (set_attr "bdver1_decode" "vector")])
4715 (define_insn "x86_fldcw_1"
4716   [(set (reg:HI FPCR_REG)
4717         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4718   "TARGET_80387"
4719   "fldcw\t%0"
4720   [(set (attr "length")
4721         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4722    (set_attr "mode" "HI")
4723    (set_attr "unit" "i387")
4724    (set_attr "athlon_decode" "vector")
4725    (set_attr "amdfam10_decode" "vector")
4726    (set_attr "bdver1_decode" "vector")])
4728 ;; Conversion between fixed point and floating point.
4730 ;; Even though we only accept memory inputs, the backend _really_
4731 ;; wants to be able to do this between registers.
4733 (define_expand "floathi<mode>2"
4734   [(set (match_operand:X87MODEF 0 "register_operand" "")
4735         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4736   "TARGET_80387
4737    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4738        || TARGET_MIX_SSE_I387)")
4740 ;; Pre-reload splitter to add memory clobber to the pattern.
4741 (define_insn_and_split "*floathi<mode>2_1"
4742   [(set (match_operand:X87MODEF 0 "register_operand" "")
4743         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4744   "TARGET_80387
4745    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4746        || TARGET_MIX_SSE_I387)
4747    && can_create_pseudo_p ()"
4748   "#"
4749   "&& 1"
4750   [(parallel [(set (match_dup 0)
4751               (float:X87MODEF (match_dup 1)))
4752    (clobber (match_dup 2))])]
4753   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4755 (define_insn "*floathi<mode>2_i387_with_temp"
4756   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4757         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4758   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4759   "TARGET_80387
4760    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4761        || TARGET_MIX_SSE_I387)"
4762   "#"
4763   [(set_attr "type" "fmov,multi")
4764    (set_attr "mode" "<MODE>")
4765    (set_attr "unit" "*,i387")
4766    (set_attr "fp_int_src" "true")])
4768 (define_insn "*floathi<mode>2_i387"
4769   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4770         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4771   "TARGET_80387
4772    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4773        || TARGET_MIX_SSE_I387)"
4774   "fild%Z1\t%1"
4775   [(set_attr "type" "fmov")
4776    (set_attr "mode" "<MODE>")
4777    (set_attr "fp_int_src" "true")])
4779 (define_split
4780   [(set (match_operand:X87MODEF 0 "register_operand" "")
4781         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4782    (clobber (match_operand:HI 2 "memory_operand" ""))]
4783   "TARGET_80387
4784    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4785        || TARGET_MIX_SSE_I387)
4786    && reload_completed"
4787   [(set (match_dup 2) (match_dup 1))
4788    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4790 (define_split
4791   [(set (match_operand:X87MODEF 0 "register_operand" "")
4792         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4793    (clobber (match_operand:HI 2 "memory_operand" ""))]
4794    "TARGET_80387
4795     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4796         || TARGET_MIX_SSE_I387)
4797     && reload_completed"
4798   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4800 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4801   [(set (match_operand:X87MODEF 0 "register_operand" "")
4802         (float:X87MODEF
4803           (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4804   "TARGET_80387
4805    || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4806        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4808   if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4809         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4810       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4811     {
4812       rtx reg = gen_reg_rtx (XFmode);
4813       rtx (*insn)(rtx, rtx);
4815       emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4817       if (<X87MODEF:MODE>mode == SFmode)
4818         insn = gen_truncxfsf2;
4819       else if (<X87MODEF:MODE>mode == DFmode)
4820         insn = gen_truncxfdf2;
4821       else
4822         gcc_unreachable ();
4824       emit_insn (insn (operands[0], reg));
4825       DONE;
4826     }
4829 ;; Pre-reload splitter to add memory clobber to the pattern.
4830 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4831   [(set (match_operand:X87MODEF 0 "register_operand" "")
4832         (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4833   "((TARGET_80387
4834      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4835      && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4836            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4837          || TARGET_MIX_SSE_I387))
4838     || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4839         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4840         && ((<SWI48x:MODE>mode == SImode
4841              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4842              && optimize_function_for_speed_p (cfun)
4843              && flag_trapping_math)
4844             || !(TARGET_INTER_UNIT_CONVERSIONS
4845                  || optimize_function_for_size_p (cfun)))))
4846    && can_create_pseudo_p ()"
4847   "#"
4848   "&& 1"
4849   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4850               (clobber (match_dup 2))])]
4852   operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4854   /* Avoid store forwarding (partial memory) stall penalty
4855      by passing DImode value through XMM registers.  */
4856   if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4857       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4858       && optimize_function_for_speed_p (cfun))
4859     {
4860       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4861                                                             operands[1],
4862                                                             operands[2]));
4863       DONE;
4864     }
4867 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4868   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4869         (float:MODEF
4870           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4871    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4872   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4873    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4874   "#"
4875   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4876    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4877    (set_attr "unit" "*,i387,*,*,*")
4878    (set_attr "athlon_decode" "*,*,double,direct,double")
4879    (set_attr "amdfam10_decode" "*,*,vector,double,double")
4880    (set_attr "bdver1_decode" "*,*,double,direct,double")
4881    (set_attr "fp_int_src" "true")])
4883 (define_insn "*floatsi<mode>2_vector_mixed"
4884   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4885         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4886   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4887    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4888   "@
4889    fild%Z1\t%1
4890    #"
4891   [(set_attr "type" "fmov,sseicvt")
4892    (set_attr "mode" "<MODE>,<ssevecmode>")
4893    (set_attr "unit" "i387,*")
4894    (set_attr "athlon_decode" "*,direct")
4895    (set_attr "amdfam10_decode" "*,double")
4896    (set_attr "bdver1_decode" "*,direct")
4897    (set_attr "fp_int_src" "true")])
4899 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4900   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4901         (float:MODEF
4902           (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4903    (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4904   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4905    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4906   "#"
4907   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4908    (set_attr "mode" "<MODEF:MODE>")
4909    (set_attr "unit" "*,i387,*,*")
4910    (set_attr "athlon_decode" "*,*,double,direct")
4911    (set_attr "amdfam10_decode" "*,*,vector,double")
4912    (set_attr "bdver1_decode" "*,*,double,direct")
4913    (set_attr "fp_int_src" "true")])
4915 (define_split
4916   [(set (match_operand:MODEF 0 "register_operand" "")
4917         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4918    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4919   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4920    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4921    && TARGET_INTER_UNIT_CONVERSIONS
4922    && reload_completed
4923    && (SSE_REG_P (operands[0])
4924        || (GET_CODE (operands[0]) == SUBREG
4925            && SSE_REG_P (operands[0])))"
4926   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4928 (define_split
4929   [(set (match_operand:MODEF 0 "register_operand" "")
4930         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4931    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4932   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4933    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4934    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4935    && reload_completed
4936    && (SSE_REG_P (operands[0])
4937        || (GET_CODE (operands[0]) == SUBREG
4938            && SSE_REG_P (operands[0])))"
4939   [(set (match_dup 2) (match_dup 1))
4940    (set (match_dup 0) (float:MODEF (match_dup 2)))])
4942 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4943   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4944         (float:MODEF
4945           (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4946   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4947    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4948    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4949   "@
4950    fild%Z1\t%1
4951    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4952    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4953   [(set_attr "type" "fmov,sseicvt,sseicvt")
4954    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4955    (set_attr "mode" "<MODEF:MODE>")
4956    (set (attr "prefix_rex")
4957      (if_then_else
4958        (and (eq_attr "prefix" "maybe_vex")
4959             (match_test "<SWI48x:MODE>mode == DImode"))
4960        (const_string "1")
4961        (const_string "*")))
4962    (set_attr "unit" "i387,*,*")
4963    (set_attr "athlon_decode" "*,double,direct")
4964    (set_attr "amdfam10_decode" "*,vector,double")
4965    (set_attr "bdver1_decode" "*,double,direct")
4966    (set_attr "fp_int_src" "true")])
4968 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4969   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4970         (float:MODEF
4971           (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4972   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4973    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4974    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4975   "@
4976    fild%Z1\t%1
4977    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4978   [(set_attr "type" "fmov,sseicvt")
4979    (set_attr "prefix" "orig,maybe_vex")
4980    (set_attr "mode" "<MODEF:MODE>")
4981    (set (attr "prefix_rex")
4982      (if_then_else
4983        (and (eq_attr "prefix" "maybe_vex")
4984             (match_test "<SWI48x:MODE>mode == DImode"))
4985        (const_string "1")
4986        (const_string "*")))
4987    (set_attr "athlon_decode" "*,direct")
4988    (set_attr "amdfam10_decode" "*,double")
4989    (set_attr "bdver1_decode" "*,direct")
4990    (set_attr "fp_int_src" "true")])
4992 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4993   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4994         (float:MODEF
4995           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4996    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4997   "TARGET_SSE2 && TARGET_SSE_MATH
4998    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4999   "#"
5000   [(set_attr "type" "sseicvt")
5001    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5002    (set_attr "athlon_decode" "double,direct,double")
5003    (set_attr "amdfam10_decode" "vector,double,double")
5004    (set_attr "bdver1_decode" "double,direct,double")
5005    (set_attr "fp_int_src" "true")])
5007 (define_insn "*floatsi<mode>2_vector_sse"
5008   [(set (match_operand:MODEF 0 "register_operand" "=x")
5009         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5010   "TARGET_SSE2 && TARGET_SSE_MATH
5011    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5012   "#"
5013   [(set_attr "type" "sseicvt")
5014    (set_attr "mode" "<MODE>")
5015    (set_attr "athlon_decode" "direct")
5016    (set_attr "amdfam10_decode" "double")
5017    (set_attr "bdver1_decode" "direct")
5018    (set_attr "fp_int_src" "true")])
5020 (define_split
5021   [(set (match_operand:MODEF 0 "register_operand" "")
5022         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5023    (clobber (match_operand:SI 2 "memory_operand" ""))]
5024   "TARGET_SSE2 && TARGET_SSE_MATH
5025    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5026    && reload_completed
5027    && (SSE_REG_P (operands[0])
5028        || (GET_CODE (operands[0]) == SUBREG
5029            && SSE_REG_P (operands[0])))"
5030   [(const_int 0)]
5032   rtx op1 = operands[1];
5034   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5035                                      <MODE>mode, 0);
5036   if (GET_CODE (op1) == SUBREG)
5037     op1 = SUBREG_REG (op1);
5039   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5040     {
5041       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5042       emit_insn (gen_sse2_loadld (operands[4],
5043                                   CONST0_RTX (V4SImode), operands[1]));
5044     }
5045   /* We can ignore possible trapping value in the
5046      high part of SSE register for non-trapping math. */
5047   else if (SSE_REG_P (op1) && !flag_trapping_math)
5048     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5049   else
5050     {
5051       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5052       emit_move_insn (operands[2], operands[1]);
5053       emit_insn (gen_sse2_loadld (operands[4],
5054                                   CONST0_RTX (V4SImode), operands[2]));
5055     }
5056   if (<ssevecmode>mode == V4SImode)
5057     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5058   else
5059     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5060   DONE;
5063 (define_split
5064   [(set (match_operand:MODEF 0 "register_operand" "")
5065         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5066    (clobber (match_operand:SI 2 "memory_operand" ""))]
5067   "TARGET_SSE2 && TARGET_SSE_MATH
5068    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5069    && reload_completed
5070    && (SSE_REG_P (operands[0])
5071        || (GET_CODE (operands[0]) == SUBREG
5072            && SSE_REG_P (operands[0])))"
5073   [(const_int 0)]
5075   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5076                                      <MODE>mode, 0);
5077   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5079   emit_insn (gen_sse2_loadld (operands[4],
5080                               CONST0_RTX (V4SImode), operands[1]));
5081   if (<ssevecmode>mode == V4SFmode)
5082     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5083   else
5084     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5085   DONE;
5088 (define_split
5089   [(set (match_operand:MODEF 0 "register_operand" "")
5090         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5091   "TARGET_SSE2 && TARGET_SSE_MATH
5092    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5093    && reload_completed
5094    && (SSE_REG_P (operands[0])
5095        || (GET_CODE (operands[0]) == SUBREG
5096            && SSE_REG_P (operands[0])))"
5097   [(const_int 0)]
5099   rtx op1 = operands[1];
5101   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5102                                      <MODE>mode, 0);
5103   if (GET_CODE (op1) == SUBREG)
5104     op1 = SUBREG_REG (op1);
5106   if (GENERAL_REG_P (op1))
5107     {
5108       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5109       if (TARGET_INTER_UNIT_MOVES)
5110         emit_insn (gen_sse2_loadld (operands[4],
5111                                     CONST0_RTX (V4SImode), operands[1]));
5112       else
5113         {
5114           operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5115                                               operands[1]);
5116           emit_insn (gen_sse2_loadld (operands[4],
5117                                       CONST0_RTX (V4SImode), operands[5]));
5118           ix86_free_from_memory (GET_MODE (operands[1]));
5119         }
5120     }
5121   /* We can ignore possible trapping value in the
5122      high part of SSE register for non-trapping math. */
5123   else if (SSE_REG_P (op1) && !flag_trapping_math)
5124     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5125   else
5126     gcc_unreachable ();
5127   if (<ssevecmode>mode == V4SFmode)
5128     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5129   else
5130     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5131   DONE;
5134 (define_split
5135   [(set (match_operand:MODEF 0 "register_operand" "")
5136         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5137   "TARGET_SSE2 && TARGET_SSE_MATH
5138    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5139    && reload_completed
5140    && (SSE_REG_P (operands[0])
5141        || (GET_CODE (operands[0]) == SUBREG
5142            && SSE_REG_P (operands[0])))"
5143   [(const_int 0)]
5145   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5146                                      <MODE>mode, 0);
5147   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5149   emit_insn (gen_sse2_loadld (operands[4],
5150                               CONST0_RTX (V4SImode), operands[1]));
5151   if (<ssevecmode>mode == V4SFmode)
5152     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5153   else
5154     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5155   DONE;
5158 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5159   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5160         (float:MODEF
5161           (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5162   (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5163   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5164    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5165   "#"
5166   [(set_attr "type" "sseicvt")
5167    (set_attr "mode" "<MODEF:MODE>")
5168    (set_attr "athlon_decode" "double,direct")
5169    (set_attr "amdfam10_decode" "vector,double")
5170    (set_attr "bdver1_decode" "double,direct")
5171    (set_attr "fp_int_src" "true")])
5173 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5174   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5175         (float:MODEF
5176           (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5177   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5178    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5179    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5180   "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5181   [(set_attr "type" "sseicvt")
5182    (set_attr "prefix" "maybe_vex")
5183    (set_attr "mode" "<MODEF:MODE>")
5184    (set (attr "prefix_rex")
5185      (if_then_else
5186        (and (eq_attr "prefix" "maybe_vex")
5187             (match_test "<SWI48x:MODE>mode == DImode"))
5188        (const_string "1")
5189        (const_string "*")))
5190    (set_attr "athlon_decode" "double,direct")
5191    (set_attr "amdfam10_decode" "vector,double")
5192    (set_attr "bdver1_decode" "double,direct")
5193    (set_attr "fp_int_src" "true")])
5195 (define_split
5196   [(set (match_operand:MODEF 0 "register_operand" "")
5197         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5198    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5199   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5200    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5201    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5202    && reload_completed
5203    && (SSE_REG_P (operands[0])
5204        || (GET_CODE (operands[0]) == SUBREG
5205            && SSE_REG_P (operands[0])))"
5206   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5208 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5209   [(set (match_operand:MODEF 0 "register_operand" "=x")
5210         (float:MODEF
5211           (match_operand:SWI48x 1 "memory_operand" "m")))]
5212   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5213    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5214    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5215   "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5216   [(set_attr "type" "sseicvt")
5217    (set_attr "prefix" "maybe_vex")
5218    (set_attr "mode" "<MODEF:MODE>")
5219    (set (attr "prefix_rex")
5220      (if_then_else
5221        (and (eq_attr "prefix" "maybe_vex")
5222             (match_test "<SWI48x:MODE>mode == DImode"))
5223        (const_string "1")
5224        (const_string "*")))
5225    (set_attr "athlon_decode" "direct")
5226    (set_attr "amdfam10_decode" "double")
5227    (set_attr "bdver1_decode" "direct")
5228    (set_attr "fp_int_src" "true")])
5230 (define_split
5231   [(set (match_operand:MODEF 0 "register_operand" "")
5232         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5233    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5234   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5235    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5236    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5237    && reload_completed
5238    && (SSE_REG_P (operands[0])
5239        || (GET_CODE (operands[0]) == SUBREG
5240            && SSE_REG_P (operands[0])))"
5241   [(set (match_dup 2) (match_dup 1))
5242    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5244 (define_split
5245   [(set (match_operand:MODEF 0 "register_operand" "")
5246         (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5247    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5248   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5249    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5250    && reload_completed
5251    && (SSE_REG_P (operands[0])
5252        || (GET_CODE (operands[0]) == SUBREG
5253            && SSE_REG_P (operands[0])))"
5254   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5256 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5257   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5258         (float:X87MODEF
5259           (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5260   (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5261   "TARGET_80387
5262    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5263   "@
5264    fild%Z1\t%1
5265    #"
5266   [(set_attr "type" "fmov,multi")
5267    (set_attr "mode" "<X87MODEF:MODE>")
5268    (set_attr "unit" "*,i387")
5269    (set_attr "fp_int_src" "true")])
5271 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5272   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5273         (float:X87MODEF
5274           (match_operand:SWI48x 1 "memory_operand" "m")))]
5275   "TARGET_80387
5276    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5277   "fild%Z1\t%1"
5278   [(set_attr "type" "fmov")
5279    (set_attr "mode" "<X87MODEF:MODE>")
5280    (set_attr "fp_int_src" "true")])
5282 (define_split
5283   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5284         (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5285    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5286   "TARGET_80387
5287    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5288    && reload_completed"
5289   [(set (match_dup 2) (match_dup 1))
5290    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5292 (define_split
5293   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5294         (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5295    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5296   "TARGET_80387
5297    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5298    && reload_completed"
5299   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5301 ;; Avoid store forwarding (partial memory) stall penalty
5302 ;; by passing DImode value through XMM registers.  */
5304 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5305   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5306         (float:X87MODEF
5307           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5308    (clobber (match_scratch:V4SI 3 "=X,x"))
5309    (clobber (match_scratch:V4SI 4 "=X,x"))
5310    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5311   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5312    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5313    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5314   "#"
5315   [(set_attr "type" "multi")
5316    (set_attr "mode" "<X87MODEF:MODE>")
5317    (set_attr "unit" "i387")
5318    (set_attr "fp_int_src" "true")])
5320 (define_split
5321   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5322         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5323    (clobber (match_scratch:V4SI 3 ""))
5324    (clobber (match_scratch:V4SI 4 ""))
5325    (clobber (match_operand:DI 2 "memory_operand" ""))]
5326   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5327    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5328    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5329    && reload_completed"
5330   [(set (match_dup 2) (match_dup 3))
5331    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5333   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5334      Assemble the 64-bit DImode value in an xmm register.  */
5335   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5336                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5337   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5338                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5339   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5340                                          operands[4]));
5342   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5345 (define_split
5346   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5347         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5348    (clobber (match_scratch:V4SI 3 ""))
5349    (clobber (match_scratch:V4SI 4 ""))
5350    (clobber (match_operand:DI 2 "memory_operand" ""))]
5351   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5352    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5353    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5354    && reload_completed"
5355   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5357 ;; Avoid store forwarding (partial memory) stall penalty by extending
5358 ;; SImode value to DImode through XMM register instead of pushing two
5359 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5360 ;; targets benefit from this optimization. Also note that fild
5361 ;; loads from memory only.
5363 (define_insn "*floatunssi<mode>2_1"
5364   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5365         (unsigned_float:X87MODEF
5366           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5367    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5368    (clobber (match_scratch:SI 3 "=X,x"))]
5369   "!TARGET_64BIT
5370    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5371    && TARGET_SSE"
5372   "#"
5373   [(set_attr "type" "multi")
5374    (set_attr "mode" "<MODE>")])
5376 (define_split
5377   [(set (match_operand:X87MODEF 0 "register_operand" "")
5378         (unsigned_float:X87MODEF
5379           (match_operand:SI 1 "register_operand" "")))
5380    (clobber (match_operand:DI 2 "memory_operand" ""))
5381    (clobber (match_scratch:SI 3 ""))]
5382   "!TARGET_64BIT
5383    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5384    && TARGET_SSE
5385    && reload_completed"
5386   [(set (match_dup 2) (match_dup 1))
5387    (set (match_dup 0)
5388         (float:X87MODEF (match_dup 2)))]
5389   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5391 (define_split
5392   [(set (match_operand:X87MODEF 0 "register_operand" "")
5393         (unsigned_float:X87MODEF
5394           (match_operand:SI 1 "memory_operand" "")))
5395    (clobber (match_operand:DI 2 "memory_operand" ""))
5396    (clobber (match_scratch:SI 3 ""))]
5397   "!TARGET_64BIT
5398    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5399    && TARGET_SSE
5400    && reload_completed"
5401   [(set (match_dup 2) (match_dup 3))
5402    (set (match_dup 0)
5403         (float:X87MODEF (match_dup 2)))]
5405   emit_move_insn (operands[3], operands[1]);
5406   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5409 (define_expand "floatunssi<mode>2"
5410   [(parallel
5411      [(set (match_operand:X87MODEF 0 "register_operand" "")
5412            (unsigned_float:X87MODEF
5413              (match_operand:SI 1 "nonimmediate_operand" "")))
5414       (clobber (match_dup 2))
5415       (clobber (match_scratch:SI 3 ""))])]
5416   "!TARGET_64BIT
5417    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5418         && TARGET_SSE)
5419        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5421   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5422     {
5423       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5424       DONE;
5425     }
5426   else
5427     {
5428       enum ix86_stack_slot slot = (virtuals_instantiated
5429                                    ? SLOT_TEMP
5430                                    : SLOT_VIRTUAL);
5431       operands[2] = assign_386_stack_local (DImode, slot);
5432     }
5435 (define_expand "floatunsdisf2"
5436   [(use (match_operand:SF 0 "register_operand" ""))
5437    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5438   "TARGET_64BIT && TARGET_SSE_MATH"
5439   "x86_emit_floatuns (operands); DONE;")
5441 (define_expand "floatunsdidf2"
5442   [(use (match_operand:DF 0 "register_operand" ""))
5443    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5444   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5445    && TARGET_SSE2 && TARGET_SSE_MATH"
5447   if (TARGET_64BIT)
5448     x86_emit_floatuns (operands);
5449   else
5450     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5451   DONE;
5454 ;; Add instructions
5456 (define_expand "add<mode>3"
5457   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5458         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5459                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5460   ""
5461   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5463 (define_insn_and_split "*add<dwi>3_doubleword"
5464   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5465         (plus:<DWI>
5466           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5467           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5468    (clobber (reg:CC FLAGS_REG))]
5469   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5470   "#"
5471   "reload_completed"
5472   [(parallel [(set (reg:CC FLAGS_REG)
5473                    (unspec:CC [(match_dup 1) (match_dup 2)]
5474                               UNSPEC_ADD_CARRY))
5475               (set (match_dup 0)
5476                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5477    (parallel [(set (match_dup 3)
5478                    (plus:DWIH
5479                      (match_dup 4)
5480                      (plus:DWIH
5481                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5482                        (match_dup 5))))
5483               (clobber (reg:CC FLAGS_REG))])]
5484   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5486 (define_insn "*add<mode>3_cc"
5487   [(set (reg:CC FLAGS_REG)
5488         (unspec:CC
5489           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5490            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5491           UNSPEC_ADD_CARRY))
5492    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5493         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5494   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5495   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5496   [(set_attr "type" "alu")
5497    (set_attr "mode" "<MODE>")])
5499 (define_insn "addqi3_cc"
5500   [(set (reg:CC FLAGS_REG)
5501         (unspec:CC
5502           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5503            (match_operand:QI 2 "general_operand" "qn,qm")]
5504           UNSPEC_ADD_CARRY))
5505    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5506         (plus:QI (match_dup 1) (match_dup 2)))]
5507   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5508   "add{b}\t{%2, %0|%0, %2}"
5509   [(set_attr "type" "alu")
5510    (set_attr "mode" "QI")])
5512 (define_insn_and_split "*lea_1"
5513   [(set (match_operand:SI 0 "register_operand" "=r")
5514         (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
5515   "TARGET_64BIT"
5516   "lea{l}\t{%a1, %0|%0, %a1}"
5517   "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5518   [(const_int 0)]
5520   ix86_split_lea_for_addr (operands, SImode);
5521   DONE;
5523   [(set_attr "type" "lea")
5524    (set_attr "mode" "SI")])
5526 (define_insn_and_split "*lea<mode>_2"
5527   [(set (match_operand:SWI48 0 "register_operand" "=r")
5528         (match_operand:SWI48 1 "lea_address_operand" "p"))]
5529   ""
5530   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5531   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5532   [(const_int 0)]
5534   ix86_split_lea_for_addr (operands, <MODE>mode);
5535   DONE;
5537   [(set_attr "type" "lea")
5538    (set_attr "mode" "<MODE>")])
5540 (define_insn "*lea_3_zext"
5541   [(set (match_operand:DI 0 "register_operand" "=r")
5542         (zero_extend:DI
5543           (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0)))]
5544   "TARGET_64BIT"
5545   "lea{l}\t{%a1, %k0|%k0, %a1}"
5546   [(set_attr "type" "lea")
5547    (set_attr "mode" "SI")])
5549 (define_insn "*lea_4_zext"
5550   [(set (match_operand:DI 0 "register_operand" "=r")
5551         (zero_extend:DI
5552           (match_operand:SI 1 "lea_address_operand" "p")))]
5553   "TARGET_64BIT"
5554   "lea{l}\t{%a1, %k0|%k0, %a1}"
5555   [(set_attr "type" "lea")
5556    (set_attr "mode" "SI")])
5558 (define_insn "*lea_5_zext"
5559   [(set (match_operand:DI 0 "register_operand" "=r")
5560         (and:DI
5561           (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
5562           (match_operand:DI 2 "const_32bit_mask" "n")))]
5563   "TARGET_64BIT"
5564   "lea{l}\t{%a1, %k0|%k0, %a1}"
5565   [(set_attr "type" "lea")
5566    (set_attr "mode" "SI")])
5568 (define_insn "*lea_6_zext"
5569   [(set (match_operand:DI 0 "register_operand" "=r")
5570         (and:DI
5571           (match_operand:DI 1 "lea_address_operand" "p")
5572           (match_operand:DI 2 "const_32bit_mask" "n")))]
5573   "TARGET_64BIT"
5574   "lea{l}\t{%a1, %k0|%k0, %a1}"
5575   [(set_attr "type" "lea")
5576    (set_attr "mode" "SI")])
5578 (define_insn "*add<mode>_1"
5579   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5580         (plus:SWI48
5581           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5582           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5583    (clobber (reg:CC FLAGS_REG))]
5584   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5586   switch (get_attr_type (insn))
5587     {
5588     case TYPE_LEA:
5589       return "#";
5591     case TYPE_INCDEC:
5592       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5593       if (operands[2] == const1_rtx)
5594         return "inc{<imodesuffix>}\t%0";
5595       else
5596         {
5597           gcc_assert (operands[2] == constm1_rtx);
5598           return "dec{<imodesuffix>}\t%0";
5599         }
5601     default:
5602       /* For most processors, ADD is faster than LEA.  This alternative
5603          was added to use ADD as much as possible.  */
5604       if (which_alternative == 2)
5605         {
5606           rtx tmp;
5607           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5608         }
5609         
5610       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5611       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5612         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5614       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5615     }
5617   [(set (attr "type")
5618      (cond [(eq_attr "alternative" "3")
5619               (const_string "lea")
5620             (match_operand:SWI48 2 "incdec_operand" "")
5621               (const_string "incdec")
5622            ]
5623            (const_string "alu")))
5624    (set (attr "length_immediate")
5625       (if_then_else
5626         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5627         (const_string "1")
5628         (const_string "*")))
5629    (set_attr "mode" "<MODE>")])
5631 ;; It may seem that nonimmediate operand is proper one for operand 1.
5632 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5633 ;; we take care in ix86_binary_operator_ok to not allow two memory
5634 ;; operands so proper swapping will be done in reload.  This allow
5635 ;; patterns constructed from addsi_1 to match.
5637 (define_insn "addsi_1_zext"
5638   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5639         (zero_extend:DI
5640           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5641                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5642    (clobber (reg:CC FLAGS_REG))]
5643   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5645   switch (get_attr_type (insn))
5646     {
5647     case TYPE_LEA:
5648       return "#";
5650     case TYPE_INCDEC:
5651       if (operands[2] == const1_rtx)
5652         return "inc{l}\t%k0";
5653       else
5654         {
5655           gcc_assert (operands[2] == constm1_rtx);
5656           return "dec{l}\t%k0";
5657         }
5659     default:
5660       /* For most processors, ADD is faster than LEA.  This alternative
5661          was added to use ADD as much as possible.  */
5662       if (which_alternative == 1)
5663         {
5664           rtx tmp;
5665           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5666         }
5668       if (x86_maybe_negate_const_int (&operands[2], SImode))
5669         return "sub{l}\t{%2, %k0|%k0, %2}";
5671       return "add{l}\t{%2, %k0|%k0, %2}";
5672     }
5674   [(set (attr "type")
5675      (cond [(eq_attr "alternative" "2")
5676               (const_string "lea")
5677             (match_operand:SI 2 "incdec_operand" "")
5678               (const_string "incdec")
5679            ]
5680            (const_string "alu")))
5681    (set (attr "length_immediate")
5682       (if_then_else
5683         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5684         (const_string "1")
5685         (const_string "*")))
5686    (set_attr "mode" "SI")])
5688 (define_insn "*addhi_1"
5689   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5690         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5691                  (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5692    (clobber (reg:CC FLAGS_REG))]
5693   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5695   switch (get_attr_type (insn))
5696     {
5697     case TYPE_LEA:
5698       return "#";
5700     case TYPE_INCDEC:
5701       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5702       if (operands[2] == const1_rtx)
5703         return "inc{w}\t%0";
5704       else
5705         {
5706           gcc_assert (operands[2] == constm1_rtx);
5707           return "dec{w}\t%0";
5708         }
5710     default:
5711       /* For most processors, ADD is faster than LEA.  This alternative
5712          was added to use ADD as much as possible.  */
5713       if (which_alternative == 2)
5714         {
5715           rtx tmp;
5716           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5717         }
5719       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5720       if (x86_maybe_negate_const_int (&operands[2], HImode))
5721         return "sub{w}\t{%2, %0|%0, %2}";
5723       return "add{w}\t{%2, %0|%0, %2}";
5724     }
5726   [(set (attr "type")
5727      (cond [(eq_attr "alternative" "3")
5728               (const_string "lea")
5729             (match_operand:HI 2 "incdec_operand" "")
5730               (const_string "incdec")
5731            ]
5732            (const_string "alu")))
5733    (set (attr "length_immediate")
5734       (if_then_else
5735         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5736         (const_string "1")
5737         (const_string "*")))
5738    (set_attr "mode" "HI,HI,HI,SI")])
5740 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5741 (define_insn "*addqi_1"
5742   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5743         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5744                  (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5745    (clobber (reg:CC FLAGS_REG))]
5746   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5748   bool widen = (which_alternative == 3 || which_alternative == 4);
5750   switch (get_attr_type (insn))
5751     {
5752     case TYPE_LEA:
5753       return "#";
5755     case TYPE_INCDEC:
5756       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5757       if (operands[2] == const1_rtx)
5758         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5759       else
5760         {
5761           gcc_assert (operands[2] == constm1_rtx);
5762           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5763         }
5765     default:
5766       /* For most processors, ADD is faster than LEA.  These alternatives
5767          were added to use ADD as much as possible.  */
5768       if (which_alternative == 2 || which_alternative == 4)
5769         {
5770           rtx tmp;
5771           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5772         }
5774       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5775       if (x86_maybe_negate_const_int (&operands[2], QImode))
5776         {
5777           if (widen)
5778             return "sub{l}\t{%2, %k0|%k0, %2}";
5779           else
5780             return "sub{b}\t{%2, %0|%0, %2}";
5781         }
5782       if (widen)
5783         return "add{l}\t{%k2, %k0|%k0, %k2}";
5784       else
5785         return "add{b}\t{%2, %0|%0, %2}";
5786     }
5788   [(set (attr "type")
5789      (cond [(eq_attr "alternative" "5")
5790               (const_string "lea")
5791             (match_operand:QI 2 "incdec_operand" "")
5792               (const_string "incdec")
5793            ]
5794            (const_string "alu")))
5795    (set (attr "length_immediate")
5796       (if_then_else
5797         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5798         (const_string "1")
5799         (const_string "*")))
5800    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5802 (define_insn "*addqi_1_slp"
5803   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5804         (plus:QI (match_dup 0)
5805                  (match_operand:QI 1 "general_operand" "qn,qm")))
5806    (clobber (reg:CC FLAGS_REG))]
5807   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5808    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5810   switch (get_attr_type (insn))
5811     {
5812     case TYPE_INCDEC:
5813       if (operands[1] == const1_rtx)
5814         return "inc{b}\t%0";
5815       else
5816         {
5817           gcc_assert (operands[1] == constm1_rtx);
5818           return "dec{b}\t%0";
5819         }
5821     default:
5822       if (x86_maybe_negate_const_int (&operands[1], QImode))
5823         return "sub{b}\t{%1, %0|%0, %1}";
5825       return "add{b}\t{%1, %0|%0, %1}";
5826     }
5828   [(set (attr "type")
5829      (if_then_else (match_operand:QI 1 "incdec_operand" "")
5830         (const_string "incdec")
5831         (const_string "alu1")))
5832    (set (attr "memory")
5833      (if_then_else (match_operand 1 "memory_operand" "")
5834         (const_string "load")
5835         (const_string "none")))
5836    (set_attr "mode" "QI")])
5838 ;; Split non destructive adds if we cannot use lea.
5839 (define_split
5840   [(set (match_operand:SWI48 0 "register_operand" "")
5841         (plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5842               (match_operand:SWI48 2 "nonmemory_operand" "")))
5843    (clobber (reg:CC FLAGS_REG))]
5844   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5845   [(set (match_dup 0) (match_dup 1))
5846    (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5847               (clobber (reg:CC FLAGS_REG))])])
5849 ;; Convert add to the lea pattern to avoid flags dependency.
5850 (define_split
5851   [(set (match_operand:SWI 0 "register_operand" "")
5852         (plus:SWI (match_operand:SWI 1 "register_operand" "")
5853                   (match_operand:SWI 2 "<nonmemory_operand>" "")))
5854    (clobber (reg:CC FLAGS_REG))]
5855   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5856   [(const_int 0)]
5858   enum machine_mode mode = <MODE>mode;
5859   rtx pat;
5861   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5862     { 
5863       mode = SImode; 
5864       operands[0] = gen_lowpart (mode, operands[0]);
5865       operands[1] = gen_lowpart (mode, operands[1]);
5866       operands[2] = gen_lowpart (mode, operands[2]);
5867     }
5869   pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5871   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5872   DONE;
5875 ;; Convert add to the lea pattern to avoid flags dependency.
5876 (define_split
5877   [(set (match_operand:DI 0 "register_operand" "")
5878         (zero_extend:DI
5879           (plus:SI (match_operand:SI 1 "register_operand" "")
5880                    (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5881    (clobber (reg:CC FLAGS_REG))]
5882   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5883   [(set (match_dup 0)
5884         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5886 (define_insn "*add<mode>_2"
5887   [(set (reg FLAGS_REG)
5888         (compare
5889           (plus:SWI
5890             (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5891             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5892           (const_int 0)))
5893    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5894         (plus:SWI (match_dup 1) (match_dup 2)))]
5895   "ix86_match_ccmode (insn, CCGOCmode)
5896    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5898   switch (get_attr_type (insn))
5899     {
5900     case TYPE_INCDEC:
5901       if (operands[2] == const1_rtx)
5902         return "inc{<imodesuffix>}\t%0";
5903       else
5904         {
5905           gcc_assert (operands[2] == constm1_rtx);
5906           return "dec{<imodesuffix>}\t%0";
5907         }
5909     default:
5910       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5911         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5913       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5914     }
5916   [(set (attr "type")
5917      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5918         (const_string "incdec")
5919         (const_string "alu")))
5920    (set (attr "length_immediate")
5921       (if_then_else
5922         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5923         (const_string "1")
5924         (const_string "*")))
5925    (set_attr "mode" "<MODE>")])
5927 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5928 (define_insn "*addsi_2_zext"
5929   [(set (reg FLAGS_REG)
5930         (compare
5931           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5932                    (match_operand:SI 2 "x86_64_general_operand" "rme"))
5933           (const_int 0)))
5934    (set (match_operand:DI 0 "register_operand" "=r")
5935         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5936   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5937    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5939   switch (get_attr_type (insn))
5940     {
5941     case TYPE_INCDEC:
5942       if (operands[2] == const1_rtx)
5943         return "inc{l}\t%k0";
5944       else
5945         {
5946           gcc_assert (operands[2] == constm1_rtx);
5947           return "dec{l}\t%k0";
5948         }
5950     default:
5951       if (x86_maybe_negate_const_int (&operands[2], SImode))
5952         return "sub{l}\t{%2, %k0|%k0, %2}";
5954       return "add{l}\t{%2, %k0|%k0, %2}";
5955     }
5957   [(set (attr "type")
5958      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5959         (const_string "incdec")
5960         (const_string "alu")))
5961    (set (attr "length_immediate")
5962       (if_then_else
5963         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5964         (const_string "1")
5965         (const_string "*")))
5966    (set_attr "mode" "SI")])
5968 (define_insn "*add<mode>_3"
5969   [(set (reg FLAGS_REG)
5970         (compare
5971           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5972           (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5973    (clobber (match_scratch:SWI 0 "=<r>"))]
5974   "ix86_match_ccmode (insn, CCZmode)
5975    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5977   switch (get_attr_type (insn))
5978     {
5979     case TYPE_INCDEC:
5980       if (operands[2] == const1_rtx)
5981         return "inc{<imodesuffix>}\t%0";
5982       else
5983         {
5984           gcc_assert (operands[2] == constm1_rtx);
5985           return "dec{<imodesuffix>}\t%0";
5986         }
5988     default:
5989       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5990         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5992       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5993     }
5995   [(set (attr "type")
5996      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5997         (const_string "incdec")
5998         (const_string "alu")))
5999    (set (attr "length_immediate")
6000       (if_then_else
6001         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6002         (const_string "1")
6003         (const_string "*")))
6004    (set_attr "mode" "<MODE>")])
6006 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6007 (define_insn "*addsi_3_zext"
6008   [(set (reg FLAGS_REG)
6009         (compare
6010           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme"))
6011           (match_operand:SI 1 "nonimmediate_operand" "%0")))
6012    (set (match_operand:DI 0 "register_operand" "=r")
6013         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6014   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6015    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6017   switch (get_attr_type (insn))
6018     {
6019     case TYPE_INCDEC:
6020       if (operands[2] == const1_rtx)
6021         return "inc{l}\t%k0";
6022       else
6023         {
6024           gcc_assert (operands[2] == constm1_rtx);
6025           return "dec{l}\t%k0";
6026         }
6028     default:
6029       if (x86_maybe_negate_const_int (&operands[2], SImode))
6030         return "sub{l}\t{%2, %k0|%k0, %2}";
6032       return "add{l}\t{%2, %k0|%k0, %2}";
6033     }
6035   [(set (attr "type")
6036      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6037         (const_string "incdec")
6038         (const_string "alu")))
6039    (set (attr "length_immediate")
6040       (if_then_else
6041         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6042         (const_string "1")
6043         (const_string "*")))
6044    (set_attr "mode" "SI")])
6046 ; For comparisons against 1, -1 and 128, we may generate better code
6047 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6048 ; is matched then.  We can't accept general immediate, because for
6049 ; case of overflows,  the result is messed up.
6050 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6051 ; only for comparisons not depending on it.
6053 (define_insn "*adddi_4"
6054   [(set (reg FLAGS_REG)
6055         (compare
6056           (match_operand:DI 1 "nonimmediate_operand" "0")
6057           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6058    (clobber (match_scratch:DI 0 "=rm"))]
6059   "TARGET_64BIT
6060    && ix86_match_ccmode (insn, CCGCmode)"
6062   switch (get_attr_type (insn))
6063     {
6064     case TYPE_INCDEC:
6065       if (operands[2] == constm1_rtx)
6066         return "inc{q}\t%0";
6067       else
6068         {
6069           gcc_assert (operands[2] == const1_rtx);
6070           return "dec{q}\t%0";
6071         }
6073     default:
6074       if (x86_maybe_negate_const_int (&operands[2], DImode))
6075         return "add{q}\t{%2, %0|%0, %2}";
6077       return "sub{q}\t{%2, %0|%0, %2}";
6078     }
6080   [(set (attr "type")
6081      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6082         (const_string "incdec")
6083         (const_string "alu")))
6084    (set (attr "length_immediate")
6085       (if_then_else
6086         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6087         (const_string "1")
6088         (const_string "*")))
6089    (set_attr "mode" "DI")])
6091 ; For comparisons against 1, -1 and 128, we may generate better code
6092 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6093 ; is matched then.  We can't accept general immediate, because for
6094 ; case of overflows,  the result is messed up.
6095 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6096 ; only for comparisons not depending on it.
6098 (define_insn "*add<mode>_4"
6099   [(set (reg FLAGS_REG)
6100         (compare
6101           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6102           (match_operand:SWI124 2 "const_int_operand" "n")))
6103    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6104   "ix86_match_ccmode (insn, CCGCmode)"
6106   switch (get_attr_type (insn))
6107     {
6108     case TYPE_INCDEC:
6109       if (operands[2] == constm1_rtx)
6110         return "inc{<imodesuffix>}\t%0";
6111       else
6112         {
6113           gcc_assert (operands[2] == const1_rtx);
6114           return "dec{<imodesuffix>}\t%0";
6115         }
6117     default:
6118       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6119         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6121       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6122     }
6124   [(set (attr "type")
6125      (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6126         (const_string "incdec")
6127         (const_string "alu")))
6128    (set (attr "length_immediate")
6129       (if_then_else
6130         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6131         (const_string "1")
6132         (const_string "*")))
6133    (set_attr "mode" "<MODE>")])
6135 (define_insn "*add<mode>_5"
6136   [(set (reg FLAGS_REG)
6137         (compare
6138           (plus:SWI
6139             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6140             (match_operand:SWI 2 "<general_operand>" "<g>"))
6141           (const_int 0)))
6142    (clobber (match_scratch:SWI 0 "=<r>"))]
6143   "ix86_match_ccmode (insn, CCGOCmode)
6144    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6146   switch (get_attr_type (insn))
6147     {
6148     case TYPE_INCDEC:
6149       if (operands[2] == const1_rtx)
6150         return "inc{<imodesuffix>}\t%0";
6151       else
6152         {
6153           gcc_assert (operands[2] == constm1_rtx);
6154           return "dec{<imodesuffix>}\t%0";
6155         }
6157     default:
6158       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6159         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6161       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6162     }
6164   [(set (attr "type")
6165      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6166         (const_string "incdec")
6167         (const_string "alu")))
6168    (set (attr "length_immediate")
6169       (if_then_else
6170         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6171         (const_string "1")
6172         (const_string "*")))
6173    (set_attr "mode" "<MODE>")])
6175 (define_insn "*addqi_ext_1_rex64"
6176   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6177                          (const_int 8)
6178                          (const_int 8))
6179         (plus:SI
6180           (zero_extract:SI
6181             (match_operand 1 "ext_register_operand" "0")
6182             (const_int 8)
6183             (const_int 8))
6184           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6185    (clobber (reg:CC FLAGS_REG))]
6186   "TARGET_64BIT"
6188   switch (get_attr_type (insn))
6189     {
6190     case TYPE_INCDEC:
6191       if (operands[2] == const1_rtx)
6192         return "inc{b}\t%h0";
6193       else
6194         {
6195           gcc_assert (operands[2] == constm1_rtx);
6196           return "dec{b}\t%h0";
6197         }
6199     default:
6200       return "add{b}\t{%2, %h0|%h0, %2}";
6201     }
6203   [(set (attr "type")
6204      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6205         (const_string "incdec")
6206         (const_string "alu")))
6207    (set_attr "modrm" "1")
6208    (set_attr "mode" "QI")])
6210 (define_insn "addqi_ext_1"
6211   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6212                          (const_int 8)
6213                          (const_int 8))
6214         (plus:SI
6215           (zero_extract:SI
6216             (match_operand 1 "ext_register_operand" "0")
6217             (const_int 8)
6218             (const_int 8))
6219           (match_operand:QI 2 "general_operand" "Qmn")))
6220    (clobber (reg:CC FLAGS_REG))]
6221   "!TARGET_64BIT"
6223   switch (get_attr_type (insn))
6224     {
6225     case TYPE_INCDEC:
6226       if (operands[2] == const1_rtx)
6227         return "inc{b}\t%h0";
6228       else
6229         {
6230           gcc_assert (operands[2] == constm1_rtx);
6231           return "dec{b}\t%h0";
6232         }
6234     default:
6235       return "add{b}\t{%2, %h0|%h0, %2}";
6236     }
6238   [(set (attr "type")
6239      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6240         (const_string "incdec")
6241         (const_string "alu")))
6242    (set_attr "modrm" "1")
6243    (set_attr "mode" "QI")])
6245 (define_insn "*addqi_ext_2"
6246   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6247                          (const_int 8)
6248                          (const_int 8))
6249         (plus:SI
6250           (zero_extract:SI
6251             (match_operand 1 "ext_register_operand" "%0")
6252             (const_int 8)
6253             (const_int 8))
6254           (zero_extract:SI
6255             (match_operand 2 "ext_register_operand" "Q")
6256             (const_int 8)
6257             (const_int 8))))
6258    (clobber (reg:CC FLAGS_REG))]
6259   ""
6260   "add{b}\t{%h2, %h0|%h0, %h2}"
6261   [(set_attr "type" "alu")
6262    (set_attr "mode" "QI")])
6264 ;; The lea patterns for modes less than 32 bits need to be matched by
6265 ;; several insns converted to real lea by splitters.
6267 (define_insn_and_split "*lea_general_1"
6268   [(set (match_operand 0 "register_operand" "=r")
6269         (plus (plus (match_operand 1 "index_register_operand" "l")
6270                     (match_operand 2 "register_operand" "r"))
6271               (match_operand 3 "immediate_operand" "i")))]
6272   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6273    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6274    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6275    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6276    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6277        || GET_MODE (operands[3]) == VOIDmode)"
6278   "#"
6279   "&& reload_completed"
6280   [(const_int 0)]
6282   enum machine_mode mode = SImode;
6283   rtx pat;
6285   operands[0] = gen_lowpart (mode, operands[0]);
6286   operands[1] = gen_lowpart (mode, operands[1]);
6287   operands[2] = gen_lowpart (mode, operands[2]);
6288   operands[3] = gen_lowpart (mode, operands[3]);
6290   pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6291                       operands[3]);
6293   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6294   DONE;
6296   [(set_attr "type" "lea")
6297    (set_attr "mode" "SI")])
6299 (define_insn_and_split "*lea_general_2"
6300   [(set (match_operand 0 "register_operand" "=r")
6301         (plus (mult (match_operand 1 "index_register_operand" "l")
6302                     (match_operand 2 "const248_operand" "n"))
6303               (match_operand 3 "nonmemory_operand" "ri")))]
6304   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6305    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6306    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6307    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6308        || GET_MODE (operands[3]) == VOIDmode)"
6309   "#"
6310   "&& reload_completed"
6311   [(const_int 0)]
6313   enum machine_mode mode = SImode;
6314   rtx pat;
6316   operands[0] = gen_lowpart (mode, operands[0]);
6317   operands[1] = gen_lowpart (mode, operands[1]);
6318   operands[3] = gen_lowpart (mode, operands[3]);
6320   pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6321                       operands[3]);
6323   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6324   DONE;
6326   [(set_attr "type" "lea")
6327    (set_attr "mode" "SI")])
6329 (define_insn_and_split "*lea_general_3"
6330   [(set (match_operand 0 "register_operand" "=r")
6331         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6332                           (match_operand 2 "const248_operand" "n"))
6333                     (match_operand 3 "register_operand" "r"))
6334               (match_operand 4 "immediate_operand" "i")))]
6335   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6336    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6337    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6338    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6339   "#"
6340   "&& reload_completed"
6341   [(const_int 0)]
6343   enum machine_mode mode = SImode;
6344   rtx pat;
6346   operands[0] = gen_lowpart (mode, operands[0]);
6347   operands[1] = gen_lowpart (mode, operands[1]);
6348   operands[3] = gen_lowpart (mode, operands[3]);
6349   operands[4] = gen_lowpart (mode, operands[4]);
6351   pat = gen_rtx_PLUS (mode,
6352                       gen_rtx_PLUS (mode,
6353                                     gen_rtx_MULT (mode, operands[1],
6354                                                         operands[2]),
6355                                     operands[3]),
6356                       operands[4]);
6358   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6359   DONE;
6361   [(set_attr "type" "lea")
6362    (set_attr "mode" "SI")])
6364 (define_insn_and_split "*lea_general_4"
6365   [(set (match_operand 0 "register_operand" "=r")
6366         (any_or (ashift
6367                   (match_operand 1 "index_register_operand" "l")
6368                   (match_operand 2 "const_int_operand" "n"))
6369                 (match_operand 3 "const_int_operand" "n")))]
6370   "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6371       && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6372     || GET_MODE (operands[0]) == SImode
6373     || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6374    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6375    && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6376    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6377        < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6378   "#"
6379   "&& reload_completed"
6380   [(const_int 0)]
6382   enum machine_mode mode = GET_MODE (operands[0]);
6383   rtx pat;
6385   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6386     { 
6387       mode = SImode; 
6388       operands[0] = gen_lowpart (mode, operands[0]);
6389       operands[1] = gen_lowpart (mode, operands[1]);
6390     }
6392   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6394   pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6395                        INTVAL (operands[3]));
6397   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6398   DONE;
6400   [(set_attr "type" "lea")
6401    (set (attr "mode")
6402       (if_then_else (match_operand:DI 0 "" "")
6403         (const_string "DI")
6404         (const_string "SI")))])
6406 ;; Subtract instructions
6408 (define_expand "sub<mode>3"
6409   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6410         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6411                      (match_operand:SDWIM 2 "<general_operand>" "")))]
6412   ""
6413   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6415 (define_insn_and_split "*sub<dwi>3_doubleword"
6416   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6417         (minus:<DWI>
6418           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6419           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6420    (clobber (reg:CC FLAGS_REG))]
6421   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6422   "#"
6423   "reload_completed"
6424   [(parallel [(set (reg:CC FLAGS_REG)
6425                    (compare:CC (match_dup 1) (match_dup 2)))
6426               (set (match_dup 0)
6427                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6428    (parallel [(set (match_dup 3)
6429                    (minus:DWIH
6430                      (match_dup 4)
6431                      (plus:DWIH
6432                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6433                        (match_dup 5))))
6434               (clobber (reg:CC FLAGS_REG))])]
6435   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6437 (define_insn "*sub<mode>_1"
6438   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6439         (minus:SWI
6440           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6441           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6442    (clobber (reg:CC FLAGS_REG))]
6443   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6444   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6445   [(set_attr "type" "alu")
6446    (set_attr "mode" "<MODE>")])
6448 (define_insn "*subsi_1_zext"
6449   [(set (match_operand:DI 0 "register_operand" "=r")
6450         (zero_extend:DI
6451           (minus:SI (match_operand:SI 1 "register_operand" "0")
6452                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6453    (clobber (reg:CC FLAGS_REG))]
6454   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6455   "sub{l}\t{%2, %k0|%k0, %2}"
6456   [(set_attr "type" "alu")
6457    (set_attr "mode" "SI")])
6459 (define_insn "*subqi_1_slp"
6460   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6461         (minus:QI (match_dup 0)
6462                   (match_operand:QI 1 "general_operand" "qn,qm")))
6463    (clobber (reg:CC FLAGS_REG))]
6464   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6465    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6466   "sub{b}\t{%1, %0|%0, %1}"
6467   [(set_attr "type" "alu1")
6468    (set_attr "mode" "QI")])
6470 (define_insn "*sub<mode>_2"
6471   [(set (reg FLAGS_REG)
6472         (compare
6473           (minus:SWI
6474             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6475             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6476           (const_int 0)))
6477    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6478         (minus:SWI (match_dup 1) (match_dup 2)))]
6479   "ix86_match_ccmode (insn, CCGOCmode)
6480    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6481   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6482   [(set_attr "type" "alu")
6483    (set_attr "mode" "<MODE>")])
6485 (define_insn "*subsi_2_zext"
6486   [(set (reg FLAGS_REG)
6487         (compare
6488           (minus:SI (match_operand:SI 1 "register_operand" "0")
6489                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6490           (const_int 0)))
6491    (set (match_operand:DI 0 "register_operand" "=r")
6492         (zero_extend:DI
6493           (minus:SI (match_dup 1)
6494                     (match_dup 2))))]
6495   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6496    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6497   "sub{l}\t{%2, %k0|%k0, %2}"
6498   [(set_attr "type" "alu")
6499    (set_attr "mode" "SI")])
6501 (define_insn "*sub<mode>_3"
6502   [(set (reg FLAGS_REG)
6503         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6504                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6505    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6506         (minus:SWI (match_dup 1) (match_dup 2)))]
6507   "ix86_match_ccmode (insn, CCmode)
6508    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6509   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6510   [(set_attr "type" "alu")
6511    (set_attr "mode" "<MODE>")])
6513 (define_insn "*subsi_3_zext"
6514   [(set (reg FLAGS_REG)
6515         (compare (match_operand:SI 1 "register_operand" "0")
6516                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6517    (set (match_operand:DI 0 "register_operand" "=r")
6518         (zero_extend:DI
6519           (minus:SI (match_dup 1)
6520                     (match_dup 2))))]
6521   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6522    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6523   "sub{l}\t{%2, %1|%1, %2}"
6524   [(set_attr "type" "alu")
6525    (set_attr "mode" "SI")])
6527 ;; Add with carry and subtract with borrow
6529 (define_expand "<plusminus_insn><mode>3_carry"
6530   [(parallel
6531     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6532           (plusminus:SWI
6533             (match_operand:SWI 1 "nonimmediate_operand" "")
6534             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6535                        [(match_operand 3 "flags_reg_operand" "")
6536                         (const_int 0)])
6537                       (match_operand:SWI 2 "<general_operand>" ""))))
6538      (clobber (reg:CC FLAGS_REG))])]
6539   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6541 (define_insn "*<plusminus_insn><mode>3_carry"
6542   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6543         (plusminus:SWI
6544           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6545           (plus:SWI
6546             (match_operator 3 "ix86_carry_flag_operator"
6547              [(reg FLAGS_REG) (const_int 0)])
6548             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6549    (clobber (reg:CC FLAGS_REG))]
6550   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6551   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6552   [(set_attr "type" "alu")
6553    (set_attr "use_carry" "1")
6554    (set_attr "pent_pair" "pu")
6555    (set_attr "mode" "<MODE>")])
6557 (define_insn "*addsi3_carry_zext"
6558   [(set (match_operand:DI 0 "register_operand" "=r")
6559         (zero_extend:DI
6560           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6561                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6562                              [(reg FLAGS_REG) (const_int 0)])
6563                             (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6564    (clobber (reg:CC FLAGS_REG))]
6565   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6566   "adc{l}\t{%2, %k0|%k0, %2}"
6567   [(set_attr "type" "alu")
6568    (set_attr "use_carry" "1")
6569    (set_attr "pent_pair" "pu")
6570    (set_attr "mode" "SI")])
6572 (define_insn "*subsi3_carry_zext"
6573   [(set (match_operand:DI 0 "register_operand" "=r")
6574         (zero_extend:DI
6575           (minus:SI (match_operand:SI 1 "register_operand" "0")
6576                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6577                               [(reg FLAGS_REG) (const_int 0)])
6578                              (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6579    (clobber (reg:CC FLAGS_REG))]
6580   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6581   "sbb{l}\t{%2, %k0|%k0, %2}"
6582   [(set_attr "type" "alu")
6583    (set_attr "pent_pair" "pu")
6584    (set_attr "mode" "SI")])
6586 ;; Overflow setting add and subtract instructions
6588 (define_insn "*add<mode>3_cconly_overflow"
6589   [(set (reg:CCC FLAGS_REG)
6590         (compare:CCC
6591           (plus:SWI
6592             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6593             (match_operand:SWI 2 "<general_operand>" "<g>"))
6594           (match_dup 1)))
6595    (clobber (match_scratch:SWI 0 "=<r>"))]
6596   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6597   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6598   [(set_attr "type" "alu")
6599    (set_attr "mode" "<MODE>")])
6601 (define_insn "*sub<mode>3_cconly_overflow"
6602   [(set (reg:CCC FLAGS_REG)
6603         (compare:CCC
6604           (minus:SWI
6605             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6606             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6607           (match_dup 0)))]
6608   ""
6609   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6610   [(set_attr "type" "icmp")
6611    (set_attr "mode" "<MODE>")])
6613 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6614   [(set (reg:CCC FLAGS_REG)
6615         (compare:CCC
6616             (plusminus:SWI
6617                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6618                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6619             (match_dup 1)))
6620    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6621         (plusminus:SWI (match_dup 1) (match_dup 2)))]
6622   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6623   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6624   [(set_attr "type" "alu")
6625    (set_attr "mode" "<MODE>")])
6627 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6628   [(set (reg:CCC FLAGS_REG)
6629         (compare:CCC
6630           (plusminus:SI
6631             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6632             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6633           (match_dup 1)))
6634    (set (match_operand:DI 0 "register_operand" "=r")
6635         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6636   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6637   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6638   [(set_attr "type" "alu")
6639    (set_attr "mode" "SI")])
6641 ;; The patterns that match these are at the end of this file.
6643 (define_expand "<plusminus_insn>xf3"
6644   [(set (match_operand:XF 0 "register_operand" "")
6645         (plusminus:XF
6646           (match_operand:XF 1 "register_operand" "")
6647           (match_operand:XF 2 "register_operand" "")))]
6648   "TARGET_80387")
6650 (define_expand "<plusminus_insn><mode>3"
6651   [(set (match_operand:MODEF 0 "register_operand" "")
6652         (plusminus:MODEF
6653           (match_operand:MODEF 1 "register_operand" "")
6654           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6655   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6656     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6658 ;; Multiply instructions
6660 (define_expand "mul<mode>3"
6661   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6662                    (mult:SWIM248
6663                      (match_operand:SWIM248 1 "register_operand" "")
6664                      (match_operand:SWIM248 2 "<general_operand>" "")))
6665               (clobber (reg:CC FLAGS_REG))])])
6667 (define_expand "mulqi3"
6668   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6669                    (mult:QI
6670                      (match_operand:QI 1 "register_operand" "")
6671                      (match_operand:QI 2 "nonimmediate_operand" "")))
6672               (clobber (reg:CC FLAGS_REG))])]
6673   "TARGET_QIMODE_MATH")
6675 ;; On AMDFAM10
6676 ;; IMUL reg32/64, reg32/64, imm8        Direct
6677 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6678 ;; IMUL reg32/64, reg32/64, imm32       Direct
6679 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6680 ;; IMUL reg32/64, reg32/64              Direct
6681 ;; IMUL reg32/64, mem32/64              Direct
6683 ;; On BDVER1, all above IMULs use DirectPath
6685 (define_insn "*mul<mode>3_1"
6686   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6687         (mult:SWI48
6688           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6689           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6690    (clobber (reg:CC FLAGS_REG))]
6691   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6692   "@
6693    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6694    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6695    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6696   [(set_attr "type" "imul")
6697    (set_attr "prefix_0f" "0,0,1")
6698    (set (attr "athlon_decode")
6699         (cond [(eq_attr "cpu" "athlon")
6700                   (const_string "vector")
6701                (eq_attr "alternative" "1")
6702                   (const_string "vector")
6703                (and (eq_attr "alternative" "2")
6704                     (match_operand 1 "memory_operand" ""))
6705                   (const_string "vector")]
6706               (const_string "direct")))
6707    (set (attr "amdfam10_decode")
6708         (cond [(and (eq_attr "alternative" "0,1")
6709                     (match_operand 1 "memory_operand" ""))
6710                   (const_string "vector")]
6711               (const_string "direct")))
6712    (set_attr "bdver1_decode" "direct")
6713    (set_attr "mode" "<MODE>")])
6715 (define_insn "*mulsi3_1_zext"
6716   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6717         (zero_extend:DI
6718           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6719                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6720    (clobber (reg:CC FLAGS_REG))]
6721   "TARGET_64BIT
6722    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6723   "@
6724    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6725    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6726    imul{l}\t{%2, %k0|%k0, %2}"
6727   [(set_attr "type" "imul")
6728    (set_attr "prefix_0f" "0,0,1")
6729    (set (attr "athlon_decode")
6730         (cond [(eq_attr "cpu" "athlon")
6731                   (const_string "vector")
6732                (eq_attr "alternative" "1")
6733                   (const_string "vector")
6734                (and (eq_attr "alternative" "2")
6735                     (match_operand 1 "memory_operand" ""))
6736                   (const_string "vector")]
6737               (const_string "direct")))
6738    (set (attr "amdfam10_decode")
6739         (cond [(and (eq_attr "alternative" "0,1")
6740                     (match_operand 1 "memory_operand" ""))
6741                   (const_string "vector")]
6742               (const_string "direct")))
6743    (set_attr "bdver1_decode" "direct")
6744    (set_attr "mode" "SI")])
6746 ;; On AMDFAM10
6747 ;; IMUL reg16, reg16, imm8      VectorPath
6748 ;; IMUL reg16, mem16, imm8      VectorPath
6749 ;; IMUL reg16, reg16, imm16     VectorPath
6750 ;; IMUL reg16, mem16, imm16     VectorPath
6751 ;; IMUL reg16, reg16            Direct
6752 ;; IMUL reg16, mem16            Direct
6754 ;; On BDVER1, all HI MULs use DoublePath
6756 (define_insn "*mulhi3_1"
6757   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6758         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6759                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6760    (clobber (reg:CC FLAGS_REG))]
6761   "TARGET_HIMODE_MATH
6762    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6763   "@
6764    imul{w}\t{%2, %1, %0|%0, %1, %2}
6765    imul{w}\t{%2, %1, %0|%0, %1, %2}
6766    imul{w}\t{%2, %0|%0, %2}"
6767   [(set_attr "type" "imul")
6768    (set_attr "prefix_0f" "0,0,1")
6769    (set (attr "athlon_decode")
6770         (cond [(eq_attr "cpu" "athlon")
6771                   (const_string "vector")
6772                (eq_attr "alternative" "1,2")
6773                   (const_string "vector")]
6774               (const_string "direct")))
6775    (set (attr "amdfam10_decode")
6776         (cond [(eq_attr "alternative" "0,1")
6777                   (const_string "vector")]
6778               (const_string "direct")))
6779    (set_attr "bdver1_decode" "double")
6780    (set_attr "mode" "HI")])
6782 ;;On AMDFAM10 and BDVER1
6783 ;; MUL reg8     Direct
6784 ;; MUL mem8     Direct
6786 (define_insn "*mulqi3_1"
6787   [(set (match_operand:QI 0 "register_operand" "=a")
6788         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6789                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6790    (clobber (reg:CC FLAGS_REG))]
6791   "TARGET_QIMODE_MATH
6792    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6793   "mul{b}\t%2"
6794   [(set_attr "type" "imul")
6795    (set_attr "length_immediate" "0")
6796    (set (attr "athlon_decode")
6797      (if_then_else (eq_attr "cpu" "athlon")
6798         (const_string "vector")
6799         (const_string "direct")))
6800    (set_attr "amdfam10_decode" "direct")
6801    (set_attr "bdver1_decode" "direct")
6802    (set_attr "mode" "QI")])
6804 (define_expand "<u>mul<mode><dwi>3"
6805   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6806                    (mult:<DWI>
6807                      (any_extend:<DWI>
6808                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
6809                      (any_extend:<DWI>
6810                        (match_operand:DWIH 2 "register_operand" ""))))
6811               (clobber (reg:CC FLAGS_REG))])])
6813 (define_expand "<u>mulqihi3"
6814   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6815                    (mult:HI
6816                      (any_extend:HI
6817                        (match_operand:QI 1 "nonimmediate_operand" ""))
6818                      (any_extend:HI
6819                        (match_operand:QI 2 "register_operand" ""))))
6820               (clobber (reg:CC FLAGS_REG))])]
6821   "TARGET_QIMODE_MATH")
6823 (define_insn "*bmi2_umulditi3_1"
6824   [(set (match_operand:DI 0 "register_operand" "=r")
6825         (mult:DI
6826           (match_operand:DI 2 "nonimmediate_operand" "%d")
6827           (match_operand:DI 3 "nonimmediate_operand" "rm")))
6828    (set (match_operand:DI 1 "register_operand" "=r")
6829         (truncate:DI
6830           (lshiftrt:TI
6831             (mult:TI (zero_extend:TI (match_dup 2))
6832                      (zero_extend:TI (match_dup 3)))
6833             (const_int 64))))]
6834   "TARGET_64BIT && TARGET_BMI2
6835    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6836   "mulx\t{%3, %0, %1|%1, %0, %3}"
6837   [(set_attr "type" "imulx")
6838    (set_attr "prefix" "vex")
6839    (set_attr "mode" "DI")])
6841 (define_insn "*bmi2_umulsidi3_1"
6842   [(set (match_operand:SI 0 "register_operand" "=r")
6843         (mult:SI
6844           (match_operand:SI 2 "nonimmediate_operand" "%d")
6845           (match_operand:SI 3 "nonimmediate_operand" "rm")))
6846    (set (match_operand:SI 1 "register_operand" "=r")
6847         (truncate:SI
6848           (lshiftrt:DI
6849             (mult:DI (zero_extend:DI (match_dup 2))
6850                      (zero_extend:DI (match_dup 3)))
6851             (const_int 32))))]
6852   "!TARGET_64BIT && TARGET_BMI2
6853    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6854   "mulx\t{%3, %0, %1|%1, %0, %3}"
6855   [(set_attr "type" "imulx")
6856    (set_attr "prefix" "vex")
6857    (set_attr "mode" "SI")])
6859 (define_insn "*umul<mode><dwi>3_1"
6860   [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6861         (mult:<DWI>
6862           (zero_extend:<DWI>
6863             (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6864           (zero_extend:<DWI>
6865             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6866    (clobber (reg:CC FLAGS_REG))]
6867   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6868   "@
6869    mul{<imodesuffix>}\t%2
6870    #"
6871   [(set_attr "isa" "*,bmi2")
6872    (set_attr "type" "imul,imulx")
6873    (set_attr "length_immediate" "0,*")
6874    (set (attr "athlon_decode")
6875         (cond [(eq_attr "alternative" "0")
6876                  (if_then_else (eq_attr "cpu" "athlon")
6877                    (const_string "vector")
6878                    (const_string "double"))]
6879               (const_string "*")))
6880    (set_attr "amdfam10_decode" "double,*")
6881    (set_attr "bdver1_decode" "direct,*")
6882    (set_attr "prefix" "orig,vex")
6883    (set_attr "mode" "<MODE>")])
6885 ;; Convert mul to the mulx pattern to avoid flags dependency.
6886 (define_split
6887  [(set (match_operand:<DWI> 0 "register_operand" "")
6888        (mult:<DWI>
6889          (zero_extend:<DWI>
6890            (match_operand:DWIH 1 "register_operand" ""))
6891          (zero_extend:<DWI>
6892            (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6893   (clobber (reg:CC FLAGS_REG))]
6894  "TARGET_BMI2 && reload_completed
6895   && true_regnum (operands[1]) == DX_REG"
6896   [(parallel [(set (match_dup 3)
6897                    (mult:DWIH (match_dup 1) (match_dup 2)))
6898               (set (match_dup 4)
6899                    (truncate:DWIH
6900                      (lshiftrt:<DWI>
6901                        (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6902                                    (zero_extend:<DWI> (match_dup 2)))
6903                        (match_dup 5))))])]
6905   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6907   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6910 (define_insn "*mul<mode><dwi>3_1"
6911   [(set (match_operand:<DWI> 0 "register_operand" "=A")
6912         (mult:<DWI>
6913           (sign_extend:<DWI>
6914             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6915           (sign_extend:<DWI>
6916             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6917    (clobber (reg:CC FLAGS_REG))]
6918   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6919   "imul{<imodesuffix>}\t%2"
6920   [(set_attr "type" "imul")
6921    (set_attr "length_immediate" "0")
6922    (set (attr "athlon_decode")
6923      (if_then_else (eq_attr "cpu" "athlon")
6924         (const_string "vector")
6925         (const_string "double")))
6926    (set_attr "amdfam10_decode" "double")
6927    (set_attr "bdver1_decode" "direct")
6928    (set_attr "mode" "<MODE>")])
6930 (define_insn "*<u>mulqihi3_1"
6931   [(set (match_operand:HI 0 "register_operand" "=a")
6932         (mult:HI
6933           (any_extend:HI
6934             (match_operand:QI 1 "nonimmediate_operand" "%0"))
6935           (any_extend:HI
6936             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6937    (clobber (reg:CC FLAGS_REG))]
6938   "TARGET_QIMODE_MATH
6939    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6940   "<sgnprefix>mul{b}\t%2"
6941   [(set_attr "type" "imul")
6942    (set_attr "length_immediate" "0")
6943    (set (attr "athlon_decode")
6944      (if_then_else (eq_attr "cpu" "athlon")
6945         (const_string "vector")
6946         (const_string "direct")))
6947    (set_attr "amdfam10_decode" "direct")
6948    (set_attr "bdver1_decode" "direct")
6949    (set_attr "mode" "QI")])
6951 (define_expand "<s>mul<mode>3_highpart"
6952   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6953                    (truncate:SWI48
6954                      (lshiftrt:<DWI>
6955                        (mult:<DWI>
6956                          (any_extend:<DWI>
6957                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
6958                          (any_extend:<DWI>
6959                            (match_operand:SWI48 2 "register_operand" "")))
6960                        (match_dup 4))))
6961               (clobber (match_scratch:SWI48 3 ""))
6962               (clobber (reg:CC FLAGS_REG))])]
6963   ""
6964   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6966 (define_insn "*<s>muldi3_highpart_1"
6967   [(set (match_operand:DI 0 "register_operand" "=d")
6968         (truncate:DI
6969           (lshiftrt:TI
6970             (mult:TI
6971               (any_extend:TI
6972                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6973               (any_extend:TI
6974                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6975             (const_int 64))))
6976    (clobber (match_scratch:DI 3 "=1"))
6977    (clobber (reg:CC FLAGS_REG))]
6978   "TARGET_64BIT
6979    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6980   "<sgnprefix>mul{q}\t%2"
6981   [(set_attr "type" "imul")
6982    (set_attr "length_immediate" "0")
6983    (set (attr "athlon_decode")
6984      (if_then_else (eq_attr "cpu" "athlon")
6985         (const_string "vector")
6986         (const_string "double")))
6987    (set_attr "amdfam10_decode" "double")
6988    (set_attr "bdver1_decode" "direct")
6989    (set_attr "mode" "DI")])
6991 (define_insn "*<s>mulsi3_highpart_1"
6992   [(set (match_operand:SI 0 "register_operand" "=d")
6993         (truncate:SI
6994           (lshiftrt:DI
6995             (mult:DI
6996               (any_extend:DI
6997                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6998               (any_extend:DI
6999                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7000             (const_int 32))))
7001    (clobber (match_scratch:SI 3 "=1"))
7002    (clobber (reg:CC FLAGS_REG))]
7003   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7004   "<sgnprefix>mul{l}\t%2"
7005   [(set_attr "type" "imul")
7006    (set_attr "length_immediate" "0")
7007    (set (attr "athlon_decode")
7008      (if_then_else (eq_attr "cpu" "athlon")
7009         (const_string "vector")
7010         (const_string "double")))
7011    (set_attr "amdfam10_decode" "double")
7012    (set_attr "bdver1_decode" "direct")
7013    (set_attr "mode" "SI")])
7015 (define_insn "*<s>mulsi3_highpart_zext"
7016   [(set (match_operand:DI 0 "register_operand" "=d")
7017         (zero_extend:DI (truncate:SI
7018           (lshiftrt:DI
7019             (mult:DI (any_extend:DI
7020                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7021                      (any_extend:DI
7022                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7023             (const_int 32)))))
7024    (clobber (match_scratch:SI 3 "=1"))
7025    (clobber (reg:CC FLAGS_REG))]
7026   "TARGET_64BIT
7027    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7028   "<sgnprefix>mul{l}\t%2"
7029   [(set_attr "type" "imul")
7030    (set_attr "length_immediate" "0")
7031    (set (attr "athlon_decode")
7032      (if_then_else (eq_attr "cpu" "athlon")
7033         (const_string "vector")
7034         (const_string "double")))
7035    (set_attr "amdfam10_decode" "double")
7036    (set_attr "bdver1_decode" "direct")
7037    (set_attr "mode" "SI")])
7039 ;; The patterns that match these are at the end of this file.
7041 (define_expand "mulxf3"
7042   [(set (match_operand:XF 0 "register_operand" "")
7043         (mult:XF (match_operand:XF 1 "register_operand" "")
7044                  (match_operand:XF 2 "register_operand" "")))]
7045   "TARGET_80387")
7047 (define_expand "mul<mode>3"
7048   [(set (match_operand:MODEF 0 "register_operand" "")
7049         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7050                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7051   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7052     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7054 ;; Divide instructions
7056 ;; The patterns that match these are at the end of this file.
7058 (define_expand "divxf3"
7059   [(set (match_operand:XF 0 "register_operand" "")
7060         (div:XF (match_operand:XF 1 "register_operand" "")
7061                 (match_operand:XF 2 "register_operand" "")))]
7062   "TARGET_80387")
7064 (define_expand "divdf3"
7065   [(set (match_operand:DF 0 "register_operand" "")
7066         (div:DF (match_operand:DF 1 "register_operand" "")
7067                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7068    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7069     || (TARGET_SSE2 && TARGET_SSE_MATH)")
7071 (define_expand "divsf3"
7072   [(set (match_operand:SF 0 "register_operand" "")
7073         (div:SF (match_operand:SF 1 "register_operand" "")
7074                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7075   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7076     || TARGET_SSE_MATH"
7078   if (TARGET_SSE_MATH
7079       && TARGET_RECIP_DIV
7080       && optimize_insn_for_speed_p ()
7081       && flag_finite_math_only && !flag_trapping_math
7082       && flag_unsafe_math_optimizations)
7083     {
7084       ix86_emit_swdivsf (operands[0], operands[1],
7085                          operands[2], SFmode);
7086       DONE;
7087     }
7090 ;; Divmod instructions.
7092 (define_expand "divmod<mode>4"
7093   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7094                    (div:SWIM248
7095                      (match_operand:SWIM248 1 "register_operand" "")
7096                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7097               (set (match_operand:SWIM248 3 "register_operand" "")
7098                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7099               (clobber (reg:CC FLAGS_REG))])])
7101 ;; Split with 8bit unsigned divide:
7102 ;;      if (dividend an divisor are in [0-255])
7103 ;;         use 8bit unsigned integer divide
7104 ;;       else
7105 ;;         use original integer divide
7106 (define_split
7107   [(set (match_operand:SWI48 0 "register_operand" "")
7108         (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7109                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7110    (set (match_operand:SWI48 1 "register_operand" "")
7111         (mod:SWI48 (match_dup 2) (match_dup 3)))
7112    (clobber (reg:CC FLAGS_REG))]
7113   "TARGET_USE_8BIT_IDIV
7114    && TARGET_QIMODE_MATH
7115    && can_create_pseudo_p ()
7116    && !optimize_insn_for_size_p ()"
7117   [(const_int 0)]
7118   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7120 (define_insn_and_split "divmod<mode>4_1"
7121   [(set (match_operand:SWI48 0 "register_operand" "=a")
7122         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7123                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7124    (set (match_operand:SWI48 1 "register_operand" "=&d")
7125         (mod:SWI48 (match_dup 2) (match_dup 3)))
7126    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7127    (clobber (reg:CC FLAGS_REG))]
7128   ""
7129   "#"
7130   "reload_completed"
7131   [(parallel [(set (match_dup 1)
7132                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7133               (clobber (reg:CC FLAGS_REG))])
7134    (parallel [(set (match_dup 0)
7135                    (div:SWI48 (match_dup 2) (match_dup 3)))
7136               (set (match_dup 1)
7137                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7138               (use (match_dup 1))
7139               (clobber (reg:CC FLAGS_REG))])]
7141   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7143   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7144     operands[4] = operands[2];
7145   else
7146     {
7147       /* Avoid use of cltd in favor of a mov+shift.  */
7148       emit_move_insn (operands[1], operands[2]);
7149       operands[4] = operands[1];
7150     }
7152   [(set_attr "type" "multi")
7153    (set_attr "mode" "<MODE>")])
7155 (define_insn_and_split "*divmod<mode>4"
7156   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7157         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7158                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7159    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7160         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7161    (clobber (reg:CC FLAGS_REG))]
7162   ""
7163   "#"
7164   "reload_completed"
7165   [(parallel [(set (match_dup 1)
7166                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7167               (clobber (reg:CC FLAGS_REG))])
7168    (parallel [(set (match_dup 0)
7169                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7170               (set (match_dup 1)
7171                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7172               (use (match_dup 1))
7173               (clobber (reg:CC FLAGS_REG))])]
7175   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7177   if (<MODE>mode != HImode
7178       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7179     operands[4] = operands[2];
7180   else
7181     {
7182       /* Avoid use of cltd in favor of a mov+shift.  */
7183       emit_move_insn (operands[1], operands[2]);
7184       operands[4] = operands[1];
7185     }
7187   [(set_attr "type" "multi")
7188    (set_attr "mode" "<MODE>")])
7190 (define_insn "*divmod<mode>4_noext"
7191   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7192         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7193                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7194    (set (match_operand:SWIM248 1 "register_operand" "=d")
7195         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7196    (use (match_operand:SWIM248 4 "register_operand" "1"))
7197    (clobber (reg:CC FLAGS_REG))]
7198   ""
7199   "idiv{<imodesuffix>}\t%3"
7200   [(set_attr "type" "idiv")
7201    (set_attr "mode" "<MODE>")])
7203 (define_expand "divmodqi4"
7204   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7205                    (div:QI
7206                      (match_operand:QI 1 "register_operand" "")
7207                      (match_operand:QI 2 "nonimmediate_operand" "")))
7208               (set (match_operand:QI 3 "register_operand" "")
7209                    (mod:QI (match_dup 1) (match_dup 2)))
7210               (clobber (reg:CC FLAGS_REG))])]
7211   "TARGET_QIMODE_MATH"
7213   rtx div, mod, insn;
7214   rtx tmp0, tmp1;
7215   
7216   tmp0 = gen_reg_rtx (HImode);
7217   tmp1 = gen_reg_rtx (HImode);
7219   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7220      in AX.  */
7221   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7222   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7224   /* Extract remainder from AH.  */
7225   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7226   insn = emit_move_insn (operands[3], tmp1);
7228   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7229   set_unique_reg_note (insn, REG_EQUAL, mod);
7231   /* Extract quotient from AL.  */
7232   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7234   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7235   set_unique_reg_note (insn, REG_EQUAL, div);
7237   DONE;
7240 ;; Divide AX by r/m8, with result stored in
7241 ;; AL <- Quotient
7242 ;; AH <- Remainder
7243 ;; Change div/mod to HImode and extend the second argument to HImode
7244 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7245 ;; combine may fail.
7246 (define_insn "divmodhiqi3"
7247   [(set (match_operand:HI 0 "register_operand" "=a")
7248         (ior:HI
7249           (ashift:HI
7250             (zero_extend:HI
7251               (truncate:QI
7252                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7253                         (sign_extend:HI
7254                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7255             (const_int 8))
7256           (zero_extend:HI
7257             (truncate:QI
7258               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7259    (clobber (reg:CC FLAGS_REG))]
7260   "TARGET_QIMODE_MATH"
7261   "idiv{b}\t%2"
7262   [(set_attr "type" "idiv")
7263    (set_attr "mode" "QI")])
7265 (define_expand "udivmod<mode>4"
7266   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7267                    (udiv:SWIM248
7268                      (match_operand:SWIM248 1 "register_operand" "")
7269                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7270               (set (match_operand:SWIM248 3 "register_operand" "")
7271                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7272               (clobber (reg:CC FLAGS_REG))])])
7274 ;; Split with 8bit unsigned divide:
7275 ;;      if (dividend an divisor are in [0-255])
7276 ;;         use 8bit unsigned integer divide
7277 ;;       else
7278 ;;         use original integer divide
7279 (define_split
7280   [(set (match_operand:SWI48 0 "register_operand" "")
7281         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7282                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7283    (set (match_operand:SWI48 1 "register_operand" "")
7284         (umod:SWI48 (match_dup 2) (match_dup 3)))
7285    (clobber (reg:CC FLAGS_REG))]
7286   "TARGET_USE_8BIT_IDIV
7287    && TARGET_QIMODE_MATH
7288    && can_create_pseudo_p ()
7289    && !optimize_insn_for_size_p ()"
7290   [(const_int 0)]
7291   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7293 (define_insn_and_split "udivmod<mode>4_1"
7294   [(set (match_operand:SWI48 0 "register_operand" "=a")
7295         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7296                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7297    (set (match_operand:SWI48 1 "register_operand" "=&d")
7298         (umod:SWI48 (match_dup 2) (match_dup 3)))
7299    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7300    (clobber (reg:CC FLAGS_REG))]
7301   ""
7302   "#"
7303   "reload_completed"
7304   [(set (match_dup 1) (const_int 0))
7305    (parallel [(set (match_dup 0)
7306                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7307               (set (match_dup 1)
7308                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7309               (use (match_dup 1))
7310               (clobber (reg:CC FLAGS_REG))])]
7311   ""
7312   [(set_attr "type" "multi")
7313    (set_attr "mode" "<MODE>")])
7315 (define_insn_and_split "*udivmod<mode>4"
7316   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7317         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7318                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7319    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7320         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7321    (clobber (reg:CC FLAGS_REG))]
7322   ""
7323   "#"
7324   "reload_completed"
7325   [(set (match_dup 1) (const_int 0))
7326    (parallel [(set (match_dup 0)
7327                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7328               (set (match_dup 1)
7329                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7330               (use (match_dup 1))
7331               (clobber (reg:CC FLAGS_REG))])]
7332   ""
7333   [(set_attr "type" "multi")
7334    (set_attr "mode" "<MODE>")])
7336 (define_insn "*udivmod<mode>4_noext"
7337   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7338         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7339                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7340    (set (match_operand:SWIM248 1 "register_operand" "=d")
7341         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7342    (use (match_operand:SWIM248 4 "register_operand" "1"))
7343    (clobber (reg:CC FLAGS_REG))]
7344   ""
7345   "div{<imodesuffix>}\t%3"
7346   [(set_attr "type" "idiv")
7347    (set_attr "mode" "<MODE>")])
7349 (define_expand "udivmodqi4"
7350   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7351                    (udiv:QI
7352                      (match_operand:QI 1 "register_operand" "")
7353                      (match_operand:QI 2 "nonimmediate_operand" "")))
7354               (set (match_operand:QI 3 "register_operand" "")
7355                    (umod:QI (match_dup 1) (match_dup 2)))
7356               (clobber (reg:CC FLAGS_REG))])]
7357   "TARGET_QIMODE_MATH"
7359   rtx div, mod, insn;
7360   rtx tmp0, tmp1;
7361   
7362   tmp0 = gen_reg_rtx (HImode);
7363   tmp1 = gen_reg_rtx (HImode);
7365   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7366      in AX.  */
7367   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7368   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7370   /* Extract remainder from AH.  */
7371   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7372   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7373   insn = emit_move_insn (operands[3], tmp1);
7375   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7376   set_unique_reg_note (insn, REG_EQUAL, mod);
7378   /* Extract quotient from AL.  */
7379   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7381   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7382   set_unique_reg_note (insn, REG_EQUAL, div);
7384   DONE;
7387 (define_insn "udivmodhiqi3"
7388   [(set (match_operand:HI 0 "register_operand" "=a")
7389         (ior:HI
7390           (ashift:HI
7391             (zero_extend:HI
7392               (truncate:QI
7393                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7394                         (zero_extend:HI
7395                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7396             (const_int 8))
7397           (zero_extend:HI
7398             (truncate:QI
7399               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7400    (clobber (reg:CC FLAGS_REG))]
7401   "TARGET_QIMODE_MATH"
7402   "div{b}\t%2"
7403   [(set_attr "type" "idiv")
7404    (set_attr "mode" "QI")])
7406 ;; We cannot use div/idiv for double division, because it causes
7407 ;; "division by zero" on the overflow and that's not what we expect
7408 ;; from truncate.  Because true (non truncating) double division is
7409 ;; never generated, we can't create this insn anyway.
7411 ;(define_insn ""
7412 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7413 ;       (truncate:SI
7414 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7415 ;                  (zero_extend:DI
7416 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7417 ;   (set (match_operand:SI 3 "register_operand" "=d")
7418 ;       (truncate:SI
7419 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7420 ;   (clobber (reg:CC FLAGS_REG))]
7421 ;  ""
7422 ;  "div{l}\t{%2, %0|%0, %2}"
7423 ;  [(set_attr "type" "idiv")])
7425 ;;- Logical AND instructions
7427 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7428 ;; Note that this excludes ah.
7430 (define_expand "testsi_ccno_1"
7431   [(set (reg:CCNO FLAGS_REG)
7432         (compare:CCNO
7433           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7434                   (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7435           (const_int 0)))])
7437 (define_expand "testqi_ccz_1"
7438   [(set (reg:CCZ FLAGS_REG)
7439         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7440                              (match_operand:QI 1 "nonmemory_operand" ""))
7441                  (const_int 0)))])
7443 (define_expand "testdi_ccno_1"
7444   [(set (reg:CCNO FLAGS_REG)
7445         (compare:CCNO
7446           (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7447                   (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7448           (const_int 0)))]
7449   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7451 (define_insn "*testdi_1"
7452   [(set (reg FLAGS_REG)
7453         (compare
7454          (and:DI
7455           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7456           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7457          (const_int 0)))]
7458   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7459    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7460   "@
7461    test{l}\t{%k1, %k0|%k0, %k1}
7462    test{l}\t{%k1, %k0|%k0, %k1}
7463    test{q}\t{%1, %0|%0, %1}
7464    test{q}\t{%1, %0|%0, %1}
7465    test{q}\t{%1, %0|%0, %1}"
7466   [(set_attr "type" "test")
7467    (set_attr "modrm" "0,1,0,1,1")
7468    (set_attr "mode" "SI,SI,DI,DI,DI")])
7470 (define_insn "*testqi_1_maybe_si"
7471   [(set (reg FLAGS_REG)
7472         (compare
7473           (and:QI
7474             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7475             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7476           (const_int 0)))]
7477    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7478     && ix86_match_ccmode (insn,
7479                          CONST_INT_P (operands[1])
7480                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7482   if (which_alternative == 3)
7483     {
7484       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7485         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7486       return "test{l}\t{%1, %k0|%k0, %1}";
7487     }
7488   return "test{b}\t{%1, %0|%0, %1}";
7490   [(set_attr "type" "test")
7491    (set_attr "modrm" "0,1,1,1")
7492    (set_attr "mode" "QI,QI,QI,SI")
7493    (set_attr "pent_pair" "uv,np,uv,np")])
7495 (define_insn "*test<mode>_1"
7496   [(set (reg FLAGS_REG)
7497         (compare
7498          (and:SWI124
7499           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7500           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7501          (const_int 0)))]
7502   "ix86_match_ccmode (insn, CCNOmode)
7503    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7504   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7505   [(set_attr "type" "test")
7506    (set_attr "modrm" "0,1,1")
7507    (set_attr "mode" "<MODE>")
7508    (set_attr "pent_pair" "uv,np,uv")])
7510 (define_expand "testqi_ext_ccno_0"
7511   [(set (reg:CCNO FLAGS_REG)
7512         (compare:CCNO
7513           (and:SI
7514             (zero_extract:SI
7515               (match_operand 0 "ext_register_operand" "")
7516               (const_int 8)
7517               (const_int 8))
7518             (match_operand 1 "const_int_operand" ""))
7519           (const_int 0)))])
7521 (define_insn "*testqi_ext_0"
7522   [(set (reg FLAGS_REG)
7523         (compare
7524           (and:SI
7525             (zero_extract:SI
7526               (match_operand 0 "ext_register_operand" "Q")
7527               (const_int 8)
7528               (const_int 8))
7529             (match_operand 1 "const_int_operand" "n"))
7530           (const_int 0)))]
7531   "ix86_match_ccmode (insn, CCNOmode)"
7532   "test{b}\t{%1, %h0|%h0, %1}"
7533   [(set_attr "type" "test")
7534    (set_attr "mode" "QI")
7535    (set_attr "length_immediate" "1")
7536    (set_attr "modrm" "1")
7537    (set_attr "pent_pair" "np")])
7539 (define_insn "*testqi_ext_1_rex64"
7540   [(set (reg FLAGS_REG)
7541         (compare
7542           (and:SI
7543             (zero_extract:SI
7544               (match_operand 0 "ext_register_operand" "Q")
7545               (const_int 8)
7546               (const_int 8))
7547             (zero_extend:SI
7548               (match_operand:QI 1 "register_operand" "Q")))
7549           (const_int 0)))]
7550   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7551   "test{b}\t{%1, %h0|%h0, %1}"
7552   [(set_attr "type" "test")
7553    (set_attr "mode" "QI")])
7555 (define_insn "*testqi_ext_1"
7556   [(set (reg FLAGS_REG)
7557         (compare
7558           (and:SI
7559             (zero_extract:SI
7560               (match_operand 0 "ext_register_operand" "Q")
7561               (const_int 8)
7562               (const_int 8))
7563             (zero_extend:SI
7564               (match_operand:QI 1 "general_operand" "Qm")))
7565           (const_int 0)))]
7566   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7567   "test{b}\t{%1, %h0|%h0, %1}"
7568   [(set_attr "type" "test")
7569    (set_attr "mode" "QI")])
7571 (define_insn "*testqi_ext_2"
7572   [(set (reg FLAGS_REG)
7573         (compare
7574           (and:SI
7575             (zero_extract:SI
7576               (match_operand 0 "ext_register_operand" "Q")
7577               (const_int 8)
7578               (const_int 8))
7579             (zero_extract:SI
7580               (match_operand 1 "ext_register_operand" "Q")
7581               (const_int 8)
7582               (const_int 8)))
7583           (const_int 0)))]
7584   "ix86_match_ccmode (insn, CCNOmode)"
7585   "test{b}\t{%h1, %h0|%h0, %h1}"
7586   [(set_attr "type" "test")
7587    (set_attr "mode" "QI")])
7589 (define_insn "*testqi_ext_3_rex64"
7590   [(set (reg FLAGS_REG)
7591         (compare (zero_extract:DI
7592                    (match_operand 0 "nonimmediate_operand" "rm")
7593                    (match_operand:DI 1 "const_int_operand" "")
7594                    (match_operand:DI 2 "const_int_operand" ""))
7595                  (const_int 0)))]
7596   "TARGET_64BIT
7597    && ix86_match_ccmode (insn, CCNOmode)
7598    && INTVAL (operands[1]) > 0
7599    && INTVAL (operands[2]) >= 0
7600    /* Ensure that resulting mask is zero or sign extended operand.  */
7601    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7602        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7603            && INTVAL (operands[1]) > 32))
7604    && (GET_MODE (operands[0]) == SImode
7605        || GET_MODE (operands[0]) == DImode
7606        || GET_MODE (operands[0]) == HImode
7607        || GET_MODE (operands[0]) == QImode)"
7608   "#")
7610 ;; Combine likes to form bit extractions for some tests.  Humor it.
7611 (define_insn "*testqi_ext_3"
7612   [(set (reg FLAGS_REG)
7613         (compare (zero_extract:SI
7614                    (match_operand 0 "nonimmediate_operand" "rm")
7615                    (match_operand:SI 1 "const_int_operand" "")
7616                    (match_operand:SI 2 "const_int_operand" ""))
7617                  (const_int 0)))]
7618   "ix86_match_ccmode (insn, CCNOmode)
7619    && INTVAL (operands[1]) > 0
7620    && INTVAL (operands[2]) >= 0
7621    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7622    && (GET_MODE (operands[0]) == SImode
7623        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7624        || GET_MODE (operands[0]) == HImode
7625        || GET_MODE (operands[0]) == QImode)"
7626   "#")
7628 (define_split
7629   [(set (match_operand 0 "flags_reg_operand" "")
7630         (match_operator 1 "compare_operator"
7631           [(zero_extract
7632              (match_operand 2 "nonimmediate_operand" "")
7633              (match_operand 3 "const_int_operand" "")
7634              (match_operand 4 "const_int_operand" ""))
7635            (const_int 0)]))]
7636   "ix86_match_ccmode (insn, CCNOmode)"
7637   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7639   rtx val = operands[2];
7640   HOST_WIDE_INT len = INTVAL (operands[3]);
7641   HOST_WIDE_INT pos = INTVAL (operands[4]);
7642   HOST_WIDE_INT mask;
7643   enum machine_mode mode, submode;
7645   mode = GET_MODE (val);
7646   if (MEM_P (val))
7647     {
7648       /* ??? Combine likes to put non-volatile mem extractions in QImode
7649          no matter the size of the test.  So find a mode that works.  */
7650       if (! MEM_VOLATILE_P (val))
7651         {
7652           mode = smallest_mode_for_size (pos + len, MODE_INT);
7653           val = adjust_address (val, mode, 0);
7654         }
7655     }
7656   else if (GET_CODE (val) == SUBREG
7657            && (submode = GET_MODE (SUBREG_REG (val)),
7658                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7659            && pos + len <= GET_MODE_BITSIZE (submode)
7660            && GET_MODE_CLASS (submode) == MODE_INT)
7661     {
7662       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7663       mode = submode;
7664       val = SUBREG_REG (val);
7665     }
7666   else if (mode == HImode && pos + len <= 8)
7667     {
7668       /* Small HImode tests can be converted to QImode.  */
7669       mode = QImode;
7670       val = gen_lowpart (QImode, val);
7671     }
7673   if (len == HOST_BITS_PER_WIDE_INT)
7674     mask = -1;
7675   else
7676     mask = ((HOST_WIDE_INT)1 << len) - 1;
7677   mask <<= pos;
7679   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7682 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7683 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7684 ;; this is relatively important trick.
7685 ;; Do the conversion only post-reload to avoid limiting of the register class
7686 ;; to QI regs.
7687 (define_split
7688   [(set (match_operand 0 "flags_reg_operand" "")
7689         (match_operator 1 "compare_operator"
7690           [(and (match_operand 2 "register_operand" "")
7691                 (match_operand 3 "const_int_operand" ""))
7692            (const_int 0)]))]
7693    "reload_completed
7694     && QI_REG_P (operands[2])
7695     && GET_MODE (operands[2]) != QImode
7696     && ((ix86_match_ccmode (insn, CCZmode)
7697          && !(INTVAL (operands[3]) & ~(255 << 8)))
7698         || (ix86_match_ccmode (insn, CCNOmode)
7699             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7700   [(set (match_dup 0)
7701         (match_op_dup 1
7702           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7703                    (match_dup 3))
7704            (const_int 0)]))]
7705   "operands[2] = gen_lowpart (SImode, operands[2]);
7706    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7708 (define_split
7709   [(set (match_operand 0 "flags_reg_operand" "")
7710         (match_operator 1 "compare_operator"
7711           [(and (match_operand 2 "nonimmediate_operand" "")
7712                 (match_operand 3 "const_int_operand" ""))
7713            (const_int 0)]))]
7714    "reload_completed
7715     && GET_MODE (operands[2]) != QImode
7716     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7717     && ((ix86_match_ccmode (insn, CCZmode)
7718          && !(INTVAL (operands[3]) & ~255))
7719         || (ix86_match_ccmode (insn, CCNOmode)
7720             && !(INTVAL (operands[3]) & ~127)))"
7721   [(set (match_dup 0)
7722         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7723                          (const_int 0)]))]
7724   "operands[2] = gen_lowpart (QImode, operands[2]);
7725    operands[3] = gen_lowpart (QImode, operands[3]);")
7727 ;; %%% This used to optimize known byte-wide and operations to memory,
7728 ;; and sometimes to QImode registers.  If this is considered useful,
7729 ;; it should be done with splitters.
7731 (define_expand "and<mode>3"
7732   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7733         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7734                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7735   ""
7736   "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7738 (define_insn "*anddi_1"
7739   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7740         (and:DI
7741          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7742          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7743    (clobber (reg:CC FLAGS_REG))]
7744   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7746   switch (get_attr_type (insn))
7747     {
7748     case TYPE_IMOVX:
7749       {
7750         enum machine_mode mode;
7752         gcc_assert (CONST_INT_P (operands[2]));
7753         if (INTVAL (operands[2]) == 0xff)
7754           mode = QImode;
7755         else
7756           {
7757             gcc_assert (INTVAL (operands[2]) == 0xffff);
7758             mode = HImode;
7759           }
7761         operands[1] = gen_lowpart (mode, operands[1]);
7762         if (mode == QImode)
7763           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7764         else
7765           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7766       }
7768     default:
7769       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7770       if (get_attr_mode (insn) == MODE_SI)
7771         return "and{l}\t{%k2, %k0|%k0, %k2}";
7772       else
7773         return "and{q}\t{%2, %0|%0, %2}";
7774     }
7776   [(set_attr "type" "alu,alu,alu,imovx")
7777    (set_attr "length_immediate" "*,*,*,0")
7778    (set (attr "prefix_rex")
7779      (if_then_else
7780        (and (eq_attr "type" "imovx")
7781             (and (match_test "INTVAL (operands[2]) == 0xff")
7782                  (match_operand 1 "ext_QIreg_operand" "")))
7783        (const_string "1")
7784        (const_string "*")))
7785    (set_attr "mode" "SI,DI,DI,SI")])
7787 (define_insn "*andsi_1"
7788   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7789         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7790                 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7791    (clobber (reg:CC FLAGS_REG))]
7792   "ix86_binary_operator_ok (AND, SImode, operands)"
7794   switch (get_attr_type (insn))
7795     {
7796     case TYPE_IMOVX:
7797       {
7798         enum machine_mode mode;
7800         gcc_assert (CONST_INT_P (operands[2]));
7801         if (INTVAL (operands[2]) == 0xff)
7802           mode = QImode;
7803         else
7804           {
7805             gcc_assert (INTVAL (operands[2]) == 0xffff);
7806             mode = HImode;
7807           }
7809         operands[1] = gen_lowpart (mode, operands[1]);
7810         if (mode == QImode)
7811           return "movz{bl|x}\t{%1, %0|%0, %1}";
7812         else
7813           return "movz{wl|x}\t{%1, %0|%0, %1}";
7814       }
7816     default:
7817       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7818       return "and{l}\t{%2, %0|%0, %2}";
7819     }
7821   [(set_attr "type" "alu,alu,imovx")
7822    (set (attr "prefix_rex")
7823      (if_then_else
7824        (and (eq_attr "type" "imovx")
7825             (and (match_test "INTVAL (operands[2]) == 0xff")
7826                  (match_operand 1 "ext_QIreg_operand" "")))
7827        (const_string "1")
7828        (const_string "*")))
7829    (set_attr "length_immediate" "*,*,0")
7830    (set_attr "mode" "SI")])
7832 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7833 (define_insn "*andsi_1_zext"
7834   [(set (match_operand:DI 0 "register_operand" "=r")
7835         (zero_extend:DI
7836           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7837                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7838    (clobber (reg:CC FLAGS_REG))]
7839   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7840   "and{l}\t{%2, %k0|%k0, %2}"
7841   [(set_attr "type" "alu")
7842    (set_attr "mode" "SI")])
7844 (define_insn "*andhi_1"
7845   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7846         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7847                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7848    (clobber (reg:CC FLAGS_REG))]
7849   "ix86_binary_operator_ok (AND, HImode, operands)"
7851   switch (get_attr_type (insn))
7852     {
7853     case TYPE_IMOVX:
7854       gcc_assert (CONST_INT_P (operands[2]));
7855       gcc_assert (INTVAL (operands[2]) == 0xff);
7856       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7858     default:
7859       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7861       return "and{w}\t{%2, %0|%0, %2}";
7862     }
7864   [(set_attr "type" "alu,alu,imovx")
7865    (set_attr "length_immediate" "*,*,0")
7866    (set (attr "prefix_rex")
7867      (if_then_else
7868        (and (eq_attr "type" "imovx")
7869             (match_operand 1 "ext_QIreg_operand" ""))
7870        (const_string "1")
7871        (const_string "*")))
7872    (set_attr "mode" "HI,HI,SI")])
7874 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7875 (define_insn "*andqi_1"
7876   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7877         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7878                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7879    (clobber (reg:CC FLAGS_REG))]
7880   "ix86_binary_operator_ok (AND, QImode, operands)"
7881   "@
7882    and{b}\t{%2, %0|%0, %2}
7883    and{b}\t{%2, %0|%0, %2}
7884    and{l}\t{%k2, %k0|%k0, %k2}"
7885   [(set_attr "type" "alu")
7886    (set_attr "mode" "QI,QI,SI")])
7888 (define_insn "*andqi_1_slp"
7889   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7890         (and:QI (match_dup 0)
7891                 (match_operand:QI 1 "general_operand" "qn,qmn")))
7892    (clobber (reg:CC FLAGS_REG))]
7893   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7894    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7895   "and{b}\t{%1, %0|%0, %1}"
7896   [(set_attr "type" "alu1")
7897    (set_attr "mode" "QI")])
7899 (define_split
7900   [(set (match_operand 0 "register_operand" "")
7901         (and (match_dup 0)
7902              (const_int -65536)))
7903    (clobber (reg:CC FLAGS_REG))]
7904   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7905     || optimize_function_for_size_p (cfun)"
7906   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7907   "operands[1] = gen_lowpart (HImode, operands[0]);")
7909 (define_split
7910   [(set (match_operand 0 "ext_register_operand" "")
7911         (and (match_dup 0)
7912              (const_int -256)))
7913    (clobber (reg:CC FLAGS_REG))]
7914   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7915    && reload_completed"
7916   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7917   "operands[1] = gen_lowpart (QImode, operands[0]);")
7919 (define_split
7920   [(set (match_operand 0 "ext_register_operand" "")
7921         (and (match_dup 0)
7922              (const_int -65281)))
7923    (clobber (reg:CC FLAGS_REG))]
7924   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7925    && reload_completed"
7926   [(parallel [(set (zero_extract:SI (match_dup 0)
7927                                     (const_int 8)
7928                                     (const_int 8))
7929                    (xor:SI
7930                      (zero_extract:SI (match_dup 0)
7931                                       (const_int 8)
7932                                       (const_int 8))
7933                      (zero_extract:SI (match_dup 0)
7934                                       (const_int 8)
7935                                       (const_int 8))))
7936               (clobber (reg:CC FLAGS_REG))])]
7937   "operands[0] = gen_lowpart (SImode, operands[0]);")
7939 (define_insn "*anddi_2"
7940   [(set (reg FLAGS_REG)
7941         (compare
7942          (and:DI
7943           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7944           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7945          (const_int 0)))
7946    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7947         (and:DI (match_dup 1) (match_dup 2)))]
7948   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7949    && ix86_binary_operator_ok (AND, DImode, operands)"
7950   "@
7951    and{l}\t{%k2, %k0|%k0, %k2}
7952    and{q}\t{%2, %0|%0, %2}
7953    and{q}\t{%2, %0|%0, %2}"
7954   [(set_attr "type" "alu")
7955    (set_attr "mode" "SI,DI,DI")])
7957 (define_insn "*andqi_2_maybe_si"
7958   [(set (reg FLAGS_REG)
7959         (compare (and:QI
7960                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7961                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7962                  (const_int 0)))
7963    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7964         (and:QI (match_dup 1) (match_dup 2)))]
7965   "ix86_binary_operator_ok (AND, QImode, operands)
7966    && ix86_match_ccmode (insn,
7967                          CONST_INT_P (operands[2])
7968                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7970   if (which_alternative == 2)
7971     {
7972       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7973         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7974       return "and{l}\t{%2, %k0|%k0, %2}";
7975     }
7976   return "and{b}\t{%2, %0|%0, %2}";
7978   [(set_attr "type" "alu")
7979    (set_attr "mode" "QI,QI,SI")])
7981 (define_insn "*and<mode>_2"
7982   [(set (reg FLAGS_REG)
7983         (compare (and:SWI124
7984                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7985                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7986                  (const_int 0)))
7987    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7988         (and:SWI124 (match_dup 1) (match_dup 2)))]
7989   "ix86_match_ccmode (insn, CCNOmode)
7990    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7991   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7992   [(set_attr "type" "alu")
7993    (set_attr "mode" "<MODE>")])
7995 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7996 (define_insn "*andsi_2_zext"
7997   [(set (reg FLAGS_REG)
7998         (compare (and:SI
7999                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8000                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
8001                  (const_int 0)))
8002    (set (match_operand:DI 0 "register_operand" "=r")
8003         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8004   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8005    && ix86_binary_operator_ok (AND, SImode, operands)"
8006   "and{l}\t{%2, %k0|%k0, %2}"
8007   [(set_attr "type" "alu")
8008    (set_attr "mode" "SI")])
8010 (define_insn "*andqi_2_slp"
8011   [(set (reg FLAGS_REG)
8012         (compare (and:QI
8013                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8014                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8015                  (const_int 0)))
8016    (set (strict_low_part (match_dup 0))
8017         (and:QI (match_dup 0) (match_dup 1)))]
8018   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8019    && ix86_match_ccmode (insn, CCNOmode)
8020    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8021   "and{b}\t{%1, %0|%0, %1}"
8022   [(set_attr "type" "alu1")
8023    (set_attr "mode" "QI")])
8025 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8026 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8027 ;; for a QImode operand, which of course failed.
8028 (define_insn "andqi_ext_0"
8029   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8030                          (const_int 8)
8031                          (const_int 8))
8032         (and:SI
8033           (zero_extract:SI
8034             (match_operand 1 "ext_register_operand" "0")
8035             (const_int 8)
8036             (const_int 8))
8037           (match_operand 2 "const_int_operand" "n")))
8038    (clobber (reg:CC FLAGS_REG))]
8039   ""
8040   "and{b}\t{%2, %h0|%h0, %2}"
8041   [(set_attr "type" "alu")
8042    (set_attr "length_immediate" "1")
8043    (set_attr "modrm" "1")
8044    (set_attr "mode" "QI")])
8046 ;; Generated by peephole translating test to and.  This shows up
8047 ;; often in fp comparisons.
8048 (define_insn "*andqi_ext_0_cc"
8049   [(set (reg FLAGS_REG)
8050         (compare
8051           (and:SI
8052             (zero_extract:SI
8053               (match_operand 1 "ext_register_operand" "0")
8054               (const_int 8)
8055               (const_int 8))
8056             (match_operand 2 "const_int_operand" "n"))
8057           (const_int 0)))
8058    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8059                          (const_int 8)
8060                          (const_int 8))
8061         (and:SI
8062           (zero_extract:SI
8063             (match_dup 1)
8064             (const_int 8)
8065             (const_int 8))
8066           (match_dup 2)))]
8067   "ix86_match_ccmode (insn, CCNOmode)"
8068   "and{b}\t{%2, %h0|%h0, %2}"
8069   [(set_attr "type" "alu")
8070    (set_attr "length_immediate" "1")
8071    (set_attr "modrm" "1")
8072    (set_attr "mode" "QI")])
8074 (define_insn "*andqi_ext_1_rex64"
8075   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8076                          (const_int 8)
8077                          (const_int 8))
8078         (and:SI
8079           (zero_extract:SI
8080             (match_operand 1 "ext_register_operand" "0")
8081             (const_int 8)
8082             (const_int 8))
8083           (zero_extend:SI
8084             (match_operand 2 "ext_register_operand" "Q"))))
8085    (clobber (reg:CC FLAGS_REG))]
8086   "TARGET_64BIT"
8087   "and{b}\t{%2, %h0|%h0, %2}"
8088   [(set_attr "type" "alu")
8089    (set_attr "length_immediate" "0")
8090    (set_attr "mode" "QI")])
8092 (define_insn "*andqi_ext_1"
8093   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8094                          (const_int 8)
8095                          (const_int 8))
8096         (and:SI
8097           (zero_extract:SI
8098             (match_operand 1 "ext_register_operand" "0")
8099             (const_int 8)
8100             (const_int 8))
8101           (zero_extend:SI
8102             (match_operand:QI 2 "general_operand" "Qm"))))
8103    (clobber (reg:CC FLAGS_REG))]
8104   "!TARGET_64BIT"
8105   "and{b}\t{%2, %h0|%h0, %2}"
8106   [(set_attr "type" "alu")
8107    (set_attr "length_immediate" "0")
8108    (set_attr "mode" "QI")])
8110 (define_insn "*andqi_ext_2"
8111   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8112                          (const_int 8)
8113                          (const_int 8))
8114         (and:SI
8115           (zero_extract:SI
8116             (match_operand 1 "ext_register_operand" "%0")
8117             (const_int 8)
8118             (const_int 8))
8119           (zero_extract:SI
8120             (match_operand 2 "ext_register_operand" "Q")
8121             (const_int 8)
8122             (const_int 8))))
8123    (clobber (reg:CC FLAGS_REG))]
8124   ""
8125   "and{b}\t{%h2, %h0|%h0, %h2}"
8126   [(set_attr "type" "alu")
8127    (set_attr "length_immediate" "0")
8128    (set_attr "mode" "QI")])
8130 ;; Convert wide AND instructions with immediate operand to shorter QImode
8131 ;; equivalents when possible.
8132 ;; Don't do the splitting with memory operands, since it introduces risk
8133 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8134 ;; for size, but that can (should?) be handled by generic code instead.
8135 (define_split
8136   [(set (match_operand 0 "register_operand" "")
8137         (and (match_operand 1 "register_operand" "")
8138              (match_operand 2 "const_int_operand" "")))
8139    (clobber (reg:CC FLAGS_REG))]
8140    "reload_completed
8141     && QI_REG_P (operands[0])
8142     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8143     && !(~INTVAL (operands[2]) & ~(255 << 8))
8144     && GET_MODE (operands[0]) != QImode"
8145   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8146                    (and:SI (zero_extract:SI (match_dup 1)
8147                                             (const_int 8) (const_int 8))
8148                            (match_dup 2)))
8149               (clobber (reg:CC FLAGS_REG))])]
8150   "operands[0] = gen_lowpart (SImode, operands[0]);
8151    operands[1] = gen_lowpart (SImode, operands[1]);
8152    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8154 ;; Since AND can be encoded with sign extended immediate, this is only
8155 ;; profitable when 7th bit is not set.
8156 (define_split
8157   [(set (match_operand 0 "register_operand" "")
8158         (and (match_operand 1 "general_operand" "")
8159              (match_operand 2 "const_int_operand" "")))
8160    (clobber (reg:CC FLAGS_REG))]
8161    "reload_completed
8162     && ANY_QI_REG_P (operands[0])
8163     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8164     && !(~INTVAL (operands[2]) & ~255)
8165     && !(INTVAL (operands[2]) & 128)
8166     && GET_MODE (operands[0]) != QImode"
8167   [(parallel [(set (strict_low_part (match_dup 0))
8168                    (and:QI (match_dup 1)
8169                            (match_dup 2)))
8170               (clobber (reg:CC FLAGS_REG))])]
8171   "operands[0] = gen_lowpart (QImode, operands[0]);
8172    operands[1] = gen_lowpart (QImode, operands[1]);
8173    operands[2] = gen_lowpart (QImode, operands[2]);")
8175 ;; Logical inclusive and exclusive OR instructions
8177 ;; %%% This used to optimize known byte-wide and operations to memory.
8178 ;; If this is considered useful, it should be done with splitters.
8180 (define_expand "<code><mode>3"
8181   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8182         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8183                      (match_operand:SWIM 2 "<general_operand>" "")))]
8184   ""
8185   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8187 (define_insn "*<code><mode>_1"
8188   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8189         (any_or:SWI248
8190          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8191          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8192    (clobber (reg:CC FLAGS_REG))]
8193   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8194   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8195   [(set_attr "type" "alu")
8196    (set_attr "mode" "<MODE>")])
8198 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8199 (define_insn "*<code>qi_1"
8200   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8201         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8202                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8203    (clobber (reg:CC FLAGS_REG))]
8204   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8205   "@
8206    <logic>{b}\t{%2, %0|%0, %2}
8207    <logic>{b}\t{%2, %0|%0, %2}
8208    <logic>{l}\t{%k2, %k0|%k0, %k2}"
8209   [(set_attr "type" "alu")
8210    (set_attr "mode" "QI,QI,SI")])
8212 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8213 (define_insn "*<code>si_1_zext"
8214   [(set (match_operand:DI 0 "register_operand" "=r")
8215         (zero_extend:DI
8216          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8217                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8218    (clobber (reg:CC FLAGS_REG))]
8219   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8220   "<logic>{l}\t{%2, %k0|%k0, %2}"
8221   [(set_attr "type" "alu")
8222    (set_attr "mode" "SI")])
8224 (define_insn "*<code>si_1_zext_imm"
8225   [(set (match_operand:DI 0 "register_operand" "=r")
8226         (any_or:DI
8227          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8228          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8229    (clobber (reg:CC FLAGS_REG))]
8230   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8231   "<logic>{l}\t{%2, %k0|%k0, %2}"
8232   [(set_attr "type" "alu")
8233    (set_attr "mode" "SI")])
8235 (define_insn "*<code>qi_1_slp"
8236   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8237         (any_or:QI (match_dup 0)
8238                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8239    (clobber (reg:CC FLAGS_REG))]
8240   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8241    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8242   "<logic>{b}\t{%1, %0|%0, %1}"
8243   [(set_attr "type" "alu1")
8244    (set_attr "mode" "QI")])
8246 (define_insn "*<code><mode>_2"
8247   [(set (reg FLAGS_REG)
8248         (compare (any_or:SWI
8249                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8250                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8251                  (const_int 0)))
8252    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8253         (any_or:SWI (match_dup 1) (match_dup 2)))]
8254   "ix86_match_ccmode (insn, CCNOmode)
8255    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8256   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8257   [(set_attr "type" "alu")
8258    (set_attr "mode" "<MODE>")])
8260 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8261 ;; ??? Special case for immediate operand is missing - it is tricky.
8262 (define_insn "*<code>si_2_zext"
8263   [(set (reg FLAGS_REG)
8264         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8265                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
8266                  (const_int 0)))
8267    (set (match_operand:DI 0 "register_operand" "=r")
8268         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8269   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8270    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8271   "<logic>{l}\t{%2, %k0|%k0, %2}"
8272   [(set_attr "type" "alu")
8273    (set_attr "mode" "SI")])
8275 (define_insn "*<code>si_2_zext_imm"
8276   [(set (reg FLAGS_REG)
8277         (compare (any_or:SI
8278                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8279                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8280                  (const_int 0)))
8281    (set (match_operand:DI 0 "register_operand" "=r")
8282         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8283   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8284    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8285   "<logic>{l}\t{%2, %k0|%k0, %2}"
8286   [(set_attr "type" "alu")
8287    (set_attr "mode" "SI")])
8289 (define_insn "*<code>qi_2_slp"
8290   [(set (reg FLAGS_REG)
8291         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8292                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8293                  (const_int 0)))
8294    (set (strict_low_part (match_dup 0))
8295         (any_or:QI (match_dup 0) (match_dup 1)))]
8296   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8297    && ix86_match_ccmode (insn, CCNOmode)
8298    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8299   "<logic>{b}\t{%1, %0|%0, %1}"
8300   [(set_attr "type" "alu1")
8301    (set_attr "mode" "QI")])
8303 (define_insn "*<code><mode>_3"
8304   [(set (reg FLAGS_REG)
8305         (compare (any_or:SWI
8306                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8307                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8308                  (const_int 0)))
8309    (clobber (match_scratch:SWI 0 "=<r>"))]
8310   "ix86_match_ccmode (insn, CCNOmode)
8311    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8312   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8313   [(set_attr "type" "alu")
8314    (set_attr "mode" "<MODE>")])
8316 (define_insn "*<code>qi_ext_0"
8317   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8318                          (const_int 8)
8319                          (const_int 8))
8320         (any_or:SI
8321           (zero_extract:SI
8322             (match_operand 1 "ext_register_operand" "0")
8323             (const_int 8)
8324             (const_int 8))
8325           (match_operand 2 "const_int_operand" "n")))
8326    (clobber (reg:CC FLAGS_REG))]
8327   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8328   "<logic>{b}\t{%2, %h0|%h0, %2}"
8329   [(set_attr "type" "alu")
8330    (set_attr "length_immediate" "1")
8331    (set_attr "modrm" "1")
8332    (set_attr "mode" "QI")])
8334 (define_insn "*<code>qi_ext_1_rex64"
8335   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8336                          (const_int 8)
8337                          (const_int 8))
8338         (any_or:SI
8339           (zero_extract:SI
8340             (match_operand 1 "ext_register_operand" "0")
8341             (const_int 8)
8342             (const_int 8))
8343           (zero_extend:SI
8344             (match_operand 2 "ext_register_operand" "Q"))))
8345    (clobber (reg:CC FLAGS_REG))]
8346   "TARGET_64BIT
8347    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8348   "<logic>{b}\t{%2, %h0|%h0, %2}"
8349   [(set_attr "type" "alu")
8350    (set_attr "length_immediate" "0")
8351    (set_attr "mode" "QI")])
8353 (define_insn "*<code>qi_ext_1"
8354   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8355                          (const_int 8)
8356                          (const_int 8))
8357         (any_or:SI
8358           (zero_extract:SI
8359             (match_operand 1 "ext_register_operand" "0")
8360             (const_int 8)
8361             (const_int 8))
8362           (zero_extend:SI
8363             (match_operand:QI 2 "general_operand" "Qm"))))
8364    (clobber (reg:CC FLAGS_REG))]
8365   "!TARGET_64BIT
8366    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8367   "<logic>{b}\t{%2, %h0|%h0, %2}"
8368   [(set_attr "type" "alu")
8369    (set_attr "length_immediate" "0")
8370    (set_attr "mode" "QI")])
8372 (define_insn "*<code>qi_ext_2"
8373   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8374                          (const_int 8)
8375                          (const_int 8))
8376         (any_or:SI
8377           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8378                            (const_int 8)
8379                            (const_int 8))
8380           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8381                            (const_int 8)
8382                            (const_int 8))))
8383    (clobber (reg:CC FLAGS_REG))]
8384   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8385   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8386   [(set_attr "type" "alu")
8387    (set_attr "length_immediate" "0")
8388    (set_attr "mode" "QI")])
8390 (define_split
8391   [(set (match_operand 0 "register_operand" "")
8392         (any_or (match_operand 1 "register_operand" "")
8393                 (match_operand 2 "const_int_operand" "")))
8394    (clobber (reg:CC FLAGS_REG))]
8395    "reload_completed
8396     && QI_REG_P (operands[0])
8397     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8398     && !(INTVAL (operands[2]) & ~(255 << 8))
8399     && GET_MODE (operands[0]) != QImode"
8400   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8401                    (any_or:SI (zero_extract:SI (match_dup 1)
8402                                                (const_int 8) (const_int 8))
8403                               (match_dup 2)))
8404               (clobber (reg:CC FLAGS_REG))])]
8405   "operands[0] = gen_lowpart (SImode, operands[0]);
8406    operands[1] = gen_lowpart (SImode, operands[1]);
8407    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8409 ;; Since OR can be encoded with sign extended immediate, this is only
8410 ;; profitable when 7th bit is set.
8411 (define_split
8412   [(set (match_operand 0 "register_operand" "")
8413         (any_or (match_operand 1 "general_operand" "")
8414                 (match_operand 2 "const_int_operand" "")))
8415    (clobber (reg:CC FLAGS_REG))]
8416    "reload_completed
8417     && ANY_QI_REG_P (operands[0])
8418     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8419     && !(INTVAL (operands[2]) & ~255)
8420     && (INTVAL (operands[2]) & 128)
8421     && GET_MODE (operands[0]) != QImode"
8422   [(parallel [(set (strict_low_part (match_dup 0))
8423                    (any_or:QI (match_dup 1)
8424                               (match_dup 2)))
8425               (clobber (reg:CC FLAGS_REG))])]
8426   "operands[0] = gen_lowpart (QImode, operands[0]);
8427    operands[1] = gen_lowpart (QImode, operands[1]);
8428    operands[2] = gen_lowpart (QImode, operands[2]);")
8430 (define_expand "xorqi_cc_ext_1"
8431   [(parallel [
8432      (set (reg:CCNO FLAGS_REG)
8433           (compare:CCNO
8434             (xor:SI
8435               (zero_extract:SI
8436                 (match_operand 1 "ext_register_operand" "")
8437                 (const_int 8)
8438                 (const_int 8))
8439               (match_operand:QI 2 "general_operand" ""))
8440             (const_int 0)))
8441      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8442                            (const_int 8)
8443                            (const_int 8))
8444           (xor:SI
8445             (zero_extract:SI
8446              (match_dup 1)
8447              (const_int 8)
8448              (const_int 8))
8449             (match_dup 2)))])])
8451 (define_insn "*xorqi_cc_ext_1_rex64"
8452   [(set (reg FLAGS_REG)
8453         (compare
8454           (xor:SI
8455             (zero_extract:SI
8456               (match_operand 1 "ext_register_operand" "0")
8457               (const_int 8)
8458               (const_int 8))
8459             (match_operand:QI 2 "nonmemory_operand" "Qn"))
8460           (const_int 0)))
8461    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8462                          (const_int 8)
8463                          (const_int 8))
8464         (xor:SI
8465           (zero_extract:SI
8466            (match_dup 1)
8467            (const_int 8)
8468            (const_int 8))
8469           (match_dup 2)))]
8470   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8471   "xor{b}\t{%2, %h0|%h0, %2}"
8472   [(set_attr "type" "alu")
8473    (set_attr "modrm" "1")
8474    (set_attr "mode" "QI")])
8476 (define_insn "*xorqi_cc_ext_1"
8477   [(set (reg FLAGS_REG)
8478         (compare
8479           (xor:SI
8480             (zero_extract:SI
8481               (match_operand 1 "ext_register_operand" "0")
8482               (const_int 8)
8483               (const_int 8))
8484             (match_operand:QI 2 "general_operand" "qmn"))
8485           (const_int 0)))
8486    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8487                          (const_int 8)
8488                          (const_int 8))
8489         (xor:SI
8490           (zero_extract:SI
8491            (match_dup 1)
8492            (const_int 8)
8493            (const_int 8))
8494           (match_dup 2)))]
8495   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8496   "xor{b}\t{%2, %h0|%h0, %2}"
8497   [(set_attr "type" "alu")
8498    (set_attr "modrm" "1")
8499    (set_attr "mode" "QI")])
8501 ;; Negation instructions
8503 (define_expand "neg<mode>2"
8504   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8505         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8506   ""
8507   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8509 (define_insn_and_split "*neg<dwi>2_doubleword"
8510   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8511         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8512    (clobber (reg:CC FLAGS_REG))]
8513   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8514   "#"
8515   "reload_completed"
8516   [(parallel
8517     [(set (reg:CCZ FLAGS_REG)
8518           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8519      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8520    (parallel
8521     [(set (match_dup 2)
8522           (plus:DWIH (match_dup 3)
8523                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8524                                 (const_int 0))))
8525      (clobber (reg:CC FLAGS_REG))])
8526    (parallel
8527     [(set (match_dup 2)
8528           (neg:DWIH (match_dup 2)))
8529      (clobber (reg:CC FLAGS_REG))])]
8530   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8532 (define_insn "*neg<mode>2_1"
8533   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8534         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8535    (clobber (reg:CC FLAGS_REG))]
8536   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8537   "neg{<imodesuffix>}\t%0"
8538   [(set_attr "type" "negnot")
8539    (set_attr "mode" "<MODE>")])
8541 ;; Combine is quite creative about this pattern.
8542 (define_insn "*negsi2_1_zext"
8543   [(set (match_operand:DI 0 "register_operand" "=r")
8544         (lshiftrt:DI
8545           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8546                              (const_int 32)))
8547         (const_int 32)))
8548    (clobber (reg:CC FLAGS_REG))]
8549   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8550   "neg{l}\t%k0"
8551   [(set_attr "type" "negnot")
8552    (set_attr "mode" "SI")])
8554 ;; The problem with neg is that it does not perform (compare x 0),
8555 ;; it really performs (compare 0 x), which leaves us with the zero
8556 ;; flag being the only useful item.
8558 (define_insn "*neg<mode>2_cmpz"
8559   [(set (reg:CCZ FLAGS_REG)
8560         (compare:CCZ
8561           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8562                    (const_int 0)))
8563    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8564         (neg:SWI (match_dup 1)))]
8565   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8566   "neg{<imodesuffix>}\t%0"
8567   [(set_attr "type" "negnot")
8568    (set_attr "mode" "<MODE>")])
8570 (define_insn "*negsi2_cmpz_zext"
8571   [(set (reg:CCZ FLAGS_REG)
8572         (compare:CCZ
8573           (lshiftrt:DI
8574             (neg:DI (ashift:DI
8575                       (match_operand:DI 1 "register_operand" "0")
8576                       (const_int 32)))
8577             (const_int 32))
8578           (const_int 0)))
8579    (set (match_operand:DI 0 "register_operand" "=r")
8580         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8581                                         (const_int 32)))
8582                      (const_int 32)))]
8583   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8584   "neg{l}\t%k0"
8585   [(set_attr "type" "negnot")
8586    (set_attr "mode" "SI")])
8588 ;; Changing of sign for FP values is doable using integer unit too.
8590 (define_expand "<code><mode>2"
8591   [(set (match_operand:X87MODEF 0 "register_operand" "")
8592         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8593   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8594   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8596 (define_insn "*absneg<mode>2_mixed"
8597   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8598         (match_operator:MODEF 3 "absneg_operator"
8599           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8600    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8601    (clobber (reg:CC FLAGS_REG))]
8602   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8603   "#")
8605 (define_insn "*absneg<mode>2_sse"
8606   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8607         (match_operator:MODEF 3 "absneg_operator"
8608           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8609    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8610    (clobber (reg:CC FLAGS_REG))]
8611   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8612   "#")
8614 (define_insn "*absneg<mode>2_i387"
8615   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8616         (match_operator:X87MODEF 3 "absneg_operator"
8617           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8618    (use (match_operand 2 "" ""))
8619    (clobber (reg:CC FLAGS_REG))]
8620   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8621   "#")
8623 (define_expand "<code>tf2"
8624   [(set (match_operand:TF 0 "register_operand" "")
8625         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8626   "TARGET_SSE2"
8627   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8629 (define_insn "*absnegtf2_sse"
8630   [(set (match_operand:TF 0 "register_operand" "=x,x")
8631         (match_operator:TF 3 "absneg_operator"
8632           [(match_operand:TF 1 "register_operand" "0,x")]))
8633    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8634    (clobber (reg:CC FLAGS_REG))]
8635   "TARGET_SSE2"
8636   "#")
8638 ;; Splitters for fp abs and neg.
8640 (define_split
8641   [(set (match_operand 0 "fp_register_operand" "")
8642         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8643    (use (match_operand 2 "" ""))
8644    (clobber (reg:CC FLAGS_REG))]
8645   "reload_completed"
8646   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8648 (define_split
8649   [(set (match_operand 0 "register_operand" "")
8650         (match_operator 3 "absneg_operator"
8651           [(match_operand 1 "register_operand" "")]))
8652    (use (match_operand 2 "nonimmediate_operand" ""))
8653    (clobber (reg:CC FLAGS_REG))]
8654   "reload_completed && SSE_REG_P (operands[0])"
8655   [(set (match_dup 0) (match_dup 3))]
8657   enum machine_mode mode = GET_MODE (operands[0]);
8658   enum machine_mode vmode = GET_MODE (operands[2]);
8659   rtx tmp;
8661   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8662   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8663   if (operands_match_p (operands[0], operands[2]))
8664     {
8665       tmp = operands[1];
8666       operands[1] = operands[2];
8667       operands[2] = tmp;
8668     }
8669   if (GET_CODE (operands[3]) == ABS)
8670     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8671   else
8672     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8673   operands[3] = tmp;
8676 (define_split
8677   [(set (match_operand:SF 0 "register_operand" "")
8678         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8679    (use (match_operand:V4SF 2 "" ""))
8680    (clobber (reg:CC FLAGS_REG))]
8681   "reload_completed"
8682   [(parallel [(set (match_dup 0) (match_dup 1))
8683               (clobber (reg:CC FLAGS_REG))])]
8685   rtx tmp;
8686   operands[0] = gen_lowpart (SImode, operands[0]);
8687   if (GET_CODE (operands[1]) == ABS)
8688     {
8689       tmp = gen_int_mode (0x7fffffff, SImode);
8690       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8691     }
8692   else
8693     {
8694       tmp = gen_int_mode (0x80000000, SImode);
8695       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8696     }
8697   operands[1] = tmp;
8700 (define_split
8701   [(set (match_operand:DF 0 "register_operand" "")
8702         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8703    (use (match_operand 2 "" ""))
8704    (clobber (reg:CC FLAGS_REG))]
8705   "reload_completed"
8706   [(parallel [(set (match_dup 0) (match_dup 1))
8707               (clobber (reg:CC FLAGS_REG))])]
8709   rtx tmp;
8710   if (TARGET_64BIT)
8711     {
8712       tmp = gen_lowpart (DImode, operands[0]);
8713       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8714       operands[0] = tmp;
8716       if (GET_CODE (operands[1]) == ABS)
8717         tmp = const0_rtx;
8718       else
8719         tmp = gen_rtx_NOT (DImode, tmp);
8720     }
8721   else
8722     {
8723       operands[0] = gen_highpart (SImode, operands[0]);
8724       if (GET_CODE (operands[1]) == ABS)
8725         {
8726           tmp = gen_int_mode (0x7fffffff, SImode);
8727           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8728         }
8729       else
8730         {
8731           tmp = gen_int_mode (0x80000000, SImode);
8732           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8733         }
8734     }
8735   operands[1] = tmp;
8738 (define_split
8739   [(set (match_operand:XF 0 "register_operand" "")
8740         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8741    (use (match_operand 2 "" ""))
8742    (clobber (reg:CC FLAGS_REG))]
8743   "reload_completed"
8744   [(parallel [(set (match_dup 0) (match_dup 1))
8745               (clobber (reg:CC FLAGS_REG))])]
8747   rtx tmp;
8748   operands[0] = gen_rtx_REG (SImode,
8749                              true_regnum (operands[0])
8750                              + (TARGET_64BIT ? 1 : 2));
8751   if (GET_CODE (operands[1]) == ABS)
8752     {
8753       tmp = GEN_INT (0x7fff);
8754       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8755     }
8756   else
8757     {
8758       tmp = GEN_INT (0x8000);
8759       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8760     }
8761   operands[1] = tmp;
8764 ;; Conditionalize these after reload. If they match before reload, we
8765 ;; lose the clobber and ability to use integer instructions.
8767 (define_insn "*<code><mode>2_1"
8768   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8769         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8770   "TARGET_80387
8771    && (reload_completed
8772        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8773   "f<absneg_mnemonic>"
8774   [(set_attr "type" "fsgn")
8775    (set_attr "mode" "<MODE>")])
8777 (define_insn "*<code>extendsfdf2"
8778   [(set (match_operand:DF 0 "register_operand" "=f")
8779         (absneg:DF (float_extend:DF
8780                      (match_operand:SF 1 "register_operand" "0"))))]
8781   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8782   "f<absneg_mnemonic>"
8783   [(set_attr "type" "fsgn")
8784    (set_attr "mode" "DF")])
8786 (define_insn "*<code>extendsfxf2"
8787   [(set (match_operand:XF 0 "register_operand" "=f")
8788         (absneg:XF (float_extend:XF
8789                      (match_operand:SF 1 "register_operand" "0"))))]
8790   "TARGET_80387"
8791   "f<absneg_mnemonic>"
8792   [(set_attr "type" "fsgn")
8793    (set_attr "mode" "XF")])
8795 (define_insn "*<code>extenddfxf2"
8796   [(set (match_operand:XF 0 "register_operand" "=f")
8797         (absneg:XF (float_extend:XF
8798                      (match_operand:DF 1 "register_operand" "0"))))]
8799   "TARGET_80387"
8800   "f<absneg_mnemonic>"
8801   [(set_attr "type" "fsgn")
8802    (set_attr "mode" "XF")])
8804 ;; Copysign instructions
8806 (define_mode_iterator CSGNMODE [SF DF TF])
8807 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8809 (define_expand "copysign<mode>3"
8810   [(match_operand:CSGNMODE 0 "register_operand" "")
8811    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8812    (match_operand:CSGNMODE 2 "register_operand" "")]
8813   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8814    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8815   "ix86_expand_copysign (operands); DONE;")
8817 (define_insn_and_split "copysign<mode>3_const"
8818   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8819         (unspec:CSGNMODE
8820           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8821            (match_operand:CSGNMODE 2 "register_operand" "0")
8822            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8823           UNSPEC_COPYSIGN))]
8824   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8825    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8826   "#"
8827   "&& reload_completed"
8828   [(const_int 0)]
8829   "ix86_split_copysign_const (operands); DONE;")
8831 (define_insn "copysign<mode>3_var"
8832   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8833         (unspec:CSGNMODE
8834           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8835            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8836            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8837            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8838           UNSPEC_COPYSIGN))
8839    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8840   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8841    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8842   "#")
8844 (define_split
8845   [(set (match_operand:CSGNMODE 0 "register_operand" "")
8846         (unspec:CSGNMODE
8847           [(match_operand:CSGNMODE 2 "register_operand" "")
8848            (match_operand:CSGNMODE 3 "register_operand" "")
8849            (match_operand:<CSGNVMODE> 4 "" "")
8850            (match_operand:<CSGNVMODE> 5 "" "")]
8851           UNSPEC_COPYSIGN))
8852    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8853   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8854     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8855    && reload_completed"
8856   [(const_int 0)]
8857   "ix86_split_copysign_var (operands); DONE;")
8859 ;; One complement instructions
8861 (define_expand "one_cmpl<mode>2"
8862   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8863         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8864   ""
8865   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8867 (define_insn "*one_cmpl<mode>2_1"
8868   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8869         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8870   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8871   "not{<imodesuffix>}\t%0"
8872   [(set_attr "type" "negnot")
8873    (set_attr "mode" "<MODE>")])
8875 ;; %%% Potential partial reg stall on alternative 1.  What to do?
8876 (define_insn "*one_cmplqi2_1"
8877   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8878         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8879   "ix86_unary_operator_ok (NOT, QImode, operands)"
8880   "@
8881    not{b}\t%0
8882    not{l}\t%k0"
8883   [(set_attr "type" "negnot")
8884    (set_attr "mode" "QI,SI")])
8886 ;; ??? Currently never generated - xor is used instead.
8887 (define_insn "*one_cmplsi2_1_zext"
8888   [(set (match_operand:DI 0 "register_operand" "=r")
8889         (zero_extend:DI
8890           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8891   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8892   "not{l}\t%k0"
8893   [(set_attr "type" "negnot")
8894    (set_attr "mode" "SI")])
8896 (define_insn "*one_cmpl<mode>2_2"
8897   [(set (reg FLAGS_REG)
8898         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8899                  (const_int 0)))
8900    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8901         (not:SWI (match_dup 1)))]
8902   "ix86_match_ccmode (insn, CCNOmode)
8903    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8904   "#"
8905   [(set_attr "type" "alu1")
8906    (set_attr "mode" "<MODE>")])
8908 (define_split
8909   [(set (match_operand 0 "flags_reg_operand" "")
8910         (match_operator 2 "compare_operator"
8911           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8912            (const_int 0)]))
8913    (set (match_operand:SWI 1 "nonimmediate_operand" "")
8914         (not:SWI (match_dup 3)))]
8915   "ix86_match_ccmode (insn, CCNOmode)"
8916   [(parallel [(set (match_dup 0)
8917                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8918                                     (const_int 0)]))
8919               (set (match_dup 1)
8920                    (xor:SWI (match_dup 3) (const_int -1)))])])
8922 ;; ??? Currently never generated - xor is used instead.
8923 (define_insn "*one_cmplsi2_2_zext"
8924   [(set (reg FLAGS_REG)
8925         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8926                  (const_int 0)))
8927    (set (match_operand:DI 0 "register_operand" "=r")
8928         (zero_extend:DI (not:SI (match_dup 1))))]
8929   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8930    && ix86_unary_operator_ok (NOT, SImode, operands)"
8931   "#"
8932   [(set_attr "type" "alu1")
8933    (set_attr "mode" "SI")])
8935 (define_split
8936   [(set (match_operand 0 "flags_reg_operand" "")
8937         (match_operator 2 "compare_operator"
8938           [(not:SI (match_operand:SI 3 "register_operand" ""))
8939            (const_int 0)]))
8940    (set (match_operand:DI 1 "register_operand" "")
8941         (zero_extend:DI (not:SI (match_dup 3))))]
8942   "ix86_match_ccmode (insn, CCNOmode)"
8943   [(parallel [(set (match_dup 0)
8944                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8945                                     (const_int 0)]))
8946               (set (match_dup 1)
8947                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8949 ;; Shift instructions
8951 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8952 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
8953 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8954 ;; from the assembler input.
8956 ;; This instruction shifts the target reg/mem as usual, but instead of
8957 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
8958 ;; is a left shift double, bits are taken from the high order bits of
8959 ;; reg, else if the insn is a shift right double, bits are taken from the
8960 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
8961 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8963 ;; Since sh[lr]d does not change the `reg' operand, that is done
8964 ;; separately, making all shifts emit pairs of shift double and normal
8965 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
8966 ;; support a 63 bit shift, each shift where the count is in a reg expands
8967 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8969 ;; If the shift count is a constant, we need never emit more than one
8970 ;; shift pair, instead using moves and sign extension for counts greater
8971 ;; than 31.
8973 (define_expand "ashl<mode>3"
8974   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8975         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8976                       (match_operand:QI 2 "nonmemory_operand" "")))]
8977   ""
8978   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8980 (define_insn "*ashl<mode>3_doubleword"
8981   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8982         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8983                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8984    (clobber (reg:CC FLAGS_REG))]
8985   ""
8986   "#"
8987   [(set_attr "type" "multi")])
8989 (define_split
8990   [(set (match_operand:DWI 0 "register_operand" "")
8991         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8992                     (match_operand:QI 2 "nonmemory_operand" "")))
8993    (clobber (reg:CC FLAGS_REG))]
8994   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8995   [(const_int 0)]
8996   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8998 ;; By default we don't ask for a scratch register, because when DWImode
8999 ;; values are manipulated, registers are already at a premium.  But if
9000 ;; we have one handy, we won't turn it away.
9002 (define_peephole2
9003   [(match_scratch:DWIH 3 "r")
9004    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9005                    (ashift:<DWI>
9006                      (match_operand:<DWI> 1 "nonmemory_operand" "")
9007                      (match_operand:QI 2 "nonmemory_operand" "")))
9008               (clobber (reg:CC FLAGS_REG))])
9009    (match_dup 3)]
9010   "TARGET_CMOVE"
9011   [(const_int 0)]
9012   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9014 (define_insn "x86_64_shld"
9015   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9016         (ior:DI (ashift:DI (match_dup 0)
9017                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9018                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9019                   (minus:QI (const_int 64) (match_dup 2)))))
9020    (clobber (reg:CC FLAGS_REG))]
9021   "TARGET_64BIT"
9022   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9023   [(set_attr "type" "ishift")
9024    (set_attr "prefix_0f" "1")
9025    (set_attr "mode" "DI")
9026    (set_attr "athlon_decode" "vector")
9027    (set_attr "amdfam10_decode" "vector")
9028    (set_attr "bdver1_decode" "vector")])
9030 (define_insn "x86_shld"
9031   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9032         (ior:SI (ashift:SI (match_dup 0)
9033                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9034                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9035                   (minus:QI (const_int 32) (match_dup 2)))))
9036    (clobber (reg:CC FLAGS_REG))]
9037   ""
9038   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9039   [(set_attr "type" "ishift")
9040    (set_attr "prefix_0f" "1")
9041    (set_attr "mode" "SI")
9042    (set_attr "pent_pair" "np")
9043    (set_attr "athlon_decode" "vector")
9044    (set_attr "amdfam10_decode" "vector")
9045    (set_attr "bdver1_decode" "vector")])
9047 (define_expand "x86_shift<mode>_adj_1"
9048   [(set (reg:CCZ FLAGS_REG)
9049         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9050                              (match_dup 4))
9051                      (const_int 0)))
9052    (set (match_operand:SWI48 0 "register_operand" "")
9053         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9054                             (match_operand:SWI48 1 "register_operand" "")
9055                             (match_dup 0)))
9056    (set (match_dup 1)
9057         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9058                             (match_operand:SWI48 3 "register_operand" "r")
9059                             (match_dup 1)))]
9060   "TARGET_CMOVE"
9061   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9063 (define_expand "x86_shift<mode>_adj_2"
9064   [(use (match_operand:SWI48 0 "register_operand" ""))
9065    (use (match_operand:SWI48 1 "register_operand" ""))
9066    (use (match_operand:QI 2 "register_operand" ""))]
9067   ""
9069   rtx label = gen_label_rtx ();
9070   rtx tmp;
9072   emit_insn (gen_testqi_ccz_1 (operands[2],
9073                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9075   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9076   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9077   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9078                               gen_rtx_LABEL_REF (VOIDmode, label),
9079                               pc_rtx);
9080   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9081   JUMP_LABEL (tmp) = label;
9083   emit_move_insn (operands[0], operands[1]);
9084   ix86_expand_clear (operands[1]);
9086   emit_label (label);
9087   LABEL_NUSES (label) = 1;
9089   DONE;
9092 ;; Avoid useless masking of count operand.
9093 (define_insn_and_split "*ashl<mode>3_mask"
9094   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9095         (ashift:SWI48
9096           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9097           (subreg:QI
9098             (and:SI
9099               (match_operand:SI 2 "nonimmediate_operand" "c")
9100               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9101    (clobber (reg:CC FLAGS_REG))]
9102   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9103    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9104       == GET_MODE_BITSIZE (<MODE>mode)-1"
9105   "#"
9106   "&& 1"
9107   [(parallel [(set (match_dup 0)
9108                    (ashift:SWI48 (match_dup 1) (match_dup 2)))
9109               (clobber (reg:CC FLAGS_REG))])]
9111   if (can_create_pseudo_p ())
9112     operands [2] = force_reg (SImode, operands[2]);
9114   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9116   [(set_attr "type" "ishift")
9117    (set_attr "mode" "<MODE>")])
9119 (define_insn "*bmi2_ashl<mode>3_1"
9120   [(set (match_operand:SWI48 0 "register_operand" "=r")
9121         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9122                       (match_operand:SWI48 2 "register_operand" "r")))]
9123   "TARGET_BMI2"
9124   "shlx\t{%2, %1, %0|%0, %1, %2}"
9125   [(set_attr "type" "ishiftx")
9126    (set_attr "mode" "<MODE>")])
9128 (define_insn "*ashl<mode>3_1"
9129   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9130         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9131                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9132    (clobber (reg:CC FLAGS_REG))]
9133   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9135   switch (get_attr_type (insn))
9136     {
9137     case TYPE_LEA:
9138     case TYPE_ISHIFTX:
9139       return "#";
9141     case TYPE_ALU:
9142       gcc_assert (operands[2] == const1_rtx);
9143       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9144       return "add{<imodesuffix>}\t%0, %0";
9146     default:
9147       if (operands[2] == const1_rtx
9148           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9149         return "sal{<imodesuffix>}\t%0";
9150       else
9151         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9152     }
9154   [(set_attr "isa" "*,*,bmi2")
9155    (set (attr "type")
9156      (cond [(eq_attr "alternative" "1")
9157               (const_string "lea")
9158             (eq_attr "alternative" "2")
9159               (const_string "ishiftx")
9160             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9161                       (match_operand 0 "register_operand" ""))
9162                  (match_operand 2 "const1_operand" ""))
9163               (const_string "alu")
9164            ]
9165            (const_string "ishift")))
9166    (set (attr "length_immediate")
9167      (if_then_else
9168        (ior (eq_attr "type" "alu")
9169             (and (eq_attr "type" "ishift")
9170                  (and (match_operand 2 "const1_operand" "")
9171                       (ior (match_test "TARGET_SHIFT1")
9172                            (match_test "optimize_function_for_size_p (cfun)")))))
9173        (const_string "0")
9174        (const_string "*")))
9175    (set_attr "mode" "<MODE>")])
9177 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9178 (define_split
9179   [(set (match_operand:SWI48 0 "register_operand" "")
9180         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9181                       (match_operand:QI 2 "register_operand" "")))
9182    (clobber (reg:CC FLAGS_REG))]
9183   "TARGET_BMI2 && reload_completed"
9184   [(set (match_dup 0)
9185         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9186   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9188 (define_insn "*bmi2_ashlsi3_1_zext"
9189   [(set (match_operand:DI 0 "register_operand" "=r")
9190         (zero_extend:DI
9191           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9192                      (match_operand:SI 2 "register_operand" "r"))))]
9193   "TARGET_64BIT && TARGET_BMI2"
9194   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9195   [(set_attr "type" "ishiftx")
9196    (set_attr "mode" "SI")])
9198 (define_insn "*ashlsi3_1_zext"
9199   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9200         (zero_extend:DI
9201           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9202                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9203    (clobber (reg:CC FLAGS_REG))]
9204   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9206   switch (get_attr_type (insn))
9207     {
9208     case TYPE_LEA:
9209     case TYPE_ISHIFTX:
9210       return "#";
9212     case TYPE_ALU:
9213       gcc_assert (operands[2] == const1_rtx);
9214       return "add{l}\t%k0, %k0";
9216     default:
9217       if (operands[2] == const1_rtx
9218           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9219         return "sal{l}\t%k0";
9220       else
9221         return "sal{l}\t{%2, %k0|%k0, %2}";
9222     }
9224   [(set_attr "isa" "*,*,bmi2")
9225    (set (attr "type")
9226      (cond [(eq_attr "alternative" "1")
9227               (const_string "lea")
9228             (eq_attr "alternative" "2")
9229               (const_string "ishiftx")
9230             (and (match_test "TARGET_DOUBLE_WITH_ADD")
9231                  (match_operand 2 "const1_operand" ""))
9232               (const_string "alu")
9233            ]
9234            (const_string "ishift")))
9235    (set (attr "length_immediate")
9236      (if_then_else
9237        (ior (eq_attr "type" "alu")
9238             (and (eq_attr "type" "ishift")
9239                  (and (match_operand 2 "const1_operand" "")
9240                       (ior (match_test "TARGET_SHIFT1")
9241                            (match_test "optimize_function_for_size_p (cfun)")))))
9242        (const_string "0")
9243        (const_string "*")))
9244    (set_attr "mode" "SI")])
9246 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9247 (define_split
9248   [(set (match_operand:DI 0 "register_operand" "")
9249         (zero_extend:DI
9250           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9251                      (match_operand:QI 2 "register_operand" ""))))
9252    (clobber (reg:CC FLAGS_REG))]
9253   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9254   [(set (match_dup 0)
9255         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9256   "operands[2] = gen_lowpart (SImode, operands[2]);")
9258 (define_insn "*ashlhi3_1"
9259   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9260         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9261                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9262    (clobber (reg:CC FLAGS_REG))]
9263   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9265   switch (get_attr_type (insn))
9266     {
9267     case TYPE_LEA:
9268       return "#";
9270     case TYPE_ALU:
9271       gcc_assert (operands[2] == const1_rtx);
9272       return "add{w}\t%0, %0";
9274     default:
9275       if (operands[2] == const1_rtx
9276           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9277         return "sal{w}\t%0";
9278       else
9279         return "sal{w}\t{%2, %0|%0, %2}";
9280     }
9282   [(set (attr "type")
9283      (cond [(eq_attr "alternative" "1")
9284               (const_string "lea")
9285             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9286                       (match_operand 0 "register_operand" ""))
9287                  (match_operand 2 "const1_operand" ""))
9288               (const_string "alu")
9289            ]
9290            (const_string "ishift")))
9291    (set (attr "length_immediate")
9292      (if_then_else
9293        (ior (eq_attr "type" "alu")
9294             (and (eq_attr "type" "ishift")
9295                  (and (match_operand 2 "const1_operand" "")
9296                       (ior (match_test "TARGET_SHIFT1")
9297                            (match_test "optimize_function_for_size_p (cfun)")))))
9298        (const_string "0")
9299        (const_string "*")))
9300    (set_attr "mode" "HI,SI")])
9302 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9303 (define_insn "*ashlqi3_1"
9304   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9305         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9306                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9307    (clobber (reg:CC FLAGS_REG))]
9308   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9310   switch (get_attr_type (insn))
9311     {
9312     case TYPE_LEA:
9313       return "#";
9315     case TYPE_ALU:
9316       gcc_assert (operands[2] == const1_rtx);
9317       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9318         return "add{l}\t%k0, %k0";
9319       else
9320         return "add{b}\t%0, %0";
9322     default:
9323       if (operands[2] == const1_rtx
9324           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9325         {
9326           if (get_attr_mode (insn) == MODE_SI)
9327             return "sal{l}\t%k0";
9328           else
9329             return "sal{b}\t%0";
9330         }
9331       else
9332         {
9333           if (get_attr_mode (insn) == MODE_SI)
9334             return "sal{l}\t{%2, %k0|%k0, %2}";
9335           else
9336             return "sal{b}\t{%2, %0|%0, %2}";
9337         }
9338     }
9340   [(set (attr "type")
9341      (cond [(eq_attr "alternative" "2")
9342               (const_string "lea")
9343             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9344                       (match_operand 0 "register_operand" ""))
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" "QI,SI,SI")])
9360 (define_insn "*ashlqi3_1_slp"
9361   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9362         (ashift:QI (match_dup 0)
9363                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9364    (clobber (reg:CC FLAGS_REG))]
9365   "(optimize_function_for_size_p (cfun)
9366     || !TARGET_PARTIAL_FLAG_REG_STALL
9367     || (operands[1] == const1_rtx
9368         && (TARGET_SHIFT1
9369             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9371   switch (get_attr_type (insn))
9372     {
9373     case TYPE_ALU:
9374       gcc_assert (operands[1] == const1_rtx);
9375       return "add{b}\t%0, %0";
9377     default:
9378       if (operands[1] == const1_rtx
9379           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9380         return "sal{b}\t%0";
9381       else
9382         return "sal{b}\t{%1, %0|%0, %1}";
9383     }
9385   [(set (attr "type")
9386      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9387                       (match_operand 0 "register_operand" ""))
9388                  (match_operand 1 "const1_operand" ""))
9389               (const_string "alu")
9390            ]
9391            (const_string "ishift1")))
9392    (set (attr "length_immediate")
9393      (if_then_else
9394        (ior (eq_attr "type" "alu")
9395             (and (eq_attr "type" "ishift1")
9396                  (and (match_operand 1 "const1_operand" "")
9397                       (ior (match_test "TARGET_SHIFT1")
9398                            (match_test "optimize_function_for_size_p (cfun)")))))
9399        (const_string "0")
9400        (const_string "*")))
9401    (set_attr "mode" "QI")])
9403 ;; Convert ashift to the lea pattern to avoid flags dependency.
9404 (define_split
9405   [(set (match_operand 0 "register_operand" "")
9406         (ashift (match_operand 1 "index_register_operand" "")
9407                 (match_operand:QI 2 "const_int_operand" "")))
9408    (clobber (reg:CC FLAGS_REG))]
9409   "GET_MODE (operands[0]) == GET_MODE (operands[1])
9410    && reload_completed
9411    && true_regnum (operands[0]) != true_regnum (operands[1])"
9412   [(const_int 0)]
9414   enum machine_mode mode = GET_MODE (operands[0]);
9415   rtx pat;
9417   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9418     { 
9419       mode = SImode; 
9420       operands[0] = gen_lowpart (mode, operands[0]);
9421       operands[1] = gen_lowpart (mode, operands[1]);
9422     }
9424   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9426   pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9428   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9429   DONE;
9432 ;; Convert ashift to the lea pattern to avoid flags dependency.
9433 (define_split
9434   [(set (match_operand:DI 0 "register_operand" "")
9435         (zero_extend:DI
9436           (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9437                      (match_operand:QI 2 "const_int_operand" ""))))
9438    (clobber (reg:CC FLAGS_REG))]
9439   "TARGET_64BIT && reload_completed
9440    && true_regnum (operands[0]) != true_regnum (operands[1])"
9441   [(set (match_dup 0)
9442         (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9444   operands[1] = gen_lowpart (DImode, operands[1]);
9445   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9448 ;; This pattern can't accept a variable shift count, since shifts by
9449 ;; zero don't affect the flags.  We assume that shifts by constant
9450 ;; zero are optimized away.
9451 (define_insn "*ashl<mode>3_cmp"
9452   [(set (reg FLAGS_REG)
9453         (compare
9454           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9455                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9456           (const_int 0)))
9457    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9458         (ashift:SWI (match_dup 1) (match_dup 2)))]
9459   "(optimize_function_for_size_p (cfun)
9460     || !TARGET_PARTIAL_FLAG_REG_STALL
9461     || (operands[2] == const1_rtx
9462         && (TARGET_SHIFT1
9463             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9464    && ix86_match_ccmode (insn, CCGOCmode)
9465    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9467   switch (get_attr_type (insn))
9468     {
9469     case TYPE_ALU:
9470       gcc_assert (operands[2] == const1_rtx);
9471       return "add{<imodesuffix>}\t%0, %0";
9473     default:
9474       if (operands[2] == const1_rtx
9475           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9476         return "sal{<imodesuffix>}\t%0";
9477       else
9478         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9479     }
9481   [(set (attr "type")
9482      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9483                       (match_operand 0 "register_operand" ""))
9484                  (match_operand 2 "const1_operand" ""))
9485               (const_string "alu")
9486            ]
9487            (const_string "ishift")))
9488    (set (attr "length_immediate")
9489      (if_then_else
9490        (ior (eq_attr "type" "alu")
9491             (and (eq_attr "type" "ishift")
9492                  (and (match_operand 2 "const1_operand" "")
9493                       (ior (match_test "TARGET_SHIFT1")
9494                            (match_test "optimize_function_for_size_p (cfun)")))))
9495        (const_string "0")
9496        (const_string "*")))
9497    (set_attr "mode" "<MODE>")])
9499 (define_insn "*ashlsi3_cmp_zext"
9500   [(set (reg FLAGS_REG)
9501         (compare
9502           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9503                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9504           (const_int 0)))
9505    (set (match_operand:DI 0 "register_operand" "=r")
9506         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9507   "TARGET_64BIT
9508    && (optimize_function_for_size_p (cfun)
9509        || !TARGET_PARTIAL_FLAG_REG_STALL
9510        || (operands[2] == const1_rtx
9511            && (TARGET_SHIFT1
9512                || TARGET_DOUBLE_WITH_ADD)))
9513    && ix86_match_ccmode (insn, CCGOCmode)
9514    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9516   switch (get_attr_type (insn))
9517     {
9518     case TYPE_ALU:
9519       gcc_assert (operands[2] == const1_rtx);
9520       return "add{l}\t%k0, %k0";
9522     default:
9523       if (operands[2] == const1_rtx
9524           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9525         return "sal{l}\t%k0";
9526       else
9527         return "sal{l}\t{%2, %k0|%k0, %2}";
9528     }
9530   [(set (attr "type")
9531      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9532                  (match_operand 2 "const1_operand" ""))
9533               (const_string "alu")
9534            ]
9535            (const_string "ishift")))
9536    (set (attr "length_immediate")
9537      (if_then_else
9538        (ior (eq_attr "type" "alu")
9539             (and (eq_attr "type" "ishift")
9540                  (and (match_operand 2 "const1_operand" "")
9541                       (ior (match_test "TARGET_SHIFT1")
9542                            (match_test "optimize_function_for_size_p (cfun)")))))
9543        (const_string "0")
9544        (const_string "*")))
9545    (set_attr "mode" "SI")])
9547 (define_insn "*ashl<mode>3_cconly"
9548   [(set (reg FLAGS_REG)
9549         (compare
9550           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9551                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9552           (const_int 0)))
9553    (clobber (match_scratch:SWI 0 "=<r>"))]
9554   "(optimize_function_for_size_p (cfun)
9555     || !TARGET_PARTIAL_FLAG_REG_STALL
9556     || (operands[2] == const1_rtx
9557         && (TARGET_SHIFT1
9558             || TARGET_DOUBLE_WITH_ADD)))
9559    && ix86_match_ccmode (insn, CCGOCmode)"
9561   switch (get_attr_type (insn))
9562     {
9563     case TYPE_ALU:
9564       gcc_assert (operands[2] == const1_rtx);
9565       return "add{<imodesuffix>}\t%0, %0";
9567     default:
9568       if (operands[2] == const1_rtx
9569           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9570         return "sal{<imodesuffix>}\t%0";
9571       else
9572         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9573     }
9575   [(set (attr "type")
9576      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9577                       (match_operand 0 "register_operand" ""))
9578                  (match_operand 2 "const1_operand" ""))
9579               (const_string "alu")
9580            ]
9581            (const_string "ishift")))
9582    (set (attr "length_immediate")
9583      (if_then_else
9584        (ior (eq_attr "type" "alu")
9585             (and (eq_attr "type" "ishift")
9586                  (and (match_operand 2 "const1_operand" "")
9587                       (ior (match_test "TARGET_SHIFT1")
9588                            (match_test "optimize_function_for_size_p (cfun)")))))
9589        (const_string "0")
9590        (const_string "*")))
9591    (set_attr "mode" "<MODE>")])
9593 ;; See comment above `ashl<mode>3' about how this works.
9595 (define_expand "<shift_insn><mode>3"
9596   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9597         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9598                            (match_operand:QI 2 "nonmemory_operand" "")))]
9599   ""
9600   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9602 ;; Avoid useless masking of count operand.
9603 (define_insn_and_split "*<shift_insn><mode>3_mask"
9604   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9605         (any_shiftrt:SWI48
9606           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9607           (subreg:QI
9608             (and:SI
9609               (match_operand:SI 2 "nonimmediate_operand" "c")
9610               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9611    (clobber (reg:CC FLAGS_REG))]
9612   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9613    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9614       == GET_MODE_BITSIZE (<MODE>mode)-1"
9615   "#"
9616   "&& 1"
9617   [(parallel [(set (match_dup 0)
9618                    (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9619               (clobber (reg:CC FLAGS_REG))])]
9621   if (can_create_pseudo_p ())
9622     operands [2] = force_reg (SImode, operands[2]);
9624   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9626   [(set_attr "type" "ishift")
9627    (set_attr "mode" "<MODE>")])
9629 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9630   [(set (match_operand:DWI 0 "register_operand" "=r")
9631         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9632                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9633    (clobber (reg:CC FLAGS_REG))]
9634   ""
9635   "#"
9636   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9637   [(const_int 0)]
9638   "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9639   [(set_attr "type" "multi")])
9641 ;; By default we don't ask for a scratch register, because when DWImode
9642 ;; values are manipulated, registers are already at a premium.  But if
9643 ;; we have one handy, we won't turn it away.
9645 (define_peephole2
9646   [(match_scratch:DWIH 3 "r")
9647    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9648                    (any_shiftrt:<DWI>
9649                      (match_operand:<DWI> 1 "register_operand" "")
9650                      (match_operand:QI 2 "nonmemory_operand" "")))
9651               (clobber (reg:CC FLAGS_REG))])
9652    (match_dup 3)]
9653   "TARGET_CMOVE"
9654   [(const_int 0)]
9655   "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9657 (define_insn "x86_64_shrd"
9658   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9659         (ior:DI (ashiftrt:DI (match_dup 0)
9660                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9661                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9662                   (minus:QI (const_int 64) (match_dup 2)))))
9663    (clobber (reg:CC FLAGS_REG))]
9664   "TARGET_64BIT"
9665   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9666   [(set_attr "type" "ishift")
9667    (set_attr "prefix_0f" "1")
9668    (set_attr "mode" "DI")
9669    (set_attr "athlon_decode" "vector")
9670    (set_attr "amdfam10_decode" "vector")
9671    (set_attr "bdver1_decode" "vector")])
9673 (define_insn "x86_shrd"
9674   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9675         (ior:SI (ashiftrt:SI (match_dup 0)
9676                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9677                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9678                   (minus:QI (const_int 32) (match_dup 2)))))
9679    (clobber (reg:CC FLAGS_REG))]
9680   ""
9681   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9682   [(set_attr "type" "ishift")
9683    (set_attr "prefix_0f" "1")
9684    (set_attr "mode" "SI")
9685    (set_attr "pent_pair" "np")
9686    (set_attr "athlon_decode" "vector")
9687    (set_attr "amdfam10_decode" "vector")
9688    (set_attr "bdver1_decode" "vector")])
9690 (define_insn "ashrdi3_cvt"
9691   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9692         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9693                      (match_operand:QI 2 "const_int_operand" "")))
9694    (clobber (reg:CC FLAGS_REG))]
9695   "TARGET_64BIT && INTVAL (operands[2]) == 63
9696    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9697    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9698   "@
9699    {cqto|cqo}
9700    sar{q}\t{%2, %0|%0, %2}"
9701   [(set_attr "type" "imovx,ishift")
9702    (set_attr "prefix_0f" "0,*")
9703    (set_attr "length_immediate" "0,*")
9704    (set_attr "modrm" "0,1")
9705    (set_attr "mode" "DI")])
9707 (define_insn "ashrsi3_cvt"
9708   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9709         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9710                      (match_operand:QI 2 "const_int_operand" "")))
9711    (clobber (reg:CC FLAGS_REG))]
9712   "INTVAL (operands[2]) == 31
9713    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9714    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9715   "@
9716    {cltd|cdq}
9717    sar{l}\t{%2, %0|%0, %2}"
9718   [(set_attr "type" "imovx,ishift")
9719    (set_attr "prefix_0f" "0,*")
9720    (set_attr "length_immediate" "0,*")
9721    (set_attr "modrm" "0,1")
9722    (set_attr "mode" "SI")])
9724 (define_insn "*ashrsi3_cvt_zext"
9725   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9726         (zero_extend:DI
9727           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9728                        (match_operand:QI 2 "const_int_operand" ""))))
9729    (clobber (reg:CC FLAGS_REG))]
9730   "TARGET_64BIT && INTVAL (operands[2]) == 31
9731    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9732    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9733   "@
9734    {cltd|cdq}
9735    sar{l}\t{%2, %k0|%k0, %2}"
9736   [(set_attr "type" "imovx,ishift")
9737    (set_attr "prefix_0f" "0,*")
9738    (set_attr "length_immediate" "0,*")
9739    (set_attr "modrm" "0,1")
9740    (set_attr "mode" "SI")])
9742 (define_expand "x86_shift<mode>_adj_3"
9743   [(use (match_operand:SWI48 0 "register_operand" ""))
9744    (use (match_operand:SWI48 1 "register_operand" ""))
9745    (use (match_operand:QI 2 "register_operand" ""))]
9746   ""
9748   rtx label = gen_label_rtx ();
9749   rtx tmp;
9751   emit_insn (gen_testqi_ccz_1 (operands[2],
9752                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9754   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9755   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9756   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9757                               gen_rtx_LABEL_REF (VOIDmode, label),
9758                               pc_rtx);
9759   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9760   JUMP_LABEL (tmp) = label;
9762   emit_move_insn (operands[0], operands[1]);
9763   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9764                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9765   emit_label (label);
9766   LABEL_NUSES (label) = 1;
9768   DONE;
9771 (define_insn "*bmi2_<shift_insn><mode>3_1"
9772   [(set (match_operand:SWI48 0 "register_operand" "=r")
9773         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9774                            (match_operand:SWI48 2 "register_operand" "r")))]
9775   "TARGET_BMI2"
9776   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9777   [(set_attr "type" "ishiftx")
9778    (set_attr "mode" "<MODE>")])
9780 (define_insn "*<shift_insn><mode>3_1"
9781   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9782         (any_shiftrt:SWI48
9783           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9784           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9785    (clobber (reg:CC FLAGS_REG))]
9786   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9788   switch (get_attr_type (insn))
9789     {
9790     case TYPE_ISHIFTX:
9791       return "#";
9793     default:
9794       if (operands[2] == const1_rtx
9795           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9796         return "<shift>{<imodesuffix>}\t%0";
9797       else
9798         return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9799     }
9801   [(set_attr "isa" "*,bmi2")
9802    (set_attr "type" "ishift,ishiftx")
9803    (set (attr "length_immediate")
9804      (if_then_else
9805        (and (match_operand 2 "const1_operand" "")
9806             (ior (match_test "TARGET_SHIFT1")
9807                  (match_test "optimize_function_for_size_p (cfun)")))
9808        (const_string "0")
9809        (const_string "*")))
9810    (set_attr "mode" "<MODE>")])
9812 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9813 (define_split
9814   [(set (match_operand:SWI48 0 "register_operand" "")
9815         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9816                            (match_operand:QI 2 "register_operand" "")))
9817    (clobber (reg:CC FLAGS_REG))]
9818   "TARGET_BMI2 && reload_completed"
9819   [(set (match_dup 0)
9820         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9821   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9823 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9824   [(set (match_operand:DI 0 "register_operand" "=r")
9825         (zero_extend:DI
9826           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9827                           (match_operand:SI 2 "register_operand" "r"))))]
9828   "TARGET_64BIT && TARGET_BMI2"
9829   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9830   [(set_attr "type" "ishiftx")
9831    (set_attr "mode" "SI")])
9833 (define_insn "*<shift_insn>si3_1_zext"
9834   [(set (match_operand:DI 0 "register_operand" "=r,r")
9835         (zero_extend:DI
9836           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9837                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9838    (clobber (reg:CC FLAGS_REG))]
9839   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9841   switch (get_attr_type (insn))
9842     {
9843     case TYPE_ISHIFTX:
9844       return "#";
9846     default:
9847       if (operands[2] == const1_rtx
9848           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9849         return "<shift>{l}\t%k0";
9850       else
9851         return "<shift>{l}\t{%2, %k0|%k0, %2}";
9852     }
9854   [(set_attr "isa" "*,bmi2")
9855    (set_attr "type" "ishift,ishiftx")
9856    (set (attr "length_immediate")
9857      (if_then_else
9858        (and (match_operand 2 "const1_operand" "")
9859             (ior (match_test "TARGET_SHIFT1")
9860                  (match_test "optimize_function_for_size_p (cfun)")))
9861        (const_string "0")
9862        (const_string "*")))
9863    (set_attr "mode" "SI")])
9865 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9866 (define_split
9867   [(set (match_operand:DI 0 "register_operand" "")
9868         (zero_extend:DI
9869           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9870                           (match_operand:QI 2 "register_operand" ""))))
9871    (clobber (reg:CC FLAGS_REG))]
9872   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9873   [(set (match_dup 0)
9874         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9875   "operands[2] = gen_lowpart (SImode, operands[2]);")
9877 (define_insn "*<shift_insn><mode>3_1"
9878   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9879         (any_shiftrt:SWI12
9880           (match_operand:SWI12 1 "nonimmediate_operand" "0")
9881           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9882    (clobber (reg:CC FLAGS_REG))]
9883   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9885   if (operands[2] == const1_rtx
9886       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9887     return "<shift>{<imodesuffix>}\t%0";
9888   else
9889     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9891   [(set_attr "type" "ishift")
9892    (set (attr "length_immediate")
9893      (if_then_else
9894        (and (match_operand 2 "const1_operand" "")
9895             (ior (match_test "TARGET_SHIFT1")
9896                  (match_test "optimize_function_for_size_p (cfun)")))
9897        (const_string "0")
9898        (const_string "*")))
9899    (set_attr "mode" "<MODE>")])
9901 (define_insn "*<shift_insn>qi3_1_slp"
9902   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9903         (any_shiftrt:QI (match_dup 0)
9904                         (match_operand:QI 1 "nonmemory_operand" "cI")))
9905    (clobber (reg:CC FLAGS_REG))]
9906   "(optimize_function_for_size_p (cfun)
9907     || !TARGET_PARTIAL_REG_STALL
9908     || (operands[1] == const1_rtx
9909         && TARGET_SHIFT1))"
9911   if (operands[1] == const1_rtx
9912       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9913     return "<shift>{b}\t%0";
9914   else
9915     return "<shift>{b}\t{%1, %0|%0, %1}";
9917   [(set_attr "type" "ishift1")
9918    (set (attr "length_immediate")
9919      (if_then_else
9920        (and (match_operand 1 "const1_operand" "")
9921             (ior (match_test "TARGET_SHIFT1")
9922                  (match_test "optimize_function_for_size_p (cfun)")))
9923        (const_string "0")
9924        (const_string "*")))
9925    (set_attr "mode" "QI")])
9927 ;; This pattern can't accept a variable shift count, since shifts by
9928 ;; zero don't affect the flags.  We assume that shifts by constant
9929 ;; zero are optimized away.
9930 (define_insn "*<shift_insn><mode>3_cmp"
9931   [(set (reg FLAGS_REG)
9932         (compare
9933           (any_shiftrt:SWI
9934             (match_operand:SWI 1 "nonimmediate_operand" "0")
9935             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9936           (const_int 0)))
9937    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9938         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9939   "(optimize_function_for_size_p (cfun)
9940     || !TARGET_PARTIAL_FLAG_REG_STALL
9941     || (operands[2] == const1_rtx
9942         && TARGET_SHIFT1))
9943    && ix86_match_ccmode (insn, CCGOCmode)
9944    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9946   if (operands[2] == const1_rtx
9947       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9948     return "<shift>{<imodesuffix>}\t%0";
9949   else
9950     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9952   [(set_attr "type" "ishift")
9953    (set (attr "length_immediate")
9954      (if_then_else
9955        (and (match_operand 2 "const1_operand" "")
9956             (ior (match_test "TARGET_SHIFT1")
9957                  (match_test "optimize_function_for_size_p (cfun)")))
9958        (const_string "0")
9959        (const_string "*")))
9960    (set_attr "mode" "<MODE>")])
9962 (define_insn "*<shift_insn>si3_cmp_zext"
9963   [(set (reg FLAGS_REG)
9964         (compare
9965           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9966                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
9967           (const_int 0)))
9968    (set (match_operand:DI 0 "register_operand" "=r")
9969         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9970   "TARGET_64BIT
9971    && (optimize_function_for_size_p (cfun)
9972        || !TARGET_PARTIAL_FLAG_REG_STALL
9973        || (operands[2] == const1_rtx
9974            && TARGET_SHIFT1))
9975    && ix86_match_ccmode (insn, CCGOCmode)
9976    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9978   if (operands[2] == const1_rtx
9979       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9980     return "<shift>{l}\t%k0";
9981   else
9982     return "<shift>{l}\t{%2, %k0|%k0, %2}";
9984   [(set_attr "type" "ishift")
9985    (set (attr "length_immediate")
9986      (if_then_else
9987        (and (match_operand 2 "const1_operand" "")
9988             (ior (match_test "TARGET_SHIFT1")
9989                  (match_test "optimize_function_for_size_p (cfun)")))
9990        (const_string "0")
9991        (const_string "*")))
9992    (set_attr "mode" "SI")])
9994 (define_insn "*<shift_insn><mode>3_cconly"
9995   [(set (reg FLAGS_REG)
9996         (compare
9997           (any_shiftrt:SWI
9998             (match_operand:SWI 1 "register_operand" "0")
9999             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10000           (const_int 0)))
10001    (clobber (match_scratch:SWI 0 "=<r>"))]
10002   "(optimize_function_for_size_p (cfun)
10003     || !TARGET_PARTIAL_FLAG_REG_STALL
10004     || (operands[2] == const1_rtx
10005         && TARGET_SHIFT1))
10006    && ix86_match_ccmode (insn, CCGOCmode)"
10008   if (operands[2] == const1_rtx
10009       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10010     return "<shift>{<imodesuffix>}\t%0";
10011   else
10012     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10014   [(set_attr "type" "ishift")
10015    (set (attr "length_immediate")
10016      (if_then_else
10017        (and (match_operand 2 "const1_operand" "")
10018             (ior (match_test "TARGET_SHIFT1")
10019                  (match_test "optimize_function_for_size_p (cfun)")))
10020        (const_string "0")
10021        (const_string "*")))
10022    (set_attr "mode" "<MODE>")])
10024 ;; Rotate instructions
10026 (define_expand "<rotate_insn>ti3"
10027   [(set (match_operand:TI 0 "register_operand" "")
10028         (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10029                        (match_operand:QI 2 "nonmemory_operand" "")))]
10030   "TARGET_64BIT"
10032   if (const_1_to_63_operand (operands[2], VOIDmode))
10033     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10034                 (operands[0], operands[1], operands[2]));
10035   else
10036     FAIL;
10038   DONE;
10041 (define_expand "<rotate_insn>di3"
10042   [(set (match_operand:DI 0 "shiftdi_operand" "")
10043         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10044                        (match_operand:QI 2 "nonmemory_operand" "")))]
10045  ""
10047   if (TARGET_64BIT)
10048     ix86_expand_binary_operator (<CODE>, DImode, operands);
10049   else if (const_1_to_31_operand (operands[2], VOIDmode))
10050     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10051                 (operands[0], operands[1], operands[2]));
10052   else
10053     FAIL;
10055   DONE;
10058 (define_expand "<rotate_insn><mode>3"
10059   [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10060         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10061                             (match_operand:QI 2 "nonmemory_operand" "")))]
10062   ""
10063   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10065 ;; Avoid useless masking of count operand.
10066 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10067   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10068         (any_rotate:SWI48
10069           (match_operand:SWI48 1 "nonimmediate_operand" "0")
10070           (subreg:QI
10071             (and:SI
10072               (match_operand:SI 2 "nonimmediate_operand" "c")
10073               (match_operand:SI 3 "const_int_operand" "n")) 0)))
10074    (clobber (reg:CC FLAGS_REG))]
10075   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10076    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10077       == GET_MODE_BITSIZE (<MODE>mode)-1"
10078   "#"
10079   "&& 1"
10080   [(parallel [(set (match_dup 0)
10081                    (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10082               (clobber (reg:CC FLAGS_REG))])]
10084   if (can_create_pseudo_p ())
10085     operands [2] = force_reg (SImode, operands[2]);
10087   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10089   [(set_attr "type" "rotate")
10090    (set_attr "mode" "<MODE>")])
10092 ;; Implement rotation using two double-precision
10093 ;; shift instructions and a scratch register.
10095 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10096  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10097        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10098                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10099   (clobber (reg:CC FLAGS_REG))
10100   (clobber (match_scratch:DWIH 3 "=&r"))]
10101  ""
10102  "#"
10103  "reload_completed"
10104  [(set (match_dup 3) (match_dup 4))
10105   (parallel
10106    [(set (match_dup 4)
10107          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10108                    (lshiftrt:DWIH (match_dup 5)
10109                                   (minus:QI (match_dup 6) (match_dup 2)))))
10110     (clobber (reg:CC FLAGS_REG))])
10111   (parallel
10112    [(set (match_dup 5)
10113          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10114                    (lshiftrt:DWIH (match_dup 3)
10115                                   (minus:QI (match_dup 6) (match_dup 2)))))
10116     (clobber (reg:CC FLAGS_REG))])]
10118   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10120   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10123 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10124  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10125        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10126                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10127   (clobber (reg:CC FLAGS_REG))
10128   (clobber (match_scratch:DWIH 3 "=&r"))]
10129  ""
10130  "#"
10131  "reload_completed"
10132  [(set (match_dup 3) (match_dup 4))
10133   (parallel
10134    [(set (match_dup 4)
10135          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10136                    (ashift:DWIH (match_dup 5)
10137                                 (minus:QI (match_dup 6) (match_dup 2)))))
10138     (clobber (reg:CC FLAGS_REG))])
10139   (parallel
10140    [(set (match_dup 5)
10141          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10142                    (ashift:DWIH (match_dup 3)
10143                                 (minus:QI (match_dup 6) (match_dup 2)))))
10144     (clobber (reg:CC FLAGS_REG))])]
10146   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10148   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10151 (define_insn "*bmi2_rorx<mode>3_1"
10152   [(set (match_operand:SWI48 0 "register_operand" "=r")
10153         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10154                         (match_operand:QI 2 "immediate_operand" "<S>")))]
10155   "TARGET_BMI2"
10156   "rorx\t{%2, %1, %0|%0, %1, %2}"
10157   [(set_attr "type" "rotatex")
10158    (set_attr "mode" "<MODE>")])
10160 (define_insn "*<rotate_insn><mode>3_1"
10161   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10162         (any_rotate:SWI48
10163           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10164           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10165    (clobber (reg:CC FLAGS_REG))]
10166   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10168   switch (get_attr_type (insn))
10169     {
10170     case TYPE_ROTATEX:
10171       return "#";
10173     default:
10174       if (operands[2] == const1_rtx
10175           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10176         return "<rotate>{<imodesuffix>}\t%0";
10177       else
10178         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10179     }
10181   [(set_attr "isa" "*,bmi2")
10182    (set_attr "type" "rotate,rotatex")
10183    (set (attr "length_immediate")
10184      (if_then_else
10185        (and (eq_attr "type" "rotate")
10186             (and (match_operand 2 "const1_operand" "")
10187                  (ior (match_test "TARGET_SHIFT1")
10188                       (match_test "optimize_function_for_size_p (cfun)"))))
10189        (const_string "0")
10190        (const_string "*")))
10191    (set_attr "mode" "<MODE>")])
10193 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10194 (define_split
10195   [(set (match_operand:SWI48 0 "register_operand" "")
10196         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10197                       (match_operand:QI 2 "immediate_operand" "")))
10198    (clobber (reg:CC FLAGS_REG))]
10199   "TARGET_BMI2 && reload_completed"
10200   [(set (match_dup 0)
10201         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10203   operands[2]
10204     = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10207 (define_split
10208   [(set (match_operand:SWI48 0 "register_operand" "")
10209         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10210                         (match_operand:QI 2 "immediate_operand" "")))
10211    (clobber (reg:CC FLAGS_REG))]
10212   "TARGET_BMI2 && reload_completed"
10213   [(set (match_dup 0)
10214         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10216 (define_insn "*bmi2_rorxsi3_1_zext"
10217   [(set (match_operand:DI 0 "register_operand" "=r")
10218         (zero_extend:DI
10219           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10220                        (match_operand:QI 2 "immediate_operand" "I"))))]
10221   "TARGET_64BIT && TARGET_BMI2"
10222   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10223   [(set_attr "type" "rotatex")
10224    (set_attr "mode" "SI")])
10226 (define_insn "*<rotate_insn>si3_1_zext"
10227   [(set (match_operand:DI 0 "register_operand" "=r,r")
10228         (zero_extend:DI
10229           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10230                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10231    (clobber (reg:CC FLAGS_REG))]
10232   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10234   switch (get_attr_type (insn))
10235     {
10236     case TYPE_ROTATEX:
10237       return "#";
10239     default:
10240       if (operands[2] == const1_rtx
10241           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10242         return "<rotate>{l}\t%k0";
10243       else
10244         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10245     }
10247   [(set_attr "isa" "*,bmi2")
10248    (set_attr "type" "rotate,rotatex")
10249    (set (attr "length_immediate")
10250      (if_then_else
10251        (and (eq_attr "type" "rotate")
10252             (and (match_operand 2 "const1_operand" "")
10253                  (ior (match_test "TARGET_SHIFT1")
10254                       (match_test "optimize_function_for_size_p (cfun)"))))
10255        (const_string "0")
10256        (const_string "*")))
10257    (set_attr "mode" "SI")])
10259 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10260 (define_split
10261   [(set (match_operand:DI 0 "register_operand" "")
10262         (zero_extend:DI
10263           (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10264                      (match_operand:QI 2 "immediate_operand" ""))))
10265    (clobber (reg:CC FLAGS_REG))]
10266   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10267   [(set (match_dup 0)
10268         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10270   operands[2]
10271     = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10274 (define_split
10275   [(set (match_operand:DI 0 "register_operand" "")
10276         (zero_extend:DI
10277           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10278                        (match_operand:QI 2 "immediate_operand" ""))))
10279    (clobber (reg:CC FLAGS_REG))]
10280   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10281   [(set (match_dup 0)
10282         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10284 (define_insn "*<rotate_insn><mode>3_1"
10285   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10286         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10287                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10288    (clobber (reg:CC FLAGS_REG))]
10289   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10291   if (operands[2] == const1_rtx
10292       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10293     return "<rotate>{<imodesuffix>}\t%0";
10294   else
10295     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10297   [(set_attr "type" "rotate")
10298    (set (attr "length_immediate")
10299      (if_then_else
10300        (and (match_operand 2 "const1_operand" "")
10301             (ior (match_test "TARGET_SHIFT1")
10302                  (match_test "optimize_function_for_size_p (cfun)")))
10303        (const_string "0")
10304        (const_string "*")))
10305    (set_attr "mode" "<MODE>")])
10307 (define_insn "*<rotate_insn>qi3_1_slp"
10308   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10309         (any_rotate:QI (match_dup 0)
10310                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10311    (clobber (reg:CC FLAGS_REG))]
10312   "(optimize_function_for_size_p (cfun)
10313     || !TARGET_PARTIAL_REG_STALL
10314     || (operands[1] == const1_rtx
10315         && TARGET_SHIFT1))"
10317   if (operands[1] == const1_rtx
10318       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10319     return "<rotate>{b}\t%0";
10320   else
10321     return "<rotate>{b}\t{%1, %0|%0, %1}";
10323   [(set_attr "type" "rotate1")
10324    (set (attr "length_immediate")
10325      (if_then_else
10326        (and (match_operand 1 "const1_operand" "")
10327             (ior (match_test "TARGET_SHIFT1")
10328                  (match_test "optimize_function_for_size_p (cfun)")))
10329        (const_string "0")
10330        (const_string "*")))
10331    (set_attr "mode" "QI")])
10333 (define_split
10334  [(set (match_operand:HI 0 "register_operand" "")
10335        (any_rotate:HI (match_dup 0) (const_int 8)))
10336   (clobber (reg:CC FLAGS_REG))]
10337  "reload_completed
10338   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10339  [(parallel [(set (strict_low_part (match_dup 0))
10340                   (bswap:HI (match_dup 0)))
10341              (clobber (reg:CC FLAGS_REG))])])
10343 ;; Bit set / bit test instructions
10345 (define_expand "extv"
10346   [(set (match_operand:SI 0 "register_operand" "")
10347         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10348                          (match_operand:SI 2 "const8_operand" "")
10349                          (match_operand:SI 3 "const8_operand" "")))]
10350   ""
10352   /* Handle extractions from %ah et al.  */
10353   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10354     FAIL;
10356   /* From mips.md: extract_bit_field doesn't verify that our source
10357      matches the predicate, so check it again here.  */
10358   if (! ext_register_operand (operands[1], VOIDmode))
10359     FAIL;
10362 (define_expand "extzv"
10363   [(set (match_operand:SI 0 "register_operand" "")
10364         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10365                          (match_operand:SI 2 "const8_operand" "")
10366                          (match_operand:SI 3 "const8_operand" "")))]
10367   ""
10369   /* Handle extractions from %ah et al.  */
10370   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10371     FAIL;
10373   /* From mips.md: extract_bit_field doesn't verify that our source
10374      matches the predicate, so check it again here.  */
10375   if (! ext_register_operand (operands[1], VOIDmode))
10376     FAIL;
10379 (define_expand "insv"
10380   [(set (zero_extract (match_operand 0 "register_operand" "")
10381                       (match_operand 1 "const_int_operand" "")
10382                       (match_operand 2 "const_int_operand" ""))
10383         (match_operand 3 "register_operand" ""))]
10384   ""
10386   rtx (*gen_mov_insv_1) (rtx, rtx);
10388   if (ix86_expand_pinsr (operands))
10389     DONE;
10391   /* Handle insertions to %ah et al.  */
10392   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10393     FAIL;
10395   /* From mips.md: insert_bit_field doesn't verify that our source
10396      matches the predicate, so check it again here.  */
10397   if (! ext_register_operand (operands[0], VOIDmode))
10398     FAIL;
10400   gen_mov_insv_1 = (TARGET_64BIT
10401                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10403   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10404   DONE;
10407 ;; %%% bts, btr, btc, bt.
10408 ;; In general these instructions are *slow* when applied to memory,
10409 ;; since they enforce atomic operation.  When applied to registers,
10410 ;; it depends on the cpu implementation.  They're never faster than
10411 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10412 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10413 ;; within the instruction itself, so operating on bits in the high
10414 ;; 32-bits of a register becomes easier.
10416 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10417 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10418 ;; negdf respectively, so they can never be disabled entirely.
10420 (define_insn "*btsq"
10421   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10422                          (const_int 1)
10423                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10424         (const_int 1))
10425    (clobber (reg:CC FLAGS_REG))]
10426   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10427   "bts{q}\t{%1, %0|%0, %1}"
10428   [(set_attr "type" "alu1")
10429    (set_attr "prefix_0f" "1")
10430    (set_attr "mode" "DI")])
10432 (define_insn "*btrq"
10433   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10434                          (const_int 1)
10435                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10436         (const_int 0))
10437    (clobber (reg:CC FLAGS_REG))]
10438   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10439   "btr{q}\t{%1, %0|%0, %1}"
10440   [(set_attr "type" "alu1")
10441    (set_attr "prefix_0f" "1")
10442    (set_attr "mode" "DI")])
10444 (define_insn "*btcq"
10445   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10446                          (const_int 1)
10447                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10448         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10449    (clobber (reg:CC FLAGS_REG))]
10450   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10451   "btc{q}\t{%1, %0|%0, %1}"
10452   [(set_attr "type" "alu1")
10453    (set_attr "prefix_0f" "1")
10454    (set_attr "mode" "DI")])
10456 ;; Allow Nocona to avoid these instructions if a register is available.
10458 (define_peephole2
10459   [(match_scratch:DI 2 "r")
10460    (parallel [(set (zero_extract:DI
10461                      (match_operand:DI 0 "register_operand" "")
10462                      (const_int 1)
10463                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10464                    (const_int 1))
10465               (clobber (reg:CC FLAGS_REG))])]
10466   "TARGET_64BIT && !TARGET_USE_BT"
10467   [(const_int 0)]
10469   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10470   rtx op1;
10472   if (HOST_BITS_PER_WIDE_INT >= 64)
10473     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10474   else if (i < HOST_BITS_PER_WIDE_INT)
10475     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10476   else
10477     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10479   op1 = immed_double_const (lo, hi, DImode);
10480   if (i >= 31)
10481     {
10482       emit_move_insn (operands[2], op1);
10483       op1 = operands[2];
10484     }
10486   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10487   DONE;
10490 (define_peephole2
10491   [(match_scratch:DI 2 "r")
10492    (parallel [(set (zero_extract:DI
10493                      (match_operand:DI 0 "register_operand" "")
10494                      (const_int 1)
10495                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10496                    (const_int 0))
10497               (clobber (reg:CC FLAGS_REG))])]
10498   "TARGET_64BIT && !TARGET_USE_BT"
10499   [(const_int 0)]
10501   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10502   rtx op1;
10504   if (HOST_BITS_PER_WIDE_INT >= 64)
10505     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10506   else if (i < HOST_BITS_PER_WIDE_INT)
10507     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10508   else
10509     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10511   op1 = immed_double_const (~lo, ~hi, DImode);
10512   if (i >= 32)
10513     {
10514       emit_move_insn (operands[2], op1);
10515       op1 = operands[2];
10516     }
10518   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10519   DONE;
10522 (define_peephole2
10523   [(match_scratch:DI 2 "r")
10524    (parallel [(set (zero_extract:DI
10525                      (match_operand:DI 0 "register_operand" "")
10526                      (const_int 1)
10527                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10528               (not:DI (zero_extract:DI
10529                         (match_dup 0) (const_int 1) (match_dup 1))))
10530               (clobber (reg:CC FLAGS_REG))])]
10531   "TARGET_64BIT && !TARGET_USE_BT"
10532   [(const_int 0)]
10534   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10535   rtx op1;
10537   if (HOST_BITS_PER_WIDE_INT >= 64)
10538     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10539   else if (i < HOST_BITS_PER_WIDE_INT)
10540     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10541   else
10542     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10544   op1 = immed_double_const (lo, hi, DImode);
10545   if (i >= 31)
10546     {
10547       emit_move_insn (operands[2], op1);
10548       op1 = operands[2];
10549     }
10551   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10552   DONE;
10555 (define_insn "*bt<mode>"
10556   [(set (reg:CCC FLAGS_REG)
10557         (compare:CCC
10558           (zero_extract:SWI48
10559             (match_operand:SWI48 0 "register_operand" "r")
10560             (const_int 1)
10561             (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10562           (const_int 0)))]
10563   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10564   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10565   [(set_attr "type" "alu1")
10566    (set_attr "prefix_0f" "1")
10567    (set_attr "mode" "<MODE>")])
10569 ;; Store-flag instructions.
10571 ;; For all sCOND expanders, also expand the compare or test insn that
10572 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10574 (define_insn_and_split "*setcc_di_1"
10575   [(set (match_operand:DI 0 "register_operand" "=q")
10576         (match_operator:DI 1 "ix86_comparison_operator"
10577           [(reg FLAGS_REG) (const_int 0)]))]
10578   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10579   "#"
10580   "&& reload_completed"
10581   [(set (match_dup 2) (match_dup 1))
10582    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10584   PUT_MODE (operands[1], QImode);
10585   operands[2] = gen_lowpart (QImode, operands[0]);
10588 (define_insn_and_split "*setcc_si_1_and"
10589   [(set (match_operand:SI 0 "register_operand" "=q")
10590         (match_operator:SI 1 "ix86_comparison_operator"
10591           [(reg FLAGS_REG) (const_int 0)]))
10592    (clobber (reg:CC FLAGS_REG))]
10593   "!TARGET_PARTIAL_REG_STALL
10594    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10595   "#"
10596   "&& reload_completed"
10597   [(set (match_dup 2) (match_dup 1))
10598    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10599               (clobber (reg:CC FLAGS_REG))])]
10601   PUT_MODE (operands[1], QImode);
10602   operands[2] = gen_lowpart (QImode, operands[0]);
10605 (define_insn_and_split "*setcc_si_1_movzbl"
10606   [(set (match_operand:SI 0 "register_operand" "=q")
10607         (match_operator:SI 1 "ix86_comparison_operator"
10608           [(reg FLAGS_REG) (const_int 0)]))]
10609   "!TARGET_PARTIAL_REG_STALL
10610    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10611   "#"
10612   "&& reload_completed"
10613   [(set (match_dup 2) (match_dup 1))
10614    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10616   PUT_MODE (operands[1], QImode);
10617   operands[2] = gen_lowpart (QImode, operands[0]);
10620 (define_insn "*setcc_qi"
10621   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10622         (match_operator:QI 1 "ix86_comparison_operator"
10623           [(reg FLAGS_REG) (const_int 0)]))]
10624   ""
10625   "set%C1\t%0"
10626   [(set_attr "type" "setcc")
10627    (set_attr "mode" "QI")])
10629 (define_insn "*setcc_qi_slp"
10630   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10631         (match_operator:QI 1 "ix86_comparison_operator"
10632           [(reg FLAGS_REG) (const_int 0)]))]
10633   ""
10634   "set%C1\t%0"
10635   [(set_attr "type" "setcc")
10636    (set_attr "mode" "QI")])
10638 ;; In general it is not safe to assume too much about CCmode registers,
10639 ;; so simplify-rtx stops when it sees a second one.  Under certain
10640 ;; conditions this is safe on x86, so help combine not create
10642 ;;      seta    %al
10643 ;;      testb   %al, %al
10644 ;;      sete    %al
10646 (define_split
10647   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10648         (ne:QI (match_operator 1 "ix86_comparison_operator"
10649                  [(reg FLAGS_REG) (const_int 0)])
10650             (const_int 0)))]
10651   ""
10652   [(set (match_dup 0) (match_dup 1))]
10653   "PUT_MODE (operands[1], QImode);")
10655 (define_split
10656   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10657         (ne:QI (match_operator 1 "ix86_comparison_operator"
10658                  [(reg FLAGS_REG) (const_int 0)])
10659             (const_int 0)))]
10660   ""
10661   [(set (match_dup 0) (match_dup 1))]
10662   "PUT_MODE (operands[1], QImode);")
10664 (define_split
10665   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10666         (eq:QI (match_operator 1 "ix86_comparison_operator"
10667                  [(reg FLAGS_REG) (const_int 0)])
10668             (const_int 0)))]
10669   ""
10670   [(set (match_dup 0) (match_dup 1))]
10672   rtx new_op1 = copy_rtx (operands[1]);
10673   operands[1] = new_op1;
10674   PUT_MODE (new_op1, QImode);
10675   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10676                                              GET_MODE (XEXP (new_op1, 0))));
10678   /* Make sure that (a) the CCmode we have for the flags is strong
10679      enough for the reversed compare or (b) we have a valid FP compare.  */
10680   if (! ix86_comparison_operator (new_op1, VOIDmode))
10681     FAIL;
10684 (define_split
10685   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10686         (eq:QI (match_operator 1 "ix86_comparison_operator"
10687                  [(reg FLAGS_REG) (const_int 0)])
10688             (const_int 0)))]
10689   ""
10690   [(set (match_dup 0) (match_dup 1))]
10692   rtx new_op1 = copy_rtx (operands[1]);
10693   operands[1] = new_op1;
10694   PUT_MODE (new_op1, QImode);
10695   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10696                                              GET_MODE (XEXP (new_op1, 0))));
10698   /* Make sure that (a) the CCmode we have for the flags is strong
10699      enough for the reversed compare or (b) we have a valid FP compare.  */
10700   if (! ix86_comparison_operator (new_op1, VOIDmode))
10701     FAIL;
10704 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10705 ;; subsequent logical operations are used to imitate conditional moves.
10706 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10707 ;; it directly.
10709 (define_insn "setcc_<mode>_sse"
10710   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10711         (match_operator:MODEF 3 "sse_comparison_operator"
10712           [(match_operand:MODEF 1 "register_operand" "0,x")
10713            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10714   "SSE_FLOAT_MODE_P (<MODE>mode)"
10715   "@
10716    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10717    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10718   [(set_attr "isa" "noavx,avx")
10719    (set_attr "type" "ssecmp")
10720    (set_attr "length_immediate" "1")
10721    (set_attr "prefix" "orig,vex")
10722    (set_attr "mode" "<MODE>")])
10724 ;; Basic conditional jump instructions.
10725 ;; We ignore the overflow flag for signed branch instructions.
10727 (define_insn "*jcc_1"
10728   [(set (pc)
10729         (if_then_else (match_operator 1 "ix86_comparison_operator"
10730                                       [(reg FLAGS_REG) (const_int 0)])
10731                       (label_ref (match_operand 0 "" ""))
10732                       (pc)))]
10733   ""
10734   "%+j%C1\t%l0"
10735   [(set_attr "type" "ibr")
10736    (set_attr "modrm" "0")
10737    (set (attr "length")
10738            (if_then_else (and (ge (minus (match_dup 0) (pc))
10739                                   (const_int -126))
10740                               (lt (minus (match_dup 0) (pc))
10741                                   (const_int 128)))
10742              (const_int 2)
10743              (const_int 6)))])
10745 (define_insn "*jcc_2"
10746   [(set (pc)
10747         (if_then_else (match_operator 1 "ix86_comparison_operator"
10748                                       [(reg FLAGS_REG) (const_int 0)])
10749                       (pc)
10750                       (label_ref (match_operand 0 "" ""))))]
10751   ""
10752   "%+j%c1\t%l0"
10753   [(set_attr "type" "ibr")
10754    (set_attr "modrm" "0")
10755    (set (attr "length")
10756            (if_then_else (and (ge (minus (match_dup 0) (pc))
10757                                   (const_int -126))
10758                               (lt (minus (match_dup 0) (pc))
10759                                   (const_int 128)))
10760              (const_int 2)
10761              (const_int 6)))])
10763 ;; In general it is not safe to assume too much about CCmode registers,
10764 ;; so simplify-rtx stops when it sees a second one.  Under certain
10765 ;; conditions this is safe on x86, so help combine not create
10767 ;;      seta    %al
10768 ;;      testb   %al, %al
10769 ;;      je      Lfoo
10771 (define_split
10772   [(set (pc)
10773         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10774                                       [(reg FLAGS_REG) (const_int 0)])
10775                           (const_int 0))
10776                       (label_ref (match_operand 1 "" ""))
10777                       (pc)))]
10778   ""
10779   [(set (pc)
10780         (if_then_else (match_dup 0)
10781                       (label_ref (match_dup 1))
10782                       (pc)))]
10783   "PUT_MODE (operands[0], VOIDmode);")
10785 (define_split
10786   [(set (pc)
10787         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10788                                       [(reg FLAGS_REG) (const_int 0)])
10789                           (const_int 0))
10790                       (label_ref (match_operand 1 "" ""))
10791                       (pc)))]
10792   ""
10793   [(set (pc)
10794         (if_then_else (match_dup 0)
10795                       (label_ref (match_dup 1))
10796                       (pc)))]
10798   rtx new_op0 = copy_rtx (operands[0]);
10799   operands[0] = new_op0;
10800   PUT_MODE (new_op0, VOIDmode);
10801   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10802                                              GET_MODE (XEXP (new_op0, 0))));
10804   /* Make sure that (a) the CCmode we have for the flags is strong
10805      enough for the reversed compare or (b) we have a valid FP compare.  */
10806   if (! ix86_comparison_operator (new_op0, VOIDmode))
10807     FAIL;
10810 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10811 ;; pass generates from shift insn with QImode operand.  Actually, the mode
10812 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10813 ;; appropriate modulo of the bit offset value.
10815 (define_insn_and_split "*jcc_bt<mode>"
10816   [(set (pc)
10817         (if_then_else (match_operator 0 "bt_comparison_operator"
10818                         [(zero_extract:SWI48
10819                            (match_operand:SWI48 1 "register_operand" "r")
10820                            (const_int 1)
10821                            (zero_extend:SI
10822                              (match_operand:QI 2 "register_operand" "r")))
10823                          (const_int 0)])
10824                       (label_ref (match_operand 3 "" ""))
10825                       (pc)))
10826    (clobber (reg:CC FLAGS_REG))]
10827   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10828   "#"
10829   "&& 1"
10830   [(set (reg:CCC FLAGS_REG)
10831         (compare:CCC
10832           (zero_extract:SWI48
10833             (match_dup 1)
10834             (const_int 1)
10835             (match_dup 2))
10836           (const_int 0)))
10837    (set (pc)
10838         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10839                       (label_ref (match_dup 3))
10840                       (pc)))]
10842   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10844   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10847 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10848 ;; also for DImode, this is what combine produces.
10849 (define_insn_and_split "*jcc_bt<mode>_mask"
10850   [(set (pc)
10851         (if_then_else (match_operator 0 "bt_comparison_operator"
10852                         [(zero_extract:SWI48
10853                            (match_operand:SWI48 1 "register_operand" "r")
10854                            (const_int 1)
10855                            (and:SI
10856                              (match_operand:SI 2 "register_operand" "r")
10857                              (match_operand:SI 3 "const_int_operand" "n")))])
10858                       (label_ref (match_operand 4 "" ""))
10859                       (pc)))
10860    (clobber (reg:CC FLAGS_REG))]
10861   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10862    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10863       == GET_MODE_BITSIZE (<MODE>mode)-1"
10864   "#"
10865   "&& 1"
10866   [(set (reg:CCC FLAGS_REG)
10867         (compare:CCC
10868           (zero_extract:SWI48
10869             (match_dup 1)
10870             (const_int 1)
10871             (match_dup 2))
10872           (const_int 0)))
10873    (set (pc)
10874         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10875                       (label_ref (match_dup 4))
10876                       (pc)))]
10878   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10880   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10883 (define_insn_and_split "*jcc_btsi_1"
10884   [(set (pc)
10885         (if_then_else (match_operator 0 "bt_comparison_operator"
10886                         [(and:SI
10887                            (lshiftrt:SI
10888                              (match_operand:SI 1 "register_operand" "r")
10889                              (match_operand:QI 2 "register_operand" "r"))
10890                            (const_int 1))
10891                          (const_int 0)])
10892                       (label_ref (match_operand 3 "" ""))
10893                       (pc)))
10894    (clobber (reg:CC FLAGS_REG))]
10895   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10896   "#"
10897   "&& 1"
10898   [(set (reg:CCC FLAGS_REG)
10899         (compare:CCC
10900           (zero_extract:SI
10901             (match_dup 1)
10902             (const_int 1)
10903             (match_dup 2))
10904           (const_int 0)))
10905    (set (pc)
10906         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10907                       (label_ref (match_dup 3))
10908                       (pc)))]
10910   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10912   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10915 ;; avoid useless masking of bit offset operand
10916 (define_insn_and_split "*jcc_btsi_mask_1"
10917   [(set (pc)
10918         (if_then_else
10919           (match_operator 0 "bt_comparison_operator"
10920             [(and:SI
10921                (lshiftrt:SI
10922                  (match_operand:SI 1 "register_operand" "r")
10923                  (subreg:QI
10924                    (and:SI
10925                      (match_operand:SI 2 "register_operand" "r")
10926                      (match_operand:SI 3 "const_int_operand" "n")) 0))
10927                (const_int 1))
10928              (const_int 0)])
10929           (label_ref (match_operand 4 "" ""))
10930           (pc)))
10931    (clobber (reg:CC FLAGS_REG))]
10932   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10933    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10934   "#"
10935   "&& 1"
10936   [(set (reg:CCC FLAGS_REG)
10937         (compare:CCC
10938           (zero_extract:SI
10939             (match_dup 1)
10940             (const_int 1)
10941             (match_dup 2))
10942           (const_int 0)))
10943    (set (pc)
10944         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10945                       (label_ref (match_dup 4))
10946                       (pc)))]
10947   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10949 ;; Define combination compare-and-branch fp compare instructions to help
10950 ;; combine.
10952 (define_insn "*fp_jcc_1_387"
10953   [(set (pc)
10954         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10955                         [(match_operand 1 "register_operand" "f")
10956                          (match_operand 2 "nonimmediate_operand" "fm")])
10957           (label_ref (match_operand 3 "" ""))
10958           (pc)))
10959    (clobber (reg:CCFP FPSR_REG))
10960    (clobber (reg:CCFP FLAGS_REG))
10961    (clobber (match_scratch:HI 4 "=a"))]
10962   "TARGET_80387
10963    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10964    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10965    && SELECT_CC_MODE (GET_CODE (operands[0]),
10966                       operands[1], operands[2]) == CCFPmode
10967    && !TARGET_CMOVE"
10968   "#")
10970 (define_insn "*fp_jcc_1r_387"
10971   [(set (pc)
10972         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10973                         [(match_operand 1 "register_operand" "f")
10974                          (match_operand 2 "nonimmediate_operand" "fm")])
10975           (pc)
10976           (label_ref (match_operand 3 "" ""))))
10977    (clobber (reg:CCFP FPSR_REG))
10978    (clobber (reg:CCFP FLAGS_REG))
10979    (clobber (match_scratch:HI 4 "=a"))]
10980   "TARGET_80387
10981    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10982    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10983    && SELECT_CC_MODE (GET_CODE (operands[0]),
10984                       operands[1], operands[2]) == CCFPmode
10985    && !TARGET_CMOVE"
10986   "#")
10988 (define_insn "*fp_jcc_2_387"
10989   [(set (pc)
10990         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10991                         [(match_operand 1 "register_operand" "f")
10992                          (match_operand 2 "register_operand" "f")])
10993           (label_ref (match_operand 3 "" ""))
10994           (pc)))
10995    (clobber (reg:CCFP FPSR_REG))
10996    (clobber (reg:CCFP FLAGS_REG))
10997    (clobber (match_scratch:HI 4 "=a"))]
10998   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10999    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11000    && !TARGET_CMOVE"
11001   "#")
11003 (define_insn "*fp_jcc_2r_387"
11004   [(set (pc)
11005         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11006                         [(match_operand 1 "register_operand" "f")
11007                          (match_operand 2 "register_operand" "f")])
11008           (pc)
11009           (label_ref (match_operand 3 "" ""))))
11010    (clobber (reg:CCFP FPSR_REG))
11011    (clobber (reg:CCFP FLAGS_REG))
11012    (clobber (match_scratch:HI 4 "=a"))]
11013   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11014    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11015    && !TARGET_CMOVE"
11016   "#")
11018 (define_insn "*fp_jcc_3_387"
11019   [(set (pc)
11020         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11021                         [(match_operand 1 "register_operand" "f")
11022                          (match_operand 2 "const0_operand" "")])
11023           (label_ref (match_operand 3 "" ""))
11024           (pc)))
11025    (clobber (reg:CCFP FPSR_REG))
11026    (clobber (reg:CCFP FLAGS_REG))
11027    (clobber (match_scratch:HI 4 "=a"))]
11028   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11029    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11030    && SELECT_CC_MODE (GET_CODE (operands[0]),
11031                       operands[1], operands[2]) == CCFPmode
11032    && !TARGET_CMOVE"
11033   "#")
11035 (define_split
11036   [(set (pc)
11037         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11038                         [(match_operand 1 "register_operand" "")
11039                          (match_operand 2 "nonimmediate_operand" "")])
11040           (match_operand 3 "" "")
11041           (match_operand 4 "" "")))
11042    (clobber (reg:CCFP FPSR_REG))
11043    (clobber (reg:CCFP FLAGS_REG))]
11044   "reload_completed"
11045   [(const_int 0)]
11047   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11048                         operands[3], operands[4], NULL_RTX, NULL_RTX);
11049   DONE;
11052 (define_split
11053   [(set (pc)
11054         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11055                         [(match_operand 1 "register_operand" "")
11056                          (match_operand 2 "general_operand" "")])
11057           (match_operand 3 "" "")
11058           (match_operand 4 "" "")))
11059    (clobber (reg:CCFP FPSR_REG))
11060    (clobber (reg:CCFP FLAGS_REG))
11061    (clobber (match_scratch:HI 5 "=a"))]
11062   "reload_completed"
11063   [(const_int 0)]
11065   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11066                         operands[3], operands[4], operands[5], NULL_RTX);
11067   DONE;
11070 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11071 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11072 ;; with a precedence over other operators and is always put in the first
11073 ;; place. Swap condition and operands to match ficom instruction.
11075 (define_insn "*fp_jcc_4_<mode>_387"
11076   [(set (pc)
11077         (if_then_else
11078           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11079             [(match_operator 1 "float_operator"
11080               [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11081              (match_operand 3 "register_operand" "f,f")])
11082           (label_ref (match_operand 4 "" ""))
11083           (pc)))
11084    (clobber (reg:CCFP FPSR_REG))
11085    (clobber (reg:CCFP FLAGS_REG))
11086    (clobber (match_scratch:HI 5 "=a,a"))]
11087   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11088    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11089    && GET_MODE (operands[1]) == GET_MODE (operands[3])
11090    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11091    && !TARGET_CMOVE"
11092   "#")
11094 (define_split
11095   [(set (pc)
11096         (if_then_else
11097           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11098             [(match_operator 1 "float_operator"
11099               [(match_operand:SWI24 2 "memory_operand" "")])
11100              (match_operand 3 "register_operand" "")])
11101           (match_operand 4 "" "")
11102           (match_operand 5 "" "")))
11103    (clobber (reg:CCFP FPSR_REG))
11104    (clobber (reg:CCFP FLAGS_REG))
11105    (clobber (match_scratch:HI 6 "=a"))]
11106   "reload_completed"
11107   [(const_int 0)]
11109   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11111   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11112                         operands[3], operands[7],
11113                         operands[4], operands[5], operands[6], NULL_RTX);
11114   DONE;
11117 ;; %%% Kill this when reload knows how to do it.
11118 (define_split
11119   [(set (pc)
11120         (if_then_else
11121           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11122             [(match_operator 1 "float_operator"
11123               [(match_operand:SWI24 2 "register_operand" "")])
11124              (match_operand 3 "register_operand" "")])
11125           (match_operand 4 "" "")
11126           (match_operand 5 "" "")))
11127    (clobber (reg:CCFP FPSR_REG))
11128    (clobber (reg:CCFP FLAGS_REG))
11129    (clobber (match_scratch:HI 6 "=a"))]
11130   "reload_completed"
11131   [(const_int 0)]
11133   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11134   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11136   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11137                         operands[3], operands[7],
11138                         operands[4], operands[5], operands[6], operands[2]);
11139   DONE;
11142 ;; Unconditional and other jump instructions
11144 (define_insn "jump"
11145   [(set (pc)
11146         (label_ref (match_operand 0 "" "")))]
11147   ""
11148   "jmp\t%l0"
11149   [(set_attr "type" "ibr")
11150    (set (attr "length")
11151            (if_then_else (and (ge (minus (match_dup 0) (pc))
11152                                   (const_int -126))
11153                               (lt (minus (match_dup 0) (pc))
11154                                   (const_int 128)))
11155              (const_int 2)
11156              (const_int 5)))
11157    (set_attr "modrm" "0")])
11159 (define_expand "indirect_jump"
11160   [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11162 (define_insn "*indirect_jump"
11163   [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11164   ""
11165   "jmp\t%A0"
11166   [(set_attr "type" "ibr")
11167    (set_attr "length_immediate" "0")])
11169 (define_expand "tablejump"
11170   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11171               (use (label_ref (match_operand 1 "" "")))])]
11172   ""
11174   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11175      relative.  Convert the relative address to an absolute address.  */
11176   if (flag_pic)
11177     {
11178       rtx op0, op1;
11179       enum rtx_code code;
11181       /* We can't use @GOTOFF for text labels on VxWorks;
11182          see gotoff_operand.  */
11183       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11184         {
11185           code = PLUS;
11186           op0 = operands[0];
11187           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11188         }
11189       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11190         {
11191           code = PLUS;
11192           op0 = operands[0];
11193           op1 = pic_offset_table_rtx;
11194         }
11195       else
11196         {
11197           code = MINUS;
11198           op0 = pic_offset_table_rtx;
11199           op1 = operands[0];
11200         }
11202       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11203                                          OPTAB_DIRECT);
11204     }
11205   else if (TARGET_X32)
11206     operands[0] = convert_memory_address (Pmode, operands[0]);
11209 (define_insn "*tablejump_1"
11210   [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11211    (use (label_ref (match_operand 1 "" "")))]
11212   ""
11213   "jmp\t%A0"
11214   [(set_attr "type" "ibr")
11215    (set_attr "length_immediate" "0")])
11217 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11219 (define_peephole2
11220   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11221    (set (match_operand:QI 1 "register_operand" "")
11222         (match_operator:QI 2 "ix86_comparison_operator"
11223           [(reg FLAGS_REG) (const_int 0)]))
11224    (set (match_operand 3 "q_regs_operand" "")
11225         (zero_extend (match_dup 1)))]
11226   "(peep2_reg_dead_p (3, operands[1])
11227     || operands_match_p (operands[1], operands[3]))
11228    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11229   [(set (match_dup 4) (match_dup 0))
11230    (set (strict_low_part (match_dup 5))
11231         (match_dup 2))]
11233   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11234   operands[5] = gen_lowpart (QImode, operands[3]);
11235   ix86_expand_clear (operands[3]);
11238 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11240 (define_peephole2
11241   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11242    (set (match_operand:QI 1 "register_operand" "")
11243         (match_operator:QI 2 "ix86_comparison_operator"
11244           [(reg FLAGS_REG) (const_int 0)]))
11245    (parallel [(set (match_operand 3 "q_regs_operand" "")
11246                    (zero_extend (match_dup 1)))
11247               (clobber (reg:CC FLAGS_REG))])]
11248   "(peep2_reg_dead_p (3, operands[1])
11249     || operands_match_p (operands[1], operands[3]))
11250    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11251   [(set (match_dup 4) (match_dup 0))
11252    (set (strict_low_part (match_dup 5))
11253         (match_dup 2))]
11255   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11256   operands[5] = gen_lowpart (QImode, operands[3]);
11257   ix86_expand_clear (operands[3]);
11260 ;; Call instructions.
11262 ;; The predicates normally associated with named expanders are not properly
11263 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11264 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11266 ;; P6 processors will jump to the address after the decrement when %esp
11267 ;; is used as a call operand, so they will execute return address as a code.
11268 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11270 ;; Register constraint for call instruction.
11271 (define_mode_attr c [(SI "l") (DI "r")])
11273 ;; Call subroutine returning no value.
11275 (define_expand "call"
11276   [(call (match_operand:QI 0 "" "")
11277          (match_operand 1 "" ""))
11278    (use (match_operand 2 "" ""))]
11279   ""
11281   ix86_expand_call (NULL, operands[0], operands[1],
11282                     operands[2], NULL, false);
11283   DONE;
11286 (define_expand "sibcall"
11287   [(call (match_operand:QI 0 "" "")
11288          (match_operand 1 "" ""))
11289    (use (match_operand 2 "" ""))]
11290   ""
11292   ix86_expand_call (NULL, operands[0], operands[1],
11293                     operands[2], NULL, true);
11294   DONE;
11297 (define_insn_and_split "*call_vzeroupper"
11298   [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11299          (match_operand 1 "" ""))
11300    (unspec [(match_operand 2 "const_int_operand" "")]
11301            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11302   "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11303   "#"
11304   "&& reload_completed"
11305   [(const_int 0)]
11306   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11307   [(set_attr "type" "call")])
11309 (define_insn "*call"
11310   [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11311          (match_operand 1 "" ""))]
11312   "!SIBLING_CALL_P (insn)"
11313   "* return ix86_output_call_insn (insn, operands[0]);"
11314   [(set_attr "type" "call")])
11316 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11317   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11318          (match_operand 1 "" ""))
11319    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11320    (clobber (reg:TI XMM6_REG))
11321    (clobber (reg:TI XMM7_REG))
11322    (clobber (reg:TI XMM8_REG))
11323    (clobber (reg:TI XMM9_REG))
11324    (clobber (reg:TI XMM10_REG))
11325    (clobber (reg:TI XMM11_REG))
11326    (clobber (reg:TI XMM12_REG))
11327    (clobber (reg:TI XMM13_REG))
11328    (clobber (reg:TI XMM14_REG))
11329    (clobber (reg:TI XMM15_REG))
11330    (clobber (reg:DI SI_REG))
11331    (clobber (reg:DI DI_REG))
11332    (unspec [(match_operand 2 "const_int_operand" "")]
11333            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11334   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11335   "#"
11336   "&& reload_completed"
11337   [(const_int 0)]
11338   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11339   [(set_attr "type" "call")])
11341 (define_insn "*call_rex64_ms_sysv"
11342   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11343          (match_operand 1 "" ""))
11344    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11345    (clobber (reg:TI XMM6_REG))
11346    (clobber (reg:TI XMM7_REG))
11347    (clobber (reg:TI XMM8_REG))
11348    (clobber (reg:TI XMM9_REG))
11349    (clobber (reg:TI XMM10_REG))
11350    (clobber (reg:TI XMM11_REG))
11351    (clobber (reg:TI XMM12_REG))
11352    (clobber (reg:TI XMM13_REG))
11353    (clobber (reg:TI XMM14_REG))
11354    (clobber (reg:TI XMM15_REG))
11355    (clobber (reg:DI SI_REG))
11356    (clobber (reg:DI DI_REG))]
11357   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11358   "* return ix86_output_call_insn (insn, operands[0]);"
11359   [(set_attr "type" "call")])
11361 (define_insn_and_split "*sibcall_vzeroupper"
11362   [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11363          (match_operand 1 "" ""))
11364    (unspec [(match_operand 2 "const_int_operand" "")]
11365            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11366   "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11367   "#"
11368   "&& reload_completed"
11369   [(const_int 0)]
11370   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11371   [(set_attr "type" "call")])
11373 (define_insn "*sibcall"
11374   [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11375          (match_operand 1 "" ""))]
11376   "SIBLING_CALL_P (insn)"
11377   "* return ix86_output_call_insn (insn, operands[0]);"
11378   [(set_attr "type" "call")])
11380 (define_expand "call_pop"
11381   [(parallel [(call (match_operand:QI 0 "" "")
11382                     (match_operand:SI 1 "" ""))
11383               (set (reg:SI SP_REG)
11384                    (plus:SI (reg:SI SP_REG)
11385                             (match_operand:SI 3 "" "")))])]
11386   "!TARGET_64BIT"
11388   ix86_expand_call (NULL, operands[0], operands[1],
11389                     operands[2], operands[3], false);
11390   DONE;
11393 (define_insn_and_split "*call_pop_vzeroupper"
11394   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11395          (match_operand:SI 1 "" ""))
11396    (set (reg:SI SP_REG)
11397         (plus:SI (reg:SI SP_REG)
11398                  (match_operand:SI 2 "immediate_operand" "i")))
11399    (unspec [(match_operand 3 "const_int_operand" "")]
11400            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11401   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11402   "#"
11403   "&& reload_completed"
11404   [(const_int 0)]
11405   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11406   [(set_attr "type" "call")])
11408 (define_insn "*call_pop"
11409   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11410          (match_operand 1 "" ""))
11411    (set (reg:SI SP_REG)
11412         (plus:SI (reg:SI SP_REG)
11413                  (match_operand:SI 2 "immediate_operand" "i")))]
11414   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11415   "* return ix86_output_call_insn (insn, operands[0]);"
11416   [(set_attr "type" "call")])
11418 (define_insn_and_split "*sibcall_pop_vzeroupper"
11419   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11420          (match_operand 1 "" ""))
11421    (set (reg:SI SP_REG)
11422         (plus:SI (reg:SI SP_REG)
11423                  (match_operand:SI 2 "immediate_operand" "i")))
11424    (unspec [(match_operand 3 "const_int_operand" "")]
11425            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11426   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11427   "#"
11428   "&& reload_completed"
11429   [(const_int 0)]
11430   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11431   [(set_attr "type" "call")])
11433 (define_insn "*sibcall_pop"
11434   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11435          (match_operand 1 "" ""))
11436    (set (reg:SI SP_REG)
11437         (plus:SI (reg:SI SP_REG)
11438                  (match_operand:SI 2 "immediate_operand" "i")))]
11439   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11440   "* return ix86_output_call_insn (insn, operands[0]);"
11441   [(set_attr "type" "call")])
11443 ;; Call subroutine, returning value in operand 0
11445 (define_expand "call_value"
11446   [(set (match_operand 0 "" "")
11447         (call (match_operand:QI 1 "" "")
11448               (match_operand 2 "" "")))
11449    (use (match_operand 3 "" ""))]
11450   ""
11452   ix86_expand_call (operands[0], operands[1], operands[2],
11453                     operands[3], NULL, false);
11454   DONE;
11457 (define_expand "sibcall_value"
11458   [(set (match_operand 0 "" "")
11459         (call (match_operand:QI 1 "" "")
11460               (match_operand 2 "" "")))
11461    (use (match_operand 3 "" ""))]
11462   ""
11464   ix86_expand_call (operands[0], operands[1], operands[2],
11465                     operands[3], NULL, true);
11466   DONE;
11469 (define_insn_and_split "*call_value_vzeroupper"
11470   [(set (match_operand 0 "" "")
11471         (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11472               (match_operand 2 "" "")))
11473    (unspec [(match_operand 3 "const_int_operand" "")]
11474            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11475   "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11476   "#"
11477   "&& reload_completed"
11478   [(const_int 0)]
11479   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11480   [(set_attr "type" "callv")])
11482 (define_insn "*call_value"
11483   [(set (match_operand 0 "" "")
11484         (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11485               (match_operand 2 "" "")))]
11486   "!SIBLING_CALL_P (insn)"
11487   "* return ix86_output_call_insn (insn, operands[1]);"
11488   [(set_attr "type" "callv")])
11490 (define_insn_and_split "*sibcall_value_vzeroupper"
11491   [(set (match_operand 0 "" "")
11492         (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11493               (match_operand 2 "" "")))
11494    (unspec [(match_operand 3 "const_int_operand" "")]
11495            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11496   "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11497   "#"
11498   "&& reload_completed"
11499   [(const_int 0)]
11500   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11501   [(set_attr "type" "callv")])
11503 (define_insn "*sibcall_value"
11504   [(set (match_operand 0 "" "")
11505         (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11506               (match_operand 2 "" "")))]
11507   "SIBLING_CALL_P (insn)"
11508   "* return ix86_output_call_insn (insn, operands[1]);"
11509   [(set_attr "type" "callv")])
11511 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11512   [(set (match_operand 0 "" "")
11513         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11514               (match_operand 2 "" "")))
11515    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11516    (clobber (reg:TI XMM6_REG))
11517    (clobber (reg:TI XMM7_REG))
11518    (clobber (reg:TI XMM8_REG))
11519    (clobber (reg:TI XMM9_REG))
11520    (clobber (reg:TI XMM10_REG))
11521    (clobber (reg:TI XMM11_REG))
11522    (clobber (reg:TI XMM12_REG))
11523    (clobber (reg:TI XMM13_REG))
11524    (clobber (reg:TI XMM14_REG))
11525    (clobber (reg:TI XMM15_REG))
11526    (clobber (reg:DI SI_REG))
11527    (clobber (reg:DI DI_REG))
11528    (unspec [(match_operand 3 "const_int_operand" "")]
11529            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11530   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11531   "#"
11532   "&& reload_completed"
11533   [(const_int 0)]
11534   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11535   [(set_attr "type" "callv")])
11537 (define_insn "*call_value_rex64_ms_sysv"
11538   [(set (match_operand 0 "" "")
11539         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11540               (match_operand 2 "" "")))
11541    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11542    (clobber (reg:TI XMM6_REG))
11543    (clobber (reg:TI XMM7_REG))
11544    (clobber (reg:TI XMM8_REG))
11545    (clobber (reg:TI XMM9_REG))
11546    (clobber (reg:TI XMM10_REG))
11547    (clobber (reg:TI XMM11_REG))
11548    (clobber (reg:TI XMM12_REG))
11549    (clobber (reg:TI XMM13_REG))
11550    (clobber (reg:TI XMM14_REG))
11551    (clobber (reg:TI XMM15_REG))
11552    (clobber (reg:DI SI_REG))
11553    (clobber (reg:DI DI_REG))]
11554   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11555   "* return ix86_output_call_insn (insn, operands[1]);"
11556   [(set_attr "type" "callv")])
11558 (define_expand "call_value_pop"
11559   [(parallel [(set (match_operand 0 "" "")
11560                    (call (match_operand:QI 1 "" "")
11561                          (match_operand:SI 2 "" "")))
11562               (set (reg:SI SP_REG)
11563                    (plus:SI (reg:SI SP_REG)
11564                             (match_operand:SI 4 "" "")))])]
11565   "!TARGET_64BIT"
11567   ix86_expand_call (operands[0], operands[1], operands[2],
11568                     operands[3], operands[4], false);
11569   DONE;
11572 (define_insn_and_split "*call_value_pop_vzeroupper"
11573   [(set (match_operand 0 "" "")
11574         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11575               (match_operand 2 "" "")))
11576    (set (reg:SI SP_REG)
11577         (plus:SI (reg:SI SP_REG)
11578                  (match_operand:SI 3 "immediate_operand" "i")))
11579    (unspec [(match_operand 4 "const_int_operand" "")]
11580            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11581   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11582   "#"
11583   "&& reload_completed"
11584   [(const_int 0)]
11585   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11586   [(set_attr "type" "callv")])
11588 (define_insn "*call_value_pop"
11589   [(set (match_operand 0 "" "")
11590         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11591               (match_operand 2 "" "")))
11592    (set (reg:SI SP_REG)
11593         (plus:SI (reg:SI SP_REG)
11594                  (match_operand:SI 3 "immediate_operand" "i")))]
11595   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11596   "* return ix86_output_call_insn (insn, operands[1]);"
11597   [(set_attr "type" "callv")])
11599 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11600   [(set (match_operand 0 "" "")
11601         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11602               (match_operand 2 "" "")))
11603    (set (reg:SI SP_REG)
11604         (plus:SI (reg:SI SP_REG)
11605                  (match_operand:SI 3 "immediate_operand" "i")))
11606    (unspec [(match_operand 4 "const_int_operand" "")]
11607            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11608   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11609   "#"
11610   "&& reload_completed"
11611   [(const_int 0)]
11612   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11613   [(set_attr "type" "callv")])
11615 (define_insn "*sibcall_value_pop"
11616   [(set (match_operand 0 "" "")
11617         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11618               (match_operand 2 "" "")))
11619    (set (reg:SI SP_REG)
11620         (plus:SI (reg:SI SP_REG)
11621                  (match_operand:SI 3 "immediate_operand" "i")))]
11622   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11623   "* return ix86_output_call_insn (insn, operands[1]);"
11624   [(set_attr "type" "callv")])
11626 ;; Call subroutine returning any type.
11628 (define_expand "untyped_call"
11629   [(parallel [(call (match_operand 0 "" "")
11630                     (const_int 0))
11631               (match_operand 1 "" "")
11632               (match_operand 2 "" "")])]
11633   ""
11635   int i;
11637   /* In order to give reg-stack an easier job in validating two
11638      coprocessor registers as containing a possible return value,
11639      simply pretend the untyped call returns a complex long double
11640      value. 
11642      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11643      and should have the default ABI.  */
11645   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11646                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11647                     operands[0], const0_rtx,
11648                     GEN_INT ((TARGET_64BIT
11649                               ? (ix86_abi == SYSV_ABI
11650                                  ? X86_64_SSE_REGPARM_MAX
11651                                  : X86_64_MS_SSE_REGPARM_MAX)
11652                               : X86_32_SSE_REGPARM_MAX)
11653                              - 1),
11654                     NULL, false);
11656   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11657     {
11658       rtx set = XVECEXP (operands[2], 0, i);
11659       emit_move_insn (SET_DEST (set), SET_SRC (set));
11660     }
11662   /* The optimizer does not know that the call sets the function value
11663      registers we stored in the result block.  We avoid problems by
11664      claiming that all hard registers are used and clobbered at this
11665      point.  */
11666   emit_insn (gen_blockage ());
11668   DONE;
11671 ;; Prologue and epilogue instructions
11673 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11674 ;; all of memory.  This blocks insns from being moved across this point.
11676 (define_insn "blockage"
11677   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11678   ""
11679   ""
11680   [(set_attr "length" "0")])
11682 ;; Do not schedule instructions accessing memory across this point.
11684 (define_expand "memory_blockage"
11685   [(set (match_dup 0)
11686         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11687   ""
11689   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11690   MEM_VOLATILE_P (operands[0]) = 1;
11693 (define_insn "*memory_blockage"
11694   [(set (match_operand:BLK 0 "" "")
11695         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11696   ""
11697   ""
11698   [(set_attr "length" "0")])
11700 ;; As USE insns aren't meaningful after reload, this is used instead
11701 ;; to prevent deleting instructions setting registers for PIC code
11702 (define_insn "prologue_use"
11703   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11704   ""
11705   ""
11706   [(set_attr "length" "0")])
11708 ;; Insn emitted into the body of a function to return from a function.
11709 ;; This is only done if the function's epilogue is known to be simple.
11710 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11712 (define_expand "return"
11713   [(simple_return)]
11714   "ix86_can_use_return_insn_p ()"
11716   if (crtl->args.pops_args)
11717     {
11718       rtx popc = GEN_INT (crtl->args.pops_args);
11719       emit_jump_insn (gen_simple_return_pop_internal (popc));
11720       DONE;
11721     }
11724 ;; We need to disable this for TARGET_SEH, as otherwise
11725 ;; shrink-wrapped prologue gets enabled too.  This might exceed
11726 ;; the maximum size of prologue in unwind information.
11728 (define_expand "simple_return"
11729   [(simple_return)]
11730   "!TARGET_SEH"
11732   if (crtl->args.pops_args)
11733     {
11734       rtx popc = GEN_INT (crtl->args.pops_args);
11735       emit_jump_insn (gen_simple_return_pop_internal (popc));
11736       DONE;
11737     }
11740 (define_insn "simple_return_internal"
11741   [(simple_return)]
11742   "reload_completed"
11743   "ret"
11744   [(set_attr "length" "1")
11745    (set_attr "atom_unit" "jeu")
11746    (set_attr "length_immediate" "0")
11747    (set_attr "modrm" "0")])
11749 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11750 ;; instruction Athlon and K8 have.
11752 (define_insn "simple_return_internal_long"
11753   [(simple_return)
11754    (unspec [(const_int 0)] UNSPEC_REP)]
11755   "reload_completed"
11756   "rep\;ret"
11757   [(set_attr "length" "2")
11758    (set_attr "atom_unit" "jeu")
11759    (set_attr "length_immediate" "0")
11760    (set_attr "prefix_rep" "1")
11761    (set_attr "modrm" "0")])
11763 (define_insn "simple_return_pop_internal"
11764   [(simple_return)
11765    (use (match_operand:SI 0 "const_int_operand" ""))]
11766   "reload_completed"
11767   "ret\t%0"
11768   [(set_attr "length" "3")
11769    (set_attr "atom_unit" "jeu")
11770    (set_attr "length_immediate" "2")
11771    (set_attr "modrm" "0")])
11773 (define_insn "simple_return_indirect_internal"
11774   [(simple_return)
11775    (use (match_operand:SI 0 "register_operand" "r"))]
11776   "reload_completed"
11777   "jmp\t%A0"
11778   [(set_attr "type" "ibr")
11779    (set_attr "length_immediate" "0")])
11781 (define_insn "nop"
11782   [(const_int 0)]
11783   ""
11784   "nop"
11785   [(set_attr "length" "1")
11786    (set_attr "length_immediate" "0")
11787    (set_attr "modrm" "0")])
11789 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
11790 (define_insn "nops"
11791   [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11792                     UNSPECV_NOPS)]
11793   "reload_completed"
11795   int num = INTVAL (operands[0]);
11797   gcc_assert (num >= 1 && num <= 8);
11799   while (num--)
11800     fputs ("\tnop\n", asm_out_file);
11802   return "";
11804   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11805    (set_attr "length_immediate" "0")
11806    (set_attr "modrm" "0")])
11808 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11809 ;; branch prediction penalty for the third jump in a 16-byte
11810 ;; block on K8.
11812 (define_insn "pad"
11813   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11814   ""
11816 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11817   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11818 #else
11819   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11820      The align insn is used to avoid 3 jump instructions in the row to improve
11821      branch prediction and the benefits hardly outweigh the cost of extra 8
11822      nops on the average inserted by full alignment pseudo operation.  */
11823 #endif
11824   return "";
11826   [(set_attr "length" "16")])
11828 (define_expand "prologue"
11829   [(const_int 0)]
11830   ""
11831   "ix86_expand_prologue (); DONE;")
11833 (define_insn "set_got"
11834   [(set (match_operand:SI 0 "register_operand" "=r")
11835         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11836    (clobber (reg:CC FLAGS_REG))]
11837   "!TARGET_64BIT"
11838   "* return output_set_got (operands[0], NULL_RTX);"
11839   [(set_attr "type" "multi")
11840    (set_attr "length" "12")])
11842 (define_insn "set_got_labelled"
11843   [(set (match_operand:SI 0 "register_operand" "=r")
11844         (unspec:SI [(label_ref (match_operand 1 "" ""))]
11845          UNSPEC_SET_GOT))
11846    (clobber (reg:CC FLAGS_REG))]
11847   "!TARGET_64BIT"
11848   "* return output_set_got (operands[0], operands[1]);"
11849   [(set_attr "type" "multi")
11850    (set_attr "length" "12")])
11852 (define_insn "set_got_rex64"
11853   [(set (match_operand:DI 0 "register_operand" "=r")
11854         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11855   "TARGET_64BIT"
11856   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11857   [(set_attr "type" "lea")
11858    (set_attr "length_address" "4")
11859    (set_attr "mode" "DI")])
11861 (define_insn "set_rip_rex64"
11862   [(set (match_operand:DI 0 "register_operand" "=r")
11863         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11864   "TARGET_64BIT"
11865   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11866   [(set_attr "type" "lea")
11867    (set_attr "length_address" "4")
11868    (set_attr "mode" "DI")])
11870 (define_insn "set_got_offset_rex64"
11871   [(set (match_operand:DI 0 "register_operand" "=r")
11872         (unspec:DI
11873           [(label_ref (match_operand 1 "" ""))]
11874           UNSPEC_SET_GOT_OFFSET))]
11875   "TARGET_LP64"
11876   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11877   [(set_attr "type" "imov")
11878    (set_attr "length_immediate" "0")
11879    (set_attr "length_address" "8")
11880    (set_attr "mode" "DI")])
11882 (define_expand "epilogue"
11883   [(const_int 0)]
11884   ""
11885   "ix86_expand_epilogue (1); DONE;")
11887 (define_expand "sibcall_epilogue"
11888   [(const_int 0)]
11889   ""
11890   "ix86_expand_epilogue (0); DONE;")
11892 (define_expand "eh_return"
11893   [(use (match_operand 0 "register_operand" ""))]
11894   ""
11896   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11898   /* Tricky bit: we write the address of the handler to which we will
11899      be returning into someone else's stack frame, one word below the
11900      stack address we wish to restore.  */
11901   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11902   tmp = plus_constant (tmp, -UNITS_PER_WORD);
11903   tmp = gen_rtx_MEM (Pmode, tmp);
11904   emit_move_insn (tmp, ra);
11906   emit_jump_insn (gen_eh_return_internal ());
11907   emit_barrier ();
11908   DONE;
11911 (define_insn_and_split "eh_return_internal"
11912   [(eh_return)]
11913   ""
11914   "#"
11915   "epilogue_completed"
11916   [(const_int 0)]
11917   "ix86_expand_epilogue (2); DONE;")
11919 (define_insn "leave"
11920   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11921    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11922    (clobber (mem:BLK (scratch)))]
11923   "!TARGET_64BIT"
11924   "leave"
11925   [(set_attr "type" "leave")])
11927 (define_insn "leave_rex64"
11928   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11929    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11930    (clobber (mem:BLK (scratch)))]
11931   "TARGET_64BIT"
11932   "leave"
11933   [(set_attr "type" "leave")])
11935 ;; Handle -fsplit-stack.
11937 (define_expand "split_stack_prologue"
11938   [(const_int 0)]
11939   ""
11941   ix86_expand_split_stack_prologue ();
11942   DONE;
11945 ;; In order to support the call/return predictor, we use a return
11946 ;; instruction which the middle-end doesn't see.
11947 (define_insn "split_stack_return"
11948   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11949                      UNSPECV_SPLIT_STACK_RETURN)]
11950   ""
11952   if (operands[0] == const0_rtx)
11953     return "ret";
11954   else
11955     return "ret\t%0";
11957   [(set_attr "atom_unit" "jeu")
11958    (set_attr "modrm" "0")
11959    (set (attr "length")
11960         (if_then_else (match_operand:SI 0 "const0_operand" "")
11961                       (const_int 1)
11962                       (const_int 3)))
11963    (set (attr "length_immediate")
11964         (if_then_else (match_operand:SI 0 "const0_operand" "")
11965                       (const_int 0)
11966                       (const_int 2)))])
11968 ;; If there are operand 0 bytes available on the stack, jump to
11969 ;; operand 1.
11971 (define_expand "split_stack_space_check"
11972   [(set (pc) (if_then_else
11973               (ltu (minus (reg SP_REG)
11974                           (match_operand 0 "register_operand" ""))
11975                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11976               (label_ref (match_operand 1 "" ""))
11977               (pc)))]
11978   ""
11980   rtx reg, size, limit;
11982   reg = gen_reg_rtx (Pmode);
11983   size = force_reg (Pmode, operands[0]);
11984   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11985   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11986                           UNSPEC_STACK_CHECK);
11987   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11988   ix86_expand_branch (GEU, reg, limit, operands[1]);
11990   DONE;
11993 ;; Bit manipulation instructions.
11995 (define_expand "ffs<mode>2"
11996   [(set (match_dup 2) (const_int -1))
11997    (parallel [(set (reg:CCZ FLAGS_REG)
11998                    (compare:CCZ
11999                      (match_operand:SWI48 1 "nonimmediate_operand" "")
12000                      (const_int 0)))
12001               (set (match_operand:SWI48 0 "register_operand" "")
12002                    (ctz:SWI48 (match_dup 1)))])
12003    (set (match_dup 0) (if_then_else:SWI48
12004                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
12005                         (match_dup 2)
12006                         (match_dup 0)))
12007    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12008               (clobber (reg:CC FLAGS_REG))])]
12009   ""
12011   if (<MODE>mode == SImode && !TARGET_CMOVE)
12012     {
12013       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12014       DONE;
12015     }
12016   operands[2] = gen_reg_rtx (<MODE>mode);
12019 (define_insn_and_split "ffssi2_no_cmove"
12020   [(set (match_operand:SI 0 "register_operand" "=r")
12021         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12022    (clobber (match_scratch:SI 2 "=&q"))
12023    (clobber (reg:CC FLAGS_REG))]
12024   "!TARGET_CMOVE"
12025   "#"
12026   "&& reload_completed"
12027   [(parallel [(set (reg:CCZ FLAGS_REG)
12028                    (compare:CCZ (match_dup 1) (const_int 0)))
12029               (set (match_dup 0) (ctz:SI (match_dup 1)))])
12030    (set (strict_low_part (match_dup 3))
12031         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12032    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12033               (clobber (reg:CC FLAGS_REG))])
12034    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12035               (clobber (reg:CC FLAGS_REG))])
12036    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12037               (clobber (reg:CC FLAGS_REG))])]
12039   operands[3] = gen_lowpart (QImode, operands[2]);
12040   ix86_expand_clear (operands[2]);
12043 (define_insn "*ffs<mode>_1"
12044   [(set (reg:CCZ FLAGS_REG)
12045         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12046                      (const_int 0)))
12047    (set (match_operand:SWI48 0 "register_operand" "=r")
12048         (ctz:SWI48 (match_dup 1)))]
12049   ""
12050   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12051   [(set_attr "type" "alu1")
12052    (set_attr "prefix_0f" "1")
12053    (set_attr "mode" "<MODE>")])
12055 (define_insn "ctz<mode>2"
12056   [(set (match_operand:SWI248 0 "register_operand" "=r")
12057         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12058    (clobber (reg:CC FLAGS_REG))]
12059   ""
12061   if (TARGET_BMI)
12062     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12063   else
12064     return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12066   [(set_attr "type" "alu1")
12067    (set_attr "prefix_0f" "1")
12068    (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12069    (set_attr "mode" "<MODE>")])
12071 (define_expand "clz<mode>2"
12072   [(parallel
12073      [(set (match_operand:SWI248 0 "register_operand" "")
12074            (minus:SWI248
12075              (match_dup 2)
12076              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12077       (clobber (reg:CC FLAGS_REG))])
12078    (parallel
12079      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12080       (clobber (reg:CC FLAGS_REG))])]
12081   ""
12083   if (TARGET_LZCNT)
12084     {
12085       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12086       DONE;
12087     }
12088   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12091 (define_insn "clz<mode>2_lzcnt"
12092   [(set (match_operand:SWI248 0 "register_operand" "=r")
12093         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12094    (clobber (reg:CC FLAGS_REG))]
12095   "TARGET_LZCNT"
12096   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12097   [(set_attr "prefix_rep" "1")
12098    (set_attr "type" "bitmanip")
12099    (set_attr "mode" "<MODE>")])
12101 ;; BMI instructions.
12102 (define_insn "*bmi_andn_<mode>"
12103   [(set (match_operand:SWI48 0 "register_operand" "=r")
12104         (and:SWI48
12105           (not:SWI48
12106             (match_operand:SWI48 1 "register_operand" "r"))
12107             (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12108    (clobber (reg:CC FLAGS_REG))]
12109   "TARGET_BMI"
12110   "andn\t{%2, %1, %0|%0, %1, %2}"
12111   [(set_attr "type" "bitmanip")
12112    (set_attr "mode" "<MODE>")])
12114 (define_insn "bmi_bextr_<mode>"
12115   [(set (match_operand:SWI48 0 "register_operand" "=r")
12116         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12117                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12118                        UNSPEC_BEXTR))
12119    (clobber (reg:CC FLAGS_REG))]
12120   "TARGET_BMI"
12121   "bextr\t{%2, %1, %0|%0, %1, %2}"
12122   [(set_attr "type" "bitmanip")
12123    (set_attr "mode" "<MODE>")])
12125 (define_insn "*bmi_blsi_<mode>"
12126   [(set (match_operand:SWI48 0 "register_operand" "=r")
12127         (and:SWI48
12128           (neg:SWI48
12129             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12130           (match_dup 1)))
12131    (clobber (reg:CC FLAGS_REG))]
12132   "TARGET_BMI"
12133   "blsi\t{%1, %0|%0, %1}"
12134   [(set_attr "type" "bitmanip")
12135    (set_attr "mode" "<MODE>")])
12137 (define_insn "*bmi_blsmsk_<mode>"
12138   [(set (match_operand:SWI48 0 "register_operand" "=r")
12139         (xor:SWI48
12140           (plus:SWI48
12141             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12142             (const_int -1))
12143           (match_dup 1)))
12144    (clobber (reg:CC FLAGS_REG))]
12145   "TARGET_BMI"
12146   "blsmsk\t{%1, %0|%0, %1}"
12147   [(set_attr "type" "bitmanip")
12148    (set_attr "mode" "<MODE>")])
12150 (define_insn "*bmi_blsr_<mode>"
12151   [(set (match_operand:SWI48 0 "register_operand" "=r")
12152         (and:SWI48
12153           (plus:SWI48
12154             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12155             (const_int -1))
12156           (match_dup 1)))
12157    (clobber (reg:CC FLAGS_REG))]
12158    "TARGET_BMI"
12159    "blsr\t{%1, %0|%0, %1}"
12160   [(set_attr "type" "bitmanip")
12161    (set_attr "mode" "<MODE>")])
12163 ;; BMI2 instructions.
12164 (define_insn "bmi2_bzhi_<mode>3"
12165   [(set (match_operand:SWI48 0 "register_operand" "=r")
12166         (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12167                    (lshiftrt:SWI48 (const_int -1)
12168                                    (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12169    (clobber (reg:CC FLAGS_REG))]
12170   "TARGET_BMI2"
12171   "bzhi\t{%2, %1, %0|%0, %1, %2}"
12172   [(set_attr "type" "bitmanip")
12173    (set_attr "prefix" "vex")
12174    (set_attr "mode" "<MODE>")])
12176 (define_insn "bmi2_pdep_<mode>3"
12177   [(set (match_operand:SWI48 0 "register_operand" "=r")
12178         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12179                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12180                        UNSPEC_PDEP))]
12181   "TARGET_BMI2"
12182   "pdep\t{%2, %1, %0|%0, %1, %2}"
12183   [(set_attr "type" "bitmanip")
12184    (set_attr "prefix" "vex")
12185    (set_attr "mode" "<MODE>")])
12187 (define_insn "bmi2_pext_<mode>3"
12188   [(set (match_operand:SWI48 0 "register_operand" "=r")
12189         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12190                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12191                        UNSPEC_PEXT))]
12192   "TARGET_BMI2"
12193   "pext\t{%2, %1, %0|%0, %1, %2}"
12194   [(set_attr "type" "bitmanip")
12195    (set_attr "prefix" "vex")
12196    (set_attr "mode" "<MODE>")])
12198 ;; TBM instructions.
12199 (define_insn "tbm_bextri_<mode>"
12200   [(set (match_operand:SWI48 0 "register_operand" "=r")
12201         (zero_extract:SWI48
12202           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12203           (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12204           (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12205    (clobber (reg:CC FLAGS_REG))]
12206    "TARGET_TBM"
12208   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12209   return "bextr\t{%2, %1, %0|%0, %1, %2}";
12211   [(set_attr "type" "bitmanip")
12212    (set_attr "mode" "<MODE>")])
12214 (define_insn "*tbm_blcfill_<mode>"
12215   [(set (match_operand:SWI48 0 "register_operand" "=r")
12216         (and:SWI48
12217           (plus:SWI48
12218             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12219             (const_int 1))
12220           (match_dup 1)))
12221    (clobber (reg:CC FLAGS_REG))]
12222    "TARGET_TBM"
12223    "blcfill\t{%1, %0|%0, %1}"
12224   [(set_attr "type" "bitmanip")
12225    (set_attr "mode" "<MODE>")])
12227 (define_insn "*tbm_blci_<mode>"
12228   [(set (match_operand:SWI48 0 "register_operand" "=r")
12229         (ior:SWI48
12230           (not:SWI48
12231             (plus:SWI48
12232               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12233               (const_int 1)))
12234           (match_dup 1)))
12235    (clobber (reg:CC FLAGS_REG))]
12236    "TARGET_TBM"
12237    "blci\t{%1, %0|%0, %1}"
12238   [(set_attr "type" "bitmanip")
12239    (set_attr "mode" "<MODE>")])
12241 (define_insn "*tbm_blcic_<mode>"
12242   [(set (match_operand:SWI48 0 "register_operand" "=r")
12243         (and:SWI48
12244           (plus:SWI48
12245             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12246             (const_int 1))
12247           (not:SWI48
12248             (match_dup 1))))
12249    (clobber (reg:CC FLAGS_REG))]
12250    "TARGET_TBM"
12251    "blcic\t{%1, %0|%0, %1}"
12252   [(set_attr "type" "bitmanip")
12253    (set_attr "mode" "<MODE>")])
12255 (define_insn "*tbm_blcmsk_<mode>"
12256   [(set (match_operand:SWI48 0 "register_operand" "=r")
12257         (xor:SWI48
12258           (plus:SWI48
12259             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12260             (const_int 1))
12261           (match_dup 1)))
12262    (clobber (reg:CC FLAGS_REG))]
12263    "TARGET_TBM"
12264    "blcmsk\t{%1, %0|%0, %1}"
12265   [(set_attr "type" "bitmanip")
12266    (set_attr "mode" "<MODE>")])
12268 (define_insn "*tbm_blcs_<mode>"
12269   [(set (match_operand:SWI48 0 "register_operand" "=r")
12270         (ior:SWI48
12271           (plus:SWI48
12272             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12273             (const_int 1))
12274           (match_dup 1)))
12275    (clobber (reg:CC FLAGS_REG))]
12276    "TARGET_TBM"
12277    "blcs\t{%1, %0|%0, %1}"
12278   [(set_attr "type" "bitmanip")
12279    (set_attr "mode" "<MODE>")])
12281 (define_insn "*tbm_blsfill_<mode>"
12282   [(set (match_operand:SWI48 0 "register_operand" "=r")
12283         (ior:SWI48
12284           (plus:SWI48
12285             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12286             (const_int -1))
12287           (match_dup 1)))
12288    (clobber (reg:CC FLAGS_REG))]
12289    "TARGET_TBM"
12290    "blsfill\t{%1, %0|%0, %1}"
12291   [(set_attr "type" "bitmanip")
12292    (set_attr "mode" "<MODE>")])
12294 (define_insn "*tbm_blsic_<mode>"
12295   [(set (match_operand:SWI48 0 "register_operand" "=r")
12296         (ior:SWI48
12297           (plus:SWI48
12298             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12299             (const_int -1))
12300           (not:SWI48
12301             (match_dup 1))))
12302    (clobber (reg:CC FLAGS_REG))]
12303    "TARGET_TBM"
12304    "blsic\t{%1, %0|%0, %1}"
12305   [(set_attr "type" "bitmanip")
12306    (set_attr "mode" "<MODE>")])
12308 (define_insn "*tbm_t1mskc_<mode>"
12309   [(set (match_operand:SWI48 0 "register_operand" "=r")
12310         (ior:SWI48
12311           (plus:SWI48
12312             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12313             (const_int 1))
12314           (not:SWI48
12315             (match_dup 1))))
12316    (clobber (reg:CC FLAGS_REG))]
12317    "TARGET_TBM"
12318    "t1mskc\t{%1, %0|%0, %1}"
12319   [(set_attr "type" "bitmanip")
12320    (set_attr "mode" "<MODE>")])
12322 (define_insn "*tbm_tzmsk_<mode>"
12323   [(set (match_operand:SWI48 0 "register_operand" "=r")
12324         (and:SWI48
12325           (plus:SWI48
12326             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12327             (const_int -1))
12328           (not:SWI48
12329             (match_dup 1))))
12330    (clobber (reg:CC FLAGS_REG))]
12331    "TARGET_TBM"
12332    "tzmsk\t{%1, %0|%0, %1}"
12333   [(set_attr "type" "bitmanip")
12334    (set_attr "mode" "<MODE>")])
12336 (define_insn "bsr_rex64"
12337   [(set (match_operand:DI 0 "register_operand" "=r")
12338         (minus:DI (const_int 63)
12339                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12340    (clobber (reg:CC FLAGS_REG))]
12341   "TARGET_64BIT"
12342   "bsr{q}\t{%1, %0|%0, %1}"
12343   [(set_attr "type" "alu1")
12344    (set_attr "prefix_0f" "1")
12345    (set_attr "mode" "DI")])
12347 (define_insn "bsr"
12348   [(set (match_operand:SI 0 "register_operand" "=r")
12349         (minus:SI (const_int 31)
12350                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12351    (clobber (reg:CC FLAGS_REG))]
12352   ""
12353   "bsr{l}\t{%1, %0|%0, %1}"
12354   [(set_attr "type" "alu1")
12355    (set_attr "prefix_0f" "1")
12356    (set_attr "mode" "SI")])
12358 (define_insn "*bsrhi"
12359   [(set (match_operand:HI 0 "register_operand" "=r")
12360         (minus:HI (const_int 15)
12361                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12362    (clobber (reg:CC FLAGS_REG))]
12363   ""
12364   "bsr{w}\t{%1, %0|%0, %1}"
12365   [(set_attr "type" "alu1")
12366    (set_attr "prefix_0f" "1")
12367    (set_attr "mode" "HI")])
12369 (define_insn "popcount<mode>2"
12370   [(set (match_operand:SWI248 0 "register_operand" "=r")
12371         (popcount:SWI248
12372           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12373    (clobber (reg:CC FLAGS_REG))]
12374   "TARGET_POPCNT"
12376 #if TARGET_MACHO
12377   return "popcnt\t{%1, %0|%0, %1}";
12378 #else
12379   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12380 #endif
12382   [(set_attr "prefix_rep" "1")
12383    (set_attr "type" "bitmanip")
12384    (set_attr "mode" "<MODE>")])
12386 (define_insn "*popcount<mode>2_cmp"
12387   [(set (reg FLAGS_REG)
12388         (compare
12389           (popcount:SWI248
12390             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12391           (const_int 0)))
12392    (set (match_operand:SWI248 0 "register_operand" "=r")
12393         (popcount:SWI248 (match_dup 1)))]
12394   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12396 #if TARGET_MACHO
12397   return "popcnt\t{%1, %0|%0, %1}";
12398 #else
12399   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12400 #endif
12402   [(set_attr "prefix_rep" "1")
12403    (set_attr "type" "bitmanip")
12404    (set_attr "mode" "<MODE>")])
12406 (define_insn "*popcountsi2_cmp_zext"
12407   [(set (reg FLAGS_REG)
12408         (compare
12409           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12410           (const_int 0)))
12411    (set (match_operand:DI 0 "register_operand" "=r")
12412         (zero_extend:DI(popcount:SI (match_dup 1))))]
12413   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12415 #if TARGET_MACHO
12416   return "popcnt\t{%1, %0|%0, %1}";
12417 #else
12418   return "popcnt{l}\t{%1, %0|%0, %1}";
12419 #endif
12421   [(set_attr "prefix_rep" "1")
12422    (set_attr "type" "bitmanip")
12423    (set_attr "mode" "SI")])
12425 (define_expand "bswap<mode>2"
12426   [(set (match_operand:SWI48 0 "register_operand" "")
12427         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12428   ""
12430   if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12431     {
12432       rtx x = operands[0];
12434       emit_move_insn (x, operands[1]);
12435       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12436       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12437       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12438       DONE;
12439     }
12442 (define_insn "*bswap<mode>2_movbe"
12443   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12444         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12445   "TARGET_MOVBE
12446    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12447   "@
12448     bswap\t%0
12449     movbe\t{%1, %0|%0, %1}
12450     movbe\t{%1, %0|%0, %1}"
12451   [(set_attr "type" "bitmanip,imov,imov")
12452    (set_attr "modrm" "0,1,1")
12453    (set_attr "prefix_0f" "*,1,1")
12454    (set_attr "prefix_extra" "*,1,1")
12455    (set_attr "mode" "<MODE>")])
12457 (define_insn "*bswap<mode>2_1"
12458   [(set (match_operand:SWI48 0 "register_operand" "=r")
12459         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12460   "TARGET_BSWAP"
12461   "bswap\t%0"
12462   [(set_attr "type" "bitmanip")
12463    (set_attr "modrm" "0")
12464    (set_attr "mode" "<MODE>")])
12466 (define_insn "*bswaphi_lowpart_1"
12467   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12468         (bswap:HI (match_dup 0)))
12469    (clobber (reg:CC FLAGS_REG))]
12470   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12471   "@
12472     xchg{b}\t{%h0, %b0|%b0, %h0}
12473     rol{w}\t{$8, %0|%0, 8}"
12474   [(set_attr "length" "2,4")
12475    (set_attr "mode" "QI,HI")])
12477 (define_insn "bswaphi_lowpart"
12478   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12479         (bswap:HI (match_dup 0)))
12480    (clobber (reg:CC FLAGS_REG))]
12481   ""
12482   "rol{w}\t{$8, %0|%0, 8}"
12483   [(set_attr "length" "4")
12484    (set_attr "mode" "HI")])
12486 (define_expand "paritydi2"
12487   [(set (match_operand:DI 0 "register_operand" "")
12488         (parity:DI (match_operand:DI 1 "register_operand" "")))]
12489   "! TARGET_POPCNT"
12491   rtx scratch = gen_reg_rtx (QImode);
12492   rtx cond;
12494   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12495                                 NULL_RTX, operands[1]));
12497   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12498                          gen_rtx_REG (CCmode, FLAGS_REG),
12499                          const0_rtx);
12500   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12502   if (TARGET_64BIT)
12503     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12504   else
12505     {
12506       rtx tmp = gen_reg_rtx (SImode);
12508       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12509       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12510     }
12511   DONE;
12514 (define_expand "paritysi2"
12515   [(set (match_operand:SI 0 "register_operand" "")
12516         (parity:SI (match_operand:SI 1 "register_operand" "")))]
12517   "! TARGET_POPCNT"
12519   rtx scratch = gen_reg_rtx (QImode);
12520   rtx cond;
12522   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12524   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12525                          gen_rtx_REG (CCmode, FLAGS_REG),
12526                          const0_rtx);
12527   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12529   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12530   DONE;
12533 (define_insn_and_split "paritydi2_cmp"
12534   [(set (reg:CC FLAGS_REG)
12535         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12536                    UNSPEC_PARITY))
12537    (clobber (match_scratch:DI 0 "=r"))
12538    (clobber (match_scratch:SI 1 "=&r"))
12539    (clobber (match_scratch:HI 2 "=Q"))]
12540   "! TARGET_POPCNT"
12541   "#"
12542   "&& reload_completed"
12543   [(parallel
12544      [(set (match_dup 1)
12545            (xor:SI (match_dup 1) (match_dup 4)))
12546       (clobber (reg:CC FLAGS_REG))])
12547    (parallel
12548      [(set (reg:CC FLAGS_REG)
12549            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12550       (clobber (match_dup 1))
12551       (clobber (match_dup 2))])]
12553   operands[4] = gen_lowpart (SImode, operands[3]);
12555   if (TARGET_64BIT)
12556     {
12557       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12558       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12559     }
12560   else
12561     operands[1] = gen_highpart (SImode, operands[3]);
12564 (define_insn_and_split "paritysi2_cmp"
12565   [(set (reg:CC FLAGS_REG)
12566         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12567                    UNSPEC_PARITY))
12568    (clobber (match_scratch:SI 0 "=r"))
12569    (clobber (match_scratch:HI 1 "=&Q"))]
12570   "! TARGET_POPCNT"
12571   "#"
12572   "&& reload_completed"
12573   [(parallel
12574      [(set (match_dup 1)
12575            (xor:HI (match_dup 1) (match_dup 3)))
12576       (clobber (reg:CC FLAGS_REG))])
12577    (parallel
12578      [(set (reg:CC FLAGS_REG)
12579            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12580       (clobber (match_dup 1))])]
12582   operands[3] = gen_lowpart (HImode, operands[2]);
12584   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12585   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12588 (define_insn "*parityhi2_cmp"
12589   [(set (reg:CC FLAGS_REG)
12590         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12591                    UNSPEC_PARITY))
12592    (clobber (match_scratch:HI 0 "=Q"))]
12593   "! TARGET_POPCNT"
12594   "xor{b}\t{%h0, %b0|%b0, %h0}"
12595   [(set_attr "length" "2")
12596    (set_attr "mode" "HI")])
12599 ;; Thread-local storage patterns for ELF.
12601 ;; Note that these code sequences must appear exactly as shown
12602 ;; in order to allow linker relaxation.
12604 (define_insn "*tls_global_dynamic_32_gnu"
12605   [(set (match_operand:SI 0 "register_operand" "=a")
12606         (unspec:SI
12607          [(match_operand:SI 1 "register_operand" "b")
12608           (match_operand:SI 2 "tls_symbolic_operand" "")
12609           (match_operand:SI 3 "constant_call_address_operand" "z")]
12610          UNSPEC_TLS_GD))
12611    (clobber (match_scratch:SI 4 "=d"))
12612    (clobber (match_scratch:SI 5 "=c"))
12613    (clobber (reg:CC FLAGS_REG))]
12614   "!TARGET_64BIT && TARGET_GNU_TLS"
12616   output_asm_insn
12617     ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12618   if (TARGET_SUN_TLS)
12619 #ifdef HAVE_AS_IX86_TLSGDPLT
12620     return "call\t%a2@tlsgdplt";
12621 #else
12622     return "call\t%p3@plt";
12623 #endif
12624   return "call\t%P3";
12626   [(set_attr "type" "multi")
12627    (set_attr "length" "12")])
12629 (define_expand "tls_global_dynamic_32"
12630   [(parallel
12631     [(set (match_operand:SI 0 "register_operand" "")
12632           (unspec:SI [(match_operand:SI 2 "register_operand" "")
12633                       (match_operand:SI 1 "tls_symbolic_operand" "")
12634                       (match_operand:SI 3 "constant_call_address_operand" "")]
12635                      UNSPEC_TLS_GD))
12636      (clobber (match_scratch:SI 4 ""))
12637      (clobber (match_scratch:SI 5 ""))
12638      (clobber (reg:CC FLAGS_REG))])])
12640 (define_insn "*tls_global_dynamic_64"
12641   [(set (match_operand:DI 0 "register_operand" "=a")
12642         (call:DI
12643          (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12644          (match_operand:DI 3 "" "")))
12645    (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12646               UNSPEC_TLS_GD)]
12647   "TARGET_64BIT"
12649   if (!TARGET_X32)
12650     fputs (ASM_BYTE "0x66\n", asm_out_file);
12651   output_asm_insn
12652     ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12653   fputs (ASM_SHORT "0x6666\n", asm_out_file);
12654   fputs ("\trex64\n", asm_out_file);
12655   if (TARGET_SUN_TLS)
12656     return "call\t%p2@plt";
12657   return "call\t%P2";
12659   [(set_attr "type" "multi")
12660    (set (attr "length")
12661         (symbol_ref "TARGET_X32 ? 15 : 16"))])
12663 (define_expand "tls_global_dynamic_64"
12664   [(parallel
12665     [(set (match_operand:DI 0 "register_operand" "")
12666           (call:DI
12667            (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12668            (const_int 0)))
12669      (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12670                 UNSPEC_TLS_GD)])])
12672 (define_insn "*tls_local_dynamic_base_32_gnu"
12673   [(set (match_operand:SI 0 "register_operand" "=a")
12674         (unspec:SI
12675          [(match_operand:SI 1 "register_operand" "b")
12676           (match_operand:SI 2 "constant_call_address_operand" "z")]
12677          UNSPEC_TLS_LD_BASE))
12678    (clobber (match_scratch:SI 3 "=d"))
12679    (clobber (match_scratch:SI 4 "=c"))
12680    (clobber (reg:CC FLAGS_REG))]
12681   "!TARGET_64BIT && TARGET_GNU_TLS"
12683   output_asm_insn
12684     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12685   if (TARGET_SUN_TLS)
12686 #ifdef HAVE_AS_IX86_TLSLDMPLT
12687     return "call\t%&@tlsldmplt";
12688 #else
12689     return "call\t%p2@plt";
12690 #endif
12691   return "call\t%P2";
12693   [(set_attr "type" "multi")
12694    (set_attr "length" "11")])
12696 (define_expand "tls_local_dynamic_base_32"
12697   [(parallel
12698      [(set (match_operand:SI 0 "register_operand" "")
12699            (unspec:SI
12700             [(match_operand:SI 1 "register_operand" "")
12701              (match_operand:SI 2 "constant_call_address_operand" "")]
12702             UNSPEC_TLS_LD_BASE))
12703       (clobber (match_scratch:SI 3 ""))
12704       (clobber (match_scratch:SI 4 ""))
12705       (clobber (reg:CC FLAGS_REG))])])
12707 (define_insn "*tls_local_dynamic_base_64"
12708   [(set (match_operand:DI 0 "register_operand" "=a")
12709         (call:DI
12710          (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12711          (match_operand:DI 2 "" "")))
12712    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12713   "TARGET_64BIT"
12715   output_asm_insn
12716     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12717   if (TARGET_SUN_TLS)
12718     return "call\t%p1@plt";
12719   return "call\t%P1";
12721   [(set_attr "type" "multi")
12722    (set_attr "length" "12")])
12724 (define_expand "tls_local_dynamic_base_64"
12725   [(parallel
12726      [(set (match_operand:DI 0 "register_operand" "")
12727            (call:DI
12728             (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12729             (const_int 0)))
12730       (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12732 ;; Local dynamic of a single variable is a lose.  Show combine how
12733 ;; to convert that back to global dynamic.
12735 (define_insn_and_split "*tls_local_dynamic_32_once"
12736   [(set (match_operand:SI 0 "register_operand" "=a")
12737         (plus:SI
12738          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12739                      (match_operand:SI 2 "constant_call_address_operand" "z")]
12740                     UNSPEC_TLS_LD_BASE)
12741          (const:SI (unspec:SI
12742                     [(match_operand:SI 3 "tls_symbolic_operand" "")]
12743                     UNSPEC_DTPOFF))))
12744    (clobber (match_scratch:SI 4 "=d"))
12745    (clobber (match_scratch:SI 5 "=c"))
12746    (clobber (reg:CC FLAGS_REG))]
12747   ""
12748   "#"
12749   ""
12750   [(parallel
12751      [(set (match_dup 0)
12752            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12753                       UNSPEC_TLS_GD))
12754       (clobber (match_dup 4))
12755       (clobber (match_dup 5))
12756       (clobber (reg:CC FLAGS_REG))])])
12758 ;; Segment register for the thread base ptr load
12759 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12761 ;; Load and add the thread base pointer from %<tp_seg>:0.
12762 (define_insn "*load_tp_x32"
12763   [(set (match_operand:SI 0 "register_operand" "=r")
12764         (unspec:SI [(const_int 0)] UNSPEC_TP))]
12765   "TARGET_X32"
12766   "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12767   [(set_attr "type" "imov")
12768    (set_attr "modrm" "0")
12769    (set_attr "length" "7")
12770    (set_attr "memory" "load")
12771    (set_attr "imm_disp" "false")])
12773 (define_insn "*load_tp_x32_zext"
12774   [(set (match_operand:DI 0 "register_operand" "=r")
12775         (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12776   "TARGET_X32"
12777   "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12778   [(set_attr "type" "imov")
12779    (set_attr "modrm" "0")
12780    (set_attr "length" "7")
12781    (set_attr "memory" "load")
12782    (set_attr "imm_disp" "false")])
12784 (define_insn "*load_tp_<mode>"
12785   [(set (match_operand:P 0 "register_operand" "=r")
12786         (unspec:P [(const_int 0)] UNSPEC_TP))]
12787   "!TARGET_X32"
12788   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12789   [(set_attr "type" "imov")
12790    (set_attr "modrm" "0")
12791    (set_attr "length" "7")
12792    (set_attr "memory" "load")
12793    (set_attr "imm_disp" "false")])
12795 (define_insn "*add_tp_x32"
12796   [(set (match_operand:SI 0 "register_operand" "=r")
12797         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12798                  (match_operand:SI 1 "register_operand" "0")))
12799    (clobber (reg:CC FLAGS_REG))]
12800   "TARGET_X32"
12801   "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12802   [(set_attr "type" "alu")
12803    (set_attr "modrm" "0")
12804    (set_attr "length" "7")
12805    (set_attr "memory" "load")
12806    (set_attr "imm_disp" "false")])
12808 (define_insn "*add_tp_x32_zext"
12809   [(set (match_operand:DI 0 "register_operand" "=r")
12810         (zero_extend:DI
12811           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12812                    (match_operand:SI 1 "register_operand" "0"))))
12813    (clobber (reg:CC FLAGS_REG))]
12814   "TARGET_X32"
12815   "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12816   [(set_attr "type" "alu")
12817    (set_attr "modrm" "0")
12818    (set_attr "length" "7")
12819    (set_attr "memory" "load")
12820    (set_attr "imm_disp" "false")])
12822 (define_insn "*add_tp_<mode>"
12823   [(set (match_operand:P 0 "register_operand" "=r")
12824         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12825                 (match_operand:P 1 "register_operand" "0")))
12826    (clobber (reg:CC FLAGS_REG))]
12827   "!TARGET_X32"
12828   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12829   [(set_attr "type" "alu")
12830    (set_attr "modrm" "0")
12831    (set_attr "length" "7")
12832    (set_attr "memory" "load")
12833    (set_attr "imm_disp" "false")])
12835 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12836 ;; %rax as destination of the initial executable code sequence.
12837 (define_insn "tls_initial_exec_64_sun"
12838   [(set (match_operand:DI 0 "register_operand" "=a")
12839         (unspec:DI
12840          [(match_operand:DI 1 "tls_symbolic_operand" "")]
12841          UNSPEC_TLS_IE_SUN))
12842    (clobber (reg:CC FLAGS_REG))]
12843   "TARGET_64BIT && TARGET_SUN_TLS"
12845   output_asm_insn
12846     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12847   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12849   [(set_attr "type" "multi")])
12851 ;; GNU2 TLS patterns can be split.
12853 (define_expand "tls_dynamic_gnu2_32"
12854   [(set (match_dup 3)
12855         (plus:SI (match_operand:SI 2 "register_operand" "")
12856                  (const:SI
12857                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12858                              UNSPEC_TLSDESC))))
12859    (parallel
12860     [(set (match_operand:SI 0 "register_operand" "")
12861           (unspec:SI [(match_dup 1) (match_dup 3)
12862                       (match_dup 2) (reg:SI SP_REG)]
12863                       UNSPEC_TLSDESC))
12864      (clobber (reg:CC FLAGS_REG))])]
12865   "!TARGET_64BIT && TARGET_GNU2_TLS"
12867   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12868   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12871 (define_insn "*tls_dynamic_gnu2_lea_32"
12872   [(set (match_operand:SI 0 "register_operand" "=r")
12873         (plus:SI (match_operand:SI 1 "register_operand" "b")
12874                  (const:SI
12875                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12876                               UNSPEC_TLSDESC))))]
12877   "!TARGET_64BIT && TARGET_GNU2_TLS"
12878   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12879   [(set_attr "type" "lea")
12880    (set_attr "mode" "SI")
12881    (set_attr "length" "6")
12882    (set_attr "length_address" "4")])
12884 (define_insn "*tls_dynamic_gnu2_call_32"
12885   [(set (match_operand:SI 0 "register_operand" "=a")
12886         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12887                     (match_operand:SI 2 "register_operand" "0")
12888                     ;; we have to make sure %ebx still points to the GOT
12889                     (match_operand:SI 3 "register_operand" "b")
12890                     (reg:SI SP_REG)]
12891                    UNSPEC_TLSDESC))
12892    (clobber (reg:CC FLAGS_REG))]
12893   "!TARGET_64BIT && TARGET_GNU2_TLS"
12894   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12895   [(set_attr "type" "call")
12896    (set_attr "length" "2")
12897    (set_attr "length_address" "0")])
12899 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12900   [(set (match_operand:SI 0 "register_operand" "=&a")
12901         (plus:SI
12902          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12903                      (match_operand:SI 4 "" "")
12904                      (match_operand:SI 2 "register_operand" "b")
12905                      (reg:SI SP_REG)]
12906                     UNSPEC_TLSDESC)
12907          (const:SI (unspec:SI
12908                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
12909                     UNSPEC_DTPOFF))))
12910    (clobber (reg:CC FLAGS_REG))]
12911   "!TARGET_64BIT && TARGET_GNU2_TLS"
12912   "#"
12913   ""
12914   [(set (match_dup 0) (match_dup 5))]
12916   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12917   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12920 (define_expand "tls_dynamic_gnu2_64"
12921   [(set (match_dup 2)
12922         (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12923                    UNSPEC_TLSDESC))
12924    (parallel
12925     [(set (match_operand:DI 0 "register_operand" "")
12926           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12927                      UNSPEC_TLSDESC))
12928      (clobber (reg:CC FLAGS_REG))])]
12929   "TARGET_64BIT && TARGET_GNU2_TLS"
12931   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12932   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12935 (define_insn "*tls_dynamic_gnu2_lea_64"
12936   [(set (match_operand:DI 0 "register_operand" "=r")
12937         (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12938                    UNSPEC_TLSDESC))]
12939   "TARGET_64BIT && TARGET_GNU2_TLS"
12940   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12941   [(set_attr "type" "lea")
12942    (set_attr "mode" "DI")
12943    (set_attr "length" "7")
12944    (set_attr "length_address" "4")])
12946 (define_insn "*tls_dynamic_gnu2_call_64"
12947   [(set (match_operand:DI 0 "register_operand" "=a")
12948         (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12949                     (match_operand:DI 2 "register_operand" "0")
12950                     (reg:DI SP_REG)]
12951                    UNSPEC_TLSDESC))
12952    (clobber (reg:CC FLAGS_REG))]
12953   "TARGET_64BIT && TARGET_GNU2_TLS"
12954   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12955   [(set_attr "type" "call")
12956    (set_attr "length" "2")
12957    (set_attr "length_address" "0")])
12959 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12960   [(set (match_operand:DI 0 "register_operand" "=&a")
12961         (plus:DI
12962          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12963                      (match_operand:DI 3 "" "")
12964                      (reg:DI SP_REG)]
12965                     UNSPEC_TLSDESC)
12966          (const:DI (unspec:DI
12967                     [(match_operand 1 "tls_symbolic_operand" "")]
12968                     UNSPEC_DTPOFF))))
12969    (clobber (reg:CC FLAGS_REG))]
12970   "TARGET_64BIT && TARGET_GNU2_TLS"
12971   "#"
12972   ""
12973   [(set (match_dup 0) (match_dup 4))]
12975   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12976   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12979 ;; These patterns match the binary 387 instructions for addM3, subM3,
12980 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
12981 ;; SFmode.  The first is the normal insn, the second the same insn but
12982 ;; with one operand a conversion, and the third the same insn but with
12983 ;; the other operand a conversion.  The conversion may be SFmode or
12984 ;; SImode if the target mode DFmode, but only SImode if the target mode
12985 ;; is SFmode.
12987 ;; Gcc is slightly more smart about handling normal two address instructions
12988 ;; so use special patterns for add and mull.
12990 (define_insn "*fop_<mode>_comm_mixed"
12991   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12992         (match_operator:MODEF 3 "binary_fp_operator"
12993           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12994            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12995   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12996    && COMMUTATIVE_ARITH_P (operands[3])
12997    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12998   "* return output_387_binary_op (insn, operands);"
12999   [(set (attr "type")
13000         (if_then_else (eq_attr "alternative" "1,2")
13001            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13002               (const_string "ssemul")
13003               (const_string "sseadd"))
13004            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13005               (const_string "fmul")
13006               (const_string "fop"))))
13007    (set_attr "isa" "*,noavx,avx")
13008    (set_attr "prefix" "orig,orig,vex")
13009    (set_attr "mode" "<MODE>")])
13011 (define_insn "*fop_<mode>_comm_sse"
13012   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13013         (match_operator:MODEF 3 "binary_fp_operator"
13014           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13015            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13016   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13017    && COMMUTATIVE_ARITH_P (operands[3])
13018    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13019   "* return output_387_binary_op (insn, operands);"
13020   [(set (attr "type")
13021         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13022            (const_string "ssemul")
13023            (const_string "sseadd")))
13024    (set_attr "isa" "noavx,avx")
13025    (set_attr "prefix" "orig,vex")
13026    (set_attr "mode" "<MODE>")])
13028 (define_insn "*fop_<mode>_comm_i387"
13029   [(set (match_operand:MODEF 0 "register_operand" "=f")
13030         (match_operator:MODEF 3 "binary_fp_operator"
13031           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13032            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13033   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13034    && COMMUTATIVE_ARITH_P (operands[3])
13035    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13036   "* return output_387_binary_op (insn, operands);"
13037   [(set (attr "type")
13038         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13039            (const_string "fmul")
13040            (const_string "fop")))
13041    (set_attr "mode" "<MODE>")])
13043 (define_insn "*fop_<mode>_1_mixed"
13044   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13045         (match_operator:MODEF 3 "binary_fp_operator"
13046           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13047            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13048   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13049    && !COMMUTATIVE_ARITH_P (operands[3])
13050    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13051   "* return output_387_binary_op (insn, operands);"
13052   [(set (attr "type")
13053         (cond [(and (eq_attr "alternative" "2,3")
13054                     (match_operand:MODEF 3 "mult_operator" ""))
13055                  (const_string "ssemul")
13056                (and (eq_attr "alternative" "2,3")
13057                     (match_operand:MODEF 3 "div_operator" ""))
13058                  (const_string "ssediv")
13059                (eq_attr "alternative" "2,3")
13060                  (const_string "sseadd")
13061                (match_operand:MODEF 3 "mult_operator" "")
13062                  (const_string "fmul")
13063                (match_operand:MODEF 3 "div_operator" "")
13064                  (const_string "fdiv")
13065               ]
13066               (const_string "fop")))
13067    (set_attr "isa" "*,*,noavx,avx")
13068    (set_attr "prefix" "orig,orig,orig,vex")
13069    (set_attr "mode" "<MODE>")])
13071 (define_insn "*rcpsf2_sse"
13072   [(set (match_operand:SF 0 "register_operand" "=x")
13073         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13074                    UNSPEC_RCP))]
13075   "TARGET_SSE_MATH"
13076   "%vrcpss\t{%1, %d0|%d0, %1}"
13077   [(set_attr "type" "sse")
13078    (set_attr "atom_sse_attr" "rcp")
13079    (set_attr "prefix" "maybe_vex")
13080    (set_attr "mode" "SF")])
13082 (define_insn "*fop_<mode>_1_sse"
13083   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13084         (match_operator:MODEF 3 "binary_fp_operator"
13085           [(match_operand:MODEF 1 "register_operand" "0,x")
13086            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13087   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13088    && !COMMUTATIVE_ARITH_P (operands[3])"
13089   "* return output_387_binary_op (insn, operands);"
13090   [(set (attr "type")
13091         (cond [(match_operand:MODEF 3 "mult_operator" "")
13092                  (const_string "ssemul")
13093                (match_operand:MODEF 3 "div_operator" "")
13094                  (const_string "ssediv")
13095               ]
13096               (const_string "sseadd")))
13097    (set_attr "isa" "noavx,avx")
13098    (set_attr "prefix" "orig,vex")
13099    (set_attr "mode" "<MODE>")])
13101 ;; This pattern is not fully shadowed by the pattern above.
13102 (define_insn "*fop_<mode>_1_i387"
13103   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13104         (match_operator:MODEF 3 "binary_fp_operator"
13105           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13106            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13107   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13108    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13109    && !COMMUTATIVE_ARITH_P (operands[3])
13110    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13111   "* return output_387_binary_op (insn, operands);"
13112   [(set (attr "type")
13113         (cond [(match_operand:MODEF 3 "mult_operator" "")
13114                  (const_string "fmul")
13115                (match_operand:MODEF 3 "div_operator" "")
13116                  (const_string "fdiv")
13117               ]
13118               (const_string "fop")))
13119    (set_attr "mode" "<MODE>")])
13121 ;; ??? Add SSE splitters for these!
13122 (define_insn "*fop_<MODEF:mode>_2_i387"
13123   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13124         (match_operator:MODEF 3 "binary_fp_operator"
13125           [(float:MODEF
13126              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13127            (match_operand:MODEF 2 "register_operand" "0,0")]))]
13128   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13129    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13130    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13131   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13132   [(set (attr "type")
13133         (cond [(match_operand:MODEF 3 "mult_operator" "")
13134                  (const_string "fmul")
13135                (match_operand:MODEF 3 "div_operator" "")
13136                  (const_string "fdiv")
13137               ]
13138               (const_string "fop")))
13139    (set_attr "fp_int_src" "true")
13140    (set_attr "mode" "<SWI24:MODE>")])
13142 (define_insn "*fop_<MODEF:mode>_3_i387"
13143   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13144         (match_operator:MODEF 3 "binary_fp_operator"
13145           [(match_operand:MODEF 1 "register_operand" "0,0")
13146            (float:MODEF
13147              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13148   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13149    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13150    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13151   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13152   [(set (attr "type")
13153         (cond [(match_operand:MODEF 3 "mult_operator" "")
13154                  (const_string "fmul")
13155                (match_operand:MODEF 3 "div_operator" "")
13156                  (const_string "fdiv")
13157               ]
13158               (const_string "fop")))
13159    (set_attr "fp_int_src" "true")
13160    (set_attr "mode" "<MODE>")])
13162 (define_insn "*fop_df_4_i387"
13163   [(set (match_operand:DF 0 "register_operand" "=f,f")
13164         (match_operator:DF 3 "binary_fp_operator"
13165            [(float_extend:DF
13166              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13167             (match_operand:DF 2 "register_operand" "0,f")]))]
13168   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13169    && !(TARGET_SSE2 && TARGET_SSE_MATH)
13170    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13171   "* return output_387_binary_op (insn, operands);"
13172   [(set (attr "type")
13173         (cond [(match_operand:DF 3 "mult_operator" "")
13174                  (const_string "fmul")
13175                (match_operand:DF 3 "div_operator" "")
13176                  (const_string "fdiv")
13177               ]
13178               (const_string "fop")))
13179    (set_attr "mode" "SF")])
13181 (define_insn "*fop_df_5_i387"
13182   [(set (match_operand:DF 0 "register_operand" "=f,f")
13183         (match_operator:DF 3 "binary_fp_operator"
13184           [(match_operand:DF 1 "register_operand" "0,f")
13185            (float_extend:DF
13186             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13187   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13188    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13189   "* return output_387_binary_op (insn, operands);"
13190   [(set (attr "type")
13191         (cond [(match_operand:DF 3 "mult_operator" "")
13192                  (const_string "fmul")
13193                (match_operand:DF 3 "div_operator" "")
13194                  (const_string "fdiv")
13195               ]
13196               (const_string "fop")))
13197    (set_attr "mode" "SF")])
13199 (define_insn "*fop_df_6_i387"
13200   [(set (match_operand:DF 0 "register_operand" "=f,f")
13201         (match_operator:DF 3 "binary_fp_operator"
13202           [(float_extend:DF
13203             (match_operand:SF 1 "register_operand" "0,f"))
13204            (float_extend:DF
13205             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13206   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13207    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13208   "* return output_387_binary_op (insn, operands);"
13209   [(set (attr "type")
13210         (cond [(match_operand:DF 3 "mult_operator" "")
13211                  (const_string "fmul")
13212                (match_operand:DF 3 "div_operator" "")
13213                  (const_string "fdiv")
13214               ]
13215               (const_string "fop")))
13216    (set_attr "mode" "SF")])
13218 (define_insn "*fop_xf_comm_i387"
13219   [(set (match_operand:XF 0 "register_operand" "=f")
13220         (match_operator:XF 3 "binary_fp_operator"
13221                         [(match_operand:XF 1 "register_operand" "%0")
13222                          (match_operand:XF 2 "register_operand" "f")]))]
13223   "TARGET_80387
13224    && COMMUTATIVE_ARITH_P (operands[3])"
13225   "* return output_387_binary_op (insn, operands);"
13226   [(set (attr "type")
13227         (if_then_else (match_operand:XF 3 "mult_operator" "")
13228            (const_string "fmul")
13229            (const_string "fop")))
13230    (set_attr "mode" "XF")])
13232 (define_insn "*fop_xf_1_i387"
13233   [(set (match_operand:XF 0 "register_operand" "=f,f")
13234         (match_operator:XF 3 "binary_fp_operator"
13235                         [(match_operand:XF 1 "register_operand" "0,f")
13236                          (match_operand:XF 2 "register_operand" "f,0")]))]
13237   "TARGET_80387
13238    && !COMMUTATIVE_ARITH_P (operands[3])"
13239   "* return output_387_binary_op (insn, operands);"
13240   [(set (attr "type")
13241         (cond [(match_operand:XF 3 "mult_operator" "")
13242                  (const_string "fmul")
13243                (match_operand:XF 3 "div_operator" "")
13244                  (const_string "fdiv")
13245               ]
13246               (const_string "fop")))
13247    (set_attr "mode" "XF")])
13249 (define_insn "*fop_xf_2_i387"
13250   [(set (match_operand:XF 0 "register_operand" "=f,f")
13251         (match_operator:XF 3 "binary_fp_operator"
13252           [(float:XF
13253              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13254            (match_operand:XF 2 "register_operand" "0,0")]))]
13255   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13256   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13257   [(set (attr "type")
13258         (cond [(match_operand:XF 3 "mult_operator" "")
13259                  (const_string "fmul")
13260                (match_operand:XF 3 "div_operator" "")
13261                  (const_string "fdiv")
13262               ]
13263               (const_string "fop")))
13264    (set_attr "fp_int_src" "true")
13265    (set_attr "mode" "<MODE>")])
13267 (define_insn "*fop_xf_3_i387"
13268   [(set (match_operand:XF 0 "register_operand" "=f,f")
13269         (match_operator:XF 3 "binary_fp_operator"
13270           [(match_operand:XF 1 "register_operand" "0,0")
13271            (float:XF
13272              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13273   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13274   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13275   [(set (attr "type")
13276         (cond [(match_operand:XF 3 "mult_operator" "")
13277                  (const_string "fmul")
13278                (match_operand:XF 3 "div_operator" "")
13279                  (const_string "fdiv")
13280               ]
13281               (const_string "fop")))
13282    (set_attr "fp_int_src" "true")
13283    (set_attr "mode" "<MODE>")])
13285 (define_insn "*fop_xf_4_i387"
13286   [(set (match_operand:XF 0 "register_operand" "=f,f")
13287         (match_operator:XF 3 "binary_fp_operator"
13288            [(float_extend:XF
13289               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13290             (match_operand:XF 2 "register_operand" "0,f")]))]
13291   "TARGET_80387"
13292   "* return output_387_binary_op (insn, operands);"
13293   [(set (attr "type")
13294         (cond [(match_operand:XF 3 "mult_operator" "")
13295                  (const_string "fmul")
13296                (match_operand:XF 3 "div_operator" "")
13297                  (const_string "fdiv")
13298               ]
13299               (const_string "fop")))
13300    (set_attr "mode" "<MODE>")])
13302 (define_insn "*fop_xf_5_i387"
13303   [(set (match_operand:XF 0 "register_operand" "=f,f")
13304         (match_operator:XF 3 "binary_fp_operator"
13305           [(match_operand:XF 1 "register_operand" "0,f")
13306            (float_extend:XF
13307              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13308   "TARGET_80387"
13309   "* return output_387_binary_op (insn, operands);"
13310   [(set (attr "type")
13311         (cond [(match_operand:XF 3 "mult_operator" "")
13312                  (const_string "fmul")
13313                (match_operand:XF 3 "div_operator" "")
13314                  (const_string "fdiv")
13315               ]
13316               (const_string "fop")))
13317    (set_attr "mode" "<MODE>")])
13319 (define_insn "*fop_xf_6_i387"
13320   [(set (match_operand:XF 0 "register_operand" "=f,f")
13321         (match_operator:XF 3 "binary_fp_operator"
13322           [(float_extend:XF
13323              (match_operand:MODEF 1 "register_operand" "0,f"))
13324            (float_extend:XF
13325              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13326   "TARGET_80387"
13327   "* return output_387_binary_op (insn, operands);"
13328   [(set (attr "type")
13329         (cond [(match_operand:XF 3 "mult_operator" "")
13330                  (const_string "fmul")
13331                (match_operand:XF 3 "div_operator" "")
13332                  (const_string "fdiv")
13333               ]
13334               (const_string "fop")))
13335    (set_attr "mode" "<MODE>")])
13337 (define_split
13338   [(set (match_operand 0 "register_operand" "")
13339         (match_operator 3 "binary_fp_operator"
13340            [(float (match_operand:SWI24 1 "register_operand" ""))
13341             (match_operand 2 "register_operand" "")]))]
13342   "reload_completed
13343    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13344    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13345   [(const_int 0)]
13347   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13348   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13349   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13350                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13351                                           GET_MODE (operands[3]),
13352                                           operands[4],
13353                                           operands[2])));
13354   ix86_free_from_memory (GET_MODE (operands[1]));
13355   DONE;
13358 (define_split
13359   [(set (match_operand 0 "register_operand" "")
13360         (match_operator 3 "binary_fp_operator"
13361            [(match_operand 1 "register_operand" "")
13362             (float (match_operand:SWI24 2 "register_operand" ""))]))]
13363   "reload_completed
13364    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13365    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13366   [(const_int 0)]
13368   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13369   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13370   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13371                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13372                                           GET_MODE (operands[3]),
13373                                           operands[1],
13374                                           operands[4])));
13375   ix86_free_from_memory (GET_MODE (operands[2]));
13376   DONE;
13379 ;; FPU special functions.
13381 ;; This pattern implements a no-op XFmode truncation for
13382 ;; all fancy i386 XFmode math functions.
13384 (define_insn "truncxf<mode>2_i387_noop_unspec"
13385   [(set (match_operand:MODEF 0 "register_operand" "=f")
13386         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13387         UNSPEC_TRUNC_NOOP))]
13388   "TARGET_USE_FANCY_MATH_387"
13389   "* return output_387_reg_move (insn, operands);"
13390   [(set_attr "type" "fmov")
13391    (set_attr "mode" "<MODE>")])
13393 (define_insn "sqrtxf2"
13394   [(set (match_operand:XF 0 "register_operand" "=f")
13395         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13396   "TARGET_USE_FANCY_MATH_387"
13397   "fsqrt"
13398   [(set_attr "type" "fpspc")
13399    (set_attr "mode" "XF")
13400    (set_attr "athlon_decode" "direct")
13401    (set_attr "amdfam10_decode" "direct")
13402    (set_attr "bdver1_decode" "direct")])
13404 (define_insn "sqrt_extend<mode>xf2_i387"
13405   [(set (match_operand:XF 0 "register_operand" "=f")
13406         (sqrt:XF
13407           (float_extend:XF
13408             (match_operand:MODEF 1 "register_operand" "0"))))]
13409   "TARGET_USE_FANCY_MATH_387"
13410   "fsqrt"
13411   [(set_attr "type" "fpspc")
13412    (set_attr "mode" "XF")
13413    (set_attr "athlon_decode" "direct")
13414    (set_attr "amdfam10_decode" "direct")
13415    (set_attr "bdver1_decode" "direct")])
13417 (define_insn "*rsqrtsf2_sse"
13418   [(set (match_operand:SF 0 "register_operand" "=x")
13419         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13420                    UNSPEC_RSQRT))]
13421   "TARGET_SSE_MATH"
13422   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13423   [(set_attr "type" "sse")
13424    (set_attr "atom_sse_attr" "rcp")
13425    (set_attr "prefix" "maybe_vex")
13426    (set_attr "mode" "SF")])
13428 (define_expand "rsqrtsf2"
13429   [(set (match_operand:SF 0 "register_operand" "")
13430         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13431                    UNSPEC_RSQRT))]
13432   "TARGET_SSE_MATH"
13434   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13435   DONE;
13438 (define_insn "*sqrt<mode>2_sse"
13439   [(set (match_operand:MODEF 0 "register_operand" "=x")
13440         (sqrt:MODEF
13441           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13442   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13443   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13444   [(set_attr "type" "sse")
13445    (set_attr "atom_sse_attr" "sqrt")
13446    (set_attr "prefix" "maybe_vex")
13447    (set_attr "mode" "<MODE>")
13448    (set_attr "athlon_decode" "*")
13449    (set_attr "amdfam10_decode" "*")
13450    (set_attr "bdver1_decode" "*")])
13452 (define_expand "sqrt<mode>2"
13453   [(set (match_operand:MODEF 0 "register_operand" "")
13454         (sqrt:MODEF
13455           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13456   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13457    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13459   if (<MODE>mode == SFmode
13460       && TARGET_SSE_MATH
13461       && TARGET_RECIP_SQRT
13462       && !optimize_function_for_size_p (cfun)
13463       && flag_finite_math_only && !flag_trapping_math
13464       && flag_unsafe_math_optimizations)
13465     {
13466       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13467       DONE;
13468     }
13470   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13471     {
13472       rtx op0 = gen_reg_rtx (XFmode);
13473       rtx op1 = force_reg (<MODE>mode, operands[1]);
13475       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13476       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13477       DONE;
13478    }
13481 (define_insn "fpremxf4_i387"
13482   [(set (match_operand:XF 0 "register_operand" "=f")
13483         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13484                     (match_operand:XF 3 "register_operand" "1")]
13485                    UNSPEC_FPREM_F))
13486    (set (match_operand:XF 1 "register_operand" "=u")
13487         (unspec:XF [(match_dup 2) (match_dup 3)]
13488                    UNSPEC_FPREM_U))
13489    (set (reg:CCFP FPSR_REG)
13490         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13491                      UNSPEC_C2_FLAG))]
13492   "TARGET_USE_FANCY_MATH_387"
13493   "fprem"
13494   [(set_attr "type" "fpspc")
13495    (set_attr "mode" "XF")])
13497 (define_expand "fmodxf3"
13498   [(use (match_operand:XF 0 "register_operand" ""))
13499    (use (match_operand:XF 1 "general_operand" ""))
13500    (use (match_operand:XF 2 "general_operand" ""))]
13501   "TARGET_USE_FANCY_MATH_387"
13503   rtx label = gen_label_rtx ();
13505   rtx op1 = gen_reg_rtx (XFmode);
13506   rtx op2 = gen_reg_rtx (XFmode);
13508   emit_move_insn (op2, operands[2]);
13509   emit_move_insn (op1, operands[1]);
13511   emit_label (label);
13512   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13513   ix86_emit_fp_unordered_jump (label);
13514   LABEL_NUSES (label) = 1;
13516   emit_move_insn (operands[0], op1);
13517   DONE;
13520 (define_expand "fmod<mode>3"
13521   [(use (match_operand:MODEF 0 "register_operand" ""))
13522    (use (match_operand:MODEF 1 "general_operand" ""))
13523    (use (match_operand:MODEF 2 "general_operand" ""))]
13524   "TARGET_USE_FANCY_MATH_387"
13526   rtx (*gen_truncxf) (rtx, rtx);
13528   rtx label = gen_label_rtx ();
13530   rtx op1 = gen_reg_rtx (XFmode);
13531   rtx op2 = gen_reg_rtx (XFmode);
13533   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13534   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13536   emit_label (label);
13537   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13538   ix86_emit_fp_unordered_jump (label);
13539   LABEL_NUSES (label) = 1;
13541   /* Truncate the result properly for strict SSE math.  */
13542   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13543       && !TARGET_MIX_SSE_I387)
13544     gen_truncxf = gen_truncxf<mode>2;
13545   else
13546     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13548   emit_insn (gen_truncxf (operands[0], op1));
13549   DONE;
13552 (define_insn "fprem1xf4_i387"
13553   [(set (match_operand:XF 0 "register_operand" "=f")
13554         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13555                     (match_operand:XF 3 "register_operand" "1")]
13556                    UNSPEC_FPREM1_F))
13557    (set (match_operand:XF 1 "register_operand" "=u")
13558         (unspec:XF [(match_dup 2) (match_dup 3)]
13559                    UNSPEC_FPREM1_U))
13560    (set (reg:CCFP FPSR_REG)
13561         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13562                      UNSPEC_C2_FLAG))]
13563   "TARGET_USE_FANCY_MATH_387"
13564   "fprem1"
13565   [(set_attr "type" "fpspc")
13566    (set_attr "mode" "XF")])
13568 (define_expand "remainderxf3"
13569   [(use (match_operand:XF 0 "register_operand" ""))
13570    (use (match_operand:XF 1 "general_operand" ""))
13571    (use (match_operand:XF 2 "general_operand" ""))]
13572   "TARGET_USE_FANCY_MATH_387"
13574   rtx label = gen_label_rtx ();
13576   rtx op1 = gen_reg_rtx (XFmode);
13577   rtx op2 = gen_reg_rtx (XFmode);
13579   emit_move_insn (op2, operands[2]);
13580   emit_move_insn (op1, operands[1]);
13582   emit_label (label);
13583   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13584   ix86_emit_fp_unordered_jump (label);
13585   LABEL_NUSES (label) = 1;
13587   emit_move_insn (operands[0], op1);
13588   DONE;
13591 (define_expand "remainder<mode>3"
13592   [(use (match_operand:MODEF 0 "register_operand" ""))
13593    (use (match_operand:MODEF 1 "general_operand" ""))
13594    (use (match_operand:MODEF 2 "general_operand" ""))]
13595   "TARGET_USE_FANCY_MATH_387"
13597   rtx (*gen_truncxf) (rtx, rtx);
13599   rtx label = gen_label_rtx ();
13601   rtx op1 = gen_reg_rtx (XFmode);
13602   rtx op2 = gen_reg_rtx (XFmode);
13604   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13605   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13607   emit_label (label);
13609   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13610   ix86_emit_fp_unordered_jump (label);
13611   LABEL_NUSES (label) = 1;
13613   /* Truncate the result properly for strict SSE math.  */
13614   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13615       && !TARGET_MIX_SSE_I387)
13616     gen_truncxf = gen_truncxf<mode>2;
13617   else
13618     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13620   emit_insn (gen_truncxf (operands[0], op1));
13621   DONE;
13624 (define_insn "*sinxf2_i387"
13625   [(set (match_operand:XF 0 "register_operand" "=f")
13626         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13627   "TARGET_USE_FANCY_MATH_387
13628    && flag_unsafe_math_optimizations"
13629   "fsin"
13630   [(set_attr "type" "fpspc")
13631    (set_attr "mode" "XF")])
13633 (define_insn "*sin_extend<mode>xf2_i387"
13634   [(set (match_operand:XF 0 "register_operand" "=f")
13635         (unspec:XF [(float_extend:XF
13636                       (match_operand:MODEF 1 "register_operand" "0"))]
13637                    UNSPEC_SIN))]
13638   "TARGET_USE_FANCY_MATH_387
13639    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13640        || TARGET_MIX_SSE_I387)
13641    && flag_unsafe_math_optimizations"
13642   "fsin"
13643   [(set_attr "type" "fpspc")
13644    (set_attr "mode" "XF")])
13646 (define_insn "*cosxf2_i387"
13647   [(set (match_operand:XF 0 "register_operand" "=f")
13648         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13649   "TARGET_USE_FANCY_MATH_387
13650    && flag_unsafe_math_optimizations"
13651   "fcos"
13652   [(set_attr "type" "fpspc")
13653    (set_attr "mode" "XF")])
13655 (define_insn "*cos_extend<mode>xf2_i387"
13656   [(set (match_operand:XF 0 "register_operand" "=f")
13657         (unspec:XF [(float_extend:XF
13658                       (match_operand:MODEF 1 "register_operand" "0"))]
13659                    UNSPEC_COS))]
13660   "TARGET_USE_FANCY_MATH_387
13661    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13662        || TARGET_MIX_SSE_I387)
13663    && flag_unsafe_math_optimizations"
13664   "fcos"
13665   [(set_attr "type" "fpspc")
13666    (set_attr "mode" "XF")])
13668 ;; When sincos pattern is defined, sin and cos builtin functions will be
13669 ;; expanded to sincos pattern with one of its outputs left unused.
13670 ;; CSE pass will figure out if two sincos patterns can be combined,
13671 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13672 ;; depending on the unused output.
13674 (define_insn "sincosxf3"
13675   [(set (match_operand:XF 0 "register_operand" "=f")
13676         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13677                    UNSPEC_SINCOS_COS))
13678    (set (match_operand:XF 1 "register_operand" "=u")
13679         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13680   "TARGET_USE_FANCY_MATH_387
13681    && flag_unsafe_math_optimizations"
13682   "fsincos"
13683   [(set_attr "type" "fpspc")
13684    (set_attr "mode" "XF")])
13686 (define_split
13687   [(set (match_operand:XF 0 "register_operand" "")
13688         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13689                    UNSPEC_SINCOS_COS))
13690    (set (match_operand:XF 1 "register_operand" "")
13691         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13692   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13693    && can_create_pseudo_p ()"
13694   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13696 (define_split
13697   [(set (match_operand:XF 0 "register_operand" "")
13698         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13699                    UNSPEC_SINCOS_COS))
13700    (set (match_operand:XF 1 "register_operand" "")
13701         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13702   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13703    && can_create_pseudo_p ()"
13704   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13706 (define_insn "sincos_extend<mode>xf3_i387"
13707   [(set (match_operand:XF 0 "register_operand" "=f")
13708         (unspec:XF [(float_extend:XF
13709                       (match_operand:MODEF 2 "register_operand" "0"))]
13710                    UNSPEC_SINCOS_COS))
13711    (set (match_operand:XF 1 "register_operand" "=u")
13712         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13713   "TARGET_USE_FANCY_MATH_387
13714    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13715        || TARGET_MIX_SSE_I387)
13716    && flag_unsafe_math_optimizations"
13717   "fsincos"
13718   [(set_attr "type" "fpspc")
13719    (set_attr "mode" "XF")])
13721 (define_split
13722   [(set (match_operand:XF 0 "register_operand" "")
13723         (unspec:XF [(float_extend:XF
13724                       (match_operand:MODEF 2 "register_operand" ""))]
13725                    UNSPEC_SINCOS_COS))
13726    (set (match_operand:XF 1 "register_operand" "")
13727         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13728   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13729    && can_create_pseudo_p ()"
13730   [(set (match_dup 1)
13731         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13733 (define_split
13734   [(set (match_operand:XF 0 "register_operand" "")
13735         (unspec:XF [(float_extend:XF
13736                       (match_operand:MODEF 2 "register_operand" ""))]
13737                    UNSPEC_SINCOS_COS))
13738    (set (match_operand:XF 1 "register_operand" "")
13739         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13740   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13741    && can_create_pseudo_p ()"
13742   [(set (match_dup 0)
13743         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13745 (define_expand "sincos<mode>3"
13746   [(use (match_operand:MODEF 0 "register_operand" ""))
13747    (use (match_operand:MODEF 1 "register_operand" ""))
13748    (use (match_operand:MODEF 2 "register_operand" ""))]
13749   "TARGET_USE_FANCY_MATH_387
13750    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13751        || TARGET_MIX_SSE_I387)
13752    && flag_unsafe_math_optimizations"
13754   rtx op0 = gen_reg_rtx (XFmode);
13755   rtx op1 = gen_reg_rtx (XFmode);
13757   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13758   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13759   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13760   DONE;
13763 (define_insn "fptanxf4_i387"
13764   [(set (match_operand:XF 0 "register_operand" "=f")
13765         (match_operand:XF 3 "const_double_operand" "F"))
13766    (set (match_operand:XF 1 "register_operand" "=u")
13767         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13768                    UNSPEC_TAN))]
13769   "TARGET_USE_FANCY_MATH_387
13770    && flag_unsafe_math_optimizations
13771    && standard_80387_constant_p (operands[3]) == 2"
13772   "fptan"
13773   [(set_attr "type" "fpspc")
13774    (set_attr "mode" "XF")])
13776 (define_insn "fptan_extend<mode>xf4_i387"
13777   [(set (match_operand:MODEF 0 "register_operand" "=f")
13778         (match_operand:MODEF 3 "const_double_operand" "F"))
13779    (set (match_operand:XF 1 "register_operand" "=u")
13780         (unspec:XF [(float_extend:XF
13781                       (match_operand:MODEF 2 "register_operand" "0"))]
13782                    UNSPEC_TAN))]
13783   "TARGET_USE_FANCY_MATH_387
13784    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13785        || TARGET_MIX_SSE_I387)
13786    && flag_unsafe_math_optimizations
13787    && standard_80387_constant_p (operands[3]) == 2"
13788   "fptan"
13789   [(set_attr "type" "fpspc")
13790    (set_attr "mode" "XF")])
13792 (define_expand "tanxf2"
13793   [(use (match_operand:XF 0 "register_operand" ""))
13794    (use (match_operand:XF 1 "register_operand" ""))]
13795   "TARGET_USE_FANCY_MATH_387
13796    && flag_unsafe_math_optimizations"
13798   rtx one = gen_reg_rtx (XFmode);
13799   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13801   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13802   DONE;
13805 (define_expand "tan<mode>2"
13806   [(use (match_operand:MODEF 0 "register_operand" ""))
13807    (use (match_operand:MODEF 1 "register_operand" ""))]
13808   "TARGET_USE_FANCY_MATH_387
13809    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13810        || TARGET_MIX_SSE_I387)
13811    && flag_unsafe_math_optimizations"
13813   rtx op0 = gen_reg_rtx (XFmode);
13815   rtx one = gen_reg_rtx (<MODE>mode);
13816   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13818   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13819                                              operands[1], op2));
13820   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13821   DONE;
13824 (define_insn "*fpatanxf3_i387"
13825   [(set (match_operand:XF 0 "register_operand" "=f")
13826         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13827                     (match_operand:XF 2 "register_operand" "u")]
13828                    UNSPEC_FPATAN))
13829    (clobber (match_scratch:XF 3 "=2"))]
13830   "TARGET_USE_FANCY_MATH_387
13831    && flag_unsafe_math_optimizations"
13832   "fpatan"
13833   [(set_attr "type" "fpspc")
13834    (set_attr "mode" "XF")])
13836 (define_insn "fpatan_extend<mode>xf3_i387"
13837   [(set (match_operand:XF 0 "register_operand" "=f")
13838         (unspec:XF [(float_extend:XF
13839                       (match_operand:MODEF 1 "register_operand" "0"))
13840                     (float_extend:XF
13841                       (match_operand:MODEF 2 "register_operand" "u"))]
13842                    UNSPEC_FPATAN))
13843    (clobber (match_scratch:XF 3 "=2"))]
13844   "TARGET_USE_FANCY_MATH_387
13845    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13846        || TARGET_MIX_SSE_I387)
13847    && flag_unsafe_math_optimizations"
13848   "fpatan"
13849   [(set_attr "type" "fpspc")
13850    (set_attr "mode" "XF")])
13852 (define_expand "atan2xf3"
13853   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13854                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
13855                                (match_operand:XF 1 "register_operand" "")]
13856                               UNSPEC_FPATAN))
13857               (clobber (match_scratch:XF 3 ""))])]
13858   "TARGET_USE_FANCY_MATH_387
13859    && flag_unsafe_math_optimizations")
13861 (define_expand "atan2<mode>3"
13862   [(use (match_operand:MODEF 0 "register_operand" ""))
13863    (use (match_operand:MODEF 1 "register_operand" ""))
13864    (use (match_operand:MODEF 2 "register_operand" ""))]
13865   "TARGET_USE_FANCY_MATH_387
13866    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13867        || TARGET_MIX_SSE_I387)
13868    && flag_unsafe_math_optimizations"
13870   rtx op0 = gen_reg_rtx (XFmode);
13872   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13873   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13874   DONE;
13877 (define_expand "atanxf2"
13878   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13879                    (unspec:XF [(match_dup 2)
13880                                (match_operand:XF 1 "register_operand" "")]
13881                               UNSPEC_FPATAN))
13882               (clobber (match_scratch:XF 3 ""))])]
13883   "TARGET_USE_FANCY_MATH_387
13884    && flag_unsafe_math_optimizations"
13886   operands[2] = gen_reg_rtx (XFmode);
13887   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13890 (define_expand "atan<mode>2"
13891   [(use (match_operand:MODEF 0 "register_operand" ""))
13892    (use (match_operand:MODEF 1 "register_operand" ""))]
13893   "TARGET_USE_FANCY_MATH_387
13894    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13895        || TARGET_MIX_SSE_I387)
13896    && flag_unsafe_math_optimizations"
13898   rtx op0 = gen_reg_rtx (XFmode);
13900   rtx op2 = gen_reg_rtx (<MODE>mode);
13901   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13903   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13904   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13905   DONE;
13908 (define_expand "asinxf2"
13909   [(set (match_dup 2)
13910         (mult:XF (match_operand:XF 1 "register_operand" "")
13911                  (match_dup 1)))
13912    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13913    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13914    (parallel [(set (match_operand:XF 0 "register_operand" "")
13915                    (unspec:XF [(match_dup 5) (match_dup 1)]
13916                               UNSPEC_FPATAN))
13917               (clobber (match_scratch:XF 6 ""))])]
13918   "TARGET_USE_FANCY_MATH_387
13919    && flag_unsafe_math_optimizations"
13921   int i;
13923   if (optimize_insn_for_size_p ())
13924     FAIL;
13926   for (i = 2; i < 6; i++)
13927     operands[i] = gen_reg_rtx (XFmode);
13929   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13932 (define_expand "asin<mode>2"
13933   [(use (match_operand:MODEF 0 "register_operand" ""))
13934    (use (match_operand:MODEF 1 "general_operand" ""))]
13935  "TARGET_USE_FANCY_MATH_387
13936    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13937        || TARGET_MIX_SSE_I387)
13938    && flag_unsafe_math_optimizations"
13940   rtx op0 = gen_reg_rtx (XFmode);
13941   rtx op1 = gen_reg_rtx (XFmode);
13943   if (optimize_insn_for_size_p ())
13944     FAIL;
13946   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13947   emit_insn (gen_asinxf2 (op0, op1));
13948   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13949   DONE;
13952 (define_expand "acosxf2"
13953   [(set (match_dup 2)
13954         (mult:XF (match_operand:XF 1 "register_operand" "")
13955                  (match_dup 1)))
13956    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13957    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13958    (parallel [(set (match_operand:XF 0 "register_operand" "")
13959                    (unspec:XF [(match_dup 1) (match_dup 5)]
13960                               UNSPEC_FPATAN))
13961               (clobber (match_scratch:XF 6 ""))])]
13962   "TARGET_USE_FANCY_MATH_387
13963    && flag_unsafe_math_optimizations"
13965   int i;
13967   if (optimize_insn_for_size_p ())
13968     FAIL;
13970   for (i = 2; i < 6; i++)
13971     operands[i] = gen_reg_rtx (XFmode);
13973   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13976 (define_expand "acos<mode>2"
13977   [(use (match_operand:MODEF 0 "register_operand" ""))
13978    (use (match_operand:MODEF 1 "general_operand" ""))]
13979  "TARGET_USE_FANCY_MATH_387
13980    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13981        || TARGET_MIX_SSE_I387)
13982    && flag_unsafe_math_optimizations"
13984   rtx op0 = gen_reg_rtx (XFmode);
13985   rtx op1 = gen_reg_rtx (XFmode);
13987   if (optimize_insn_for_size_p ())
13988     FAIL;
13990   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13991   emit_insn (gen_acosxf2 (op0, op1));
13992   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13993   DONE;
13996 (define_insn "fyl2xxf3_i387"
13997   [(set (match_operand:XF 0 "register_operand" "=f")
13998         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13999                     (match_operand:XF 2 "register_operand" "u")]
14000                    UNSPEC_FYL2X))
14001    (clobber (match_scratch:XF 3 "=2"))]
14002   "TARGET_USE_FANCY_MATH_387
14003    && flag_unsafe_math_optimizations"
14004   "fyl2x"
14005   [(set_attr "type" "fpspc")
14006    (set_attr "mode" "XF")])
14008 (define_insn "fyl2x_extend<mode>xf3_i387"
14009   [(set (match_operand:XF 0 "register_operand" "=f")
14010         (unspec:XF [(float_extend:XF
14011                       (match_operand:MODEF 1 "register_operand" "0"))
14012                     (match_operand:XF 2 "register_operand" "u")]
14013                    UNSPEC_FYL2X))
14014    (clobber (match_scratch:XF 3 "=2"))]
14015   "TARGET_USE_FANCY_MATH_387
14016    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14017        || TARGET_MIX_SSE_I387)
14018    && flag_unsafe_math_optimizations"
14019   "fyl2x"
14020   [(set_attr "type" "fpspc")
14021    (set_attr "mode" "XF")])
14023 (define_expand "logxf2"
14024   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14025                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14026                                (match_dup 2)] UNSPEC_FYL2X))
14027               (clobber (match_scratch:XF 3 ""))])]
14028   "TARGET_USE_FANCY_MATH_387
14029    && flag_unsafe_math_optimizations"
14031   operands[2] = gen_reg_rtx (XFmode);
14032   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14035 (define_expand "log<mode>2"
14036   [(use (match_operand:MODEF 0 "register_operand" ""))
14037    (use (match_operand:MODEF 1 "register_operand" ""))]
14038   "TARGET_USE_FANCY_MATH_387
14039    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14040        || TARGET_MIX_SSE_I387)
14041    && flag_unsafe_math_optimizations"
14043   rtx op0 = gen_reg_rtx (XFmode);
14045   rtx op2 = gen_reg_rtx (XFmode);
14046   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14048   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14049   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14050   DONE;
14053 (define_expand "log10xf2"
14054   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14055                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14056                                (match_dup 2)] UNSPEC_FYL2X))
14057               (clobber (match_scratch:XF 3 ""))])]
14058   "TARGET_USE_FANCY_MATH_387
14059    && flag_unsafe_math_optimizations"
14061   operands[2] = gen_reg_rtx (XFmode);
14062   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14065 (define_expand "log10<mode>2"
14066   [(use (match_operand:MODEF 0 "register_operand" ""))
14067    (use (match_operand:MODEF 1 "register_operand" ""))]
14068   "TARGET_USE_FANCY_MATH_387
14069    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14070        || TARGET_MIX_SSE_I387)
14071    && flag_unsafe_math_optimizations"
14073   rtx op0 = gen_reg_rtx (XFmode);
14075   rtx op2 = gen_reg_rtx (XFmode);
14076   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14078   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14079   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14080   DONE;
14083 (define_expand "log2xf2"
14084   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14085                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14086                                (match_dup 2)] UNSPEC_FYL2X))
14087               (clobber (match_scratch:XF 3 ""))])]
14088   "TARGET_USE_FANCY_MATH_387
14089    && flag_unsafe_math_optimizations"
14091   operands[2] = gen_reg_rtx (XFmode);
14092   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14095 (define_expand "log2<mode>2"
14096   [(use (match_operand:MODEF 0 "register_operand" ""))
14097    (use (match_operand:MODEF 1 "register_operand" ""))]
14098   "TARGET_USE_FANCY_MATH_387
14099    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14100        || TARGET_MIX_SSE_I387)
14101    && flag_unsafe_math_optimizations"
14103   rtx op0 = gen_reg_rtx (XFmode);
14105   rtx op2 = gen_reg_rtx (XFmode);
14106   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14108   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14109   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14110   DONE;
14113 (define_insn "fyl2xp1xf3_i387"
14114   [(set (match_operand:XF 0 "register_operand" "=f")
14115         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14116                     (match_operand:XF 2 "register_operand" "u")]
14117                    UNSPEC_FYL2XP1))
14118    (clobber (match_scratch:XF 3 "=2"))]
14119   "TARGET_USE_FANCY_MATH_387
14120    && flag_unsafe_math_optimizations"
14121   "fyl2xp1"
14122   [(set_attr "type" "fpspc")
14123    (set_attr "mode" "XF")])
14125 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14126   [(set (match_operand:XF 0 "register_operand" "=f")
14127         (unspec:XF [(float_extend:XF
14128                       (match_operand:MODEF 1 "register_operand" "0"))
14129                     (match_operand:XF 2 "register_operand" "u")]
14130                    UNSPEC_FYL2XP1))
14131    (clobber (match_scratch:XF 3 "=2"))]
14132   "TARGET_USE_FANCY_MATH_387
14133    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14134        || TARGET_MIX_SSE_I387)
14135    && flag_unsafe_math_optimizations"
14136   "fyl2xp1"
14137   [(set_attr "type" "fpspc")
14138    (set_attr "mode" "XF")])
14140 (define_expand "log1pxf2"
14141   [(use (match_operand:XF 0 "register_operand" ""))
14142    (use (match_operand:XF 1 "register_operand" ""))]
14143   "TARGET_USE_FANCY_MATH_387
14144    && flag_unsafe_math_optimizations"
14146   if (optimize_insn_for_size_p ())
14147     FAIL;
14149   ix86_emit_i387_log1p (operands[0], operands[1]);
14150   DONE;
14153 (define_expand "log1p<mode>2"
14154   [(use (match_operand:MODEF 0 "register_operand" ""))
14155    (use (match_operand:MODEF 1 "register_operand" ""))]
14156   "TARGET_USE_FANCY_MATH_387
14157    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14158        || TARGET_MIX_SSE_I387)
14159    && flag_unsafe_math_optimizations"
14161   rtx op0;
14163   if (optimize_insn_for_size_p ())
14164     FAIL;
14166   op0 = gen_reg_rtx (XFmode);
14168   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14170   ix86_emit_i387_log1p (op0, operands[1]);
14171   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14172   DONE;
14175 (define_insn "fxtractxf3_i387"
14176   [(set (match_operand:XF 0 "register_operand" "=f")
14177         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14178                    UNSPEC_XTRACT_FRACT))
14179    (set (match_operand:XF 1 "register_operand" "=u")
14180         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14181   "TARGET_USE_FANCY_MATH_387
14182    && flag_unsafe_math_optimizations"
14183   "fxtract"
14184   [(set_attr "type" "fpspc")
14185    (set_attr "mode" "XF")])
14187 (define_insn "fxtract_extend<mode>xf3_i387"
14188   [(set (match_operand:XF 0 "register_operand" "=f")
14189         (unspec:XF [(float_extend:XF
14190                       (match_operand:MODEF 2 "register_operand" "0"))]
14191                    UNSPEC_XTRACT_FRACT))
14192    (set (match_operand:XF 1 "register_operand" "=u")
14193         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14194   "TARGET_USE_FANCY_MATH_387
14195    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14196        || TARGET_MIX_SSE_I387)
14197    && flag_unsafe_math_optimizations"
14198   "fxtract"
14199   [(set_attr "type" "fpspc")
14200    (set_attr "mode" "XF")])
14202 (define_expand "logbxf2"
14203   [(parallel [(set (match_dup 2)
14204                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14205                               UNSPEC_XTRACT_FRACT))
14206               (set (match_operand:XF 0 "register_operand" "")
14207                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14208   "TARGET_USE_FANCY_MATH_387
14209    && flag_unsafe_math_optimizations"
14210   "operands[2] = gen_reg_rtx (XFmode);")
14212 (define_expand "logb<mode>2"
14213   [(use (match_operand:MODEF 0 "register_operand" ""))
14214    (use (match_operand:MODEF 1 "register_operand" ""))]
14215   "TARGET_USE_FANCY_MATH_387
14216    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14217        || TARGET_MIX_SSE_I387)
14218    && flag_unsafe_math_optimizations"
14220   rtx op0 = gen_reg_rtx (XFmode);
14221   rtx op1 = gen_reg_rtx (XFmode);
14223   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14224   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14225   DONE;
14228 (define_expand "ilogbxf2"
14229   [(use (match_operand:SI 0 "register_operand" ""))
14230    (use (match_operand:XF 1 "register_operand" ""))]
14231   "TARGET_USE_FANCY_MATH_387
14232    && flag_unsafe_math_optimizations"
14234   rtx op0, op1;
14236   if (optimize_insn_for_size_p ())
14237     FAIL;
14239   op0 = gen_reg_rtx (XFmode);
14240   op1 = gen_reg_rtx (XFmode);
14242   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14243   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14244   DONE;
14247 (define_expand "ilogb<mode>2"
14248   [(use (match_operand:SI 0 "register_operand" ""))
14249    (use (match_operand:MODEF 1 "register_operand" ""))]
14250   "TARGET_USE_FANCY_MATH_387
14251    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14252        || TARGET_MIX_SSE_I387)
14253    && flag_unsafe_math_optimizations"
14255   rtx op0, op1;
14257   if (optimize_insn_for_size_p ())
14258     FAIL;
14260   op0 = gen_reg_rtx (XFmode);
14261   op1 = gen_reg_rtx (XFmode);
14263   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14264   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14265   DONE;
14268 (define_insn "*f2xm1xf2_i387"
14269   [(set (match_operand:XF 0 "register_operand" "=f")
14270         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14271                    UNSPEC_F2XM1))]
14272   "TARGET_USE_FANCY_MATH_387
14273    && flag_unsafe_math_optimizations"
14274   "f2xm1"
14275   [(set_attr "type" "fpspc")
14276    (set_attr "mode" "XF")])
14278 (define_insn "*fscalexf4_i387"
14279   [(set (match_operand:XF 0 "register_operand" "=f")
14280         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14281                     (match_operand:XF 3 "register_operand" "1")]
14282                    UNSPEC_FSCALE_FRACT))
14283    (set (match_operand:XF 1 "register_operand" "=u")
14284         (unspec:XF [(match_dup 2) (match_dup 3)]
14285                    UNSPEC_FSCALE_EXP))]
14286   "TARGET_USE_FANCY_MATH_387
14287    && flag_unsafe_math_optimizations"
14288   "fscale"
14289   [(set_attr "type" "fpspc")
14290    (set_attr "mode" "XF")])
14292 (define_expand "expNcorexf3"
14293   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14294                                (match_operand:XF 2 "register_operand" "")))
14295    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14296    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14297    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14298    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14299    (parallel [(set (match_operand:XF 0 "register_operand" "")
14300                    (unspec:XF [(match_dup 8) (match_dup 4)]
14301                               UNSPEC_FSCALE_FRACT))
14302               (set (match_dup 9)
14303                    (unspec:XF [(match_dup 8) (match_dup 4)]
14304                               UNSPEC_FSCALE_EXP))])]
14305   "TARGET_USE_FANCY_MATH_387
14306    && flag_unsafe_math_optimizations"
14308   int i;
14310   if (optimize_insn_for_size_p ())
14311     FAIL;
14313   for (i = 3; i < 10; i++)
14314     operands[i] = gen_reg_rtx (XFmode);
14316   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14319 (define_expand "expxf2"
14320   [(use (match_operand:XF 0 "register_operand" ""))
14321    (use (match_operand:XF 1 "register_operand" ""))]
14322   "TARGET_USE_FANCY_MATH_387
14323    && flag_unsafe_math_optimizations"
14325   rtx op2;
14327   if (optimize_insn_for_size_p ())
14328     FAIL;
14330   op2 = gen_reg_rtx (XFmode);
14331   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14333   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14334   DONE;
14337 (define_expand "exp<mode>2"
14338   [(use (match_operand:MODEF 0 "register_operand" ""))
14339    (use (match_operand:MODEF 1 "general_operand" ""))]
14340  "TARGET_USE_FANCY_MATH_387
14341    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14342        || TARGET_MIX_SSE_I387)
14343    && flag_unsafe_math_optimizations"
14345   rtx op0, op1;
14347   if (optimize_insn_for_size_p ())
14348     FAIL;
14350   op0 = gen_reg_rtx (XFmode);
14351   op1 = gen_reg_rtx (XFmode);
14353   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14354   emit_insn (gen_expxf2 (op0, op1));
14355   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14356   DONE;
14359 (define_expand "exp10xf2"
14360   [(use (match_operand:XF 0 "register_operand" ""))
14361    (use (match_operand:XF 1 "register_operand" ""))]
14362   "TARGET_USE_FANCY_MATH_387
14363    && flag_unsafe_math_optimizations"
14365   rtx op2;
14367   if (optimize_insn_for_size_p ())
14368     FAIL;
14370   op2 = gen_reg_rtx (XFmode);
14371   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14373   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14374   DONE;
14377 (define_expand "exp10<mode>2"
14378   [(use (match_operand:MODEF 0 "register_operand" ""))
14379    (use (match_operand:MODEF 1 "general_operand" ""))]
14380  "TARGET_USE_FANCY_MATH_387
14381    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14382        || TARGET_MIX_SSE_I387)
14383    && flag_unsafe_math_optimizations"
14385   rtx op0, op1;
14387   if (optimize_insn_for_size_p ())
14388     FAIL;
14390   op0 = gen_reg_rtx (XFmode);
14391   op1 = gen_reg_rtx (XFmode);
14393   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14394   emit_insn (gen_exp10xf2 (op0, op1));
14395   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14396   DONE;
14399 (define_expand "exp2xf2"
14400   [(use (match_operand:XF 0 "register_operand" ""))
14401    (use (match_operand:XF 1 "register_operand" ""))]
14402   "TARGET_USE_FANCY_MATH_387
14403    && flag_unsafe_math_optimizations"
14405   rtx op2;
14407   if (optimize_insn_for_size_p ())
14408     FAIL;
14410   op2 = gen_reg_rtx (XFmode);
14411   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14413   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14414   DONE;
14417 (define_expand "exp2<mode>2"
14418   [(use (match_operand:MODEF 0 "register_operand" ""))
14419    (use (match_operand:MODEF 1 "general_operand" ""))]
14420  "TARGET_USE_FANCY_MATH_387
14421    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14422        || TARGET_MIX_SSE_I387)
14423    && flag_unsafe_math_optimizations"
14425   rtx op0, op1;
14427   if (optimize_insn_for_size_p ())
14428     FAIL;
14430   op0 = gen_reg_rtx (XFmode);
14431   op1 = gen_reg_rtx (XFmode);
14433   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14434   emit_insn (gen_exp2xf2 (op0, op1));
14435   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14436   DONE;
14439 (define_expand "expm1xf2"
14440   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14441                                (match_dup 2)))
14442    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14443    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14444    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14445    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14446    (parallel [(set (match_dup 7)
14447                    (unspec:XF [(match_dup 6) (match_dup 4)]
14448                               UNSPEC_FSCALE_FRACT))
14449               (set (match_dup 8)
14450                    (unspec:XF [(match_dup 6) (match_dup 4)]
14451                               UNSPEC_FSCALE_EXP))])
14452    (parallel [(set (match_dup 10)
14453                    (unspec:XF [(match_dup 9) (match_dup 8)]
14454                               UNSPEC_FSCALE_FRACT))
14455               (set (match_dup 11)
14456                    (unspec:XF [(match_dup 9) (match_dup 8)]
14457                               UNSPEC_FSCALE_EXP))])
14458    (set (match_dup 12) (minus:XF (match_dup 10)
14459                                  (float_extend:XF (match_dup 13))))
14460    (set (match_operand:XF 0 "register_operand" "")
14461         (plus:XF (match_dup 12) (match_dup 7)))]
14462   "TARGET_USE_FANCY_MATH_387
14463    && flag_unsafe_math_optimizations"
14465   int i;
14467   if (optimize_insn_for_size_p ())
14468     FAIL;
14470   for (i = 2; i < 13; i++)
14471     operands[i] = gen_reg_rtx (XFmode);
14473   operands[13]
14474     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14476   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14479 (define_expand "expm1<mode>2"
14480   [(use (match_operand:MODEF 0 "register_operand" ""))
14481    (use (match_operand:MODEF 1 "general_operand" ""))]
14482  "TARGET_USE_FANCY_MATH_387
14483    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14484        || TARGET_MIX_SSE_I387)
14485    && flag_unsafe_math_optimizations"
14487   rtx op0, op1;
14489   if (optimize_insn_for_size_p ())
14490     FAIL;
14492   op0 = gen_reg_rtx (XFmode);
14493   op1 = gen_reg_rtx (XFmode);
14495   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14496   emit_insn (gen_expm1xf2 (op0, op1));
14497   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14498   DONE;
14501 (define_expand "ldexpxf3"
14502   [(set (match_dup 3)
14503         (float:XF (match_operand:SI 2 "register_operand" "")))
14504    (parallel [(set (match_operand:XF 0 " register_operand" "")
14505                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14506                                (match_dup 3)]
14507                               UNSPEC_FSCALE_FRACT))
14508               (set (match_dup 4)
14509                    (unspec:XF [(match_dup 1) (match_dup 3)]
14510                               UNSPEC_FSCALE_EXP))])]
14511   "TARGET_USE_FANCY_MATH_387
14512    && flag_unsafe_math_optimizations"
14514   if (optimize_insn_for_size_p ())
14515     FAIL;
14517   operands[3] = gen_reg_rtx (XFmode);
14518   operands[4] = gen_reg_rtx (XFmode);
14521 (define_expand "ldexp<mode>3"
14522   [(use (match_operand:MODEF 0 "register_operand" ""))
14523    (use (match_operand:MODEF 1 "general_operand" ""))
14524    (use (match_operand:SI 2 "register_operand" ""))]
14525  "TARGET_USE_FANCY_MATH_387
14526    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14527        || TARGET_MIX_SSE_I387)
14528    && flag_unsafe_math_optimizations"
14530   rtx op0, op1;
14532   if (optimize_insn_for_size_p ())
14533     FAIL;
14535   op0 = gen_reg_rtx (XFmode);
14536   op1 = gen_reg_rtx (XFmode);
14538   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14539   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14540   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14541   DONE;
14544 (define_expand "scalbxf3"
14545   [(parallel [(set (match_operand:XF 0 " register_operand" "")
14546                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14547                                (match_operand:XF 2 "register_operand" "")]
14548                               UNSPEC_FSCALE_FRACT))
14549               (set (match_dup 3)
14550                    (unspec:XF [(match_dup 1) (match_dup 2)]
14551                               UNSPEC_FSCALE_EXP))])]
14552   "TARGET_USE_FANCY_MATH_387
14553    && flag_unsafe_math_optimizations"
14555   if (optimize_insn_for_size_p ())
14556     FAIL;
14558   operands[3] = gen_reg_rtx (XFmode);
14561 (define_expand "scalb<mode>3"
14562   [(use (match_operand:MODEF 0 "register_operand" ""))
14563    (use (match_operand:MODEF 1 "general_operand" ""))
14564    (use (match_operand:MODEF 2 "general_operand" ""))]
14565  "TARGET_USE_FANCY_MATH_387
14566    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14567        || TARGET_MIX_SSE_I387)
14568    && flag_unsafe_math_optimizations"
14570   rtx op0, op1, op2;
14572   if (optimize_insn_for_size_p ())
14573     FAIL;
14575   op0 = gen_reg_rtx (XFmode);
14576   op1 = gen_reg_rtx (XFmode);
14577   op2 = gen_reg_rtx (XFmode);
14579   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14580   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14581   emit_insn (gen_scalbxf3 (op0, op1, op2));
14582   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14583   DONE;
14586 (define_expand "significandxf2"
14587   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14588                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14589                               UNSPEC_XTRACT_FRACT))
14590               (set (match_dup 2)
14591                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14592   "TARGET_USE_FANCY_MATH_387
14593    && flag_unsafe_math_optimizations"
14594   "operands[2] = gen_reg_rtx (XFmode);")
14596 (define_expand "significand<mode>2"
14597   [(use (match_operand:MODEF 0 "register_operand" ""))
14598    (use (match_operand:MODEF 1 "register_operand" ""))]
14599   "TARGET_USE_FANCY_MATH_387
14600    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14601        || TARGET_MIX_SSE_I387)
14602    && flag_unsafe_math_optimizations"
14604   rtx op0 = gen_reg_rtx (XFmode);
14605   rtx op1 = gen_reg_rtx (XFmode);
14607   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14608   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14609   DONE;
14613 (define_insn "sse4_1_round<mode>2"
14614   [(set (match_operand:MODEF 0 "register_operand" "=x")
14615         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14616                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14617                       UNSPEC_ROUND))]
14618   "TARGET_ROUND"
14619   "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14620   [(set_attr "type" "ssecvt")
14621    (set_attr "prefix_extra" "1")
14622    (set_attr "prefix" "maybe_vex")
14623    (set_attr "mode" "<MODE>")])
14625 (define_insn "rintxf2"
14626   [(set (match_operand:XF 0 "register_operand" "=f")
14627         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14628                    UNSPEC_FRNDINT))]
14629   "TARGET_USE_FANCY_MATH_387
14630    && flag_unsafe_math_optimizations"
14631   "frndint"
14632   [(set_attr "type" "fpspc")
14633    (set_attr "mode" "XF")])
14635 (define_expand "rint<mode>2"
14636   [(use (match_operand:MODEF 0 "register_operand" ""))
14637    (use (match_operand:MODEF 1 "register_operand" ""))]
14638   "(TARGET_USE_FANCY_MATH_387
14639     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14640         || TARGET_MIX_SSE_I387)
14641     && flag_unsafe_math_optimizations)
14642    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14643        && !flag_trapping_math)"
14645   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14646       && !flag_trapping_math)
14647     {
14648       if (TARGET_ROUND)
14649         emit_insn (gen_sse4_1_round<mode>2
14650                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14651       else if (optimize_insn_for_size_p ())
14652         FAIL;
14653       else
14654         ix86_expand_rint (operand0, operand1);
14655     }
14656   else
14657     {
14658       rtx op0 = gen_reg_rtx (XFmode);
14659       rtx op1 = gen_reg_rtx (XFmode);
14661       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14662       emit_insn (gen_rintxf2 (op0, op1));
14664       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14665     }
14666   DONE;
14669 (define_expand "round<mode>2"
14670   [(match_operand:X87MODEF 0 "register_operand" "")
14671    (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14672   "(TARGET_USE_FANCY_MATH_387
14673     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14674         || TARGET_MIX_SSE_I387)
14675     && flag_unsafe_math_optimizations)
14676    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14677        && !flag_trapping_math && !flag_rounding_math)"
14679   if (optimize_insn_for_size_p ())
14680     FAIL;
14682   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14683       && !flag_trapping_math && !flag_rounding_math)
14684     {
14685       if (TARGET_ROUND)
14686         {
14687           operands[1] = force_reg (<MODE>mode, operands[1]);
14688           ix86_expand_round_sse4 (operands[0], operands[1]);
14689         }
14690       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14691         ix86_expand_round (operands[0], operands[1]);
14692       else
14693         ix86_expand_rounddf_32 (operands[0], operands[1]);
14694     }
14695   else
14696     {
14697       operands[1] = force_reg (<MODE>mode, operands[1]);
14698       ix86_emit_i387_round (operands[0], operands[1]);
14699     }
14700   DONE;
14703 (define_insn_and_split "*fistdi2_1"
14704   [(set (match_operand:DI 0 "nonimmediate_operand" "")
14705         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14706                    UNSPEC_FIST))]
14707   "TARGET_USE_FANCY_MATH_387
14708    && can_create_pseudo_p ()"
14709   "#"
14710   "&& 1"
14711   [(const_int 0)]
14713   if (memory_operand (operands[0], VOIDmode))
14714     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14715   else
14716     {
14717       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14718       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14719                                          operands[2]));
14720     }
14721   DONE;
14723   [(set_attr "type" "fpspc")
14724    (set_attr "mode" "DI")])
14726 (define_insn "fistdi2"
14727   [(set (match_operand:DI 0 "memory_operand" "=m")
14728         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14729                    UNSPEC_FIST))
14730    (clobber (match_scratch:XF 2 "=&1f"))]
14731   "TARGET_USE_FANCY_MATH_387"
14732   "* return output_fix_trunc (insn, operands, false);"
14733   [(set_attr "type" "fpspc")
14734    (set_attr "mode" "DI")])
14736 (define_insn "fistdi2_with_temp"
14737   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14738         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14739                    UNSPEC_FIST))
14740    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14741    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14742   "TARGET_USE_FANCY_MATH_387"
14743   "#"
14744   [(set_attr "type" "fpspc")
14745    (set_attr "mode" "DI")])
14747 (define_split
14748   [(set (match_operand:DI 0 "register_operand" "")
14749         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14750                    UNSPEC_FIST))
14751    (clobber (match_operand:DI 2 "memory_operand" ""))
14752    (clobber (match_scratch 3 ""))]
14753   "reload_completed"
14754   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14755               (clobber (match_dup 3))])
14756    (set (match_dup 0) (match_dup 2))])
14758 (define_split
14759   [(set (match_operand:DI 0 "memory_operand" "")
14760         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14761                    UNSPEC_FIST))
14762    (clobber (match_operand:DI 2 "memory_operand" ""))
14763    (clobber (match_scratch 3 ""))]
14764   "reload_completed"
14765   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14766               (clobber (match_dup 3))])])
14768 (define_insn_and_split "*fist<mode>2_1"
14769   [(set (match_operand:SWI24 0 "register_operand" "")
14770         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14771                       UNSPEC_FIST))]
14772   "TARGET_USE_FANCY_MATH_387
14773    && can_create_pseudo_p ()"
14774   "#"
14775   "&& 1"
14776   [(const_int 0)]
14778   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14779   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14780                                         operands[2]));
14781   DONE;
14783   [(set_attr "type" "fpspc")
14784    (set_attr "mode" "<MODE>")])
14786 (define_insn "fist<mode>2"
14787   [(set (match_operand:SWI24 0 "memory_operand" "=m")
14788         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14789                       UNSPEC_FIST))]
14790   "TARGET_USE_FANCY_MATH_387"
14791   "* return output_fix_trunc (insn, operands, false);"
14792   [(set_attr "type" "fpspc")
14793    (set_attr "mode" "<MODE>")])
14795 (define_insn "fist<mode>2_with_temp"
14796   [(set (match_operand:SWI24 0 "register_operand" "=r")
14797         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14798                       UNSPEC_FIST))
14799    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14800   "TARGET_USE_FANCY_MATH_387"
14801   "#"
14802   [(set_attr "type" "fpspc")
14803    (set_attr "mode" "<MODE>")])
14805 (define_split
14806   [(set (match_operand:SWI24 0 "register_operand" "")
14807         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14808                       UNSPEC_FIST))
14809    (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14810   "reload_completed"
14811   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14812    (set (match_dup 0) (match_dup 2))])
14814 (define_split
14815   [(set (match_operand:SWI24 0 "memory_operand" "")
14816         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14817                       UNSPEC_FIST))
14818    (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14819   "reload_completed"
14820   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14822 (define_expand "lrintxf<mode>2"
14823   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14824      (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14825                      UNSPEC_FIST))]
14826   "TARGET_USE_FANCY_MATH_387")
14828 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14829   [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14830      (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14831                         UNSPEC_FIX_NOTRUNC))]
14832   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14833    && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14835 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14836   [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14837    (match_operand:X87MODEF 1 "register_operand" "")]
14838   "(TARGET_USE_FANCY_MATH_387
14839     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14840         || TARGET_MIX_SSE_I387)
14841     && flag_unsafe_math_optimizations)
14842    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14843        && <SWI248x:MODE>mode != HImode 
14844        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14845        && !flag_trapping_math && !flag_rounding_math)"
14847   if (optimize_insn_for_size_p ())
14848     FAIL;
14850   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14851       && <SWI248x:MODE>mode != HImode
14852       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14853       && !flag_trapping_math && !flag_rounding_math)
14854     ix86_expand_lround (operand0, operand1);
14855   else
14856     ix86_emit_i387_round (operands[0], operands[1]);
14857   DONE;
14860 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14861 (define_insn_and_split "frndintxf2_floor"
14862   [(set (match_operand:XF 0 "register_operand" "")
14863         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14864          UNSPEC_FRNDINT_FLOOR))
14865    (clobber (reg:CC FLAGS_REG))]
14866   "TARGET_USE_FANCY_MATH_387
14867    && flag_unsafe_math_optimizations
14868    && can_create_pseudo_p ()"
14869   "#"
14870   "&& 1"
14871   [(const_int 0)]
14873   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14875   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14876   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14878   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14879                                         operands[2], operands[3]));
14880   DONE;
14882   [(set_attr "type" "frndint")
14883    (set_attr "i387_cw" "floor")
14884    (set_attr "mode" "XF")])
14886 (define_insn "frndintxf2_floor_i387"
14887   [(set (match_operand:XF 0 "register_operand" "=f")
14888         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14889          UNSPEC_FRNDINT_FLOOR))
14890    (use (match_operand:HI 2 "memory_operand" "m"))
14891    (use (match_operand:HI 3 "memory_operand" "m"))]
14892   "TARGET_USE_FANCY_MATH_387
14893    && flag_unsafe_math_optimizations"
14894   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14895   [(set_attr "type" "frndint")
14896    (set_attr "i387_cw" "floor")
14897    (set_attr "mode" "XF")])
14899 (define_expand "floorxf2"
14900   [(use (match_operand:XF 0 "register_operand" ""))
14901    (use (match_operand:XF 1 "register_operand" ""))]
14902   "TARGET_USE_FANCY_MATH_387
14903    && flag_unsafe_math_optimizations"
14905   if (optimize_insn_for_size_p ())
14906     FAIL;
14907   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14908   DONE;
14911 (define_expand "floor<mode>2"
14912   [(use (match_operand:MODEF 0 "register_operand" ""))
14913    (use (match_operand:MODEF 1 "register_operand" ""))]
14914   "(TARGET_USE_FANCY_MATH_387
14915     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14916         || TARGET_MIX_SSE_I387)
14917     && flag_unsafe_math_optimizations)
14918    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14919        && !flag_trapping_math)"
14921   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14922       && !flag_trapping_math)
14923     {
14924       if (TARGET_ROUND)
14925         emit_insn (gen_sse4_1_round<mode>2
14926                    (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14927       else if (optimize_insn_for_size_p ())
14928         FAIL;
14929       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14930         ix86_expand_floorceil (operand0, operand1, true);
14931       else
14932         ix86_expand_floorceildf_32 (operand0, operand1, true);
14933     }
14934   else
14935     {
14936       rtx op0, op1;
14938       if (optimize_insn_for_size_p ())
14939         FAIL;
14941       op0 = gen_reg_rtx (XFmode);
14942       op1 = gen_reg_rtx (XFmode);
14943       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14944       emit_insn (gen_frndintxf2_floor (op0, op1));
14946       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14947     }
14948   DONE;
14951 (define_insn_and_split "*fist<mode>2_floor_1"
14952   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14953         (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14954                         UNSPEC_FIST_FLOOR))
14955    (clobber (reg:CC FLAGS_REG))]
14956   "TARGET_USE_FANCY_MATH_387
14957    && flag_unsafe_math_optimizations
14958    && can_create_pseudo_p ()"
14959   "#"
14960   "&& 1"
14961   [(const_int 0)]
14963   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14965   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14966   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14967   if (memory_operand (operands[0], VOIDmode))
14968     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14969                                       operands[2], operands[3]));
14970   else
14971     {
14972       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14973       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14974                                                   operands[2], operands[3],
14975                                                   operands[4]));
14976     }
14977   DONE;
14979   [(set_attr "type" "fistp")
14980    (set_attr "i387_cw" "floor")
14981    (set_attr "mode" "<MODE>")])
14983 (define_insn "fistdi2_floor"
14984   [(set (match_operand:DI 0 "memory_operand" "=m")
14985         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14986                    UNSPEC_FIST_FLOOR))
14987    (use (match_operand:HI 2 "memory_operand" "m"))
14988    (use (match_operand:HI 3 "memory_operand" "m"))
14989    (clobber (match_scratch:XF 4 "=&1f"))]
14990   "TARGET_USE_FANCY_MATH_387
14991    && flag_unsafe_math_optimizations"
14992   "* return output_fix_trunc (insn, operands, false);"
14993   [(set_attr "type" "fistp")
14994    (set_attr "i387_cw" "floor")
14995    (set_attr "mode" "DI")])
14997 (define_insn "fistdi2_floor_with_temp"
14998   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14999         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15000                    UNSPEC_FIST_FLOOR))
15001    (use (match_operand:HI 2 "memory_operand" "m,m"))
15002    (use (match_operand:HI 3 "memory_operand" "m,m"))
15003    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15004    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15005   "TARGET_USE_FANCY_MATH_387
15006    && flag_unsafe_math_optimizations"
15007   "#"
15008   [(set_attr "type" "fistp")
15009    (set_attr "i387_cw" "floor")
15010    (set_attr "mode" "DI")])
15012 (define_split
15013   [(set (match_operand:DI 0 "register_operand" "")
15014         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15015                    UNSPEC_FIST_FLOOR))
15016    (use (match_operand:HI 2 "memory_operand" ""))
15017    (use (match_operand:HI 3 "memory_operand" ""))
15018    (clobber (match_operand:DI 4 "memory_operand" ""))
15019    (clobber (match_scratch 5 ""))]
15020   "reload_completed"
15021   [(parallel [(set (match_dup 4)
15022                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15023               (use (match_dup 2))
15024               (use (match_dup 3))
15025               (clobber (match_dup 5))])
15026    (set (match_dup 0) (match_dup 4))])
15028 (define_split
15029   [(set (match_operand:DI 0 "memory_operand" "")
15030         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15031                    UNSPEC_FIST_FLOOR))
15032    (use (match_operand:HI 2 "memory_operand" ""))
15033    (use (match_operand:HI 3 "memory_operand" ""))
15034    (clobber (match_operand:DI 4 "memory_operand" ""))
15035    (clobber (match_scratch 5 ""))]
15036   "reload_completed"
15037   [(parallel [(set (match_dup 0)
15038                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15039               (use (match_dup 2))
15040               (use (match_dup 3))
15041               (clobber (match_dup 5))])])
15043 (define_insn "fist<mode>2_floor"
15044   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15045         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15046                       UNSPEC_FIST_FLOOR))
15047    (use (match_operand:HI 2 "memory_operand" "m"))
15048    (use (match_operand:HI 3 "memory_operand" "m"))]
15049   "TARGET_USE_FANCY_MATH_387
15050    && flag_unsafe_math_optimizations"
15051   "* return output_fix_trunc (insn, operands, false);"
15052   [(set_attr "type" "fistp")
15053    (set_attr "i387_cw" "floor")
15054    (set_attr "mode" "<MODE>")])
15056 (define_insn "fist<mode>2_floor_with_temp"
15057   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15058         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15059                       UNSPEC_FIST_FLOOR))
15060    (use (match_operand:HI 2 "memory_operand" "m,m"))
15061    (use (match_operand:HI 3 "memory_operand" "m,m"))
15062    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15063   "TARGET_USE_FANCY_MATH_387
15064    && flag_unsafe_math_optimizations"
15065   "#"
15066   [(set_attr "type" "fistp")
15067    (set_attr "i387_cw" "floor")
15068    (set_attr "mode" "<MODE>")])
15070 (define_split
15071   [(set (match_operand:SWI24 0 "register_operand" "")
15072         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15073                       UNSPEC_FIST_FLOOR))
15074    (use (match_operand:HI 2 "memory_operand" ""))
15075    (use (match_operand:HI 3 "memory_operand" ""))
15076    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15077   "reload_completed"
15078   [(parallel [(set (match_dup 4)
15079                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15080               (use (match_dup 2))
15081               (use (match_dup 3))])
15082    (set (match_dup 0) (match_dup 4))])
15084 (define_split
15085   [(set (match_operand:SWI24 0 "memory_operand" "")
15086         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15087                       UNSPEC_FIST_FLOOR))
15088    (use (match_operand:HI 2 "memory_operand" ""))
15089    (use (match_operand:HI 3 "memory_operand" ""))
15090    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15091   "reload_completed"
15092   [(parallel [(set (match_dup 0)
15093                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15094               (use (match_dup 2))
15095               (use (match_dup 3))])])
15097 (define_expand "lfloorxf<mode>2"
15098   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15099                    (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15100                                    UNSPEC_FIST_FLOOR))
15101               (clobber (reg:CC FLAGS_REG))])]
15102   "TARGET_USE_FANCY_MATH_387
15103    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15104    && flag_unsafe_math_optimizations")
15106 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15107   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15108    (match_operand:MODEF 1 "register_operand" "")]
15109   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15110    && !flag_trapping_math"
15112   if (TARGET_64BIT && optimize_insn_for_size_p ())
15113     FAIL;
15114   ix86_expand_lfloorceil (operand0, operand1, true);
15115   DONE;
15118 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15119 (define_insn_and_split "frndintxf2_ceil"
15120   [(set (match_operand:XF 0 "register_operand" "")
15121         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15122          UNSPEC_FRNDINT_CEIL))
15123    (clobber (reg:CC FLAGS_REG))]
15124   "TARGET_USE_FANCY_MATH_387
15125    && flag_unsafe_math_optimizations
15126    && can_create_pseudo_p ()"
15127   "#"
15128   "&& 1"
15129   [(const_int 0)]
15131   ix86_optimize_mode_switching[I387_CEIL] = 1;
15133   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15134   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15136   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15137                                        operands[2], operands[3]));
15138   DONE;
15140   [(set_attr "type" "frndint")
15141    (set_attr "i387_cw" "ceil")
15142    (set_attr "mode" "XF")])
15144 (define_insn "frndintxf2_ceil_i387"
15145   [(set (match_operand:XF 0 "register_operand" "=f")
15146         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15147          UNSPEC_FRNDINT_CEIL))
15148    (use (match_operand:HI 2 "memory_operand" "m"))
15149    (use (match_operand:HI 3 "memory_operand" "m"))]
15150   "TARGET_USE_FANCY_MATH_387
15151    && flag_unsafe_math_optimizations"
15152   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15153   [(set_attr "type" "frndint")
15154    (set_attr "i387_cw" "ceil")
15155    (set_attr "mode" "XF")])
15157 (define_expand "ceilxf2"
15158   [(use (match_operand:XF 0 "register_operand" ""))
15159    (use (match_operand:XF 1 "register_operand" ""))]
15160   "TARGET_USE_FANCY_MATH_387
15161    && flag_unsafe_math_optimizations"
15163   if (optimize_insn_for_size_p ())
15164     FAIL;
15165   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15166   DONE;
15169 (define_expand "ceil<mode>2"
15170   [(use (match_operand:MODEF 0 "register_operand" ""))
15171    (use (match_operand:MODEF 1 "register_operand" ""))]
15172   "(TARGET_USE_FANCY_MATH_387
15173     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15174         || TARGET_MIX_SSE_I387)
15175     && flag_unsafe_math_optimizations)
15176    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15177        && !flag_trapping_math)"
15179   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15180       && !flag_trapping_math)
15181     {
15182       if (TARGET_ROUND)
15183         emit_insn (gen_sse4_1_round<mode>2
15184                    (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15185       else if (optimize_insn_for_size_p ())
15186         FAIL;
15187       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15188         ix86_expand_floorceil (operand0, operand1, false);
15189       else
15190         ix86_expand_floorceildf_32 (operand0, operand1, false);
15191     }
15192   else
15193     {
15194       rtx op0, op1;
15196       if (optimize_insn_for_size_p ())
15197         FAIL;
15199       op0 = gen_reg_rtx (XFmode);
15200       op1 = gen_reg_rtx (XFmode);
15201       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15202       emit_insn (gen_frndintxf2_ceil (op0, op1));
15204       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15205     }
15206   DONE;
15209 (define_insn_and_split "*fist<mode>2_ceil_1"
15210   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15211         (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15212                         UNSPEC_FIST_CEIL))
15213    (clobber (reg:CC FLAGS_REG))]
15214   "TARGET_USE_FANCY_MATH_387
15215    && flag_unsafe_math_optimizations
15216    && can_create_pseudo_p ()"
15217   "#"
15218   "&& 1"
15219   [(const_int 0)]
15221   ix86_optimize_mode_switching[I387_CEIL] = 1;
15223   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15224   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15225   if (memory_operand (operands[0], VOIDmode))
15226     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15227                                      operands[2], operands[3]));
15228   else
15229     {
15230       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15231       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15232                                                  operands[2], operands[3],
15233                                                  operands[4]));
15234     }
15235   DONE;
15237   [(set_attr "type" "fistp")
15238    (set_attr "i387_cw" "ceil")
15239    (set_attr "mode" "<MODE>")])
15241 (define_insn "fistdi2_ceil"
15242   [(set (match_operand:DI 0 "memory_operand" "=m")
15243         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15244                    UNSPEC_FIST_CEIL))
15245    (use (match_operand:HI 2 "memory_operand" "m"))
15246    (use (match_operand:HI 3 "memory_operand" "m"))
15247    (clobber (match_scratch:XF 4 "=&1f"))]
15248   "TARGET_USE_FANCY_MATH_387
15249    && flag_unsafe_math_optimizations"
15250   "* return output_fix_trunc (insn, operands, false);"
15251   [(set_attr "type" "fistp")
15252    (set_attr "i387_cw" "ceil")
15253    (set_attr "mode" "DI")])
15255 (define_insn "fistdi2_ceil_with_temp"
15256   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15257         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15258                    UNSPEC_FIST_CEIL))
15259    (use (match_operand:HI 2 "memory_operand" "m,m"))
15260    (use (match_operand:HI 3 "memory_operand" "m,m"))
15261    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15262    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15263   "TARGET_USE_FANCY_MATH_387
15264    && flag_unsafe_math_optimizations"
15265   "#"
15266   [(set_attr "type" "fistp")
15267    (set_attr "i387_cw" "ceil")
15268    (set_attr "mode" "DI")])
15270 (define_split
15271   [(set (match_operand:DI 0 "register_operand" "")
15272         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15273                    UNSPEC_FIST_CEIL))
15274    (use (match_operand:HI 2 "memory_operand" ""))
15275    (use (match_operand:HI 3 "memory_operand" ""))
15276    (clobber (match_operand:DI 4 "memory_operand" ""))
15277    (clobber (match_scratch 5 ""))]
15278   "reload_completed"
15279   [(parallel [(set (match_dup 4)
15280                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15281               (use (match_dup 2))
15282               (use (match_dup 3))
15283               (clobber (match_dup 5))])
15284    (set (match_dup 0) (match_dup 4))])
15286 (define_split
15287   [(set (match_operand:DI 0 "memory_operand" "")
15288         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15289                    UNSPEC_FIST_CEIL))
15290    (use (match_operand:HI 2 "memory_operand" ""))
15291    (use (match_operand:HI 3 "memory_operand" ""))
15292    (clobber (match_operand:DI 4 "memory_operand" ""))
15293    (clobber (match_scratch 5 ""))]
15294   "reload_completed"
15295   [(parallel [(set (match_dup 0)
15296                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15297               (use (match_dup 2))
15298               (use (match_dup 3))
15299               (clobber (match_dup 5))])])
15301 (define_insn "fist<mode>2_ceil"
15302   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15303         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15304                       UNSPEC_FIST_CEIL))
15305    (use (match_operand:HI 2 "memory_operand" "m"))
15306    (use (match_operand:HI 3 "memory_operand" "m"))]
15307   "TARGET_USE_FANCY_MATH_387
15308    && flag_unsafe_math_optimizations"
15309   "* return output_fix_trunc (insn, operands, false);"
15310   [(set_attr "type" "fistp")
15311    (set_attr "i387_cw" "ceil")
15312    (set_attr "mode" "<MODE>")])
15314 (define_insn "fist<mode>2_ceil_with_temp"
15315   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15316         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15317                       UNSPEC_FIST_CEIL))
15318    (use (match_operand:HI 2 "memory_operand" "m,m"))
15319    (use (match_operand:HI 3 "memory_operand" "m,m"))
15320    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15321   "TARGET_USE_FANCY_MATH_387
15322    && flag_unsafe_math_optimizations"
15323   "#"
15324   [(set_attr "type" "fistp")
15325    (set_attr "i387_cw" "ceil")
15326    (set_attr "mode" "<MODE>")])
15328 (define_split
15329   [(set (match_operand:SWI24 0 "register_operand" "")
15330         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15331                       UNSPEC_FIST_CEIL))
15332    (use (match_operand:HI 2 "memory_operand" ""))
15333    (use (match_operand:HI 3 "memory_operand" ""))
15334    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15335   "reload_completed"
15336   [(parallel [(set (match_dup 4)
15337                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15338               (use (match_dup 2))
15339               (use (match_dup 3))])
15340    (set (match_dup 0) (match_dup 4))])
15342 (define_split
15343   [(set (match_operand:SWI24 0 "memory_operand" "")
15344         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15345                       UNSPEC_FIST_CEIL))
15346    (use (match_operand:HI 2 "memory_operand" ""))
15347    (use (match_operand:HI 3 "memory_operand" ""))
15348    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15349   "reload_completed"
15350   [(parallel [(set (match_dup 0)
15351                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15352               (use (match_dup 2))
15353               (use (match_dup 3))])])
15355 (define_expand "lceilxf<mode>2"
15356   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15357                    (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15358                                    UNSPEC_FIST_CEIL))
15359               (clobber (reg:CC FLAGS_REG))])]
15360   "TARGET_USE_FANCY_MATH_387
15361    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15362    && flag_unsafe_math_optimizations")
15364 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15365   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15366    (match_operand:MODEF 1 "register_operand" "")]
15367   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15368    && !flag_trapping_math"
15370   ix86_expand_lfloorceil (operand0, operand1, false);
15371   DONE;
15374 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15375 (define_insn_and_split "frndintxf2_trunc"
15376   [(set (match_operand:XF 0 "register_operand" "")
15377         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15378          UNSPEC_FRNDINT_TRUNC))
15379    (clobber (reg:CC FLAGS_REG))]
15380   "TARGET_USE_FANCY_MATH_387
15381    && flag_unsafe_math_optimizations
15382    && can_create_pseudo_p ()"
15383   "#"
15384   "&& 1"
15385   [(const_int 0)]
15387   ix86_optimize_mode_switching[I387_TRUNC] = 1;
15389   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15390   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15392   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15393                                         operands[2], operands[3]));
15394   DONE;
15396   [(set_attr "type" "frndint")
15397    (set_attr "i387_cw" "trunc")
15398    (set_attr "mode" "XF")])
15400 (define_insn "frndintxf2_trunc_i387"
15401   [(set (match_operand:XF 0 "register_operand" "=f")
15402         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15403          UNSPEC_FRNDINT_TRUNC))
15404    (use (match_operand:HI 2 "memory_operand" "m"))
15405    (use (match_operand:HI 3 "memory_operand" "m"))]
15406   "TARGET_USE_FANCY_MATH_387
15407    && flag_unsafe_math_optimizations"
15408   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15409   [(set_attr "type" "frndint")
15410    (set_attr "i387_cw" "trunc")
15411    (set_attr "mode" "XF")])
15413 (define_expand "btruncxf2"
15414   [(use (match_operand:XF 0 "register_operand" ""))
15415    (use (match_operand:XF 1 "register_operand" ""))]
15416   "TARGET_USE_FANCY_MATH_387
15417    && flag_unsafe_math_optimizations"
15419   if (optimize_insn_for_size_p ())
15420     FAIL;
15421   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15422   DONE;
15425 (define_expand "btrunc<mode>2"
15426   [(use (match_operand:MODEF 0 "register_operand" ""))
15427    (use (match_operand:MODEF 1 "register_operand" ""))]
15428   "(TARGET_USE_FANCY_MATH_387
15429     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15430         || TARGET_MIX_SSE_I387)
15431     && flag_unsafe_math_optimizations)
15432    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15433        && !flag_trapping_math)"
15435   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15436       && !flag_trapping_math)
15437     {
15438       if (TARGET_ROUND)
15439         emit_insn (gen_sse4_1_round<mode>2
15440                    (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15441       else if (optimize_insn_for_size_p ())
15442         FAIL;
15443       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15444         ix86_expand_trunc (operand0, operand1);
15445       else
15446         ix86_expand_truncdf_32 (operand0, operand1);
15447     }
15448   else
15449     {
15450       rtx op0, op1;
15452       if (optimize_insn_for_size_p ())
15453         FAIL;
15455       op0 = gen_reg_rtx (XFmode);
15456       op1 = gen_reg_rtx (XFmode);
15457       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15458       emit_insn (gen_frndintxf2_trunc (op0, op1));
15460       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15461     }
15462   DONE;
15465 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15466 (define_insn_and_split "frndintxf2_mask_pm"
15467   [(set (match_operand:XF 0 "register_operand" "")
15468         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15469          UNSPEC_FRNDINT_MASK_PM))
15470    (clobber (reg:CC FLAGS_REG))]
15471   "TARGET_USE_FANCY_MATH_387
15472    && flag_unsafe_math_optimizations
15473    && can_create_pseudo_p ()"
15474   "#"
15475   "&& 1"
15476   [(const_int 0)]
15478   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15480   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15481   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15483   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15484                                           operands[2], operands[3]));
15485   DONE;
15487   [(set_attr "type" "frndint")
15488    (set_attr "i387_cw" "mask_pm")
15489    (set_attr "mode" "XF")])
15491 (define_insn "frndintxf2_mask_pm_i387"
15492   [(set (match_operand:XF 0 "register_operand" "=f")
15493         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15494          UNSPEC_FRNDINT_MASK_PM))
15495    (use (match_operand:HI 2 "memory_operand" "m"))
15496    (use (match_operand:HI 3 "memory_operand" "m"))]
15497   "TARGET_USE_FANCY_MATH_387
15498    && flag_unsafe_math_optimizations"
15499   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15500   [(set_attr "type" "frndint")
15501    (set_attr "i387_cw" "mask_pm")
15502    (set_attr "mode" "XF")])
15504 (define_expand "nearbyintxf2"
15505   [(use (match_operand:XF 0 "register_operand" ""))
15506    (use (match_operand:XF 1 "register_operand" ""))]
15507   "TARGET_USE_FANCY_MATH_387
15508    && flag_unsafe_math_optimizations"
15510   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15511   DONE;
15514 (define_expand "nearbyint<mode>2"
15515   [(use (match_operand:MODEF 0 "register_operand" ""))
15516    (use (match_operand:MODEF 1 "register_operand" ""))]
15517   "TARGET_USE_FANCY_MATH_387
15518    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15519        || TARGET_MIX_SSE_I387)
15520    && flag_unsafe_math_optimizations"
15522   rtx op0 = gen_reg_rtx (XFmode);
15523   rtx op1 = gen_reg_rtx (XFmode);
15525   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15526   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15528   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15529   DONE;
15532 (define_insn "fxam<mode>2_i387"
15533   [(set (match_operand:HI 0 "register_operand" "=a")
15534         (unspec:HI
15535           [(match_operand:X87MODEF 1 "register_operand" "f")]
15536           UNSPEC_FXAM))]
15537   "TARGET_USE_FANCY_MATH_387"
15538   "fxam\n\tfnstsw\t%0"
15539   [(set_attr "type" "multi")
15540    (set_attr "length" "4")
15541    (set_attr "unit" "i387")
15542    (set_attr "mode" "<MODE>")])
15544 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15545   [(set (match_operand:HI 0 "register_operand" "")
15546         (unspec:HI
15547           [(match_operand:MODEF 1 "memory_operand" "")]
15548           UNSPEC_FXAM_MEM))]
15549   "TARGET_USE_FANCY_MATH_387
15550    && can_create_pseudo_p ()"
15551   "#"
15552   "&& 1"
15553   [(set (match_dup 2)(match_dup 1))
15554    (set (match_dup 0)
15555         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15557   operands[2] = gen_reg_rtx (<MODE>mode);
15559   MEM_VOLATILE_P (operands[1]) = 1;
15561   [(set_attr "type" "multi")
15562    (set_attr "unit" "i387")
15563    (set_attr "mode" "<MODE>")])
15565 (define_expand "isinfxf2"
15566   [(use (match_operand:SI 0 "register_operand" ""))
15567    (use (match_operand:XF 1 "register_operand" ""))]
15568   "TARGET_USE_FANCY_MATH_387
15569    && TARGET_C99_FUNCTIONS"
15571   rtx mask = GEN_INT (0x45);
15572   rtx val = GEN_INT (0x05);
15574   rtx cond;
15576   rtx scratch = gen_reg_rtx (HImode);
15577   rtx res = gen_reg_rtx (QImode);
15579   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15581   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15582   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15583   cond = gen_rtx_fmt_ee (EQ, QImode,
15584                          gen_rtx_REG (CCmode, FLAGS_REG),
15585                          const0_rtx);
15586   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15587   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15588   DONE;
15591 (define_expand "isinf<mode>2"
15592   [(use (match_operand:SI 0 "register_operand" ""))
15593    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15594   "TARGET_USE_FANCY_MATH_387
15595    && TARGET_C99_FUNCTIONS
15596    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15598   rtx mask = GEN_INT (0x45);
15599   rtx val = GEN_INT (0x05);
15601   rtx cond;
15603   rtx scratch = gen_reg_rtx (HImode);
15604   rtx res = gen_reg_rtx (QImode);
15606   /* Remove excess precision by forcing value through memory. */
15607   if (memory_operand (operands[1], VOIDmode))
15608     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15609   else
15610     {
15611       enum ix86_stack_slot slot = (virtuals_instantiated
15612                                    ? SLOT_TEMP
15613                                    : SLOT_VIRTUAL);
15614       rtx temp = assign_386_stack_local (<MODE>mode, slot);
15616       emit_move_insn (temp, operands[1]);
15617       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15618     }
15620   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15621   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15622   cond = gen_rtx_fmt_ee (EQ, QImode,
15623                          gen_rtx_REG (CCmode, FLAGS_REG),
15624                          const0_rtx);
15625   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15626   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15627   DONE;
15630 (define_expand "signbitxf2"
15631   [(use (match_operand:SI 0 "register_operand" ""))
15632    (use (match_operand:XF 1 "register_operand" ""))]
15633   "TARGET_USE_FANCY_MATH_387"
15635   rtx scratch = gen_reg_rtx (HImode);
15637   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15638   emit_insn (gen_andsi3 (operands[0],
15639              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15640   DONE;
15643 (define_insn "movmsk_df"
15644   [(set (match_operand:SI 0 "register_operand" "=r")
15645         (unspec:SI
15646           [(match_operand:DF 1 "register_operand" "x")]
15647           UNSPEC_MOVMSK))]
15648   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15649   "%vmovmskpd\t{%1, %0|%0, %1}"
15650   [(set_attr "type" "ssemov")
15651    (set_attr "prefix" "maybe_vex")
15652    (set_attr "mode" "DF")])
15654 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15655 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15656 (define_expand "signbitdf2"
15657   [(use (match_operand:SI 0 "register_operand" ""))
15658    (use (match_operand:DF 1 "register_operand" ""))]
15659   "TARGET_USE_FANCY_MATH_387
15660    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15662   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15663     {
15664       emit_insn (gen_movmsk_df (operands[0], operands[1]));
15665       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15666     }
15667   else
15668     {
15669       rtx scratch = gen_reg_rtx (HImode);
15671       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15672       emit_insn (gen_andsi3 (operands[0],
15673                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15674     }
15675   DONE;
15678 (define_expand "signbitsf2"
15679   [(use (match_operand:SI 0 "register_operand" ""))
15680    (use (match_operand:SF 1 "register_operand" ""))]
15681   "TARGET_USE_FANCY_MATH_387
15682    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15684   rtx scratch = gen_reg_rtx (HImode);
15686   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15687   emit_insn (gen_andsi3 (operands[0],
15688              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15689   DONE;
15692 ;; Block operation instructions
15694 (define_insn "cld"
15695   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15696   ""
15697   "cld"
15698   [(set_attr "length" "1")
15699    (set_attr "length_immediate" "0")
15700    (set_attr "modrm" "0")])
15702 (define_expand "movmem<mode>"
15703   [(use (match_operand:BLK 0 "memory_operand" ""))
15704    (use (match_operand:BLK 1 "memory_operand" ""))
15705    (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15706    (use (match_operand:SWI48 3 "const_int_operand" ""))
15707    (use (match_operand:SI 4 "const_int_operand" ""))
15708    (use (match_operand:SI 5 "const_int_operand" ""))]
15709   ""
15711  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15712                          operands[4], operands[5]))
15713    DONE;
15714  else
15715    FAIL;
15718 ;; Most CPUs don't like single string operations
15719 ;; Handle this case here to simplify previous expander.
15721 (define_expand "strmov"
15722   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15723    (set (match_operand 1 "memory_operand" "") (match_dup 4))
15724    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15725               (clobber (reg:CC FLAGS_REG))])
15726    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15727               (clobber (reg:CC FLAGS_REG))])]
15728   ""
15730   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15732   /* If .md ever supports :P for Pmode, these can be directly
15733      in the pattern above.  */
15734   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15735   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15737   /* Can't use this if the user has appropriated esi or edi.  */
15738   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15739       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15740     {
15741       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15742                                       operands[2], operands[3],
15743                                       operands[5], operands[6]));
15744       DONE;
15745     }
15747   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15750 (define_expand "strmov_singleop"
15751   [(parallel [(set (match_operand 1 "memory_operand" "")
15752                    (match_operand 3 "memory_operand" ""))
15753               (set (match_operand 0 "register_operand" "")
15754                    (match_operand 4 "" ""))
15755               (set (match_operand 2 "register_operand" "")
15756                    (match_operand 5 "" ""))])]
15757   ""
15758   "ix86_current_function_needs_cld = 1;")
15760 (define_insn "*strmovdi_rex_1"
15761   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15762         (mem:DI (match_operand:DI 3 "register_operand" "1")))
15763    (set (match_operand:DI 0 "register_operand" "=D")
15764         (plus:DI (match_dup 2)
15765                  (const_int 8)))
15766    (set (match_operand:DI 1 "register_operand" "=S")
15767         (plus:DI (match_dup 3)
15768                  (const_int 8)))]
15769   "TARGET_64BIT
15770    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15771   "movsq"
15772   [(set_attr "type" "str")
15773    (set_attr "memory" "both")
15774    (set_attr "mode" "DI")])
15776 (define_insn "*strmovsi_1"
15777   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15778         (mem:SI (match_operand:P 3 "register_operand" "1")))
15779    (set (match_operand:P 0 "register_operand" "=D")
15780         (plus:P (match_dup 2)
15781                 (const_int 4)))
15782    (set (match_operand:P 1 "register_operand" "=S")
15783         (plus:P (match_dup 3)
15784                 (const_int 4)))]
15785   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15786   "movs{l|d}"
15787   [(set_attr "type" "str")
15788    (set_attr "memory" "both")
15789    (set_attr "mode" "SI")])
15791 (define_insn "*strmovhi_1"
15792   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15793         (mem:HI (match_operand:P 3 "register_operand" "1")))
15794    (set (match_operand:P 0 "register_operand" "=D")
15795         (plus:P (match_dup 2)
15796                 (const_int 2)))
15797    (set (match_operand:P 1 "register_operand" "=S")
15798         (plus:P (match_dup 3)
15799                 (const_int 2)))]
15800   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15801   "movsw"
15802   [(set_attr "type" "str")
15803    (set_attr "memory" "both")
15804    (set_attr "mode" "HI")])
15806 (define_insn "*strmovqi_1"
15807   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15808         (mem:QI (match_operand:P 3 "register_operand" "1")))
15809    (set (match_operand:P 0 "register_operand" "=D")
15810         (plus:P (match_dup 2)
15811                 (const_int 1)))
15812    (set (match_operand:P 1 "register_operand" "=S")
15813         (plus:P (match_dup 3)
15814                 (const_int 1)))]
15815   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15816   "movsb"
15817   [(set_attr "type" "str")
15818    (set_attr "memory" "both")
15819    (set (attr "prefix_rex")
15820         (if_then_else
15821           (match_test "<P:MODE>mode == DImode")
15822           (const_string "0")
15823           (const_string "*")))
15824    (set_attr "mode" "QI")])
15826 (define_expand "rep_mov"
15827   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15828               (set (match_operand 0 "register_operand" "")
15829                    (match_operand 5 "" ""))
15830               (set (match_operand 2 "register_operand" "")
15831                    (match_operand 6 "" ""))
15832               (set (match_operand 1 "memory_operand" "")
15833                    (match_operand 3 "memory_operand" ""))
15834               (use (match_dup 4))])]
15835   ""
15836   "ix86_current_function_needs_cld = 1;")
15838 (define_insn "*rep_movdi_rex64"
15839   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15840    (set (match_operand:DI 0 "register_operand" "=D")
15841         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15842                             (const_int 3))
15843                  (match_operand:DI 3 "register_operand" "0")))
15844    (set (match_operand:DI 1 "register_operand" "=S")
15845         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15846                  (match_operand:DI 4 "register_operand" "1")))
15847    (set (mem:BLK (match_dup 3))
15848         (mem:BLK (match_dup 4)))
15849    (use (match_dup 5))]
15850   "TARGET_64BIT
15851    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15852   "rep{%;} movsq"
15853   [(set_attr "type" "str")
15854    (set_attr "prefix_rep" "1")
15855    (set_attr "memory" "both")
15856    (set_attr "mode" "DI")])
15858 (define_insn "*rep_movsi"
15859   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15860    (set (match_operand:P 0 "register_operand" "=D")
15861         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15862                           (const_int 2))
15863                  (match_operand:P 3 "register_operand" "0")))
15864    (set (match_operand:P 1 "register_operand" "=S")
15865         (plus:P (ashift:P (match_dup 5) (const_int 2))
15866                 (match_operand:P 4 "register_operand" "1")))
15867    (set (mem:BLK (match_dup 3))
15868         (mem:BLK (match_dup 4)))
15869    (use (match_dup 5))]
15870   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15871   "rep{%;} movs{l|d}"
15872   [(set_attr "type" "str")
15873    (set_attr "prefix_rep" "1")
15874    (set_attr "memory" "both")
15875    (set_attr "mode" "SI")])
15877 (define_insn "*rep_movqi"
15878   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15879    (set (match_operand:P 0 "register_operand" "=D")
15880         (plus:P (match_operand:P 3 "register_operand" "0")
15881                 (match_operand:P 5 "register_operand" "2")))
15882    (set (match_operand:P 1 "register_operand" "=S")
15883         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15884    (set (mem:BLK (match_dup 3))
15885         (mem:BLK (match_dup 4)))
15886    (use (match_dup 5))]
15887   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15888   "rep{%;} movsb"
15889   [(set_attr "type" "str")
15890    (set_attr "prefix_rep" "1")
15891    (set_attr "memory" "both")
15892    (set_attr "mode" "QI")])
15894 (define_expand "setmem<mode>"
15895    [(use (match_operand:BLK 0 "memory_operand" ""))
15896     (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15897     (use (match_operand:QI 2 "nonmemory_operand" ""))
15898     (use (match_operand 3 "const_int_operand" ""))
15899     (use (match_operand:SI 4 "const_int_operand" ""))
15900     (use (match_operand:SI 5 "const_int_operand" ""))]
15901   ""
15903  if (ix86_expand_setmem (operands[0], operands[1],
15904                          operands[2], operands[3],
15905                          operands[4], operands[5]))
15906    DONE;
15907  else
15908    FAIL;
15911 ;; Most CPUs don't like single string operations
15912 ;; Handle this case here to simplify previous expander.
15914 (define_expand "strset"
15915   [(set (match_operand 1 "memory_operand" "")
15916         (match_operand 2 "register_operand" ""))
15917    (parallel [(set (match_operand 0 "register_operand" "")
15918                    (match_dup 3))
15919               (clobber (reg:CC FLAGS_REG))])]
15920   ""
15922   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15923     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15925   /* If .md ever supports :P for Pmode, this can be directly
15926      in the pattern above.  */
15927   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15928                               GEN_INT (GET_MODE_SIZE (GET_MODE
15929                                                       (operands[2]))));
15930   /* Can't use this if the user has appropriated eax or edi.  */
15931   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15932       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15933     {
15934       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15935                                       operands[3]));
15936       DONE;
15937     }
15940 (define_expand "strset_singleop"
15941   [(parallel [(set (match_operand 1 "memory_operand" "")
15942                    (match_operand 2 "register_operand" ""))
15943               (set (match_operand 0 "register_operand" "")
15944                    (match_operand 3 "" ""))])]
15945   ""
15946   "ix86_current_function_needs_cld = 1;")
15948 (define_insn "*strsetdi_rex_1"
15949   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15950         (match_operand:DI 2 "register_operand" "a"))
15951    (set (match_operand:DI 0 "register_operand" "=D")
15952         (plus:DI (match_dup 1)
15953                  (const_int 8)))]
15954   "TARGET_64BIT
15955    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15956   "stosq"
15957   [(set_attr "type" "str")
15958    (set_attr "memory" "store")
15959    (set_attr "mode" "DI")])
15961 (define_insn "*strsetsi_1"
15962   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15963         (match_operand:SI 2 "register_operand" "a"))
15964    (set (match_operand:P 0 "register_operand" "=D")
15965         (plus:P (match_dup 1)
15966                 (const_int 4)))]
15967   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15968   "stos{l|d}"
15969   [(set_attr "type" "str")
15970    (set_attr "memory" "store")
15971    (set_attr "mode" "SI")])
15973 (define_insn "*strsethi_1"
15974   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15975         (match_operand:HI 2 "register_operand" "a"))
15976    (set (match_operand:P 0 "register_operand" "=D")
15977         (plus:P (match_dup 1)
15978                 (const_int 2)))]
15979   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15980   "stosw"
15981   [(set_attr "type" "str")
15982    (set_attr "memory" "store")
15983    (set_attr "mode" "HI")])
15985 (define_insn "*strsetqi_1"
15986   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15987         (match_operand:QI 2 "register_operand" "a"))
15988    (set (match_operand:P 0 "register_operand" "=D")
15989         (plus:P (match_dup 1)
15990                 (const_int 1)))]
15991   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15992   "stosb"
15993   [(set_attr "type" "str")
15994    (set_attr "memory" "store")
15995    (set (attr "prefix_rex")
15996         (if_then_else
15997           (match_test "<P:MODE>mode == DImode")
15998           (const_string "0")
15999           (const_string "*")))
16000    (set_attr "mode" "QI")])
16002 (define_expand "rep_stos"
16003   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16004               (set (match_operand 0 "register_operand" "")
16005                    (match_operand 4 "" ""))
16006               (set (match_operand 2 "memory_operand" "") (const_int 0))
16007               (use (match_operand 3 "register_operand" ""))
16008               (use (match_dup 1))])]
16009   ""
16010   "ix86_current_function_needs_cld = 1;")
16012 (define_insn "*rep_stosdi_rex64"
16013   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16014    (set (match_operand:DI 0 "register_operand" "=D")
16015         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16016                             (const_int 3))
16017                  (match_operand:DI 3 "register_operand" "0")))
16018    (set (mem:BLK (match_dup 3))
16019         (const_int 0))
16020    (use (match_operand:DI 2 "register_operand" "a"))
16021    (use (match_dup 4))]
16022   "TARGET_64BIT
16023    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16024   "rep{%;} stosq"
16025   [(set_attr "type" "str")
16026    (set_attr "prefix_rep" "1")
16027    (set_attr "memory" "store")
16028    (set_attr "mode" "DI")])
16030 (define_insn "*rep_stossi"
16031   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16032    (set (match_operand:P 0 "register_operand" "=D")
16033         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16034                           (const_int 2))
16035                  (match_operand:P 3 "register_operand" "0")))
16036    (set (mem:BLK (match_dup 3))
16037         (const_int 0))
16038    (use (match_operand:SI 2 "register_operand" "a"))
16039    (use (match_dup 4))]
16040   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16041   "rep{%;} stos{l|d}"
16042   [(set_attr "type" "str")
16043    (set_attr "prefix_rep" "1")
16044    (set_attr "memory" "store")
16045    (set_attr "mode" "SI")])
16047 (define_insn "*rep_stosqi"
16048   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16049    (set (match_operand:P 0 "register_operand" "=D")
16050         (plus:P (match_operand:P 3 "register_operand" "0")
16051                 (match_operand:P 4 "register_operand" "1")))
16052    (set (mem:BLK (match_dup 3))
16053         (const_int 0))
16054    (use (match_operand:QI 2 "register_operand" "a"))
16055    (use (match_dup 4))]
16056   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16057   "rep{%;} stosb"
16058   [(set_attr "type" "str")
16059    (set_attr "prefix_rep" "1")
16060    (set_attr "memory" "store")
16061    (set (attr "prefix_rex")
16062         (if_then_else
16063           (match_test "<P:MODE>mode == DImode")
16064           (const_string "0")
16065           (const_string "*")))
16066    (set_attr "mode" "QI")])
16068 (define_expand "cmpstrnsi"
16069   [(set (match_operand:SI 0 "register_operand" "")
16070         (compare:SI (match_operand:BLK 1 "general_operand" "")
16071                     (match_operand:BLK 2 "general_operand" "")))
16072    (use (match_operand 3 "general_operand" ""))
16073    (use (match_operand 4 "immediate_operand" ""))]
16074   ""
16076   rtx addr1, addr2, out, outlow, count, countreg, align;
16078   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16079     FAIL;
16081   /* Can't use this if the user has appropriated ecx, esi or edi.  */
16082   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16083     FAIL;
16085   out = operands[0];
16086   if (!REG_P (out))
16087     out = gen_reg_rtx (SImode);
16089   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16090   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16091   if (addr1 != XEXP (operands[1], 0))
16092     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16093   if (addr2 != XEXP (operands[2], 0))
16094     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16096   count = operands[3];
16097   countreg = ix86_zero_extend_to_Pmode (count);
16099   /* %%% Iff we are testing strict equality, we can use known alignment
16100      to good advantage.  This may be possible with combine, particularly
16101      once cc0 is dead.  */
16102   align = operands[4];
16104   if (CONST_INT_P (count))
16105     {
16106       if (INTVAL (count) == 0)
16107         {
16108           emit_move_insn (operands[0], const0_rtx);
16109           DONE;
16110         }
16111       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16112                                      operands[1], operands[2]));
16113     }
16114   else
16115     {
16116       rtx (*gen_cmp) (rtx, rtx);
16118       gen_cmp = (TARGET_64BIT
16119                  ? gen_cmpdi_1 : gen_cmpsi_1);
16121       emit_insn (gen_cmp (countreg, countreg));
16122       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16123                                   operands[1], operands[2]));
16124     }
16126   outlow = gen_lowpart (QImode, out);
16127   emit_insn (gen_cmpintqi (outlow));
16128   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16130   if (operands[0] != out)
16131     emit_move_insn (operands[0], out);
16133   DONE;
16136 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16138 (define_expand "cmpintqi"
16139   [(set (match_dup 1)
16140         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16141    (set (match_dup 2)
16142         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16143    (parallel [(set (match_operand:QI 0 "register_operand" "")
16144                    (minus:QI (match_dup 1)
16145                              (match_dup 2)))
16146               (clobber (reg:CC FLAGS_REG))])]
16147   ""
16149   operands[1] = gen_reg_rtx (QImode);
16150   operands[2] = gen_reg_rtx (QImode);
16153 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16154 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16156 (define_expand "cmpstrnqi_nz_1"
16157   [(parallel [(set (reg:CC FLAGS_REG)
16158                    (compare:CC (match_operand 4 "memory_operand" "")
16159                                (match_operand 5 "memory_operand" "")))
16160               (use (match_operand 2 "register_operand" ""))
16161               (use (match_operand:SI 3 "immediate_operand" ""))
16162               (clobber (match_operand 0 "register_operand" ""))
16163               (clobber (match_operand 1 "register_operand" ""))
16164               (clobber (match_dup 2))])]
16165   ""
16166   "ix86_current_function_needs_cld = 1;")
16168 (define_insn "*cmpstrnqi_nz_1"
16169   [(set (reg:CC FLAGS_REG)
16170         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16171                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16172    (use (match_operand:P 6 "register_operand" "2"))
16173    (use (match_operand:SI 3 "immediate_operand" "i"))
16174    (clobber (match_operand:P 0 "register_operand" "=S"))
16175    (clobber (match_operand:P 1 "register_operand" "=D"))
16176    (clobber (match_operand:P 2 "register_operand" "=c"))]
16177   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16178   "repz{%;} cmpsb"
16179   [(set_attr "type" "str")
16180    (set_attr "mode" "QI")
16181    (set (attr "prefix_rex")
16182         (if_then_else
16183           (match_test "<P:MODE>mode == DImode")
16184           (const_string "0")
16185           (const_string "*")))
16186    (set_attr "prefix_rep" "1")])
16188 ;; The same, but the count is not known to not be zero.
16190 (define_expand "cmpstrnqi_1"
16191   [(parallel [(set (reg:CC FLAGS_REG)
16192                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16193                                      (const_int 0))
16194                   (compare:CC (match_operand 4 "memory_operand" "")
16195                               (match_operand 5 "memory_operand" ""))
16196                   (const_int 0)))
16197               (use (match_operand:SI 3 "immediate_operand" ""))
16198               (use (reg:CC FLAGS_REG))
16199               (clobber (match_operand 0 "register_operand" ""))
16200               (clobber (match_operand 1 "register_operand" ""))
16201               (clobber (match_dup 2))])]
16202   ""
16203   "ix86_current_function_needs_cld = 1;")
16205 (define_insn "*cmpstrnqi_1"
16206   [(set (reg:CC FLAGS_REG)
16207         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16208                              (const_int 0))
16209           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16210                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
16211           (const_int 0)))
16212    (use (match_operand:SI 3 "immediate_operand" "i"))
16213    (use (reg:CC FLAGS_REG))
16214    (clobber (match_operand:P 0 "register_operand" "=S"))
16215    (clobber (match_operand:P 1 "register_operand" "=D"))
16216    (clobber (match_operand:P 2 "register_operand" "=c"))]
16217   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16218   "repz{%;} cmpsb"
16219   [(set_attr "type" "str")
16220    (set_attr "mode" "QI")
16221    (set (attr "prefix_rex")
16222         (if_then_else
16223           (match_test "<P:MODE>mode == DImode")
16224           (const_string "0")
16225           (const_string "*")))
16226    (set_attr "prefix_rep" "1")])
16228 (define_expand "strlen<mode>"
16229   [(set (match_operand:P 0 "register_operand" "")
16230         (unspec:P [(match_operand:BLK 1 "general_operand" "")
16231                    (match_operand:QI 2 "immediate_operand" "")
16232                    (match_operand 3 "immediate_operand" "")]
16233                   UNSPEC_SCAS))]
16234   ""
16236  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16237    DONE;
16238  else
16239    FAIL;
16242 (define_expand "strlenqi_1"
16243   [(parallel [(set (match_operand 0 "register_operand" "")
16244                    (match_operand 2 "" ""))
16245               (clobber (match_operand 1 "register_operand" ""))
16246               (clobber (reg:CC FLAGS_REG))])]
16247   ""
16248   "ix86_current_function_needs_cld = 1;")
16250 (define_insn "*strlenqi_1"
16251   [(set (match_operand:P 0 "register_operand" "=&c")
16252         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16253                    (match_operand:QI 2 "register_operand" "a")
16254                    (match_operand:P 3 "immediate_operand" "i")
16255                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16256    (clobber (match_operand:P 1 "register_operand" "=D"))
16257    (clobber (reg:CC FLAGS_REG))]
16258   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16259   "repnz{%;} scasb"
16260   [(set_attr "type" "str")
16261    (set_attr "mode" "QI")
16262    (set (attr "prefix_rex")
16263         (if_then_else
16264           (match_test "<P:MODE>mode == DImode")
16265           (const_string "0")
16266           (const_string "*")))
16267    (set_attr "prefix_rep" "1")])
16269 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
16270 ;; handled in combine, but it is not currently up to the task.
16271 ;; When used for their truth value, the cmpstrn* expanders generate
16272 ;; code like this:
16274 ;;   repz cmpsb
16275 ;;   seta       %al
16276 ;;   setb       %dl
16277 ;;   cmpb       %al, %dl
16278 ;;   jcc        label
16280 ;; The intermediate three instructions are unnecessary.
16282 ;; This one handles cmpstrn*_nz_1...
16283 (define_peephole2
16284   [(parallel[
16285      (set (reg:CC FLAGS_REG)
16286           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16287                       (mem:BLK (match_operand 5 "register_operand" ""))))
16288      (use (match_operand 6 "register_operand" ""))
16289      (use (match_operand:SI 3 "immediate_operand" ""))
16290      (clobber (match_operand 0 "register_operand" ""))
16291      (clobber (match_operand 1 "register_operand" ""))
16292      (clobber (match_operand 2 "register_operand" ""))])
16293    (set (match_operand:QI 7 "register_operand" "")
16294         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16295    (set (match_operand:QI 8 "register_operand" "")
16296         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16297    (set (reg FLAGS_REG)
16298         (compare (match_dup 7) (match_dup 8)))
16299   ]
16300   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16301   [(parallel[
16302      (set (reg:CC FLAGS_REG)
16303           (compare:CC (mem:BLK (match_dup 4))
16304                       (mem:BLK (match_dup 5))))
16305      (use (match_dup 6))
16306      (use (match_dup 3))
16307      (clobber (match_dup 0))
16308      (clobber (match_dup 1))
16309      (clobber (match_dup 2))])])
16311 ;; ...and this one handles cmpstrn*_1.
16312 (define_peephole2
16313   [(parallel[
16314      (set (reg:CC FLAGS_REG)
16315           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16316                                (const_int 0))
16317             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16318                         (mem:BLK (match_operand 5 "register_operand" "")))
16319             (const_int 0)))
16320      (use (match_operand:SI 3 "immediate_operand" ""))
16321      (use (reg:CC FLAGS_REG))
16322      (clobber (match_operand 0 "register_operand" ""))
16323      (clobber (match_operand 1 "register_operand" ""))
16324      (clobber (match_operand 2 "register_operand" ""))])
16325    (set (match_operand:QI 7 "register_operand" "")
16326         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16327    (set (match_operand:QI 8 "register_operand" "")
16328         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16329    (set (reg FLAGS_REG)
16330         (compare (match_dup 7) (match_dup 8)))
16331   ]
16332   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16333   [(parallel[
16334      (set (reg:CC FLAGS_REG)
16335           (if_then_else:CC (ne (match_dup 6)
16336                                (const_int 0))
16337             (compare:CC (mem:BLK (match_dup 4))
16338                         (mem:BLK (match_dup 5)))
16339             (const_int 0)))
16340      (use (match_dup 3))
16341      (use (reg:CC FLAGS_REG))
16342      (clobber (match_dup 0))
16343      (clobber (match_dup 1))
16344      (clobber (match_dup 2))])])
16346 ;; Conditional move instructions.
16348 (define_expand "mov<mode>cc"
16349   [(set (match_operand:SWIM 0 "register_operand" "")
16350         (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16351                            (match_operand:SWIM 2 "<general_operand>" "")
16352                            (match_operand:SWIM 3 "<general_operand>" "")))]
16353   ""
16354   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16356 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16357 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16358 ;; So just document what we're doing explicitly.
16360 (define_expand "x86_mov<mode>cc_0_m1"
16361   [(parallel
16362     [(set (match_operand:SWI48 0 "register_operand" "")
16363           (if_then_else:SWI48
16364             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16365              [(match_operand 1 "flags_reg_operand" "")
16366               (const_int 0)])
16367             (const_int -1)
16368             (const_int 0)))
16369      (clobber (reg:CC FLAGS_REG))])])
16371 (define_insn "*x86_mov<mode>cc_0_m1"
16372   [(set (match_operand:SWI48 0 "register_operand" "=r")
16373         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16374                              [(reg FLAGS_REG) (const_int 0)])
16375           (const_int -1)
16376           (const_int 0)))
16377    (clobber (reg:CC FLAGS_REG))]
16378   ""
16379   "sbb{<imodesuffix>}\t%0, %0"
16380   ; Since we don't have the proper number of operands for an alu insn,
16381   ; fill in all the blanks.
16382   [(set_attr "type" "alu")
16383    (set_attr "use_carry" "1")
16384    (set_attr "pent_pair" "pu")
16385    (set_attr "memory" "none")
16386    (set_attr "imm_disp" "false")
16387    (set_attr "mode" "<MODE>")
16388    (set_attr "length_immediate" "0")])
16390 (define_insn "*x86_mov<mode>cc_0_m1_se"
16391   [(set (match_operand:SWI48 0 "register_operand" "=r")
16392         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16393                              [(reg FLAGS_REG) (const_int 0)])
16394                             (const_int 1)
16395                             (const_int 0)))
16396    (clobber (reg:CC FLAGS_REG))]
16397   ""
16398   "sbb{<imodesuffix>}\t%0, %0"
16399   [(set_attr "type" "alu")
16400    (set_attr "use_carry" "1")
16401    (set_attr "pent_pair" "pu")
16402    (set_attr "memory" "none")
16403    (set_attr "imm_disp" "false")
16404    (set_attr "mode" "<MODE>")
16405    (set_attr "length_immediate" "0")])
16407 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16408   [(set (match_operand:SWI48 0 "register_operand" "=r")
16409         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16410                     [(reg FLAGS_REG) (const_int 0)])))]
16411   ""
16412   "sbb{<imodesuffix>}\t%0, %0"
16413   [(set_attr "type" "alu")
16414    (set_attr "use_carry" "1")
16415    (set_attr "pent_pair" "pu")
16416    (set_attr "memory" "none")
16417    (set_attr "imm_disp" "false")
16418    (set_attr "mode" "<MODE>")
16419    (set_attr "length_immediate" "0")])
16421 (define_insn "*mov<mode>cc_noc"
16422   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16423         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16424                                [(reg FLAGS_REG) (const_int 0)])
16425           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16426           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16427   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16428   "@
16429    cmov%O2%C1\t{%2, %0|%0, %2}
16430    cmov%O2%c1\t{%3, %0|%0, %3}"
16431   [(set_attr "type" "icmov")
16432    (set_attr "mode" "<MODE>")])
16434 (define_insn_and_split "*movqicc_noc"
16435   [(set (match_operand:QI 0 "register_operand" "=r,r")
16436         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16437                            [(match_operand 4 "flags_reg_operand" "")
16438                             (const_int 0)])
16439                       (match_operand:QI 2 "register_operand" "r,0")
16440                       (match_operand:QI 3 "register_operand" "0,r")))]
16441   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16442   "#"
16443   "&& reload_completed"
16444   [(set (match_dup 0)
16445         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16446                       (match_dup 2)
16447                       (match_dup 3)))]
16448   "operands[0] = gen_lowpart (SImode, operands[0]);
16449    operands[2] = gen_lowpart (SImode, operands[2]);
16450    operands[3] = gen_lowpart (SImode, operands[3]);"
16451   [(set_attr "type" "icmov")
16452    (set_attr "mode" "SI")])
16454 (define_expand "mov<mode>cc"
16455   [(set (match_operand:X87MODEF 0 "register_operand" "")
16456         (if_then_else:X87MODEF
16457           (match_operand 1 "ix86_fp_comparison_operator" "")
16458           (match_operand:X87MODEF 2 "register_operand" "")
16459           (match_operand:X87MODEF 3 "register_operand" "")))]
16460   "(TARGET_80387 && TARGET_CMOVE)
16461    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16462   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16464 (define_insn "*movxfcc_1"
16465   [(set (match_operand:XF 0 "register_operand" "=f,f")
16466         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16467                                 [(reg FLAGS_REG) (const_int 0)])
16468                       (match_operand:XF 2 "register_operand" "f,0")
16469                       (match_operand:XF 3 "register_operand" "0,f")))]
16470   "TARGET_80387 && TARGET_CMOVE"
16471   "@
16472    fcmov%F1\t{%2, %0|%0, %2}
16473    fcmov%f1\t{%3, %0|%0, %3}"
16474   [(set_attr "type" "fcmov")
16475    (set_attr "mode" "XF")])
16477 (define_insn "*movdfcc_1_rex64"
16478   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16479         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16480                                 [(reg FLAGS_REG) (const_int 0)])
16481                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16482                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16483   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16484    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16485   "@
16486    fcmov%F1\t{%2, %0|%0, %2}
16487    fcmov%f1\t{%3, %0|%0, %3}
16488    cmov%O2%C1\t{%2, %0|%0, %2}
16489    cmov%O2%c1\t{%3, %0|%0, %3}"
16490   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16491    (set_attr "mode" "DF,DF,DI,DI")])
16493 (define_insn "*movdfcc_1"
16494   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16495         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16496                                 [(reg FLAGS_REG) (const_int 0)])
16497                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16498                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16499   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16500    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16501   "@
16502    fcmov%F1\t{%2, %0|%0, %2}
16503    fcmov%f1\t{%3, %0|%0, %3}
16504    #
16505    #"
16506   [(set_attr "type" "fcmov,fcmov,multi,multi")
16507    (set_attr "mode" "DF,DF,DI,DI")])
16509 (define_split
16510   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16511         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16512                                 [(match_operand 4 "flags_reg_operand" "")
16513                                  (const_int 0)])
16514                       (match_operand:DF 2 "nonimmediate_operand" "")
16515                       (match_operand:DF 3 "nonimmediate_operand" "")))]
16516   "!TARGET_64BIT && reload_completed"
16517   [(set (match_dup 2)
16518         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16519                       (match_dup 5)
16520                       (match_dup 6)))
16521    (set (match_dup 3)
16522         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16523                       (match_dup 7)
16524                       (match_dup 8)))]
16526   split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16527   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16530 (define_insn "*movsfcc_1_387"
16531   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16532         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16533                                 [(reg FLAGS_REG) (const_int 0)])
16534                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16535                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16536   "TARGET_80387 && TARGET_CMOVE
16537    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16538   "@
16539    fcmov%F1\t{%2, %0|%0, %2}
16540    fcmov%f1\t{%3, %0|%0, %3}
16541    cmov%O2%C1\t{%2, %0|%0, %2}
16542    cmov%O2%c1\t{%3, %0|%0, %3}"
16543   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16544    (set_attr "mode" "SF,SF,SI,SI")])
16546 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16547 ;; the scalar versions to have only XMM registers as operands.
16549 ;; XOP conditional move
16550 (define_insn "*xop_pcmov_<mode>"
16551   [(set (match_operand:MODEF 0 "register_operand" "=x")
16552         (if_then_else:MODEF
16553           (match_operand:MODEF 1 "register_operand" "x")
16554           (match_operand:MODEF 2 "register_operand" "x")
16555           (match_operand:MODEF 3 "register_operand" "x")))]
16556   "TARGET_XOP"
16557   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16558   [(set_attr "type" "sse4arg")])
16560 ;; These versions of the min/max patterns are intentionally ignorant of
16561 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16562 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16563 ;; are undefined in this condition, we're certain this is correct.
16565 (define_insn "<code><mode>3"
16566   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16567         (smaxmin:MODEF
16568           (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16569           (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16570   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16571   "@
16572    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16573    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16574   [(set_attr "isa" "noavx,avx")
16575    (set_attr "prefix" "orig,vex")
16576    (set_attr "type" "sseadd")
16577    (set_attr "mode" "<MODE>")])
16579 ;; These versions of the min/max patterns implement exactly the operations
16580 ;;   min = (op1 < op2 ? op1 : op2)
16581 ;;   max = (!(op1 < op2) ? op1 : op2)
16582 ;; Their operands are not commutative, and thus they may be used in the
16583 ;; presence of -0.0 and NaN.
16585 (define_insn "*ieee_smin<mode>3"
16586   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16587         (unspec:MODEF
16588           [(match_operand:MODEF 1 "register_operand" "0,x")
16589            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16590          UNSPEC_IEEE_MIN))]
16591   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16592   "@
16593    min<ssemodesuffix>\t{%2, %0|%0, %2}
16594    vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16595   [(set_attr "isa" "noavx,avx")
16596    (set_attr "prefix" "orig,vex")
16597    (set_attr "type" "sseadd")
16598    (set_attr "mode" "<MODE>")])
16600 (define_insn "*ieee_smax<mode>3"
16601   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16602         (unspec:MODEF
16603           [(match_operand:MODEF 1 "register_operand" "0,x")
16604            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16605          UNSPEC_IEEE_MAX))]
16606   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16607   "@
16608    max<ssemodesuffix>\t{%2, %0|%0, %2}
16609    vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16610   [(set_attr "isa" "noavx,avx")
16611    (set_attr "prefix" "orig,vex")
16612    (set_attr "type" "sseadd")
16613    (set_attr "mode" "<MODE>")])
16615 ;; Make two stack loads independent:
16616 ;;   fld aa              fld aa
16617 ;;   fld %st(0)     ->   fld bb
16618 ;;   fmul bb             fmul %st(1), %st
16620 ;; Actually we only match the last two instructions for simplicity.
16621 (define_peephole2
16622   [(set (match_operand 0 "fp_register_operand" "")
16623         (match_operand 1 "fp_register_operand" ""))
16624    (set (match_dup 0)
16625         (match_operator 2 "binary_fp_operator"
16626            [(match_dup 0)
16627             (match_operand 3 "memory_operand" "")]))]
16628   "REGNO (operands[0]) != REGNO (operands[1])"
16629   [(set (match_dup 0) (match_dup 3))
16630    (set (match_dup 0) (match_dup 4))]
16632   ;; The % modifier is not operational anymore in peephole2's, so we have to
16633   ;; swap the operands manually in the case of addition and multiplication.
16634   "if (COMMUTATIVE_ARITH_P (operands[2]))
16635      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16636                                    GET_MODE (operands[2]),
16637                                    operands[0], operands[1]);
16638    else
16639      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16640                                    GET_MODE (operands[2]),
16641                                    operands[1], operands[0]);")
16643 ;; Conditional addition patterns
16644 (define_expand "add<mode>cc"
16645   [(match_operand:SWI 0 "register_operand" "")
16646    (match_operand 1 "ordered_comparison_operator" "")
16647    (match_operand:SWI 2 "register_operand" "")
16648    (match_operand:SWI 3 "const_int_operand" "")]
16649   ""
16650   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16652 ;; Misc patterns (?)
16654 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16655 ;; Otherwise there will be nothing to keep
16657 ;; [(set (reg ebp) (reg esp))]
16658 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16659 ;;  (clobber (eflags)]
16660 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16662 ;; in proper program order.
16664 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16665   [(set (match_operand:P 0 "register_operand" "=r,r")
16666         (plus:P (match_operand:P 1 "register_operand" "0,r")
16667                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16668    (clobber (reg:CC FLAGS_REG))
16669    (clobber (mem:BLK (scratch)))]
16670   ""
16672   switch (get_attr_type (insn))
16673     {
16674     case TYPE_IMOV:
16675       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16677     case TYPE_ALU:
16678       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16679       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16680         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16682       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16684     default:
16685       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16686       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16687     }
16689   [(set (attr "type")
16690         (cond [(and (eq_attr "alternative" "0")
16691                     (not (match_test "TARGET_OPT_AGU")))
16692                  (const_string "alu")
16693                (match_operand:<MODE> 2 "const0_operand" "")
16694                  (const_string "imov")
16695               ]
16696               (const_string "lea")))
16697    (set (attr "length_immediate")
16698         (cond [(eq_attr "type" "imov")
16699                  (const_string "0")
16700                (and (eq_attr "type" "alu")
16701                     (match_operand 2 "const128_operand" ""))
16702                  (const_string "1")
16703               ]
16704               (const_string "*")))
16705    (set_attr "mode" "<MODE>")])
16707 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16708   [(set (match_operand:P 0 "register_operand" "=r")
16709         (minus:P (match_operand:P 1 "register_operand" "0")
16710                  (match_operand:P 2 "register_operand" "r")))
16711    (clobber (reg:CC FLAGS_REG))
16712    (clobber (mem:BLK (scratch)))]
16713   ""
16714   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16715   [(set_attr "type" "alu")
16716    (set_attr "mode" "<MODE>")])
16718 (define_insn "allocate_stack_worker_probe_<mode>"
16719   [(set (match_operand:P 0 "register_operand" "=a")
16720         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16721                             UNSPECV_STACK_PROBE))
16722    (clobber (reg:CC FLAGS_REG))]
16723   "ix86_target_stack_probe ()"
16724   "call\t___chkstk_ms"
16725   [(set_attr "type" "multi")
16726    (set_attr "length" "5")])
16728 (define_expand "allocate_stack"
16729   [(match_operand 0 "register_operand" "")
16730    (match_operand 1 "general_operand" "")]
16731   "ix86_target_stack_probe ()"
16733   rtx x;
16735 #ifndef CHECK_STACK_LIMIT
16736 #define CHECK_STACK_LIMIT 0
16737 #endif
16739   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16740       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16741     {
16742       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16743                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16744       if (x != stack_pointer_rtx)
16745         emit_move_insn (stack_pointer_rtx, x);
16746     }
16747   else
16748     {
16749       x = copy_to_mode_reg (Pmode, operands[1]);
16750       if (TARGET_64BIT)
16751         emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16752       else
16753         emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16754       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16755                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16756       if (x != stack_pointer_rtx)
16757         emit_move_insn (stack_pointer_rtx, x);
16758     }
16760   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16761   DONE;
16764 ;; Use IOR for stack probes, this is shorter.
16765 (define_expand "probe_stack"
16766   [(match_operand 0 "memory_operand" "")]
16767   ""
16769   rtx (*gen_ior3) (rtx, rtx, rtx);
16771   gen_ior3 = (GET_MODE (operands[0]) == DImode
16772               ? gen_iordi3 : gen_iorsi3);
16774   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16775   DONE;
16778 (define_insn "adjust_stack_and_probe<mode>"
16779   [(set (match_operand:P 0 "register_operand" "=r")
16780         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16781                             UNSPECV_PROBE_STACK_RANGE))
16782    (set (reg:P SP_REG)
16783         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16784    (clobber (reg:CC FLAGS_REG))
16785    (clobber (mem:BLK (scratch)))]
16786   ""
16787   "* return output_adjust_stack_and_probe (operands[0]);"
16788   [(set_attr "type" "multi")])
16790 (define_insn "probe_stack_range<mode>"
16791   [(set (match_operand:P 0 "register_operand" "=r")
16792         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16793                             (match_operand:P 2 "const_int_operand" "n")]
16794                             UNSPECV_PROBE_STACK_RANGE))
16795    (clobber (reg:CC FLAGS_REG))]
16796   ""
16797   "* return output_probe_stack_range (operands[0], operands[2]);"
16798   [(set_attr "type" "multi")])
16800 (define_expand "builtin_setjmp_receiver"
16801   [(label_ref (match_operand 0 "" ""))]
16802   "!TARGET_64BIT && flag_pic"
16804 #if TARGET_MACHO
16805   if (TARGET_MACHO)
16806     {
16807       rtx xops[3];
16808       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16809       rtx label_rtx = gen_label_rtx ();
16810       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16811       xops[0] = xops[1] = picreg;
16812       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16813       ix86_expand_binary_operator (MINUS, SImode, xops);
16814     }
16815   else
16816 #endif
16817     emit_insn (gen_set_got (pic_offset_table_rtx));
16818   DONE;
16821 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16823 (define_split
16824   [(set (match_operand 0 "register_operand" "")
16825         (match_operator 3 "promotable_binary_operator"
16826            [(match_operand 1 "register_operand" "")
16827             (match_operand 2 "aligned_operand" "")]))
16828    (clobber (reg:CC FLAGS_REG))]
16829   "! TARGET_PARTIAL_REG_STALL && reload_completed
16830    && ((GET_MODE (operands[0]) == HImode
16831         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16832             /* ??? next two lines just !satisfies_constraint_K (...) */
16833             || !CONST_INT_P (operands[2])
16834             || satisfies_constraint_K (operands[2])))
16835        || (GET_MODE (operands[0]) == QImode
16836            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16837   [(parallel [(set (match_dup 0)
16838                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16839               (clobber (reg:CC FLAGS_REG))])]
16840   "operands[0] = gen_lowpart (SImode, operands[0]);
16841    operands[1] = gen_lowpart (SImode, operands[1]);
16842    if (GET_CODE (operands[3]) != ASHIFT)
16843      operands[2] = gen_lowpart (SImode, operands[2]);
16844    PUT_MODE (operands[3], SImode);")
16846 ; Promote the QImode tests, as i386 has encoding of the AND
16847 ; instruction with 32-bit sign-extended immediate and thus the
16848 ; instruction size is unchanged, except in the %eax case for
16849 ; which it is increased by one byte, hence the ! optimize_size.
16850 (define_split
16851   [(set (match_operand 0 "flags_reg_operand" "")
16852         (match_operator 2 "compare_operator"
16853           [(and (match_operand 3 "aligned_operand" "")
16854                 (match_operand 4 "const_int_operand" ""))
16855            (const_int 0)]))
16856    (set (match_operand 1 "register_operand" "")
16857         (and (match_dup 3) (match_dup 4)))]
16858   "! TARGET_PARTIAL_REG_STALL && reload_completed
16859    && optimize_insn_for_speed_p ()
16860    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16861        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16862    /* Ensure that the operand will remain sign-extended immediate.  */
16863    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16864   [(parallel [(set (match_dup 0)
16865                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16866                                     (const_int 0)]))
16867               (set (match_dup 1)
16868                    (and:SI (match_dup 3) (match_dup 4)))])]
16870   operands[4]
16871     = gen_int_mode (INTVAL (operands[4])
16872                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16873   operands[1] = gen_lowpart (SImode, operands[1]);
16874   operands[3] = gen_lowpart (SImode, operands[3]);
16877 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16878 ; the TEST instruction with 32-bit sign-extended immediate and thus
16879 ; the instruction size would at least double, which is not what we
16880 ; want even with ! optimize_size.
16881 (define_split
16882   [(set (match_operand 0 "flags_reg_operand" "")
16883         (match_operator 1 "compare_operator"
16884           [(and (match_operand:HI 2 "aligned_operand" "")
16885                 (match_operand:HI 3 "const_int_operand" ""))
16886            (const_int 0)]))]
16887   "! TARGET_PARTIAL_REG_STALL && reload_completed
16888    && ! TARGET_FAST_PREFIX
16889    && optimize_insn_for_speed_p ()
16890    /* Ensure that the operand will remain sign-extended immediate.  */
16891    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16892   [(set (match_dup 0)
16893         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16894                          (const_int 0)]))]
16896   operands[3]
16897     = gen_int_mode (INTVAL (operands[3])
16898                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16899   operands[2] = gen_lowpart (SImode, operands[2]);
16902 (define_split
16903   [(set (match_operand 0 "register_operand" "")
16904         (neg (match_operand 1 "register_operand" "")))
16905    (clobber (reg:CC FLAGS_REG))]
16906   "! TARGET_PARTIAL_REG_STALL && reload_completed
16907    && (GET_MODE (operands[0]) == HImode
16908        || (GET_MODE (operands[0]) == QImode
16909            && (TARGET_PROMOTE_QImode
16910                || optimize_insn_for_size_p ())))"
16911   [(parallel [(set (match_dup 0)
16912                    (neg:SI (match_dup 1)))
16913               (clobber (reg:CC FLAGS_REG))])]
16914   "operands[0] = gen_lowpart (SImode, operands[0]);
16915    operands[1] = gen_lowpart (SImode, operands[1]);")
16917 (define_split
16918   [(set (match_operand 0 "register_operand" "")
16919         (not (match_operand 1 "register_operand" "")))]
16920   "! TARGET_PARTIAL_REG_STALL && reload_completed
16921    && (GET_MODE (operands[0]) == HImode
16922        || (GET_MODE (operands[0]) == QImode
16923            && (TARGET_PROMOTE_QImode
16924                || optimize_insn_for_size_p ())))"
16925   [(set (match_dup 0)
16926         (not:SI (match_dup 1)))]
16927   "operands[0] = gen_lowpart (SImode, operands[0]);
16928    operands[1] = gen_lowpart (SImode, operands[1]);")
16930 (define_split
16931   [(set (match_operand 0 "register_operand" "")
16932         (if_then_else (match_operator 1 "ordered_comparison_operator"
16933                                 [(reg FLAGS_REG) (const_int 0)])
16934                       (match_operand 2 "register_operand" "")
16935                       (match_operand 3 "register_operand" "")))]
16936   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16937    && (GET_MODE (operands[0]) == HImode
16938        || (GET_MODE (operands[0]) == QImode
16939            && (TARGET_PROMOTE_QImode
16940                || optimize_insn_for_size_p ())))"
16941   [(set (match_dup 0)
16942         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16943   "operands[0] = gen_lowpart (SImode, operands[0]);
16944    operands[2] = gen_lowpart (SImode, operands[2]);
16945    operands[3] = gen_lowpart (SImode, operands[3]);")
16947 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
16948 ;; transform a complex memory operation into two memory to register operations.
16950 ;; Don't push memory operands
16951 (define_peephole2
16952   [(set (match_operand:SWI 0 "push_operand" "")
16953         (match_operand:SWI 1 "memory_operand" ""))
16954    (match_scratch:SWI 2 "<r>")]
16955   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16956    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16957   [(set (match_dup 2) (match_dup 1))
16958    (set (match_dup 0) (match_dup 2))])
16960 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16961 ;; SImode pushes.
16962 (define_peephole2
16963   [(set (match_operand:SF 0 "push_operand" "")
16964         (match_operand:SF 1 "memory_operand" ""))
16965    (match_scratch:SF 2 "r")]
16966   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16967    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16968   [(set (match_dup 2) (match_dup 1))
16969    (set (match_dup 0) (match_dup 2))])
16971 ;; Don't move an immediate directly to memory when the instruction
16972 ;; gets too big.
16973 (define_peephole2
16974   [(match_scratch:SWI124 1 "<r>")
16975    (set (match_operand:SWI124 0 "memory_operand" "")
16976         (const_int 0))]
16977   "optimize_insn_for_speed_p ()
16978    && !TARGET_USE_MOV0
16979    && TARGET_SPLIT_LONG_MOVES
16980    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16981    && peep2_regno_dead_p (0, FLAGS_REG)"
16982   [(parallel [(set (match_dup 2) (const_int 0))
16983               (clobber (reg:CC FLAGS_REG))])
16984    (set (match_dup 0) (match_dup 1))]
16985   "operands[2] = gen_lowpart (SImode, operands[1]);")
16987 (define_peephole2
16988   [(match_scratch:SWI124 2 "<r>")
16989    (set (match_operand:SWI124 0 "memory_operand" "")
16990         (match_operand:SWI124 1 "immediate_operand" ""))]
16991   "optimize_insn_for_speed_p ()
16992    && TARGET_SPLIT_LONG_MOVES
16993    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16994   [(set (match_dup 2) (match_dup 1))
16995    (set (match_dup 0) (match_dup 2))])
16997 ;; Don't compare memory with zero, load and use a test instead.
16998 (define_peephole2
16999   [(set (match_operand 0 "flags_reg_operand" "")
17000         (match_operator 1 "compare_operator"
17001           [(match_operand:SI 2 "memory_operand" "")
17002            (const_int 0)]))
17003    (match_scratch:SI 3 "r")]
17004   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17005   [(set (match_dup 3) (match_dup 2))
17006    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17008 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17009 ;; Don't split NOTs with a displacement operand, because resulting XOR
17010 ;; will not be pairable anyway.
17012 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17013 ;; represented using a modRM byte.  The XOR replacement is long decoded,
17014 ;; so this split helps here as well.
17016 ;; Note: Can't do this as a regular split because we can't get proper
17017 ;; lifetime information then.
17019 (define_peephole2
17020   [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
17021         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
17022   "optimize_insn_for_speed_p ()
17023    && ((TARGET_NOT_UNPAIRABLE
17024         && (!MEM_P (operands[0])
17025             || !memory_displacement_operand (operands[0], <MODE>mode)))
17026        || (TARGET_NOT_VECTORMODE
17027            && long_memory_operand (operands[0], <MODE>mode)))
17028    && peep2_regno_dead_p (0, FLAGS_REG)"
17029   [(parallel [(set (match_dup 0)
17030                    (xor:SWI124 (match_dup 1) (const_int -1)))
17031               (clobber (reg:CC FLAGS_REG))])])
17033 ;; Non pairable "test imm, reg" instructions can be translated to
17034 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17035 ;; byte opcode instead of two, have a short form for byte operands),
17036 ;; so do it for other CPUs as well.  Given that the value was dead,
17037 ;; this should not create any new dependencies.  Pass on the sub-word
17038 ;; versions if we're concerned about partial register stalls.
17040 (define_peephole2
17041   [(set (match_operand 0 "flags_reg_operand" "")
17042         (match_operator 1 "compare_operator"
17043           [(and:SI (match_operand:SI 2 "register_operand" "")
17044                    (match_operand:SI 3 "immediate_operand" ""))
17045            (const_int 0)]))]
17046   "ix86_match_ccmode (insn, CCNOmode)
17047    && (true_regnum (operands[2]) != AX_REG
17048        || satisfies_constraint_K (operands[3]))
17049    && peep2_reg_dead_p (1, operands[2])"
17050   [(parallel
17051      [(set (match_dup 0)
17052            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17053                             (const_int 0)]))
17054       (set (match_dup 2)
17055            (and:SI (match_dup 2) (match_dup 3)))])])
17057 ;; We don't need to handle HImode case, because it will be promoted to SImode
17058 ;; on ! TARGET_PARTIAL_REG_STALL
17060 (define_peephole2
17061   [(set (match_operand 0 "flags_reg_operand" "")
17062         (match_operator 1 "compare_operator"
17063           [(and:QI (match_operand:QI 2 "register_operand" "")
17064                    (match_operand:QI 3 "immediate_operand" ""))
17065            (const_int 0)]))]
17066   "! TARGET_PARTIAL_REG_STALL
17067    && ix86_match_ccmode (insn, CCNOmode)
17068    && true_regnum (operands[2]) != AX_REG
17069    && peep2_reg_dead_p (1, operands[2])"
17070   [(parallel
17071      [(set (match_dup 0)
17072            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17073                             (const_int 0)]))
17074       (set (match_dup 2)
17075            (and:QI (match_dup 2) (match_dup 3)))])])
17077 (define_peephole2
17078   [(set (match_operand 0 "flags_reg_operand" "")
17079         (match_operator 1 "compare_operator"
17080           [(and:SI
17081              (zero_extract:SI
17082                (match_operand 2 "ext_register_operand" "")
17083                (const_int 8)
17084                (const_int 8))
17085              (match_operand 3 "const_int_operand" ""))
17086            (const_int 0)]))]
17087   "! TARGET_PARTIAL_REG_STALL
17088    && ix86_match_ccmode (insn, CCNOmode)
17089    && true_regnum (operands[2]) != AX_REG
17090    && peep2_reg_dead_p (1, operands[2])"
17091   [(parallel [(set (match_dup 0)
17092                    (match_op_dup 1
17093                      [(and:SI
17094                         (zero_extract:SI
17095                           (match_dup 2)
17096                           (const_int 8)
17097                           (const_int 8))
17098                         (match_dup 3))
17099                       (const_int 0)]))
17100               (set (zero_extract:SI (match_dup 2)
17101                                     (const_int 8)
17102                                     (const_int 8))
17103                    (and:SI
17104                      (zero_extract:SI
17105                        (match_dup 2)
17106                        (const_int 8)
17107                        (const_int 8))
17108                      (match_dup 3)))])])
17110 ;; Don't do logical operations with memory inputs.
17111 (define_peephole2
17112   [(match_scratch:SI 2 "r")
17113    (parallel [(set (match_operand:SI 0 "register_operand" "")
17114                    (match_operator:SI 3 "arith_or_logical_operator"
17115                      [(match_dup 0)
17116                       (match_operand:SI 1 "memory_operand" "")]))
17117               (clobber (reg:CC FLAGS_REG))])]
17118   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17119   [(set (match_dup 2) (match_dup 1))
17120    (parallel [(set (match_dup 0)
17121                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17122               (clobber (reg:CC FLAGS_REG))])])
17124 (define_peephole2
17125   [(match_scratch:SI 2 "r")
17126    (parallel [(set (match_operand:SI 0 "register_operand" "")
17127                    (match_operator:SI 3 "arith_or_logical_operator"
17128                      [(match_operand:SI 1 "memory_operand" "")
17129                       (match_dup 0)]))
17130               (clobber (reg:CC FLAGS_REG))])]
17131   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17132   [(set (match_dup 2) (match_dup 1))
17133    (parallel [(set (match_dup 0)
17134                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17135               (clobber (reg:CC FLAGS_REG))])])
17137 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17138 ;; refers to the destination of the load!
17140 (define_peephole2
17141   [(set (match_operand:SI 0 "register_operand" "")
17142         (match_operand:SI 1 "register_operand" ""))
17143    (parallel [(set (match_dup 0)
17144                    (match_operator:SI 3 "commutative_operator"
17145                      [(match_dup 0)
17146                       (match_operand:SI 2 "memory_operand" "")]))
17147               (clobber (reg:CC FLAGS_REG))])]
17148   "REGNO (operands[0]) != REGNO (operands[1])
17149    && GENERAL_REGNO_P (REGNO (operands[0]))
17150    && GENERAL_REGNO_P (REGNO (operands[1]))"
17151   [(set (match_dup 0) (match_dup 4))
17152    (parallel [(set (match_dup 0)
17153                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17154               (clobber (reg:CC FLAGS_REG))])]
17155   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17157 (define_peephole2
17158   [(set (match_operand 0 "register_operand" "")
17159         (match_operand 1 "register_operand" ""))
17160    (set (match_dup 0)
17161                    (match_operator 3 "commutative_operator"
17162                      [(match_dup 0)
17163                       (match_operand 2 "memory_operand" "")]))]
17164   "REGNO (operands[0]) != REGNO (operands[1])
17165    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
17166        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17167   [(set (match_dup 0) (match_dup 2))
17168    (set (match_dup 0)
17169         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17171 ; Don't do logical operations with memory outputs
17173 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17174 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17175 ; the same decoder scheduling characteristics as the original.
17177 (define_peephole2
17178   [(match_scratch:SI 2 "r")
17179    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17180                    (match_operator:SI 3 "arith_or_logical_operator"
17181                      [(match_dup 0)
17182                       (match_operand:SI 1 "nonmemory_operand" "")]))
17183               (clobber (reg:CC FLAGS_REG))])]
17184   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17185    /* Do not split stack checking probes.  */
17186    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17187   [(set (match_dup 2) (match_dup 0))
17188    (parallel [(set (match_dup 2)
17189                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17190               (clobber (reg:CC FLAGS_REG))])
17191    (set (match_dup 0) (match_dup 2))])
17193 (define_peephole2
17194   [(match_scratch:SI 2 "r")
17195    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17196                    (match_operator:SI 3 "arith_or_logical_operator"
17197                      [(match_operand:SI 1 "nonmemory_operand" "")
17198                       (match_dup 0)]))
17199               (clobber (reg:CC FLAGS_REG))])]
17200   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17201    /* Do not split stack checking probes.  */
17202    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17203   [(set (match_dup 2) (match_dup 0))
17204    (parallel [(set (match_dup 2)
17205                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17206               (clobber (reg:CC FLAGS_REG))])
17207    (set (match_dup 0) (match_dup 2))])
17209 ;; Attempt to use arith or logical operations with memory outputs with
17210 ;; setting of flags.
17211 (define_peephole2
17212   [(set (match_operand:SWI 0 "register_operand" "")
17213         (match_operand:SWI 1 "memory_operand" ""))
17214    (parallel [(set (match_dup 0)
17215                    (match_operator:SWI 3 "plusminuslogic_operator"
17216                      [(match_dup 0)
17217                       (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17218               (clobber (reg:CC FLAGS_REG))])
17219    (set (match_dup 1) (match_dup 0))
17220    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17221   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17222    && peep2_reg_dead_p (4, operands[0])
17223    && !reg_overlap_mentioned_p (operands[0], operands[1])
17224    && ix86_match_ccmode (peep2_next_insn (3),
17225                          (GET_CODE (operands[3]) == PLUS
17226                           || GET_CODE (operands[3]) == MINUS)
17227                          ? CCGOCmode : CCNOmode)"
17228   [(parallel [(set (match_dup 4) (match_dup 5))
17229               (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17230                                                   (match_dup 2)]))])]
17231   "operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17232    operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17233                                  copy_rtx (operands[1]),
17234                                  copy_rtx (operands[2]));
17235    operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17236                                   operands[5], const0_rtx);")
17238 (define_peephole2
17239   [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17240                    (match_operator:SWI 2 "plusminuslogic_operator"
17241                      [(match_dup 0)
17242                       (match_operand:SWI 1 "memory_operand" "")]))
17243               (clobber (reg:CC FLAGS_REG))])
17244    (set (match_dup 1) (match_dup 0))
17245    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17246   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17247    && GET_CODE (operands[2]) != MINUS
17248    && peep2_reg_dead_p (3, operands[0])
17249    && !reg_overlap_mentioned_p (operands[0], operands[1])
17250    && ix86_match_ccmode (peep2_next_insn (2),
17251                          GET_CODE (operands[2]) == PLUS
17252                          ? CCGOCmode : CCNOmode)"
17253   [(parallel [(set (match_dup 3) (match_dup 4))
17254               (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17255                                                   (match_dup 0)]))])]
17256   "operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17257    operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17258                                  copy_rtx (operands[1]),
17259                                  copy_rtx (operands[0]));
17260    operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17261                                   operands[4], const0_rtx);")
17263 (define_peephole2
17264   [(set (match_operand:SWI12 0 "register_operand" "")
17265         (match_operand:SWI12 1 "memory_operand" ""))
17266    (parallel [(set (match_operand:SI 4 "register_operand" "")
17267                    (match_operator:SI 3 "plusminuslogic_operator"
17268                      [(match_dup 4)
17269                       (match_operand:SI 2 "nonmemory_operand" "")]))
17270               (clobber (reg:CC FLAGS_REG))])
17271    (set (match_dup 1) (match_dup 0))
17272    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17273   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17274    && REG_P (operands[0]) && REG_P (operands[4])
17275    && REGNO (operands[0]) == REGNO (operands[4])
17276    && peep2_reg_dead_p (4, operands[0])
17277    && !reg_overlap_mentioned_p (operands[0], operands[1])
17278    && ix86_match_ccmode (peep2_next_insn (3),
17279                          (GET_CODE (operands[3]) == PLUS
17280                           || GET_CODE (operands[3]) == MINUS)
17281                          ? CCGOCmode : CCNOmode)"
17282   [(parallel [(set (match_dup 4) (match_dup 5))
17283               (set (match_dup 1) (match_dup 6))])]
17284   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17285    operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17286    operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17287                                  copy_rtx (operands[1]), operands[2]);
17288    operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17289                                   operands[5], const0_rtx);
17290    operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17291                                  copy_rtx (operands[1]),
17292                                  copy_rtx (operands[2]));")
17294 ;; Attempt to always use XOR for zeroing registers.
17295 (define_peephole2
17296   [(set (match_operand 0 "register_operand" "")
17297         (match_operand 1 "const0_operand" ""))]
17298   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17299    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17300    && GENERAL_REG_P (operands[0])
17301    && peep2_regno_dead_p (0, FLAGS_REG)"
17302   [(parallel [(set (match_dup 0) (const_int 0))
17303               (clobber (reg:CC FLAGS_REG))])]
17304   "operands[0] = gen_lowpart (word_mode, operands[0]);")
17306 (define_peephole2
17307   [(set (strict_low_part (match_operand 0 "register_operand" ""))
17308         (const_int 0))]
17309   "(GET_MODE (operands[0]) == QImode
17310     || GET_MODE (operands[0]) == HImode)
17311    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17312    && peep2_regno_dead_p (0, FLAGS_REG)"
17313   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17314               (clobber (reg:CC FLAGS_REG))])])
17316 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17317 (define_peephole2
17318   [(set (match_operand:SWI248 0 "register_operand" "")
17319         (const_int -1))]
17320   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17321    && peep2_regno_dead_p (0, FLAGS_REG)"
17322   [(parallel [(set (match_dup 0) (const_int -1))
17323               (clobber (reg:CC FLAGS_REG))])]
17325   if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17326     operands[0] = gen_lowpart (SImode, operands[0]);
17329 ;; Attempt to convert simple lea to add/shift.
17330 ;; These can be created by move expanders.
17332 (define_peephole2
17333   [(set (match_operand:SWI48 0 "register_operand" "")
17334         (plus:SWI48 (match_dup 0)
17335                     (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17336   "peep2_regno_dead_p (0, FLAGS_REG)"
17337   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17338               (clobber (reg:CC FLAGS_REG))])])
17340 (define_peephole2
17341   [(set (match_operand:SI 0 "register_operand" "")
17342         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17343                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17344   "TARGET_64BIT
17345    && peep2_regno_dead_p (0, FLAGS_REG)
17346    && REGNO (operands[0]) == REGNO (operands[1])"
17347   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17348               (clobber (reg:CC FLAGS_REG))])]
17349   "operands[2] = gen_lowpart (SImode, operands[2]);")
17351 (define_peephole2
17352   [(set (match_operand:SWI48 0 "register_operand" "")
17353         (mult:SWI48 (match_dup 0)
17354                     (match_operand:SWI48 1 "const_int_operand" "")))]
17355   "exact_log2 (INTVAL (operands[1])) >= 0
17356    && peep2_regno_dead_p (0, FLAGS_REG)"
17357   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17358               (clobber (reg:CC FLAGS_REG))])]
17359   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17361 (define_peephole2
17362   [(set (match_operand:SI 0 "register_operand" "")
17363         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17364                    (match_operand:DI 2 "const_int_operand" "")) 0))]
17365   "TARGET_64BIT
17366    && exact_log2 (INTVAL (operands[2])) >= 0
17367    && REGNO (operands[0]) == REGNO (operands[1])
17368    && peep2_regno_dead_p (0, FLAGS_REG)"
17369   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17370               (clobber (reg:CC FLAGS_REG))])]
17371   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17373 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17374 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17375 ;; On many CPUs it is also faster, since special hardware to avoid esp
17376 ;; dependencies is present.
17378 ;; While some of these conversions may be done using splitters, we use
17379 ;; peepholes in order to allow combine_stack_adjustments pass to see
17380 ;; nonobfuscated RTL.
17382 ;; Convert prologue esp subtractions to push.
17383 ;; We need register to push.  In order to keep verify_flow_info happy we have
17384 ;; two choices
17385 ;; - use scratch and clobber it in order to avoid dependencies
17386 ;; - use already live register
17387 ;; We can't use the second way right now, since there is no reliable way how to
17388 ;; verify that given register is live.  First choice will also most likely in
17389 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17390 ;; call clobbered registers are dead.  We may want to use base pointer as an
17391 ;; alternative when no register is available later.
17393 (define_peephole2
17394   [(match_scratch:P 1 "r")
17395    (parallel [(set (reg:P SP_REG)
17396                    (plus:P (reg:P SP_REG)
17397                            (match_operand:P 0 "const_int_operand" "")))
17398               (clobber (reg:CC FLAGS_REG))
17399               (clobber (mem:BLK (scratch)))])]
17400   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17401    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17402   [(clobber (match_dup 1))
17403    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17404               (clobber (mem:BLK (scratch)))])])
17406 (define_peephole2
17407   [(match_scratch:P 1 "r")
17408    (parallel [(set (reg:P SP_REG)
17409                    (plus:P (reg:P SP_REG)
17410                            (match_operand:P 0 "const_int_operand" "")))
17411               (clobber (reg:CC FLAGS_REG))
17412               (clobber (mem:BLK (scratch)))])]
17413   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17414    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17415   [(clobber (match_dup 1))
17416    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17417    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17418               (clobber (mem:BLK (scratch)))])])
17420 ;; Convert esp subtractions to push.
17421 (define_peephole2
17422   [(match_scratch:P 1 "r")
17423    (parallel [(set (reg:P SP_REG)
17424                    (plus:P (reg:P SP_REG)
17425                            (match_operand:P 0 "const_int_operand" "")))
17426               (clobber (reg:CC FLAGS_REG))])]
17427   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17428    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17429   [(clobber (match_dup 1))
17430    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17432 (define_peephole2
17433   [(match_scratch:P 1 "r")
17434    (parallel [(set (reg:P SP_REG)
17435                    (plus:P (reg:P SP_REG)
17436                            (match_operand:P 0 "const_int_operand" "")))
17437               (clobber (reg:CC FLAGS_REG))])]
17438   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17439    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17440   [(clobber (match_dup 1))
17441    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17442    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17444 ;; Convert epilogue deallocator to pop.
17445 (define_peephole2
17446   [(match_scratch:P 1 "r")
17447    (parallel [(set (reg:P SP_REG)
17448                    (plus:P (reg:P SP_REG)
17449                            (match_operand:P 0 "const_int_operand" "")))
17450               (clobber (reg:CC FLAGS_REG))
17451               (clobber (mem:BLK (scratch)))])]
17452   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17453    && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17454   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17455               (clobber (mem:BLK (scratch)))])])
17457 ;; Two pops case is tricky, since pop causes dependency
17458 ;; on destination register.  We use two registers if available.
17459 (define_peephole2
17460   [(match_scratch:P 1 "r")
17461    (match_scratch:P 2 "r")
17462    (parallel [(set (reg:P SP_REG)
17463                    (plus:P (reg:P SP_REG)
17464                            (match_operand:P 0 "const_int_operand" "")))
17465               (clobber (reg:CC FLAGS_REG))
17466               (clobber (mem:BLK (scratch)))])]
17467   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17468    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17469   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17470               (clobber (mem:BLK (scratch)))])
17471    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17473 (define_peephole2
17474   [(match_scratch:P 1 "r")
17475    (parallel [(set (reg:P SP_REG)
17476                    (plus:P (reg:P SP_REG)
17477                            (match_operand:P 0 "const_int_operand" "")))
17478               (clobber (reg:CC FLAGS_REG))
17479               (clobber (mem:BLK (scratch)))])]
17480   "optimize_insn_for_size_p ()
17481    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17482   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17483               (clobber (mem:BLK (scratch)))])
17484    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17486 ;; Convert esp additions to pop.
17487 (define_peephole2
17488   [(match_scratch:P 1 "r")
17489    (parallel [(set (reg:P SP_REG)
17490                    (plus:P (reg:P SP_REG)
17491                            (match_operand:P 0 "const_int_operand" "")))
17492               (clobber (reg:CC FLAGS_REG))])]
17493   "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17494   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17496 ;; Two pops case is tricky, since pop causes dependency
17497 ;; on destination register.  We use two registers if available.
17498 (define_peephole2
17499   [(match_scratch:P 1 "r")
17500    (match_scratch:P 2 "r")
17501    (parallel [(set (reg:P SP_REG)
17502                    (plus:P (reg:P SP_REG)
17503                            (match_operand:P 0 "const_int_operand" "")))
17504               (clobber (reg:CC FLAGS_REG))])]
17505   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17506   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17507    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17509 (define_peephole2
17510   [(match_scratch:P 1 "r")
17511    (parallel [(set (reg:P SP_REG)
17512                    (plus:P (reg:P SP_REG)
17513                            (match_operand:P 0 "const_int_operand" "")))
17514               (clobber (reg:CC FLAGS_REG))])]
17515   "optimize_insn_for_size_p ()
17516    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17517   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17518    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17520 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17521 ;; required and register dies.  Similarly for 128 to -128.
17522 (define_peephole2
17523   [(set (match_operand 0 "flags_reg_operand" "")
17524         (match_operator 1 "compare_operator"
17525           [(match_operand 2 "register_operand" "")
17526            (match_operand 3 "const_int_operand" "")]))]
17527   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17528      && incdec_operand (operands[3], GET_MODE (operands[3])))
17529     || (!TARGET_FUSE_CMP_AND_BRANCH
17530         && INTVAL (operands[3]) == 128))
17531    && ix86_match_ccmode (insn, CCGCmode)
17532    && peep2_reg_dead_p (1, operands[2])"
17533   [(parallel [(set (match_dup 0)
17534                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17535               (clobber (match_dup 2))])])
17537 ;; Convert imul by three, five and nine into lea
17538 (define_peephole2
17539   [(parallel
17540     [(set (match_operand:SWI48 0 "register_operand" "")
17541           (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17542                       (match_operand:SWI48 2 "const359_operand" "")))
17543      (clobber (reg:CC FLAGS_REG))])]
17544   "!TARGET_PARTIAL_REG_STALL
17545    || <MODE>mode == SImode
17546    || optimize_function_for_size_p (cfun)"
17547   [(set (match_dup 0)
17548         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17549                     (match_dup 1)))]
17550   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17552 (define_peephole2
17553   [(parallel
17554     [(set (match_operand:SWI48 0 "register_operand" "")
17555           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17556                       (match_operand:SWI48 2 "const359_operand" "")))
17557      (clobber (reg:CC FLAGS_REG))])]
17558   "optimize_insn_for_speed_p ()
17559    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17560   [(set (match_dup 0) (match_dup 1))
17561    (set (match_dup 0)
17562         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17563                     (match_dup 0)))]
17564   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17566 ;; imul $32bit_imm, mem, reg is vector decoded, while
17567 ;; imul $32bit_imm, reg, reg is direct decoded.
17568 (define_peephole2
17569   [(match_scratch:SWI48 3 "r")
17570    (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17571                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17572                                (match_operand:SWI48 2 "immediate_operand" "")))
17573               (clobber (reg:CC FLAGS_REG))])]
17574   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17575    && !satisfies_constraint_K (operands[2])"
17576   [(set (match_dup 3) (match_dup 1))
17577    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17578               (clobber (reg:CC FLAGS_REG))])])
17580 (define_peephole2
17581   [(match_scratch:SI 3 "r")
17582    (parallel [(set (match_operand:DI 0 "register_operand" "")
17583                    (zero_extend:DI
17584                      (mult:SI (match_operand:SI 1 "memory_operand" "")
17585                               (match_operand:SI 2 "immediate_operand" ""))))
17586               (clobber (reg:CC FLAGS_REG))])]
17587   "TARGET_64BIT
17588    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17589    && !satisfies_constraint_K (operands[2])"
17590   [(set (match_dup 3) (match_dup 1))
17591    (parallel [(set (match_dup 0)
17592                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17593               (clobber (reg:CC FLAGS_REG))])])
17595 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17596 ;; Convert it into imul reg, reg
17597 ;; It would be better to force assembler to encode instruction using long
17598 ;; immediate, but there is apparently no way to do so.
17599 (define_peephole2
17600   [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17601                    (mult:SWI248
17602                     (match_operand:SWI248 1 "nonimmediate_operand" "")
17603                     (match_operand:SWI248 2 "const_int_operand" "")))
17604               (clobber (reg:CC FLAGS_REG))])
17605    (match_scratch:SWI248 3 "r")]
17606   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17607    && satisfies_constraint_K (operands[2])"
17608   [(set (match_dup 3) (match_dup 2))
17609    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17610               (clobber (reg:CC FLAGS_REG))])]
17612   if (!rtx_equal_p (operands[0], operands[1]))
17613     emit_move_insn (operands[0], operands[1]);
17616 ;; After splitting up read-modify operations, array accesses with memory
17617 ;; operands might end up in form:
17618 ;;  sall    $2, %eax
17619 ;;  movl    4(%esp), %edx
17620 ;;  addl    %edx, %eax
17621 ;; instead of pre-splitting:
17622 ;;  sall    $2, %eax
17623 ;;  addl    4(%esp), %eax
17624 ;; Turn it into:
17625 ;;  movl    4(%esp), %edx
17626 ;;  leal    (%edx,%eax,4), %eax
17628 (define_peephole2
17629   [(match_scratch:P 5 "r")
17630    (parallel [(set (match_operand 0 "register_operand" "")
17631                    (ashift (match_operand 1 "register_operand" "")
17632                            (match_operand 2 "const_int_operand" "")))
17633                (clobber (reg:CC FLAGS_REG))])
17634    (parallel [(set (match_operand 3 "register_operand" "")
17635                    (plus (match_dup 0)
17636                          (match_operand 4 "x86_64_general_operand" "")))
17637                    (clobber (reg:CC FLAGS_REG))])]
17638   "IN_RANGE (INTVAL (operands[2]), 1, 3)
17639    /* Validate MODE for lea.  */
17640    && ((!TARGET_PARTIAL_REG_STALL
17641         && (GET_MODE (operands[0]) == QImode
17642             || GET_MODE (operands[0]) == HImode))
17643        || GET_MODE (operands[0]) == SImode
17644        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17645    && (rtx_equal_p (operands[0], operands[3])
17646        || peep2_reg_dead_p (2, operands[0]))
17647    /* We reorder load and the shift.  */
17648    && !reg_overlap_mentioned_p (operands[0], operands[4])"
17649   [(set (match_dup 5) (match_dup 4))
17650    (set (match_dup 0) (match_dup 1))]
17652   enum machine_mode op1mode = GET_MODE (operands[1]);
17653   enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17654   int scale = 1 << INTVAL (operands[2]);
17655   rtx index = gen_lowpart (Pmode, operands[1]);
17656   rtx base = gen_lowpart (Pmode, operands[5]);
17657   rtx dest = gen_lowpart (mode, operands[3]);
17659   operands[1] = gen_rtx_PLUS (Pmode, base,
17660                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17661   operands[5] = base;
17662   if (mode != Pmode)
17663     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17664   if (op1mode != Pmode)
17665     operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17666   operands[0] = dest;
17669 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17670 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17671 ;; caught for use by garbage collectors and the like.  Using an insn that
17672 ;; maps to SIGILL makes it more likely the program will rightfully die.
17673 ;; Keeping with tradition, "6" is in honor of #UD.
17674 (define_insn "trap"
17675   [(trap_if (const_int 1) (const_int 6))]
17676   ""
17677   { return ASM_SHORT "0x0b0f"; }
17678   [(set_attr "length" "2")])
17680 (define_expand "prefetch"
17681   [(prefetch (match_operand 0 "address_operand" "")
17682              (match_operand:SI 1 "const_int_operand" "")
17683              (match_operand:SI 2 "const_int_operand" ""))]
17684   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17686   int rw = INTVAL (operands[1]);
17687   int locality = INTVAL (operands[2]);
17689   gcc_assert (rw == 0 || rw == 1);
17690   gcc_assert (locality >= 0 && locality <= 3);
17691   gcc_assert (GET_MODE (operands[0]) == Pmode
17692               || GET_MODE (operands[0]) == VOIDmode);
17694   /* Use 3dNOW prefetch in case we are asking for write prefetch not
17695      supported by SSE counterpart or the SSE prefetch is not available
17696      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17697      of locality.  */
17698   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17699     operands[2] = GEN_INT (3);
17700   else
17701     operands[1] = const0_rtx;
17704 (define_insn "*prefetch_sse_<mode>"
17705   [(prefetch (match_operand:P 0 "address_operand" "p")
17706              (const_int 0)
17707              (match_operand:SI 1 "const_int_operand" ""))]
17708   "TARGET_PREFETCH_SSE"
17710   static const char * const patterns[4] = {
17711    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17712   };
17714   int locality = INTVAL (operands[1]);
17715   gcc_assert (locality >= 0 && locality <= 3);
17717   return patterns[locality];
17719   [(set_attr "type" "sse")
17720    (set_attr "atom_sse_attr" "prefetch")
17721    (set (attr "length_address")
17722         (symbol_ref "memory_address_length (operands[0])"))
17723    (set_attr "memory" "none")])
17725 (define_insn "*prefetch_3dnow_<mode>"
17726   [(prefetch (match_operand:P 0 "address_operand" "p")
17727              (match_operand:SI 1 "const_int_operand" "n")
17728              (const_int 3))]
17729   "TARGET_3DNOW"
17731   if (INTVAL (operands[1]) == 0)
17732     return "prefetch\t%a0";
17733   else
17734     return "prefetchw\t%a0";
17736   [(set_attr "type" "mmx")
17737    (set (attr "length_address")
17738         (symbol_ref "memory_address_length (operands[0])"))
17739    (set_attr "memory" "none")])
17741 (define_expand "stack_protect_set"
17742   [(match_operand 0 "memory_operand" "")
17743    (match_operand 1 "memory_operand" "")]
17744   ""
17746   rtx (*insn)(rtx, rtx);
17748 #ifdef TARGET_THREAD_SSP_OFFSET
17749   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17750   insn = (TARGET_LP64
17751           ? gen_stack_tls_protect_set_di
17752           : gen_stack_tls_protect_set_si);
17753 #else
17754   insn = (TARGET_LP64
17755           ? gen_stack_protect_set_di
17756           : gen_stack_protect_set_si);
17757 #endif
17759   emit_insn (insn (operands[0], operands[1]));
17760   DONE;
17763 (define_insn "stack_protect_set_<mode>"
17764   [(set (match_operand:PTR 0 "memory_operand" "=m")
17765         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17766                     UNSPEC_SP_SET))
17767    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17768    (clobber (reg:CC FLAGS_REG))]
17769   ""
17770   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17771   [(set_attr "type" "multi")])
17773 (define_insn "stack_tls_protect_set_<mode>"
17774   [(set (match_operand:PTR 0 "memory_operand" "=m")
17775         (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17776                     UNSPEC_SP_TLS_SET))
17777    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17778    (clobber (reg:CC FLAGS_REG))]
17779   ""
17780   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17781   [(set_attr "type" "multi")])
17783 (define_expand "stack_protect_test"
17784   [(match_operand 0 "memory_operand" "")
17785    (match_operand 1 "memory_operand" "")
17786    (match_operand 2 "" "")]
17787   ""
17789   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17791   rtx (*insn)(rtx, rtx, rtx);
17793 #ifdef TARGET_THREAD_SSP_OFFSET
17794   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17795   insn = (TARGET_LP64
17796           ? gen_stack_tls_protect_test_di
17797           : gen_stack_tls_protect_test_si);
17798 #else
17799   insn = (TARGET_LP64
17800           ? gen_stack_protect_test_di
17801           : gen_stack_protect_test_si);
17802 #endif
17804   emit_insn (insn (flags, operands[0], operands[1]));
17806   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17807                                   flags, const0_rtx, operands[2]));
17808   DONE;
17811 (define_insn "stack_protect_test_<mode>"
17812   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17813         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17814                      (match_operand:PTR 2 "memory_operand" "m")]
17815                     UNSPEC_SP_TEST))
17816    (clobber (match_scratch:PTR 3 "=&r"))]
17817   ""
17818   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17819   [(set_attr "type" "multi")])
17821 (define_insn "stack_tls_protect_test_<mode>"
17822   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17823         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17824                      (match_operand:PTR 2 "const_int_operand" "i")]
17825                     UNSPEC_SP_TLS_TEST))
17826    (clobber (match_scratch:PTR 3 "=r"))]
17827   ""
17828   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17829   [(set_attr "type" "multi")])
17831 (define_insn "sse4_2_crc32<mode>"
17832   [(set (match_operand:SI 0 "register_operand" "=r")
17833         (unspec:SI
17834           [(match_operand:SI 1 "register_operand" "0")
17835            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17836           UNSPEC_CRC32))]
17837   "TARGET_SSE4_2 || TARGET_CRC32"
17838   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17839   [(set_attr "type" "sselog1")
17840    (set_attr "prefix_rep" "1")
17841    (set_attr "prefix_extra" "1")
17842    (set (attr "prefix_data16")
17843      (if_then_else (match_operand:HI 2 "" "")
17844        (const_string "1")
17845        (const_string "*")))
17846    (set (attr "prefix_rex")
17847      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17848        (const_string "1")
17849        (const_string "*")))
17850    (set_attr "mode" "SI")])
17852 (define_insn "sse4_2_crc32di"
17853   [(set (match_operand:DI 0 "register_operand" "=r")
17854         (unspec:DI
17855           [(match_operand:DI 1 "register_operand" "0")
17856            (match_operand:DI 2 "nonimmediate_operand" "rm")]
17857           UNSPEC_CRC32))]
17858   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17859   "crc32{q}\t{%2, %0|%0, %2}"
17860   [(set_attr "type" "sselog1")
17861    (set_attr "prefix_rep" "1")
17862    (set_attr "prefix_extra" "1")
17863    (set_attr "mode" "DI")])
17865 (define_expand "rdpmc"
17866   [(match_operand:DI 0 "register_operand" "")
17867    (match_operand:SI 1 "register_operand" "")]
17868   ""
17870   rtx reg = gen_reg_rtx (DImode);
17871   rtx si;
17873   /* Force operand 1 into ECX.  */
17874   rtx ecx = gen_rtx_REG (SImode, CX_REG);
17875   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17876   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17877                                 UNSPECV_RDPMC);
17879   if (TARGET_64BIT)
17880     {
17881       rtvec vec = rtvec_alloc (2);
17882       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17883       rtx upper = gen_reg_rtx (DImode);
17884       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17885                                         gen_rtvec (1, const0_rtx),
17886                                         UNSPECV_RDPMC);
17887       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17888       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17889       emit_insn (load);
17890       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17891                                    NULL, 1, OPTAB_DIRECT);
17892       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17893                                  OPTAB_DIRECT);
17894     }
17895   else
17896     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17897   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17898   DONE;
17901 (define_insn "*rdpmc"
17902   [(set (match_operand:DI 0 "register_operand" "=A")
17903         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17904                             UNSPECV_RDPMC))]
17905   "!TARGET_64BIT"
17906   "rdpmc"
17907   [(set_attr "type" "other")
17908    (set_attr "length" "2")])
17910 (define_insn "*rdpmc_rex64"
17911   [(set (match_operand:DI 0 "register_operand" "=a")
17912         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17913                             UNSPECV_RDPMC))
17914   (set (match_operand:DI 1 "register_operand" "=d")
17915        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17916   "TARGET_64BIT"
17917   "rdpmc"
17918   [(set_attr "type" "other")
17919    (set_attr "length" "2")])
17921 (define_expand "rdtsc"
17922   [(set (match_operand:DI 0 "register_operand" "")
17923         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17924   ""
17926   if (TARGET_64BIT)
17927     {
17928       rtvec vec = rtvec_alloc (2);
17929       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17930       rtx upper = gen_reg_rtx (DImode);
17931       rtx lower = gen_reg_rtx (DImode);
17932       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17933                                          gen_rtvec (1, const0_rtx),
17934                                          UNSPECV_RDTSC);
17935       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17936       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17937       emit_insn (load);
17938       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17939                                    NULL, 1, OPTAB_DIRECT);
17940       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17941                                    OPTAB_DIRECT);
17942       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17943       DONE;
17944     }
17947 (define_insn "*rdtsc"
17948   [(set (match_operand:DI 0 "register_operand" "=A")
17949         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17950   "!TARGET_64BIT"
17951   "rdtsc"
17952   [(set_attr "type" "other")
17953    (set_attr "length" "2")])
17955 (define_insn "*rdtsc_rex64"
17956   [(set (match_operand:DI 0 "register_operand" "=a")
17957         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17958    (set (match_operand:DI 1 "register_operand" "=d")
17959         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17960   "TARGET_64BIT"
17961   "rdtsc"
17962   [(set_attr "type" "other")
17963    (set_attr "length" "2")])
17965 (define_expand "rdtscp"
17966   [(match_operand:DI 0 "register_operand" "")
17967    (match_operand:SI 1 "memory_operand" "")]
17968   ""
17970   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17971                                     gen_rtvec (1, const0_rtx),
17972                                     UNSPECV_RDTSCP);
17973   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17974                                     gen_rtvec (1, const0_rtx),
17975                                     UNSPECV_RDTSCP);
17976   rtx reg = gen_reg_rtx (DImode);
17977   rtx tmp = gen_reg_rtx (SImode);
17979   if (TARGET_64BIT)
17980     {
17981       rtvec vec = rtvec_alloc (3);
17982       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17983       rtx upper = gen_reg_rtx (DImode);
17984       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17985       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17986       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17987       emit_insn (load);
17988       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17989                                    NULL, 1, OPTAB_DIRECT);
17990       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17991                                  OPTAB_DIRECT);
17992     }
17993   else
17994     {
17995       rtvec vec = rtvec_alloc (2);
17996       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17997       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17998       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17999       emit_insn (load);
18000     }
18001   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18002   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18003   DONE;
18006 (define_insn "*rdtscp"
18007   [(set (match_operand:DI 0 "register_operand" "=A")
18008         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18009    (set (match_operand:SI 1 "register_operand" "=c")
18010         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18011   "!TARGET_64BIT"
18012   "rdtscp"
18013   [(set_attr "type" "other")
18014    (set_attr "length" "3")])
18016 (define_insn "*rdtscp_rex64"
18017   [(set (match_operand:DI 0 "register_operand" "=a")
18018         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18019    (set (match_operand:DI 1 "register_operand" "=d")
18020         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18021    (set (match_operand:SI 2 "register_operand" "=c")
18022         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18023   "TARGET_64BIT"
18024   "rdtscp"
18025   [(set_attr "type" "other")
18026    (set_attr "length" "3")])
18028 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18030 ;; LWP instructions
18032 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18034 (define_expand "lwp_llwpcb"
18035   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18036                     UNSPECV_LLWP_INTRINSIC)]
18037   "TARGET_LWP")
18039 (define_insn "*lwp_llwpcb<mode>1"
18040   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18041                     UNSPECV_LLWP_INTRINSIC)]
18042   "TARGET_LWP"
18043   "llwpcb\t%0"
18044   [(set_attr "type" "lwp")
18045    (set_attr "mode" "<MODE>")
18046    (set_attr "length" "5")])
18048 (define_expand "lwp_slwpcb"
18049   [(set (match_operand 0 "register_operand" "=r")
18050         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18051   "TARGET_LWP"
18053   rtx (*insn)(rtx);
18055   insn = (TARGET_64BIT
18056           ? gen_lwp_slwpcbdi
18057           : gen_lwp_slwpcbsi);
18059   emit_insn (insn (operands[0]));
18060   DONE;
18063 (define_insn "lwp_slwpcb<mode>"
18064   [(set (match_operand:P 0 "register_operand" "=r")
18065         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18066   "TARGET_LWP"
18067   "slwpcb\t%0"
18068   [(set_attr "type" "lwp")
18069    (set_attr "mode" "<MODE>")
18070    (set_attr "length" "5")])
18072 (define_expand "lwp_lwpval<mode>3"
18073   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18074                      (match_operand:SI 2 "nonimmediate_operand" "rm")
18075                      (match_operand:SI 3 "const_int_operand" "i")]
18076                     UNSPECV_LWPVAL_INTRINSIC)]
18077   "TARGET_LWP"
18078   "/* Avoid unused variable warning.  */
18079    (void) operand0;")
18081 (define_insn "*lwp_lwpval<mode>3_1"
18082   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18083                      (match_operand:SI 1 "nonimmediate_operand" "rm")
18084                      (match_operand:SI 2 "const_int_operand" "i")]
18085                     UNSPECV_LWPVAL_INTRINSIC)]
18086   "TARGET_LWP"
18087   "lwpval\t{%2, %1, %0|%0, %1, %2}"
18088   [(set_attr "type" "lwp")
18089    (set_attr "mode" "<MODE>")
18090    (set (attr "length")
18091         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18093 (define_expand "lwp_lwpins<mode>3"
18094   [(set (reg:CCC FLAGS_REG)
18095         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18096                               (match_operand:SI 2 "nonimmediate_operand" "rm")
18097                               (match_operand:SI 3 "const_int_operand" "i")]
18098                              UNSPECV_LWPINS_INTRINSIC))
18099    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18100         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18101   "TARGET_LWP")
18103 (define_insn "*lwp_lwpins<mode>3_1"
18104   [(set (reg:CCC FLAGS_REG)
18105         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18106                               (match_operand:SI 1 "nonimmediate_operand" "rm")
18107                               (match_operand:SI 2 "const_int_operand" "i")]
18108                              UNSPECV_LWPINS_INTRINSIC))]
18109   "TARGET_LWP"
18110   "lwpins\t{%2, %1, %0|%0, %1, %2}"
18111   [(set_attr "type" "lwp")
18112    (set_attr "mode" "<MODE>")
18113    (set (attr "length")
18114         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18116 (define_insn "rdfsbase<mode>"
18117   [(set (match_operand:SWI48 0 "register_operand" "=r")
18118         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18119   "TARGET_64BIT && TARGET_FSGSBASE"
18120   "rdfsbase %0"
18121   [(set_attr "type" "other")
18122    (set_attr "prefix_extra" "2")])
18124 (define_insn "rdgsbase<mode>"
18125   [(set (match_operand:SWI48 0 "register_operand" "=r")
18126         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18127   "TARGET_64BIT && TARGET_FSGSBASE"
18128   "rdgsbase %0"
18129   [(set_attr "type" "other")
18130    (set_attr "prefix_extra" "2")])
18132 (define_insn "wrfsbase<mode>"
18133   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18134                     UNSPECV_WRFSBASE)]
18135   "TARGET_64BIT && TARGET_FSGSBASE"
18136   "wrfsbase %0"
18137   [(set_attr "type" "other")
18138    (set_attr "prefix_extra" "2")])
18140 (define_insn "wrgsbase<mode>"
18141   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18142                     UNSPECV_WRGSBASE)]
18143   "TARGET_64BIT && TARGET_FSGSBASE"
18144   "wrgsbase %0"
18145   [(set_attr "type" "other")
18146    (set_attr "prefix_extra" "2")])
18148 (define_insn "rdrand<mode>_1"
18149   [(set (match_operand:SWI248 0 "register_operand" "=r")
18150         (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18151    (set (reg:CCC FLAGS_REG)
18152         (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18153   "TARGET_RDRND"
18154   "rdrand\t%0"
18155   [(set_attr "type" "other")
18156    (set_attr "prefix_extra" "1")])
18158 (define_expand "pause"
18159   [(set (match_dup 0)
18160         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18161   ""
18163   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18164   MEM_VOLATILE_P (operands[0]) = 1;
18167 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18168 ;; They have the same encoding.
18169 (define_insn "*pause"
18170   [(set (match_operand:BLK 0 "" "")
18171         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18172   ""
18173   "rep; nop"
18174   [(set_attr "length" "2")
18175    (set_attr "memory" "unknown")])
18177 (include "mmx.md")
18178 (include "sse.md")
18179 (include "sync.md")