OSDN Git Service

* config/i386/i386.md (maxmin): New code iterator.
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
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.
14 ;;
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.
19 ;;
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/>.  */
23 ;;
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
26 ;;
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;
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
64
65 ;; UNSPEC usage:
66
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
81
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
91
92   ;; TLS support
93   UNSPEC_TP
94   UNSPEC_TLS_GD
95   UNSPEC_TLS_LD_BASE
96   UNSPEC_TLSDESC
97   UNSPEC_TLS_IE_SUN
98
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
113
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
133
134   ;; Generic math support
135   UNSPEC_COPYSIGN
136   UNSPEC_IEEE_MIN       ; not commutative
137   UNSPEC_IEEE_MAX       ; not commutative
138
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
150
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
158
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
170
171   UNSPEC_C2_FLAG
172   UNSPEC_FXAM_MEM
173
174   ;; SSP patterns
175   UNSPEC_SP_SET
176   UNSPEC_SP_TEST
177   UNSPEC_SP_TLS_SET
178   UNSPEC_SP_TLS_TEST
179
180   ;; SSSE3
181   UNSPEC_PSHUFB
182   UNSPEC_PSIGN
183   UNSPEC_PALIGNR
184
185   ;; For SSE4A support
186   UNSPEC_EXTRQI
187   UNSPEC_EXTRQ
188   UNSPEC_INSERTQI
189   UNSPEC_INSERTQ
190
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
200
201   ;; For SSE4.2 support
202   UNSPEC_CRC32
203   UNSPEC_PCMPESTR
204   UNSPEC_PCMPISTR
205
206   ;; For FMA4 support
207   UNSPEC_FMADDSUB
208   UNSPEC_XOP_UNSIGNED_CMP
209   UNSPEC_XOP_TRUEFALSE
210   UNSPEC_XOP_PERMUTE
211   UNSPEC_FRCZ
212
213   ;; For AES support
214   UNSPEC_AESENC
215   UNSPEC_AESENCLAST
216   UNSPEC_AESDEC
217   UNSPEC_AESDECLAST
218   UNSPEC_AESIMC
219   UNSPEC_AESKEYGENASSIST
220
221   ;; For PCLMUL support
222   UNSPEC_PCLMUL
223
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
233
234   ;; For AVX2 support
235   UNSPEC_VPERMSI
236   UNSPEC_VPERMDF
237   UNSPEC_VPERMSF
238   UNSPEC_VPERMDI
239   UNSPEC_VPERMTI
240   UNSPEC_GATHER
241
242   ;; For BMI support
243   UNSPEC_BEXTR
244
245   ;; For RDRAND support
246   UNSPEC_RDRAND
247
248   ;; For BMI2 support
249   UNSPEC_PDEP
250   UNSPEC_PEXT
251 ])
252
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
285 ])
286
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   ])
295
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   ])
305
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    ])
319
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   ])
372
373 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
374 ;; from i386.c.
375
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".
380
381 \f
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")))
386
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"))
402
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"))
407
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")))
421
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")))
449
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)")))
462
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)))
473
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)))
482
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)))
490
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)))
509
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)))
521
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")))
527
528 ;; VEX W bit is used.
529 (define_attr "prefix_vex_w" "" (const_int 0))
530
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)"))))
544
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)))
582
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")))))))
612
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.
616
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")))
678
679 ;; Indicates if an instruction has both an immediate and a displacement.
680
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")))
694
695 ;; Indicates if an FP operation has an integer source.
696
697 (define_attr "fp_int_src" "false,true"
698   (const_string "false"))
699
700 ;; Defines rounding mode of an FP operation.
701
702 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
703   (const_string "any"))
704
705 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
706 (define_attr "use_carry" "0,1" (const_string "0"))
707
708 ;; Define attribute to indicate unaligned ssemov insns
709 (define_attr "movu" "0,1" (const_string "0"))
710
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"))
714
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)))
728
729 ;; Describe a user's asm statement.
730 (define_asm_attributes
731   [(set_attr "length" "128")
732    (set_attr "type" "multi")])
733
734 (define_code_iterator plusminus [plus minus])
735
736 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
737
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")])
742
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")])
749
750 ;; Mark commutative operators as such in constraints.
751 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
752                         (minus "") (ss_minus "") (us_minus "")])
753
754 ;; Mapping of max and min
755 (define_code_iterator maxmin [smax smin umax umin])
756
757 ;; Mapping of signed max and min
758 (define_code_iterator smaxmin [smax smin])
759
760 ;; Mapping of unsigned max and min
761 (define_code_iterator umaxmin [umax umin])
762
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")])
767
768 ;; Mapping of logic operators
769 (define_code_iterator any_logic [and ior xor])
770 (define_code_iterator any_or [ior xor])
771
772 ;; Base name for insn mnemonic.
773 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
774
775 ;; Mapping of shift-right operators
776 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
777
778 ;; Base name for define_insn
779 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
780
781 ;; Base name for insn mnemonic.
782 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
783
784 ;; Mapping of rotate operators
785 (define_code_iterator any_rotate [rotate rotatert])
786
787 ;; Base name for define_insn
788 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
789
790 ;; Base name for insn mnemonic.
791 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
792
793 ;; Mapping of abs neg operators
794 (define_code_iterator absneg [abs neg])
795
796 ;; Base name for x87 insn mnemonic.
797 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
798
799 ;; Used in signed and unsigned widening multiplications.
800 (define_code_iterator any_extend [sign_extend zero_extend])
801
802 ;; Prefix for insn menmonic.
803 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
804
805 ;; Prefix for define_insn
806 (define_code_attr u [(sign_extend "") (zero_extend "u")])
807 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
808
809 ;; All integer modes.
810 (define_mode_iterator SWI1248x [QI HI SI DI])
811
812 ;; All integer modes without QImode.
813 (define_mode_iterator SWI248x [HI SI DI])
814
815 ;; All integer modes without QImode and HImode.
816 (define_mode_iterator SWI48x [SI DI])
817
818 ;; All integer modes without SImode and DImode.
819 (define_mode_iterator SWI12 [QI HI])
820
821 ;; All integer modes without DImode.
822 (define_mode_iterator SWI124 [QI HI SI])
823
824 ;; All integer modes without QImode and DImode.
825 (define_mode_iterator SWI24 [HI SI])
826
827 ;; Single word integer modes.
828 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
829
830 ;; Single word integer modes without QImode.
831 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
832
833 ;; Single word integer modes without QImode and HImode.
834 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
835
836 ;; All math-dependant single and double word integer modes.
837 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
838                              (HI "TARGET_HIMODE_MATH")
839                              SI DI (TI "TARGET_64BIT")])
840
841 ;; Math-dependant single word integer modes.
842 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
843                             (HI "TARGET_HIMODE_MATH")
844                             SI (DI "TARGET_64BIT")])
845
846 ;; Math-dependant integer modes without DImode.
847 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
848                                (HI "TARGET_HIMODE_MATH")
849                                SI])
850
851 ;; Math-dependant single word integer modes without QImode.
852 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
853                                SI (DI "TARGET_64BIT")])
854
855 ;; Double word integer modes.
856 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
857                            (TI "TARGET_64BIT")])
858
859 ;; Double word integer modes as mode attribute.
860 (define_mode_attr DWI [(SI "DI") (DI "TI")])
861 (define_mode_attr dwi [(SI "di") (DI "ti")])
862
863 ;; Half mode for double word integer modes.
864 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
865                             (DI "TARGET_64BIT")])
866
867 ;; Instruction suffix for integer modes.
868 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
869
870 ;; Pointer size prefix for integer modes (Intel asm dialect)
871 (define_mode_attr iptrsize [(QI "BYTE")
872                             (HI "WORD")
873                             (SI "DWORD")
874                             (DI "QWORD")])
875
876 ;; Register class for integer modes.
877 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
878
879 ;; Immediate operand constraint for integer modes.
880 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
881
882 ;; General operand constraint for word modes.
883 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
884
885 ;; Immediate operand constraint for double integer modes.
886 (define_mode_attr di [(SI "nF") (DI "e")])
887
888 ;; Immediate operand constraint for shifts.
889 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
890
891 ;; General operand predicate for integer modes.
892 (define_mode_attr general_operand
893         [(QI "general_operand")
894          (HI "general_operand")
895          (SI "x86_64_general_operand")
896          (DI "x86_64_general_operand")
897          (TI "x86_64_general_operand")])
898
899 ;; General sign/zero extend operand predicate for integer modes.
900 (define_mode_attr general_szext_operand
901         [(QI "general_operand")
902          (HI "general_operand")
903          (SI "x86_64_szext_general_operand")
904          (DI "x86_64_szext_general_operand")])
905
906 ;; Immediate operand predicate for integer modes.
907 (define_mode_attr immediate_operand
908         [(QI "immediate_operand")
909          (HI "immediate_operand")
910          (SI "x86_64_immediate_operand")
911          (DI "x86_64_immediate_operand")])
912
913 ;; Nonmemory operand predicate for integer modes.
914 (define_mode_attr nonmemory_operand
915         [(QI "nonmemory_operand")
916          (HI "nonmemory_operand")
917          (SI "x86_64_nonmemory_operand")
918          (DI "x86_64_nonmemory_operand")])
919
920 ;; Operand predicate for shifts.
921 (define_mode_attr shift_operand
922         [(QI "nonimmediate_operand")
923          (HI "nonimmediate_operand")
924          (SI "nonimmediate_operand")
925          (DI "shiftdi_operand")
926          (TI "register_operand")])
927
928 ;; Operand predicate for shift argument.
929 (define_mode_attr shift_immediate_operand
930         [(QI "const_1_to_31_operand")
931          (HI "const_1_to_31_operand")
932          (SI "const_1_to_31_operand")
933          (DI "const_1_to_63_operand")])
934
935 ;; Input operand predicate for arithmetic left shifts.
936 (define_mode_attr ashl_input_operand
937         [(QI "nonimmediate_operand")
938          (HI "nonimmediate_operand")
939          (SI "nonimmediate_operand")
940          (DI "ashldi_input_operand")
941          (TI "reg_or_pm1_operand")])
942
943 ;; SSE and x87 SFmode and DFmode floating point modes
944 (define_mode_iterator MODEF [SF DF])
945
946 ;; All x87 floating point modes
947 (define_mode_iterator X87MODEF [SF DF XF])
948
949 ;; SSE instruction suffix for various modes
950 (define_mode_attr ssemodesuffix
951   [(SF "ss") (DF "sd")
952    (V8SF "ps") (V4DF "pd")
953    (V4SF "ps") (V2DF "pd")
954    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
955    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
956
957 ;; SSE vector suffix for floating point modes
958 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
959
960 ;; SSE vector mode corresponding to a scalar mode
961 (define_mode_attr ssevecmode
962   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
963
964 ;; Instruction suffix for REX 64bit operators.
965 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
966
967 ;; This mode iterator allows :P to be used for patterns that operate on
968 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
969 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
970
971 ;; This mode iterator allows :PTR to be used for patterns that operate on
972 ;; ptr_mode sized quantities.
973 (define_mode_iterator PTR
974   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
975 \f
976 ;; Scheduling descriptions
977
978 (include "pentium.md")
979 (include "ppro.md")
980 (include "k6.md")
981 (include "athlon.md")
982 (include "bdver1.md")
983 (include "geode.md")
984 (include "atom.md")
985 (include "core2.md")
986
987 \f
988 ;; Operand and operator predicates and constraints
989
990 (include "predicates.md")
991 (include "constraints.md")
992
993 \f
994 ;; Compare and branch/compare and store instructions.
995
996 (define_expand "cbranch<mode>4"
997   [(set (reg:CC FLAGS_REG)
998         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
999                     (match_operand:SDWIM 2 "<general_operand>" "")))
1000    (set (pc) (if_then_else
1001                (match_operator 0 "ordered_comparison_operator"
1002                 [(reg:CC FLAGS_REG) (const_int 0)])
1003                (label_ref (match_operand 3 "" ""))
1004                (pc)))]
1005   ""
1006 {
1007   if (MEM_P (operands[1]) && MEM_P (operands[2]))
1008     operands[1] = force_reg (<MODE>mode, operands[1]);
1009   ix86_expand_branch (GET_CODE (operands[0]),
1010                       operands[1], operands[2], operands[3]);
1011   DONE;
1012 })
1013
1014 (define_expand "cstore<mode>4"
1015   [(set (reg:CC FLAGS_REG)
1016         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
1017                     (match_operand:SWIM 3 "<general_operand>" "")))
1018    (set (match_operand:QI 0 "register_operand" "")
1019         (match_operator 1 "ordered_comparison_operator"
1020           [(reg:CC FLAGS_REG) (const_int 0)]))]
1021   ""
1022 {
1023   if (MEM_P (operands[2]) && MEM_P (operands[3]))
1024     operands[2] = force_reg (<MODE>mode, operands[2]);
1025   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1026                      operands[2], operands[3]);
1027   DONE;
1028 })
1029
1030 (define_expand "cmp<mode>_1"
1031   [(set (reg:CC FLAGS_REG)
1032         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
1033                     (match_operand:SWI48 1 "<general_operand>" "")))])
1034
1035 (define_insn "*cmp<mode>_ccno_1"
1036   [(set (reg FLAGS_REG)
1037         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1038                  (match_operand:SWI 1 "const0_operand" "")))]
1039   "ix86_match_ccmode (insn, CCNOmode)"
1040   "@
1041    test{<imodesuffix>}\t%0, %0
1042    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1043   [(set_attr "type" "test,icmp")
1044    (set_attr "length_immediate" "0,1")
1045    (set_attr "mode" "<MODE>")])
1046
1047 (define_insn "*cmp<mode>_1"
1048   [(set (reg FLAGS_REG)
1049         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1050                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1051   "ix86_match_ccmode (insn, CCmode)"
1052   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1053   [(set_attr "type" "icmp")
1054    (set_attr "mode" "<MODE>")])
1055
1056 (define_insn "*cmp<mode>_minus_1"
1057   [(set (reg FLAGS_REG)
1058         (compare
1059           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1060                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1061           (const_int 0)))]
1062   "ix86_match_ccmode (insn, CCGOCmode)"
1063   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1064   [(set_attr "type" "icmp")
1065    (set_attr "mode" "<MODE>")])
1066
1067 (define_insn "*cmpqi_ext_1"
1068   [(set (reg FLAGS_REG)
1069         (compare
1070           (match_operand:QI 0 "general_operand" "Qm")
1071           (subreg:QI
1072             (zero_extract:SI
1073               (match_operand 1 "ext_register_operand" "Q")
1074               (const_int 8)
1075               (const_int 8)) 0)))]
1076   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1077   "cmp{b}\t{%h1, %0|%0, %h1}"
1078   [(set_attr "type" "icmp")
1079    (set_attr "mode" "QI")])
1080
1081 (define_insn "*cmpqi_ext_1_rex64"
1082   [(set (reg FLAGS_REG)
1083         (compare
1084           (match_operand:QI 0 "register_operand" "Q")
1085           (subreg:QI
1086             (zero_extract:SI
1087               (match_operand 1 "ext_register_operand" "Q")
1088               (const_int 8)
1089               (const_int 8)) 0)))]
1090   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1091   "cmp{b}\t{%h1, %0|%0, %h1}"
1092   [(set_attr "type" "icmp")
1093    (set_attr "mode" "QI")])
1094
1095 (define_insn "*cmpqi_ext_2"
1096   [(set (reg FLAGS_REG)
1097         (compare
1098           (subreg:QI
1099             (zero_extract:SI
1100               (match_operand 0 "ext_register_operand" "Q")
1101               (const_int 8)
1102               (const_int 8)) 0)
1103           (match_operand:QI 1 "const0_operand" "")))]
1104   "ix86_match_ccmode (insn, CCNOmode)"
1105   "test{b}\t%h0, %h0"
1106   [(set_attr "type" "test")
1107    (set_attr "length_immediate" "0")
1108    (set_attr "mode" "QI")])
1109
1110 (define_expand "cmpqi_ext_3"
1111   [(set (reg:CC FLAGS_REG)
1112         (compare:CC
1113           (subreg:QI
1114             (zero_extract:SI
1115               (match_operand 0 "ext_register_operand" "")
1116               (const_int 8)
1117               (const_int 8)) 0)
1118           (match_operand:QI 1 "immediate_operand" "")))])
1119
1120 (define_insn "*cmpqi_ext_3_insn"
1121   [(set (reg FLAGS_REG)
1122         (compare
1123           (subreg:QI
1124             (zero_extract:SI
1125               (match_operand 0 "ext_register_operand" "Q")
1126               (const_int 8)
1127               (const_int 8)) 0)
1128           (match_operand:QI 1 "general_operand" "Qmn")))]
1129   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1130   "cmp{b}\t{%1, %h0|%h0, %1}"
1131   [(set_attr "type" "icmp")
1132    (set_attr "modrm" "1")
1133    (set_attr "mode" "QI")])
1134
1135 (define_insn "*cmpqi_ext_3_insn_rex64"
1136   [(set (reg FLAGS_REG)
1137         (compare
1138           (subreg:QI
1139             (zero_extract:SI
1140               (match_operand 0 "ext_register_operand" "Q")
1141               (const_int 8)
1142               (const_int 8)) 0)
1143           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1144   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1145   "cmp{b}\t{%1, %h0|%h0, %1}"
1146   [(set_attr "type" "icmp")
1147    (set_attr "modrm" "1")
1148    (set_attr "mode" "QI")])
1149
1150 (define_insn "*cmpqi_ext_4"
1151   [(set (reg FLAGS_REG)
1152         (compare
1153           (subreg:QI
1154             (zero_extract:SI
1155               (match_operand 0 "ext_register_operand" "Q")
1156               (const_int 8)
1157               (const_int 8)) 0)
1158           (subreg:QI
1159             (zero_extract:SI
1160               (match_operand 1 "ext_register_operand" "Q")
1161               (const_int 8)
1162               (const_int 8)) 0)))]
1163   "ix86_match_ccmode (insn, CCmode)"
1164   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1165   [(set_attr "type" "icmp")
1166    (set_attr "mode" "QI")])
1167
1168 ;; These implement float point compares.
1169 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1170 ;; which would allow mix and match FP modes on the compares.  Which is what
1171 ;; the old patterns did, but with many more of them.
1172
1173 (define_expand "cbranchxf4"
1174   [(set (reg:CC FLAGS_REG)
1175         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1176                     (match_operand:XF 2 "nonmemory_operand" "")))
1177    (set (pc) (if_then_else
1178               (match_operator 0 "ix86_fp_comparison_operator"
1179                [(reg:CC FLAGS_REG)
1180                 (const_int 0)])
1181               (label_ref (match_operand 3 "" ""))
1182               (pc)))]
1183   "TARGET_80387"
1184 {
1185   ix86_expand_branch (GET_CODE (operands[0]),
1186                       operands[1], operands[2], operands[3]);
1187   DONE;
1188 })
1189
1190 (define_expand "cstorexf4"
1191   [(set (reg:CC FLAGS_REG)
1192         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1193                     (match_operand:XF 3 "nonmemory_operand" "")))
1194    (set (match_operand:QI 0 "register_operand" "")
1195               (match_operator 1 "ix86_fp_comparison_operator"
1196                [(reg:CC FLAGS_REG)
1197                 (const_int 0)]))]
1198   "TARGET_80387"
1199 {
1200   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1201                      operands[2], operands[3]);
1202   DONE;
1203 })
1204
1205 (define_expand "cbranch<mode>4"
1206   [(set (reg:CC FLAGS_REG)
1207         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1208                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1209    (set (pc) (if_then_else
1210               (match_operator 0 "ix86_fp_comparison_operator"
1211                [(reg:CC FLAGS_REG)
1212                 (const_int 0)])
1213               (label_ref (match_operand 3 "" ""))
1214               (pc)))]
1215   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1216 {
1217   ix86_expand_branch (GET_CODE (operands[0]),
1218                       operands[1], operands[2], operands[3]);
1219   DONE;
1220 })
1221
1222 (define_expand "cstore<mode>4"
1223   [(set (reg:CC FLAGS_REG)
1224         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1225                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1226    (set (match_operand:QI 0 "register_operand" "")
1227               (match_operator 1 "ix86_fp_comparison_operator"
1228                [(reg:CC FLAGS_REG)
1229                 (const_int 0)]))]
1230   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1231 {
1232   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1233                      operands[2], operands[3]);
1234   DONE;
1235 })
1236
1237 (define_expand "cbranchcc4"
1238   [(set (pc) (if_then_else
1239               (match_operator 0 "comparison_operator"
1240                [(match_operand 1 "flags_reg_operand" "")
1241                 (match_operand 2 "const0_operand" "")])
1242               (label_ref (match_operand 3 "" ""))
1243               (pc)))]
1244   ""
1245 {
1246   ix86_expand_branch (GET_CODE (operands[0]),
1247                       operands[1], operands[2], operands[3]);
1248   DONE;
1249 })
1250
1251 (define_expand "cstorecc4"
1252   [(set (match_operand:QI 0 "register_operand" "")
1253               (match_operator 1 "comparison_operator"
1254                [(match_operand 2 "flags_reg_operand" "")
1255                 (match_operand 3 "const0_operand" "")]))]
1256   ""
1257 {
1258   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1259                      operands[2], operands[3]);
1260   DONE;
1261 })
1262
1263
1264 ;; FP compares, step 1:
1265 ;; Set the FP condition codes.
1266 ;;
1267 ;; CCFPmode     compare with exceptions
1268 ;; CCFPUmode    compare with no exceptions
1269
1270 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1271 ;; used to manage the reg stack popping would not be preserved.
1272
1273 (define_insn "*cmpfp_0"
1274   [(set (match_operand:HI 0 "register_operand" "=a")
1275         (unspec:HI
1276           [(compare:CCFP
1277              (match_operand 1 "register_operand" "f")
1278              (match_operand 2 "const0_operand" ""))]
1279         UNSPEC_FNSTSW))]
1280   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1281    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1282   "* return output_fp_compare (insn, operands, false, false);"
1283   [(set_attr "type" "multi")
1284    (set_attr "unit" "i387")
1285    (set (attr "mode")
1286      (cond [(match_operand:SF 1 "" "")
1287               (const_string "SF")
1288             (match_operand:DF 1 "" "")
1289               (const_string "DF")
1290            ]
1291            (const_string "XF")))])
1292
1293 (define_insn_and_split "*cmpfp_0_cc"
1294   [(set (reg:CCFP FLAGS_REG)
1295         (compare:CCFP
1296           (match_operand 1 "register_operand" "f")
1297           (match_operand 2 "const0_operand" "")))
1298    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1299   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1300    && TARGET_SAHF && !TARGET_CMOVE
1301    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1302   "#"
1303   "&& reload_completed"
1304   [(set (match_dup 0)
1305         (unspec:HI
1306           [(compare:CCFP (match_dup 1)(match_dup 2))]
1307         UNSPEC_FNSTSW))
1308    (set (reg:CC FLAGS_REG)
1309         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1310   ""
1311   [(set_attr "type" "multi")
1312    (set_attr "unit" "i387")
1313    (set (attr "mode")
1314      (cond [(match_operand:SF 1 "" "")
1315               (const_string "SF")
1316             (match_operand:DF 1 "" "")
1317               (const_string "DF")
1318            ]
1319            (const_string "XF")))])
1320
1321 (define_insn "*cmpfp_xf"
1322   [(set (match_operand:HI 0 "register_operand" "=a")
1323         (unspec:HI
1324           [(compare:CCFP
1325              (match_operand:XF 1 "register_operand" "f")
1326              (match_operand:XF 2 "register_operand" "f"))]
1327           UNSPEC_FNSTSW))]
1328   "TARGET_80387"
1329   "* return output_fp_compare (insn, operands, false, false);"
1330   [(set_attr "type" "multi")
1331    (set_attr "unit" "i387")
1332    (set_attr "mode" "XF")])
1333
1334 (define_insn_and_split "*cmpfp_xf_cc"
1335   [(set (reg:CCFP FLAGS_REG)
1336         (compare:CCFP
1337           (match_operand:XF 1 "register_operand" "f")
1338           (match_operand:XF 2 "register_operand" "f")))
1339    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1340   "TARGET_80387
1341    && TARGET_SAHF && !TARGET_CMOVE"
1342   "#"
1343   "&& reload_completed"
1344   [(set (match_dup 0)
1345         (unspec:HI
1346           [(compare:CCFP (match_dup 1)(match_dup 2))]
1347         UNSPEC_FNSTSW))
1348    (set (reg:CC FLAGS_REG)
1349         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1350   ""
1351   [(set_attr "type" "multi")
1352    (set_attr "unit" "i387")
1353    (set_attr "mode" "XF")])
1354
1355 (define_insn "*cmpfp_<mode>"
1356   [(set (match_operand:HI 0 "register_operand" "=a")
1357         (unspec:HI
1358           [(compare:CCFP
1359              (match_operand:MODEF 1 "register_operand" "f")
1360              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1361           UNSPEC_FNSTSW))]
1362   "TARGET_80387"
1363   "* return output_fp_compare (insn, operands, false, false);"
1364   [(set_attr "type" "multi")
1365    (set_attr "unit" "i387")
1366    (set_attr "mode" "<MODE>")])
1367
1368 (define_insn_and_split "*cmpfp_<mode>_cc"
1369   [(set (reg:CCFP FLAGS_REG)
1370         (compare:CCFP
1371           (match_operand:MODEF 1 "register_operand" "f")
1372           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1373    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1374   "TARGET_80387
1375    && TARGET_SAHF && !TARGET_CMOVE"
1376   "#"
1377   "&& reload_completed"
1378   [(set (match_dup 0)
1379         (unspec:HI
1380           [(compare:CCFP (match_dup 1)(match_dup 2))]
1381         UNSPEC_FNSTSW))
1382    (set (reg:CC FLAGS_REG)
1383         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1384   ""
1385   [(set_attr "type" "multi")
1386    (set_attr "unit" "i387")
1387    (set_attr "mode" "<MODE>")])
1388
1389 (define_insn "*cmpfp_u"
1390   [(set (match_operand:HI 0 "register_operand" "=a")
1391         (unspec:HI
1392           [(compare:CCFPU
1393              (match_operand 1 "register_operand" "f")
1394              (match_operand 2 "register_operand" "f"))]
1395           UNSPEC_FNSTSW))]
1396   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1397    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1398   "* return output_fp_compare (insn, operands, false, true);"
1399   [(set_attr "type" "multi")
1400    (set_attr "unit" "i387")
1401    (set (attr "mode")
1402      (cond [(match_operand:SF 1 "" "")
1403               (const_string "SF")
1404             (match_operand:DF 1 "" "")
1405               (const_string "DF")
1406            ]
1407            (const_string "XF")))])
1408
1409 (define_insn_and_split "*cmpfp_u_cc"
1410   [(set (reg:CCFPU FLAGS_REG)
1411         (compare:CCFPU
1412           (match_operand 1 "register_operand" "f")
1413           (match_operand 2 "register_operand" "f")))
1414    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1415   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1416    && TARGET_SAHF && !TARGET_CMOVE
1417    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1418   "#"
1419   "&& reload_completed"
1420   [(set (match_dup 0)
1421         (unspec:HI
1422           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1423         UNSPEC_FNSTSW))
1424    (set (reg:CC FLAGS_REG)
1425         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1426   ""
1427   [(set_attr "type" "multi")
1428    (set_attr "unit" "i387")
1429    (set (attr "mode")
1430      (cond [(match_operand:SF 1 "" "")
1431               (const_string "SF")
1432             (match_operand:DF 1 "" "")
1433               (const_string "DF")
1434            ]
1435            (const_string "XF")))])
1436
1437 (define_insn "*cmpfp_<mode>"
1438   [(set (match_operand:HI 0 "register_operand" "=a")
1439         (unspec:HI
1440           [(compare:CCFP
1441              (match_operand 1 "register_operand" "f")
1442              (match_operator 3 "float_operator"
1443                [(match_operand:SWI24 2 "memory_operand" "m")]))]
1444           UNSPEC_FNSTSW))]
1445   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1446    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1447    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1448   "* return output_fp_compare (insn, operands, false, false);"
1449   [(set_attr "type" "multi")
1450    (set_attr "unit" "i387")
1451    (set_attr "fp_int_src" "true")
1452    (set_attr "mode" "<MODE>")])
1453
1454 (define_insn_and_split "*cmpfp_<mode>_cc"
1455   [(set (reg:CCFP FLAGS_REG)
1456         (compare:CCFP
1457           (match_operand 1 "register_operand" "f")
1458           (match_operator 3 "float_operator"
1459             [(match_operand:SWI24 2 "memory_operand" "m")])))
1460    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1461   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1462    && TARGET_SAHF && !TARGET_CMOVE
1463    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1464    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1465   "#"
1466   "&& reload_completed"
1467   [(set (match_dup 0)
1468         (unspec:HI
1469           [(compare:CCFP
1470              (match_dup 1)
1471              (match_op_dup 3 [(match_dup 2)]))]
1472         UNSPEC_FNSTSW))
1473    (set (reg:CC FLAGS_REG)
1474         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1475   ""
1476   [(set_attr "type" "multi")
1477    (set_attr "unit" "i387")
1478    (set_attr "fp_int_src" "true")
1479    (set_attr "mode" "<MODE>")])
1480
1481 ;; FP compares, step 2
1482 ;; Move the fpsw to ax.
1483
1484 (define_insn "x86_fnstsw_1"
1485   [(set (match_operand:HI 0 "register_operand" "=a")
1486         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1487   "TARGET_80387"
1488   "fnstsw\t%0"
1489   [(set (attr "length")
1490         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1491    (set_attr "mode" "SI")
1492    (set_attr "unit" "i387")])
1493
1494 ;; FP compares, step 3
1495 ;; Get ax into flags, general case.
1496
1497 (define_insn "x86_sahf_1"
1498   [(set (reg:CC FLAGS_REG)
1499         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1500                    UNSPEC_SAHF))]
1501   "TARGET_SAHF"
1502 {
1503 #ifndef HAVE_AS_IX86_SAHF
1504   if (TARGET_64BIT)
1505     return ASM_BYTE "0x9e";
1506   else
1507 #endif
1508   return "sahf";
1509 }
1510   [(set_attr "length" "1")
1511    (set_attr "athlon_decode" "vector")
1512    (set_attr "amdfam10_decode" "direct")
1513    (set_attr "bdver1_decode" "direct")
1514    (set_attr "mode" "SI")])
1515
1516 ;; Pentium Pro can do steps 1 through 3 in one go.
1517 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1518 ;; (these i387 instructions set flags directly)
1519 (define_insn "*cmpfp_i_mixed"
1520   [(set (reg:CCFP FLAGS_REG)
1521         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1522                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1523   "TARGET_MIX_SSE_I387
1524    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1525    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1526   "* return output_fp_compare (insn, operands, true, false);"
1527   [(set_attr "type" "fcmp,ssecomi")
1528    (set_attr "prefix" "orig,maybe_vex")
1529    (set (attr "mode")
1530      (if_then_else (match_operand:SF 1 "" "")
1531         (const_string "SF")
1532         (const_string "DF")))
1533    (set (attr "prefix_rep")
1534         (if_then_else (eq_attr "type" "ssecomi")
1535                       (const_string "0")
1536                       (const_string "*")))
1537    (set (attr "prefix_data16")
1538         (cond [(eq_attr "type" "fcmp")
1539                  (const_string "*")
1540                (eq_attr "mode" "DF")
1541                  (const_string "1")
1542               ]
1543               (const_string "0")))
1544    (set_attr "athlon_decode" "vector")
1545    (set_attr "amdfam10_decode" "direct")
1546    (set_attr "bdver1_decode" "double")])
1547
1548 (define_insn "*cmpfp_i_sse"
1549   [(set (reg:CCFP FLAGS_REG)
1550         (compare:CCFP (match_operand 0 "register_operand" "x")
1551                       (match_operand 1 "nonimmediate_operand" "xm")))]
1552   "TARGET_SSE_MATH
1553    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1554    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1555   "* return output_fp_compare (insn, operands, true, false);"
1556   [(set_attr "type" "ssecomi")
1557    (set_attr "prefix" "maybe_vex")
1558    (set (attr "mode")
1559      (if_then_else (match_operand:SF 1 "" "")
1560         (const_string "SF")
1561         (const_string "DF")))
1562    (set_attr "prefix_rep" "0")
1563    (set (attr "prefix_data16")
1564         (if_then_else (eq_attr "mode" "DF")
1565                       (const_string "1")
1566                       (const_string "0")))
1567    (set_attr "athlon_decode" "vector")
1568    (set_attr "amdfam10_decode" "direct")
1569    (set_attr "bdver1_decode" "double")])
1570
1571 (define_insn "*cmpfp_i_i387"
1572   [(set (reg:CCFP FLAGS_REG)
1573         (compare:CCFP (match_operand 0 "register_operand" "f")
1574                       (match_operand 1 "register_operand" "f")))]
1575   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1576    && TARGET_CMOVE
1577    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1578    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1579   "* return output_fp_compare (insn, operands, true, false);"
1580   [(set_attr "type" "fcmp")
1581    (set (attr "mode")
1582      (cond [(match_operand:SF 1 "" "")
1583               (const_string "SF")
1584             (match_operand:DF 1 "" "")
1585               (const_string "DF")
1586            ]
1587            (const_string "XF")))
1588    (set_attr "athlon_decode" "vector")
1589    (set_attr "amdfam10_decode" "direct")
1590    (set_attr "bdver1_decode" "double")])
1591
1592 (define_insn "*cmpfp_iu_mixed"
1593   [(set (reg:CCFPU FLAGS_REG)
1594         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1595                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1596   "TARGET_MIX_SSE_I387
1597    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1598    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1599   "* return output_fp_compare (insn, operands, true, true);"
1600   [(set_attr "type" "fcmp,ssecomi")
1601    (set_attr "prefix" "orig,maybe_vex")
1602    (set (attr "mode")
1603      (if_then_else (match_operand:SF 1 "" "")
1604         (const_string "SF")
1605         (const_string "DF")))
1606    (set (attr "prefix_rep")
1607         (if_then_else (eq_attr "type" "ssecomi")
1608                       (const_string "0")
1609                       (const_string "*")))
1610    (set (attr "prefix_data16")
1611         (cond [(eq_attr "type" "fcmp")
1612                  (const_string "*")
1613                (eq_attr "mode" "DF")
1614                  (const_string "1")
1615               ]
1616               (const_string "0")))
1617    (set_attr "athlon_decode" "vector")
1618    (set_attr "amdfam10_decode" "direct")
1619    (set_attr "bdver1_decode" "double")])
1620
1621 (define_insn "*cmpfp_iu_sse"
1622   [(set (reg:CCFPU FLAGS_REG)
1623         (compare:CCFPU (match_operand 0 "register_operand" "x")
1624                        (match_operand 1 "nonimmediate_operand" "xm")))]
1625   "TARGET_SSE_MATH
1626    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1627    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1628   "* return output_fp_compare (insn, operands, true, true);"
1629   [(set_attr "type" "ssecomi")
1630    (set_attr "prefix" "maybe_vex")
1631    (set (attr "mode")
1632      (if_then_else (match_operand:SF 1 "" "")
1633         (const_string "SF")
1634         (const_string "DF")))
1635    (set_attr "prefix_rep" "0")
1636    (set (attr "prefix_data16")
1637         (if_then_else (eq_attr "mode" "DF")
1638                       (const_string "1")
1639                       (const_string "0")))
1640    (set_attr "athlon_decode" "vector")
1641    (set_attr "amdfam10_decode" "direct")
1642    (set_attr "bdver1_decode" "double")])
1643
1644 (define_insn "*cmpfp_iu_387"
1645   [(set (reg:CCFPU FLAGS_REG)
1646         (compare:CCFPU (match_operand 0 "register_operand" "f")
1647                        (match_operand 1 "register_operand" "f")))]
1648   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1649    && TARGET_CMOVE
1650    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1651    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1652   "* return output_fp_compare (insn, operands, true, true);"
1653   [(set_attr "type" "fcmp")
1654    (set (attr "mode")
1655      (cond [(match_operand:SF 1 "" "")
1656               (const_string "SF")
1657             (match_operand:DF 1 "" "")
1658               (const_string "DF")
1659            ]
1660            (const_string "XF")))
1661    (set_attr "athlon_decode" "vector")
1662    (set_attr "amdfam10_decode" "direct")
1663    (set_attr "bdver1_decode" "direct")])
1664 \f
1665 ;; Push/pop instructions.
1666
1667 (define_insn "*push<mode>2"
1668   [(set (match_operand:DWI 0 "push_operand" "=<")
1669         (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1670   ""
1671   "#"
1672   [(set_attr "type" "multi")
1673    (set_attr "mode" "<MODE>")])
1674
1675 (define_split
1676   [(set (match_operand:TI 0 "push_operand" "")
1677         (match_operand:TI 1 "general_operand" ""))]
1678   "TARGET_64BIT && reload_completed
1679    && !SSE_REG_P (operands[1])"
1680   [(const_int 0)]
1681   "ix86_split_long_move (operands); DONE;")
1682
1683 (define_insn "*pushdi2_rex64"
1684   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1685         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1686   "TARGET_64BIT"
1687   "@
1688    push{q}\t%1
1689    #"
1690   [(set_attr "type" "push,multi")
1691    (set_attr "mode" "DI")])
1692
1693 ;; Convert impossible pushes of immediate to existing instructions.
1694 ;; First try to get scratch register and go through it.  In case this
1695 ;; fails, push sign extended lower part first and then overwrite
1696 ;; upper part by 32bit move.
1697 (define_peephole2
1698   [(match_scratch:DI 2 "r")
1699    (set (match_operand:DI 0 "push_operand" "")
1700         (match_operand:DI 1 "immediate_operand" ""))]
1701   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1702    && !x86_64_immediate_operand (operands[1], DImode)"
1703   [(set (match_dup 2) (match_dup 1))
1704    (set (match_dup 0) (match_dup 2))])
1705
1706 ;; We need to define this as both peepholer and splitter for case
1707 ;; peephole2 pass is not run.
1708 ;; "&& 1" is needed to keep it from matching the previous pattern.
1709 (define_peephole2
1710   [(set (match_operand:DI 0 "push_operand" "")
1711         (match_operand:DI 1 "immediate_operand" ""))]
1712   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1713    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1714   [(set (match_dup 0) (match_dup 1))
1715    (set (match_dup 2) (match_dup 3))]
1716 {
1717   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1718
1719   operands[1] = gen_lowpart (DImode, operands[2]);
1720   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1721                                                    GEN_INT (4)));
1722 })
1723
1724 (define_split
1725   [(set (match_operand:DI 0 "push_operand" "")
1726         (match_operand:DI 1 "immediate_operand" ""))]
1727   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1728                     ? epilogue_completed : reload_completed)
1729    && !symbolic_operand (operands[1], DImode)
1730    && !x86_64_immediate_operand (operands[1], DImode)"
1731   [(set (match_dup 0) (match_dup 1))
1732    (set (match_dup 2) (match_dup 3))]
1733 {
1734   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1735
1736   operands[1] = gen_lowpart (DImode, operands[2]);
1737   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1738                                                    GEN_INT (4)));
1739 })
1740
1741 (define_split
1742   [(set (match_operand:DI 0 "push_operand" "")
1743         (match_operand:DI 1 "general_operand" ""))]
1744   "!TARGET_64BIT && reload_completed
1745    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1746   [(const_int 0)]
1747   "ix86_split_long_move (operands); DONE;")
1748
1749 (define_insn "*pushsi2"
1750   [(set (match_operand:SI 0 "push_operand" "=<")
1751         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1752   "!TARGET_64BIT"
1753   "push{l}\t%1"
1754   [(set_attr "type" "push")
1755    (set_attr "mode" "SI")])
1756
1757 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1758 ;; "push a byte/word".  But actually we use pushl, which has the effect
1759 ;; of rounding the amount pushed up to a word.
1760
1761 ;; For TARGET_64BIT we always round up to 8 bytes.
1762 (define_insn "*push<mode>2_rex64"
1763   [(set (match_operand:SWI124 0 "push_operand" "=X")
1764         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1765   "TARGET_64BIT"
1766   "push{q}\t%q1"
1767   [(set_attr "type" "push")
1768    (set_attr "mode" "DI")])
1769
1770 (define_insn "*push<mode>2"
1771   [(set (match_operand:SWI12 0 "push_operand" "=X")
1772         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1773   "!TARGET_64BIT"
1774   "push{l}\t%k1"
1775   [(set_attr "type" "push")
1776    (set_attr "mode" "SI")])
1777
1778 (define_insn "*push<mode>2_prologue"
1779   [(set (match_operand:P 0 "push_operand" "=<")
1780         (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1781    (clobber (mem:BLK (scratch)))]
1782   ""
1783   "push{<imodesuffix>}\t%1"
1784   [(set_attr "type" "push")
1785    (set_attr "mode" "<MODE>")])
1786
1787 (define_insn "*pop<mode>1"
1788   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1789         (match_operand:P 1 "pop_operand" ">"))]
1790   ""
1791   "pop{<imodesuffix>}\t%0"
1792   [(set_attr "type" "pop")
1793    (set_attr "mode" "<MODE>")])
1794
1795 (define_insn "*pop<mode>1_epilogue"
1796   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1797         (match_operand:P 1 "pop_operand" ">"))
1798    (clobber (mem:BLK (scratch)))]
1799   ""
1800   "pop{<imodesuffix>}\t%0"
1801   [(set_attr "type" "pop")
1802    (set_attr "mode" "<MODE>")])
1803 \f
1804 ;; Move instructions.
1805
1806 (define_expand "movoi"
1807   [(set (match_operand:OI 0 "nonimmediate_operand" "")
1808         (match_operand:OI 1 "general_operand" ""))]
1809   "TARGET_AVX"
1810   "ix86_expand_move (OImode, operands); DONE;")
1811
1812 (define_expand "movti"
1813   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1814         (match_operand:TI 1 "nonimmediate_operand" ""))]
1815   "TARGET_64BIT || TARGET_SSE"
1816 {
1817   if (TARGET_64BIT)
1818     ix86_expand_move (TImode, operands);
1819   else if (push_operand (operands[0], TImode))
1820     ix86_expand_push (TImode, operands[1]);
1821   else
1822     ix86_expand_vector_move (TImode, operands);
1823   DONE;
1824 })
1825
1826 ;; This expands to what emit_move_complex would generate if we didn't
1827 ;; have a movti pattern.  Having this avoids problems with reload on
1828 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1829 ;; to have around all the time.
1830 (define_expand "movcdi"
1831   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1832         (match_operand:CDI 1 "general_operand" ""))]
1833   ""
1834 {
1835   if (push_operand (operands[0], CDImode))
1836     emit_move_complex_push (CDImode, operands[0], operands[1]);
1837   else
1838     emit_move_complex_parts (operands[0], operands[1]);
1839   DONE;
1840 })
1841
1842 (define_expand "mov<mode>"
1843   [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1844         (match_operand:SWI1248x 1 "general_operand" ""))]
1845   ""
1846   "ix86_expand_move (<MODE>mode, operands); DONE;")
1847
1848 (define_insn "*mov<mode>_xor"
1849   [(set (match_operand:SWI48 0 "register_operand" "=r")
1850         (match_operand:SWI48 1 "const0_operand" ""))
1851    (clobber (reg:CC FLAGS_REG))]
1852   "reload_completed"
1853   "xor{l}\t%k0, %k0"
1854   [(set_attr "type" "alu1")
1855    (set_attr "mode" "SI")
1856    (set_attr "length_immediate" "0")])
1857
1858 (define_insn "*mov<mode>_or"
1859   [(set (match_operand:SWI48 0 "register_operand" "=r")
1860         (match_operand:SWI48 1 "const_int_operand" ""))
1861    (clobber (reg:CC FLAGS_REG))]
1862   "reload_completed
1863    && operands[1] == constm1_rtx"
1864   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1865   [(set_attr "type" "alu1")
1866    (set_attr "mode" "<MODE>")
1867    (set_attr "length_immediate" "1")])
1868
1869 (define_insn "*movoi_internal_avx"
1870   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1871         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1872   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1873 {
1874   switch (which_alternative)
1875     {
1876     case 0:
1877       return standard_sse_constant_opcode (insn, operands[1]);
1878     case 1:
1879     case 2:
1880       if (misaligned_operand (operands[0], OImode)
1881           || misaligned_operand (operands[1], OImode))
1882         return "vmovdqu\t{%1, %0|%0, %1}";
1883       else
1884         return "vmovdqa\t{%1, %0|%0, %1}";
1885     default:
1886       gcc_unreachable ();
1887     }
1888 }
1889   [(set_attr "type" "sselog1,ssemov,ssemov")
1890    (set_attr "prefix" "vex")
1891    (set_attr "mode" "OI")])
1892
1893 (define_insn "*movti_internal_rex64"
1894   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1895         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1896   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1897 {
1898   switch (which_alternative)
1899     {
1900     case 0:
1901     case 1:
1902       return "#";
1903     case 2:
1904       return standard_sse_constant_opcode (insn, operands[1]);
1905     case 3:
1906     case 4:
1907       /* TDmode values are passed as TImode on the stack.  Moving them
1908          to stack may result in unaligned memory access.  */
1909       if (misaligned_operand (operands[0], TImode)
1910           || misaligned_operand (operands[1], TImode))
1911         {
1912           if (get_attr_mode (insn) == MODE_V4SF)
1913             return "%vmovups\t{%1, %0|%0, %1}";
1914           else
1915             return "%vmovdqu\t{%1, %0|%0, %1}";
1916         }
1917       else
1918         {
1919           if (get_attr_mode (insn) == MODE_V4SF)
1920             return "%vmovaps\t{%1, %0|%0, %1}";
1921           else
1922             return "%vmovdqa\t{%1, %0|%0, %1}";
1923         }
1924     default:
1925       gcc_unreachable ();
1926     }
1927 }
1928   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1929    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1930    (set (attr "mode")
1931         (cond [(eq_attr "alternative" "2,3")
1932                  (if_then_else
1933                    (match_test "optimize_function_for_size_p (cfun)")
1934                    (const_string "V4SF")
1935                    (const_string "TI"))
1936                (eq_attr "alternative" "4")
1937                  (if_then_else
1938                    (ior (match_test "TARGET_SSE_TYPELESS_STORES")
1939                         (match_test "optimize_function_for_size_p (cfun)"))
1940                    (const_string "V4SF")
1941                    (const_string "TI"))]
1942                (const_string "DI")))])
1943
1944 (define_split
1945   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1946         (match_operand:TI 1 "general_operand" ""))]
1947   "reload_completed
1948    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1949   [(const_int 0)]
1950   "ix86_split_long_move (operands); DONE;")
1951
1952 (define_insn "*movti_internal_sse"
1953   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1954         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1955   "TARGET_SSE && !TARGET_64BIT
1956    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1957 {
1958   switch (which_alternative)
1959     {
1960     case 0:
1961       return standard_sse_constant_opcode (insn, operands[1]);
1962     case 1:
1963     case 2:
1964       /* TDmode values are passed as TImode on the stack.  Moving them
1965          to stack may result in unaligned memory access.  */
1966       if (misaligned_operand (operands[0], TImode)
1967           || misaligned_operand (operands[1], TImode))
1968         {
1969           if (get_attr_mode (insn) == MODE_V4SF)
1970             return "%vmovups\t{%1, %0|%0, %1}";
1971           else
1972             return "%vmovdqu\t{%1, %0|%0, %1}";
1973         }
1974       else
1975         {
1976           if (get_attr_mode (insn) == MODE_V4SF)
1977             return "%vmovaps\t{%1, %0|%0, %1}";
1978           else
1979             return "%vmovdqa\t{%1, %0|%0, %1}";
1980         }
1981     default:
1982       gcc_unreachable ();
1983     }
1984 }
1985   [(set_attr "type" "sselog1,ssemov,ssemov")
1986    (set_attr "prefix" "maybe_vex")
1987    (set (attr "mode")
1988         (cond [(ior (not (match_test "TARGET_SSE2"))
1989                     (match_test "optimize_function_for_size_p (cfun)"))
1990                  (const_string "V4SF")
1991                (and (eq_attr "alternative" "2")
1992                     (match_test "TARGET_SSE_TYPELESS_STORES"))
1993                  (const_string "V4SF")]
1994               (const_string "TI")))])
1995
1996 (define_insn "*movdi_internal_rex64"
1997   [(set (match_operand:DI 0 "nonimmediate_operand"
1998           "=r,r  ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1999         (match_operand:DI 1 "general_operand"
2000           "Z ,rem,i,re,n ,C ,*y ,m  ,*Ym,r   ,C ,*x,*x,m ,*Yi,r   ,*Ym,*x"))]
2001   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2002 {
2003   switch (get_attr_type (insn))
2004     {
2005     case TYPE_SSECVT:
2006       if (SSE_REG_P (operands[0]))
2007         return "movq2dq\t{%1, %0|%0, %1}";
2008       else
2009         return "movdq2q\t{%1, %0|%0, %1}";
2010
2011     case TYPE_SSEMOV:
2012       if (get_attr_mode (insn) == MODE_TI)
2013         return "%vmovdqa\t{%1, %0|%0, %1}";
2014       /* Handle broken assemblers that require movd instead of movq.  */
2015       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2016         return "%vmovd\t{%1, %0|%0, %1}";
2017       else
2018         return "%vmovq\t{%1, %0|%0, %1}";
2019
2020     case TYPE_MMXMOV:
2021       /* Handle broken assemblers that require movd instead of movq.  */
2022       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2023         return "movd\t{%1, %0|%0, %1}";
2024       else
2025         return "movq\t{%1, %0|%0, %1}";
2026
2027     case TYPE_SSELOG1:
2028       return standard_sse_constant_opcode (insn, operands[1]);
2029
2030     case TYPE_MMX:
2031       return "pxor\t%0, %0";
2032
2033     case TYPE_MULTI:
2034       return "#";
2035
2036     case TYPE_LEA:
2037       return "lea{q}\t{%a1, %0|%0, %a1}";
2038
2039     default:
2040       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2041       if (get_attr_mode (insn) == MODE_SI)
2042         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2043       else if (which_alternative == 2)
2044         return "movabs{q}\t{%1, %0|%0, %1}";
2045       else
2046         return "mov{q}\t{%1, %0|%0, %1}";
2047     }
2048 }
2049   [(set (attr "type")
2050      (cond [(eq_attr "alternative" "4")
2051               (const_string "multi")
2052             (eq_attr "alternative" "5")
2053               (const_string "mmx")
2054             (eq_attr "alternative" "6,7,8,9")
2055               (const_string "mmxmov")
2056             (eq_attr "alternative" "10")
2057               (const_string "sselog1")
2058             (eq_attr "alternative" "11,12,13,14,15")
2059               (const_string "ssemov")
2060             (eq_attr "alternative" "16,17")
2061               (const_string "ssecvt")
2062             (match_operand 1 "pic_32bit_operand" "")
2063               (const_string "lea")
2064            ]
2065            (const_string "imov")))
2066    (set (attr "modrm")
2067      (if_then_else
2068        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2069          (const_string "0")
2070          (const_string "*")))
2071    (set (attr "length_immediate")
2072      (if_then_else
2073        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2074          (const_string "8")
2075          (const_string "*")))
2076    (set (attr "prefix_rex")
2077      (if_then_else (eq_attr "alternative" "8,9")
2078        (const_string "1")
2079        (const_string "*")))
2080    (set (attr "prefix_data16")
2081      (if_then_else (eq_attr "alternative" "11")
2082        (const_string "1")
2083        (const_string "*")))
2084    (set (attr "prefix")
2085      (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2086        (const_string "maybe_vex")
2087        (const_string "orig")))
2088    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2089
2090 ;; Reload patterns to support multi-word load/store
2091 ;; with non-offsetable address.
2092 (define_expand "reload_noff_store"
2093   [(parallel [(match_operand 0 "memory_operand" "=m")
2094               (match_operand 1 "register_operand" "r")
2095               (match_operand:DI 2 "register_operand" "=&r")])]
2096   "TARGET_64BIT"
2097 {
2098   rtx mem = operands[0];
2099   rtx addr = XEXP (mem, 0);
2100
2101   emit_move_insn (operands[2], addr);
2102   mem = replace_equiv_address_nv (mem, operands[2]);
2103
2104   emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2105   DONE;
2106 })
2107
2108 (define_expand "reload_noff_load"
2109   [(parallel [(match_operand 0 "register_operand" "=r")
2110               (match_operand 1 "memory_operand" "m")
2111               (match_operand:DI 2 "register_operand" "=r")])]
2112   "TARGET_64BIT"
2113 {
2114   rtx mem = operands[1];
2115   rtx addr = XEXP (mem, 0);
2116
2117   emit_move_insn (operands[2], addr);
2118   mem = replace_equiv_address_nv (mem, operands[2]);
2119
2120   emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2121   DONE;
2122 })
2123
2124 ;; Convert impossible stores of immediate to existing instructions.
2125 ;; First try to get scratch register and go through it.  In case this
2126 ;; fails, move by 32bit parts.
2127 (define_peephole2
2128   [(match_scratch:DI 2 "r")
2129    (set (match_operand:DI 0 "memory_operand" "")
2130         (match_operand:DI 1 "immediate_operand" ""))]
2131   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2132    && !x86_64_immediate_operand (operands[1], DImode)"
2133   [(set (match_dup 2) (match_dup 1))
2134    (set (match_dup 0) (match_dup 2))])
2135
2136 ;; We need to define this as both peepholer and splitter for case
2137 ;; peephole2 pass is not run.
2138 ;; "&& 1" is needed to keep it from matching the previous pattern.
2139 (define_peephole2
2140   [(set (match_operand:DI 0 "memory_operand" "")
2141         (match_operand:DI 1 "immediate_operand" ""))]
2142   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2143    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2144   [(set (match_dup 2) (match_dup 3))
2145    (set (match_dup 4) (match_dup 5))]
2146   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2147
2148 (define_split
2149   [(set (match_operand:DI 0 "memory_operand" "")
2150         (match_operand:DI 1 "immediate_operand" ""))]
2151   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2152                     ? epilogue_completed : reload_completed)
2153    && !symbolic_operand (operands[1], DImode)
2154    && !x86_64_immediate_operand (operands[1], DImode)"
2155   [(set (match_dup 2) (match_dup 3))
2156    (set (match_dup 4) (match_dup 5))]
2157   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2158
2159 (define_insn "*movdi_internal"
2160   [(set (match_operand:DI 0 "nonimmediate_operand"
2161           "=r  ,o  ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2162         (match_operand:DI 1 "general_operand"
2163           "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2164   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2165 {
2166   switch (get_attr_type (insn))
2167     {
2168     case TYPE_SSECVT:
2169       if (SSE_REG_P (operands[0]))
2170         return "movq2dq\t{%1, %0|%0, %1}";
2171       else
2172         return "movdq2q\t{%1, %0|%0, %1}";
2173
2174     case TYPE_SSEMOV:
2175       switch (get_attr_mode (insn))
2176         {
2177         case MODE_TI:
2178           return "%vmovdqa\t{%1, %0|%0, %1}";
2179         case MODE_DI:
2180            return "%vmovq\t{%1, %0|%0, %1}";
2181         case MODE_V4SF:
2182           return "movaps\t{%1, %0|%0, %1}";
2183         case MODE_V2SF:
2184           return "movlps\t{%1, %0|%0, %1}";
2185         default:
2186           gcc_unreachable ();
2187         }
2188
2189     case TYPE_MMXMOV:
2190       return "movq\t{%1, %0|%0, %1}";
2191
2192     case TYPE_SSELOG1:
2193       return standard_sse_constant_opcode (insn, operands[1]);
2194
2195     case TYPE_MMX:
2196       return "pxor\t%0, %0";
2197
2198     case TYPE_MULTI:
2199       return "#";
2200
2201     default:
2202       gcc_unreachable ();
2203     }
2204 }
2205   [(set (attr "isa")
2206      (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2207               (const_string "sse2")
2208             (eq_attr "alternative" "9,10,11,12")
2209               (const_string "noavx")
2210            ]
2211            (const_string "*")))
2212    (set (attr "type")
2213      (cond [(eq_attr "alternative" "0,1")
2214               (const_string "multi")
2215             (eq_attr "alternative" "2")
2216               (const_string "mmx")
2217             (eq_attr "alternative" "3,4")
2218               (const_string "mmxmov")
2219             (eq_attr "alternative" "5,9")
2220               (const_string "sselog1")
2221             (eq_attr "alternative" "13,14")
2222               (const_string "ssecvt")
2223            ]
2224            (const_string "ssemov")))
2225    (set (attr "prefix")
2226      (if_then_else (eq_attr "alternative" "5,6,7,8")
2227        (const_string "maybe_vex")
2228        (const_string "orig")))
2229    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2230
2231 (define_split
2232   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2233         (match_operand:DI 1 "general_operand" ""))]
2234   "!TARGET_64BIT && reload_completed
2235    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2236    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2237   [(const_int 0)]
2238   "ix86_split_long_move (operands); DONE;")
2239
2240 (define_insn "*movsi_internal"
2241   [(set (match_operand:SI 0 "nonimmediate_operand"
2242                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2243         (match_operand:SI 1 "general_operand"
2244                         "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
2245   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2246 {
2247   switch (get_attr_type (insn))
2248     {
2249     case TYPE_SSELOG1:
2250       return standard_sse_constant_opcode (insn, operands[1]);
2251
2252     case TYPE_SSEMOV:
2253       switch (get_attr_mode (insn))
2254         {
2255         case MODE_TI:
2256           return "%vmovdqa\t{%1, %0|%0, %1}";
2257         case MODE_V4SF:
2258           return "%vmovaps\t{%1, %0|%0, %1}";
2259         case MODE_SI:
2260           return "%vmovd\t{%1, %0|%0, %1}";
2261         case MODE_SF:
2262           return "%vmovss\t{%1, %0|%0, %1}";
2263         default:
2264           gcc_unreachable ();
2265         }
2266
2267     case TYPE_MMX:
2268       return "pxor\t%0, %0";
2269
2270     case TYPE_MMXMOV:
2271       if (get_attr_mode (insn) == MODE_DI)
2272         return "movq\t{%1, %0|%0, %1}";
2273       return "movd\t{%1, %0|%0, %1}";
2274
2275     case TYPE_LEA:
2276       return "lea{l}\t{%a1, %0|%0, %a1}";
2277
2278     default:
2279       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2280       return "mov{l}\t{%1, %0|%0, %1}";
2281     }
2282 }
2283   [(set (attr "type")
2284      (cond [(eq_attr "alternative" "2")
2285               (const_string "mmx")
2286             (eq_attr "alternative" "3,4,5")
2287               (const_string "mmxmov")
2288             (eq_attr "alternative" "6")
2289               (const_string "sselog1")
2290             (eq_attr "alternative" "7,8,9,10,11")
2291               (const_string "ssemov")
2292             (match_operand 1 "pic_32bit_operand" "")
2293               (const_string "lea")
2294            ]
2295            (const_string "imov")))
2296    (set (attr "prefix")
2297      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2298        (const_string "orig")
2299        (const_string "maybe_vex")))
2300    (set (attr "prefix_data16")
2301      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2302        (const_string "1")
2303        (const_string "*")))
2304    (set (attr "mode")
2305      (cond [(eq_attr "alternative" "2,3")
2306               (const_string "DI")
2307             (eq_attr "alternative" "6,7")
2308               (if_then_else
2309                 (not (match_test "TARGET_SSE2"))
2310                 (const_string "V4SF")
2311                 (const_string "TI"))
2312             (and (eq_attr "alternative" "8,9,10,11")
2313                  (not (match_test "TARGET_SSE2")))
2314               (const_string "SF")
2315            ]
2316            (const_string "SI")))])
2317
2318 (define_insn "*movhi_internal"
2319   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2320         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2321   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2322 {
2323   switch (get_attr_type (insn))
2324     {
2325     case TYPE_IMOVX:
2326       /* movzwl is faster than movw on p2 due to partial word stalls,
2327          though not as fast as an aligned movl.  */
2328       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2329     default:
2330       if (get_attr_mode (insn) == MODE_SI)
2331         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2332       else
2333         return "mov{w}\t{%1, %0|%0, %1}";
2334     }
2335 }
2336   [(set (attr "type")
2337      (cond [(match_test "optimize_function_for_size_p (cfun)")
2338               (const_string "imov")
2339             (and (eq_attr "alternative" "0")
2340                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2341                       (not (match_test "TARGET_HIMODE_MATH"))))
2342               (const_string "imov")
2343             (and (eq_attr "alternative" "1,2")
2344                  (match_operand:HI 1 "aligned_operand" ""))
2345               (const_string "imov")
2346             (and (match_test "TARGET_MOVX")
2347                  (eq_attr "alternative" "0,2"))
2348               (const_string "imovx")
2349            ]
2350            (const_string "imov")))
2351     (set (attr "mode")
2352       (cond [(eq_attr "type" "imovx")
2353                (const_string "SI")
2354              (and (eq_attr "alternative" "1,2")
2355                   (match_operand:HI 1 "aligned_operand" ""))
2356                (const_string "SI")
2357              (and (eq_attr "alternative" "0")
2358                   (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2359                        (not (match_test "TARGET_HIMODE_MATH"))))
2360                (const_string "SI")
2361             ]
2362             (const_string "HI")))])
2363
2364 ;; Situation is quite tricky about when to choose full sized (SImode) move
2365 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2366 ;; partial register dependency machines (such as AMD Athlon), where QImode
2367 ;; moves issue extra dependency and for partial register stalls machines
2368 ;; that don't use QImode patterns (and QImode move cause stall on the next
2369 ;; instruction).
2370 ;;
2371 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2372 ;; register stall machines with, where we use QImode instructions, since
2373 ;; partial register stall can be caused there.  Then we use movzx.
2374 (define_insn "*movqi_internal"
2375   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2376         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2377   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2378 {
2379   switch (get_attr_type (insn))
2380     {
2381     case TYPE_IMOVX:
2382       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2383       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2384     default:
2385       if (get_attr_mode (insn) == MODE_SI)
2386         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2387       else
2388         return "mov{b}\t{%1, %0|%0, %1}";
2389     }
2390 }
2391   [(set (attr "type")
2392      (cond [(and (eq_attr "alternative" "5")
2393                  (not (match_operand:QI 1 "aligned_operand" "")))
2394               (const_string "imovx")
2395             (match_test "optimize_function_for_size_p (cfun)")
2396               (const_string "imov")
2397             (and (eq_attr "alternative" "3")
2398                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2399                       (not (match_test "TARGET_QIMODE_MATH"))))
2400               (const_string "imov")
2401             (eq_attr "alternative" "3,5")
2402               (const_string "imovx")
2403             (and (match_test "TARGET_MOVX")
2404                  (eq_attr "alternative" "2"))
2405               (const_string "imovx")
2406            ]
2407            (const_string "imov")))
2408    (set (attr "mode")
2409       (cond [(eq_attr "alternative" "3,4,5")
2410                (const_string "SI")
2411              (eq_attr "alternative" "6")
2412                (const_string "QI")
2413              (eq_attr "type" "imovx")
2414                (const_string "SI")
2415              (and (eq_attr "type" "imov")
2416                   (and (eq_attr "alternative" "0,1")
2417                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2418                             (and (not (match_test "optimize_function_for_size_p (cfun)"))
2419                                  (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2420                (const_string "SI")
2421              ;; Avoid partial register stalls when not using QImode arithmetic
2422              (and (eq_attr "type" "imov")
2423                   (and (eq_attr "alternative" "0,1")
2424                        (and (match_test "TARGET_PARTIAL_REG_STALL")
2425                             (not (match_test "TARGET_QIMODE_MATH")))))
2426                (const_string "SI")
2427            ]
2428            (const_string "QI")))])
2429
2430 ;; Stores and loads of ax to arbitrary constant address.
2431 ;; We fake an second form of instruction to force reload to load address
2432 ;; into register when rax is not available
2433 (define_insn "*movabs<mode>_1"
2434   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2435         (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2436   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2437   "@
2438    movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2439    mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2440   [(set_attr "type" "imov")
2441    (set_attr "modrm" "0,*")
2442    (set_attr "length_address" "8,0")
2443    (set_attr "length_immediate" "0,*")
2444    (set_attr "memory" "store")
2445    (set_attr "mode" "<MODE>")])
2446
2447 (define_insn "*movabs<mode>_2"
2448   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2449         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2450   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2451   "@
2452    movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2453    mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2454   [(set_attr "type" "imov")
2455    (set_attr "modrm" "0,*")
2456    (set_attr "length_address" "8,0")
2457    (set_attr "length_immediate" "0")
2458    (set_attr "memory" "load")
2459    (set_attr "mode" "<MODE>")])
2460
2461 (define_insn "*swap<mode>"
2462   [(set (match_operand:SWI48 0 "register_operand" "+r")
2463         (match_operand:SWI48 1 "register_operand" "+r"))
2464    (set (match_dup 1)
2465         (match_dup 0))]
2466   ""
2467   "xchg{<imodesuffix>}\t%1, %0"
2468   [(set_attr "type" "imov")
2469    (set_attr "mode" "<MODE>")
2470    (set_attr "pent_pair" "np")
2471    (set_attr "athlon_decode" "vector")
2472    (set_attr "amdfam10_decode" "double")
2473    (set_attr "bdver1_decode" "double")])
2474
2475 (define_insn "*swap<mode>_1"
2476   [(set (match_operand:SWI12 0 "register_operand" "+r")
2477         (match_operand:SWI12 1 "register_operand" "+r"))
2478    (set (match_dup 1)
2479         (match_dup 0))]
2480   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2481   "xchg{l}\t%k1, %k0"
2482   [(set_attr "type" "imov")
2483    (set_attr "mode" "SI")
2484    (set_attr "pent_pair" "np")
2485    (set_attr "athlon_decode" "vector")
2486    (set_attr "amdfam10_decode" "double")
2487    (set_attr "bdver1_decode" "double")])
2488
2489 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2490 ;; is disabled for AMDFAM10
2491 (define_insn "*swap<mode>_2"
2492   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2493         (match_operand:SWI12 1 "register_operand" "+<r>"))
2494    (set (match_dup 1)
2495         (match_dup 0))]
2496   "TARGET_PARTIAL_REG_STALL"
2497   "xchg{<imodesuffix>}\t%1, %0"
2498   [(set_attr "type" "imov")
2499    (set_attr "mode" "<MODE>")
2500    (set_attr "pent_pair" "np")
2501    (set_attr "athlon_decode" "vector")])
2502
2503 (define_expand "movstrict<mode>"
2504   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2505         (match_operand:SWI12 1 "general_operand" ""))]
2506   ""
2507 {
2508   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2509     FAIL;
2510   if (GET_CODE (operands[0]) == SUBREG
2511       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2512     FAIL;
2513   /* Don't generate memory->memory moves, go through a register */
2514   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2515     operands[1] = force_reg (<MODE>mode, operands[1]);
2516 })
2517
2518 (define_insn "*movstrict<mode>_1"
2519   [(set (strict_low_part
2520           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2521         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2522   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2523    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2524   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2525   [(set_attr "type" "imov")
2526    (set_attr "mode" "<MODE>")])
2527
2528 (define_insn "*movstrict<mode>_xor"
2529   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2530         (match_operand:SWI12 1 "const0_operand" ""))
2531    (clobber (reg:CC FLAGS_REG))]
2532   "reload_completed"
2533   "xor{<imodesuffix>}\t%0, %0"
2534   [(set_attr "type" "alu1")
2535    (set_attr "mode" "<MODE>")
2536    (set_attr "length_immediate" "0")])
2537
2538 (define_insn "*mov<mode>_extv_1"
2539   [(set (match_operand:SWI24 0 "register_operand" "=R")
2540         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2541                             (const_int 8)
2542                             (const_int 8)))]
2543   ""
2544   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2545   [(set_attr "type" "imovx")
2546    (set_attr "mode" "SI")])
2547
2548 (define_insn "*movqi_extv_1_rex64"
2549   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2550         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2551                          (const_int 8)
2552                          (const_int 8)))]
2553   "TARGET_64BIT"
2554 {
2555   switch (get_attr_type (insn))
2556     {
2557     case TYPE_IMOVX:
2558       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2559     default:
2560       return "mov{b}\t{%h1, %0|%0, %h1}";
2561     }
2562 }
2563   [(set (attr "type")
2564      (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2565                         (match_test "TARGET_MOVX"))
2566         (const_string "imovx")
2567         (const_string "imov")))
2568    (set (attr "mode")
2569      (if_then_else (eq_attr "type" "imovx")
2570         (const_string "SI")
2571         (const_string "QI")))])
2572
2573 (define_insn "*movqi_extv_1"
2574   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2575         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2576                          (const_int 8)
2577                          (const_int 8)))]
2578   "!TARGET_64BIT"
2579 {
2580   switch (get_attr_type (insn))
2581     {
2582     case TYPE_IMOVX:
2583       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2584     default:
2585       return "mov{b}\t{%h1, %0|%0, %h1}";
2586     }
2587 }
2588   [(set (attr "type")
2589      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2590                         (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2591                              (match_test "TARGET_MOVX")))
2592         (const_string "imovx")
2593         (const_string "imov")))
2594    (set (attr "mode")
2595      (if_then_else (eq_attr "type" "imovx")
2596         (const_string "SI")
2597         (const_string "QI")))])
2598
2599 (define_insn "*mov<mode>_extzv_1"
2600   [(set (match_operand:SWI48 0 "register_operand" "=R")
2601         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2602                             (const_int 8)
2603                             (const_int 8)))]
2604   ""
2605   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2606   [(set_attr "type" "imovx")
2607    (set_attr "mode" "SI")])
2608
2609 (define_insn "*movqi_extzv_2_rex64"
2610   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2611         (subreg:QI
2612           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2613                            (const_int 8)
2614                            (const_int 8)) 0))]
2615   "TARGET_64BIT"
2616 {
2617   switch (get_attr_type (insn))
2618     {
2619     case TYPE_IMOVX:
2620       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2621     default:
2622       return "mov{b}\t{%h1, %0|%0, %h1}";
2623     }
2624 }
2625   [(set (attr "type")
2626      (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2627                         (match_test "TARGET_MOVX"))
2628         (const_string "imovx")
2629         (const_string "imov")))
2630    (set (attr "mode")
2631      (if_then_else (eq_attr "type" "imovx")
2632         (const_string "SI")
2633         (const_string "QI")))])
2634
2635 (define_insn "*movqi_extzv_2"
2636   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2637         (subreg:QI
2638           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2639                            (const_int 8)
2640                            (const_int 8)) 0))]
2641   "!TARGET_64BIT"
2642 {
2643   switch (get_attr_type (insn))
2644     {
2645     case TYPE_IMOVX:
2646       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2647     default:
2648       return "mov{b}\t{%h1, %0|%0, %h1}";
2649     }
2650 }
2651   [(set (attr "type")
2652      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2653                         (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2654                              (match_test "TARGET_MOVX")))
2655         (const_string "imovx")
2656         (const_string "imov")))
2657    (set (attr "mode")
2658      (if_then_else (eq_attr "type" "imovx")
2659         (const_string "SI")
2660         (const_string "QI")))])
2661
2662 (define_expand "mov<mode>_insv_1"
2663   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2664                             (const_int 8)
2665                             (const_int 8))
2666         (match_operand:SWI48 1 "nonmemory_operand" ""))])
2667
2668 (define_insn "*mov<mode>_insv_1_rex64"
2669   [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2670                              (const_int 8)
2671                              (const_int 8))
2672         (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2673   "TARGET_64BIT"
2674   "mov{b}\t{%b1, %h0|%h0, %b1}"
2675   [(set_attr "type" "imov")
2676    (set_attr "mode" "QI")])
2677
2678 (define_insn "*movsi_insv_1"
2679   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2680                          (const_int 8)
2681                          (const_int 8))
2682         (match_operand:SI 1 "general_operand" "Qmn"))]
2683   "!TARGET_64BIT"
2684   "mov{b}\t{%b1, %h0|%h0, %b1}"
2685   [(set_attr "type" "imov")
2686    (set_attr "mode" "QI")])
2687
2688 (define_insn "*movqi_insv_2"
2689   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2690                          (const_int 8)
2691                          (const_int 8))
2692         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2693                      (const_int 8)))]
2694   ""
2695   "mov{b}\t{%h1, %h0|%h0, %h1}"
2696   [(set_attr "type" "imov")
2697    (set_attr "mode" "QI")])
2698 \f
2699 ;; Floating point push instructions.
2700
2701 (define_insn "*pushtf"
2702   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2703         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2704   "TARGET_SSE2"
2705 {
2706   /* This insn should be already split before reg-stack.  */
2707   gcc_unreachable ();
2708 }
2709   [(set_attr "type" "multi")
2710    (set_attr "unit" "sse,*,*")
2711    (set_attr "mode" "TF,SI,SI")])
2712
2713 ;; %%% Kill this when call knows how to work this out.
2714 (define_split
2715   [(set (match_operand:TF 0 "push_operand" "")
2716         (match_operand:TF 1 "sse_reg_operand" ""))]
2717   "TARGET_SSE2 && reload_completed"
2718   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2719    (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2720
2721 (define_insn "*pushxf"
2722   [(set (match_operand:XF 0 "push_operand" "=<,<")
2723         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2724   "optimize_function_for_speed_p (cfun)"
2725 {
2726   /* This insn should be already split before reg-stack.  */
2727   gcc_unreachable ();
2728 }
2729   [(set_attr "type" "multi")
2730    (set_attr "unit" "i387,*")
2731    (set_attr "mode" "XF,SI")])
2732
2733 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2734 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2735 ;; Pushing using integer instructions is longer except for constants
2736 ;; and direct memory references (assuming that any given constant is pushed
2737 ;; only once, but this ought to be handled elsewhere).
2738
2739 (define_insn "*pushxf_nointeger"
2740   [(set (match_operand:XF 0 "push_operand" "=<,<")
2741         (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2742   "optimize_function_for_size_p (cfun)"
2743 {
2744   /* This insn should be already split before reg-stack.  */
2745   gcc_unreachable ();
2746 }
2747   [(set_attr "type" "multi")
2748    (set_attr "unit" "i387,*")
2749    (set_attr "mode" "XF,SI")])
2750
2751 ;; %%% Kill this when call knows how to work this out.
2752 (define_split
2753   [(set (match_operand:XF 0 "push_operand" "")
2754         (match_operand:XF 1 "fp_register_operand" ""))]
2755   "reload_completed"
2756   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2757    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2758   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2759
2760 (define_insn "*pushdf_rex64"
2761   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2762         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2763   "TARGET_64BIT"
2764 {
2765   /* This insn should be already split before reg-stack.  */
2766   gcc_unreachable ();
2767 }
2768   [(set_attr "type" "multi")
2769    (set_attr "unit" "i387,*,*")
2770    (set_attr "mode" "DF,DI,DF")])
2771
2772 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2773 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2774 ;; On the average, pushdf using integers can be still shorter.
2775
2776 (define_insn "*pushdf"
2777   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2778         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2779   "!TARGET_64BIT"
2780 {
2781   /* This insn should be already split before reg-stack.  */
2782   gcc_unreachable ();
2783 }
2784   [(set_attr "isa" "*,*,sse2")
2785    (set_attr "type" "multi")
2786    (set_attr "unit" "i387,*,*")
2787    (set_attr "mode" "DF,DI,DF")])
2788
2789 ;; %%% Kill this when call knows how to work this out.
2790 (define_split
2791   [(set (match_operand:DF 0 "push_operand" "")
2792         (match_operand:DF 1 "any_fp_register_operand" ""))]
2793   "reload_completed"
2794   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2795    (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2796
2797 (define_insn "*pushsf_rex64"
2798   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2799         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2800   "TARGET_64BIT"
2801 {
2802   /* Anything else should be already split before reg-stack.  */
2803   gcc_assert (which_alternative == 1);
2804   return "push{q}\t%q1";
2805 }
2806   [(set_attr "type" "multi,push,multi")
2807    (set_attr "unit" "i387,*,*")
2808    (set_attr "mode" "SF,DI,SF")])
2809
2810 (define_insn "*pushsf"
2811   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2812         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2813   "!TARGET_64BIT"
2814 {
2815   /* Anything else should be already split before reg-stack.  */
2816   gcc_assert (which_alternative == 1);
2817   return "push{l}\t%1";
2818 }
2819   [(set_attr "type" "multi,push,multi")
2820    (set_attr "unit" "i387,*,*")
2821    (set_attr "mode" "SF,SI,SF")])
2822
2823 ;; %%% Kill this when call knows how to work this out.
2824 (define_split
2825   [(set (match_operand:SF 0 "push_operand" "")
2826         (match_operand:SF 1 "any_fp_register_operand" ""))]
2827   "reload_completed"
2828   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2829    (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2830   "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2831
2832 (define_split
2833   [(set (match_operand:SF 0 "push_operand" "")
2834         (match_operand:SF 1 "memory_operand" ""))]
2835   "reload_completed
2836    && (operands[2] = find_constant_src (insn))"
2837   [(set (match_dup 0) (match_dup 2))])
2838
2839 (define_split
2840   [(set (match_operand 0 "push_operand" "")
2841         (match_operand 1 "general_operand" ""))]
2842   "reload_completed
2843    && (GET_MODE (operands[0]) == TFmode
2844        || GET_MODE (operands[0]) == XFmode
2845        || GET_MODE (operands[0]) == DFmode)
2846    && !ANY_FP_REG_P (operands[1])"
2847   [(const_int 0)]
2848   "ix86_split_long_move (operands); DONE;")
2849 \f
2850 ;; Floating point move instructions.
2851
2852 (define_expand "movtf"
2853   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2854         (match_operand:TF 1 "nonimmediate_operand" ""))]
2855   "TARGET_SSE2"
2856 {
2857   ix86_expand_move (TFmode, operands);
2858   DONE;
2859 })
2860
2861 (define_expand "mov<mode>"
2862   [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2863         (match_operand:X87MODEF 1 "general_operand" ""))]
2864   ""
2865   "ix86_expand_move (<MODE>mode, operands); DONE;")
2866
2867 (define_insn "*movtf_internal"
2868   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2869         (match_operand:TF 1 "general_operand"      "xm,x,C,*roF,F*r"))]
2870   "TARGET_SSE2
2871    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2872    && (!can_create_pseudo_p ()
2873        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2874        || GET_CODE (operands[1]) != CONST_DOUBLE
2875        || (optimize_function_for_size_p (cfun)
2876            && standard_sse_constant_p (operands[1])
2877            && !memory_operand (operands[0], TFmode))
2878        || (!TARGET_MEMORY_MISMATCH_STALL
2879            && memory_operand (operands[0], TFmode)))"
2880 {
2881   switch (which_alternative)
2882     {
2883     case 0:
2884     case 1:
2885       /* Handle misaligned load/store since we
2886          don't have movmisaligntf pattern. */
2887       if (misaligned_operand (operands[0], TFmode)
2888           || misaligned_operand (operands[1], TFmode))
2889         {
2890           if (get_attr_mode (insn) == MODE_V4SF)
2891             return "%vmovups\t{%1, %0|%0, %1}";
2892           else
2893             return "%vmovdqu\t{%1, %0|%0, %1}";
2894         }
2895       else
2896         {
2897           if (get_attr_mode (insn) == MODE_V4SF)
2898             return "%vmovaps\t{%1, %0|%0, %1}";
2899           else
2900             return "%vmovdqa\t{%1, %0|%0, %1}";
2901         }
2902
2903     case 2:
2904       return standard_sse_constant_opcode (insn, operands[1]);
2905
2906     case 3:
2907     case 4:
2908         return "#";
2909
2910     default:
2911       gcc_unreachable ();
2912     }
2913 }
2914   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2915    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2916    (set (attr "mode")
2917         (cond [(eq_attr "alternative" "0,2")
2918                  (if_then_else
2919                    (match_test "optimize_function_for_size_p (cfun)")
2920                    (const_string "V4SF")
2921                    (const_string "TI"))
2922                (eq_attr "alternative" "1")
2923                  (if_then_else
2924                    (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2925                         (match_test "optimize_function_for_size_p (cfun)"))
2926                    (const_string "V4SF")
2927                    (const_string "TI"))]
2928                (const_string "DI")))])
2929
2930 ;; Possible store forwarding (partial memory) stall in alternative 4.
2931 (define_insn "*movxf_internal"
2932   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2933         (match_operand:XF 1 "general_operand"      "fm,f,G,Yx*roF,FYx*r"))]
2934   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2935    && (!can_create_pseudo_p ()
2936        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2937        || GET_CODE (operands[1]) != CONST_DOUBLE
2938        || (optimize_function_for_size_p (cfun)
2939            && standard_80387_constant_p (operands[1]) > 0
2940            && !memory_operand (operands[0], XFmode))
2941        || (!TARGET_MEMORY_MISMATCH_STALL
2942            && memory_operand (operands[0], XFmode)))"
2943 {
2944   switch (which_alternative)
2945     {
2946     case 0:
2947     case 1:
2948       return output_387_reg_move (insn, operands);
2949
2950     case 2:
2951       return standard_80387_constant_opcode (operands[1]);
2952
2953     case 3:
2954     case 4:
2955       return "#";
2956
2957     default:
2958       gcc_unreachable ();
2959     }
2960 }
2961   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2962    (set_attr "mode" "XF,XF,XF,SI,SI")])
2963
2964 (define_insn "*movdf_internal_rex64"
2965   [(set (match_operand:DF 0 "nonimmediate_operand"
2966                 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2967         (match_operand:DF 1 "general_operand"
2968                 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2969   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2970    && (!can_create_pseudo_p ()
2971        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2972        || GET_CODE (operands[1]) != CONST_DOUBLE
2973        || (optimize_function_for_size_p (cfun)
2974            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2975                 && standard_80387_constant_p (operands[1]) > 0)
2976                || (TARGET_SSE2 && TARGET_SSE_MATH
2977                    && standard_sse_constant_p (operands[1]))))
2978        || memory_operand (operands[0], DFmode))"
2979 {
2980   switch (which_alternative)
2981     {
2982     case 0:
2983     case 1:
2984       return output_387_reg_move (insn, operands);
2985
2986     case 2:
2987       return standard_80387_constant_opcode (operands[1]);
2988
2989     case 3:
2990     case 4:
2991       return "mov{q}\t{%1, %0|%0, %1}";
2992
2993     case 5:
2994       return "movabs{q}\t{%1, %0|%0, %1}";
2995
2996     case 6:
2997       return "#";
2998
2999     case 7:
3000       return standard_sse_constant_opcode (insn, operands[1]);
3001
3002     case 8:
3003     case 9:
3004     case 10:
3005       switch (get_attr_mode (insn))
3006         {
3007         case MODE_V2DF:
3008           if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3009             return "%vmovapd\t{%1, %0|%0, %1}";
3010         case MODE_V4SF:
3011           return "%vmovaps\t{%1, %0|%0, %1}";
3012
3013         case MODE_DI:
3014           return "%vmovq\t{%1, %0|%0, %1}";
3015         case MODE_DF:
3016           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3017             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3018           return "%vmovsd\t{%1, %0|%0, %1}";
3019         case MODE_V1DF:
3020           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3021         case MODE_V2SF:
3022           return "%vmovlps\t{%1, %d0|%d0, %1}";
3023         default:
3024           gcc_unreachable ();
3025         }
3026
3027     case 11:
3028     case 12:
3029       /* Handle broken assemblers that require movd instead of movq.  */
3030       return "%vmovd\t{%1, %0|%0, %1}";
3031
3032     default:
3033       gcc_unreachable();
3034     }
3035 }
3036   [(set (attr "type")
3037         (cond [(eq_attr "alternative" "0,1,2")
3038                  (const_string "fmov")
3039                (eq_attr "alternative" "3,4,5")
3040                  (const_string "imov")
3041                (eq_attr "alternative" "6")
3042                  (const_string "multi")
3043                (eq_attr "alternative" "7")
3044                  (const_string "sselog1")
3045               ]
3046               (const_string "ssemov")))
3047    (set (attr "modrm")
3048      (if_then_else
3049        (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3050          (const_string "0")
3051          (const_string "*")))
3052    (set (attr "length_immediate")
3053      (if_then_else
3054        (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3055          (const_string "8")
3056          (const_string "*")))
3057    (set (attr "prefix")
3058      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3059        (const_string "orig")
3060        (const_string "maybe_vex")))
3061    (set (attr "prefix_data16")
3062      (if_then_else (eq_attr "mode" "V1DF")
3063        (const_string "1")
3064        (const_string "*")))
3065    (set (attr "mode")
3066         (cond [(eq_attr "alternative" "0,1,2")
3067                  (const_string "DF")
3068                (eq_attr "alternative" "3,4,5,6,11,12")
3069                  (const_string "DI")
3070
3071                /* xorps is one byte shorter.  */
3072                (eq_attr "alternative" "7")
3073                  (cond [(match_test "optimize_function_for_size_p (cfun)")
3074                           (const_string "V4SF")
3075                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3076                           (const_string "TI")
3077                        ]
3078                        (const_string "V2DF"))
3079
3080                /* For architectures resolving dependencies on
3081                   whole SSE registers use APD move to break dependency
3082                   chains, otherwise use short move to avoid extra work.
3083
3084                   movaps encodes one byte shorter.  */
3085                (eq_attr "alternative" "8")
3086                  (cond
3087                    [(match_test "optimize_function_for_size_p (cfun)")
3088                       (const_string "V4SF")
3089                     (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3090                       (const_string "V2DF")
3091                    ]
3092                    (const_string "DF"))
3093                /* For architectures resolving dependencies on register
3094                   parts we may avoid extra work to zero out upper part
3095                   of register.  */
3096                (eq_attr "alternative" "9")
3097                  (if_then_else
3098                    (match_test "TARGET_SSE_SPLIT_REGS")
3099                    (const_string "V1DF")
3100                    (const_string "DF"))
3101               ]
3102               (const_string "DF")))])
3103
3104 ;; Possible store forwarding (partial memory) stall in alternative 4.
3105 (define_insn "*movdf_internal"
3106   [(set (match_operand:DF 0 "nonimmediate_operand"
3107                 "=f,m,f,?Yd*r ,!o   ,x,x,x,m,*x,*x,*x,m")
3108         (match_operand:DF 1 "general_operand"
3109                 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3110   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3111    && (!can_create_pseudo_p ()
3112        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3113        || GET_CODE (operands[1]) != CONST_DOUBLE
3114        || (optimize_function_for_size_p (cfun)
3115            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3116                 && standard_80387_constant_p (operands[1]) > 0)
3117                || (TARGET_SSE2 && TARGET_SSE_MATH
3118                    && standard_sse_constant_p (operands[1])))
3119            && !memory_operand (operands[0], DFmode))
3120        || (!TARGET_MEMORY_MISMATCH_STALL
3121            && memory_operand (operands[0], DFmode)))"
3122 {
3123   switch (which_alternative)
3124     {
3125     case 0:
3126     case 1:
3127       return output_387_reg_move (insn, operands);
3128
3129     case 2:
3130       return standard_80387_constant_opcode (operands[1]);
3131
3132     case 3:
3133     case 4:
3134       return "#";
3135
3136     case 5:
3137     case 9:
3138       return standard_sse_constant_opcode (insn, operands[1]);
3139
3140     case 6:
3141     case 7:
3142     case 8:
3143     case 10:
3144     case 11:
3145     case 12:
3146       switch (get_attr_mode (insn))
3147         {
3148         case MODE_V2DF:
3149           if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3150             return "%vmovapd\t{%1, %0|%0, %1}";
3151         case MODE_V4SF:
3152           return "%vmovaps\t{%1, %0|%0, %1}";
3153
3154         case MODE_DI:
3155           return "%vmovq\t{%1, %0|%0, %1}";
3156         case MODE_DF:
3157           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3158             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3159           return "%vmovsd\t{%1, %0|%0, %1}";
3160         case MODE_V1DF:
3161           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3162         case MODE_V2SF:
3163           return "%vmovlps\t{%1, %d0|%d0, %1}";
3164         default:
3165           gcc_unreachable ();
3166         }
3167
3168     default:
3169       gcc_unreachable ();
3170     }
3171 }
3172   [(set (attr "isa")
3173      (if_then_else (eq_attr "alternative" "5,6,7,8")
3174        (const_string "sse2")
3175        (const_string "*")))
3176    (set (attr "type")
3177         (cond [(eq_attr "alternative" "0,1,2")
3178                  (const_string "fmov")
3179                (eq_attr "alternative" "3,4")
3180                  (const_string "multi")
3181                (eq_attr "alternative" "5,9")
3182                  (const_string "sselog1")
3183               ]
3184               (const_string "ssemov")))
3185    (set (attr "prefix")
3186      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3187        (const_string "orig")
3188        (const_string "maybe_vex")))
3189    (set (attr "prefix_data16")
3190      (if_then_else (eq_attr "mode" "V1DF")
3191        (const_string "1")
3192        (const_string "*")))
3193    (set (attr "mode")
3194         (cond [(eq_attr "alternative" "0,1,2")
3195                  (const_string "DF")
3196                (eq_attr "alternative" "3,4")
3197                  (const_string "SI")
3198
3199                /* For SSE1, we have many fewer alternatives.  */
3200                (not (match_test "TARGET_SSE2"))
3201                  (if_then_else
3202                    (eq_attr "alternative" "5,6,9,10")
3203                    (const_string "V4SF")
3204                    (const_string "V2SF"))
3205
3206                /* xorps is one byte shorter.  */
3207                (eq_attr "alternative" "5,9")
3208                  (cond [(match_test "optimize_function_for_size_p (cfun)")
3209                           (const_string "V4SF")
3210                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3211                           (const_string "TI")
3212                        ]
3213                        (const_string "V2DF"))
3214
3215                /* For architectures resolving dependencies on
3216                   whole SSE registers use APD move to break dependency
3217                   chains, otherwise use short move to avoid extra work.
3218
3219                   movaps encodes one byte shorter.  */
3220                (eq_attr "alternative" "6,10")
3221                  (cond
3222                    [(match_test "optimize_function_for_size_p (cfun)")
3223                       (const_string "V4SF")
3224                     (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3225                       (const_string "V2DF")
3226                    ]
3227                    (const_string "DF"))
3228                /* For architectures resolving dependencies on register
3229                   parts we may avoid extra work to zero out upper part
3230                   of register.  */
3231                (eq_attr "alternative" "7,11")
3232                  (if_then_else
3233                    (match_test "TARGET_SSE_SPLIT_REGS")
3234                    (const_string "V1DF")
3235                    (const_string "DF"))
3236               ]
3237               (const_string "DF")))])
3238
3239 (define_insn "*movsf_internal"
3240   [(set (match_operand:SF 0 "nonimmediate_operand"
3241           "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3242         (match_operand:SF 1 "general_operand"
3243           "fm,f,G,rmF,Fr,C,x,m,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
3244   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3245    && (!can_create_pseudo_p ()
3246        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3247        || GET_CODE (operands[1]) != CONST_DOUBLE
3248        || (optimize_function_for_size_p (cfun)
3249            && ((!TARGET_SSE_MATH
3250                 && standard_80387_constant_p (operands[1]) > 0)
3251                || (TARGET_SSE_MATH
3252                    && standard_sse_constant_p (operands[1]))))
3253        || memory_operand (operands[0], SFmode))"
3254 {
3255   switch (which_alternative)
3256     {
3257     case 0:
3258     case 1:
3259       return output_387_reg_move (insn, operands);
3260
3261     case 2:
3262       return standard_80387_constant_opcode (operands[1]);
3263
3264     case 3:
3265     case 4:
3266       return "mov{l}\t{%1, %0|%0, %1}";
3267
3268     case 5:
3269       return standard_sse_constant_opcode (insn, operands[1]);
3270
3271     case 6:
3272       if (get_attr_mode (insn) == MODE_V4SF)
3273         return "%vmovaps\t{%1, %0|%0, %1}";
3274       if (TARGET_AVX)
3275         return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3276
3277     case 7:
3278     case 8:
3279       return "%vmovss\t{%1, %0|%0, %1}";
3280
3281     case 9:
3282     case 10:
3283     case 14:
3284     case 15:
3285       return "movd\t{%1, %0|%0, %1}";
3286
3287     case 11:
3288       return "movq\t{%1, %0|%0, %1}";
3289
3290     case 12:
3291     case 13:
3292       return "%vmovd\t{%1, %0|%0, %1}";
3293
3294     default:
3295       gcc_unreachable ();
3296     }
3297 }
3298   [(set (attr "type")
3299         (cond [(eq_attr "alternative" "0,1,2")
3300                  (const_string "fmov")
3301                (eq_attr "alternative" "3,4")
3302                  (const_string "multi")
3303                (eq_attr "alternative" "5")
3304                  (const_string "sselog1")
3305                (eq_attr "alternative" "9,10,11,14,15")
3306                  (const_string "mmxmov")
3307               ]
3308               (const_string "ssemov")))
3309    (set (attr "prefix")
3310      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3311        (const_string "maybe_vex")
3312        (const_string "orig")))
3313    (set (attr "mode")
3314         (cond [(eq_attr "alternative" "3,4,9,10")
3315                  (const_string "SI")
3316                (eq_attr "alternative" "5")
3317                  (if_then_else
3318                    (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3319                              (match_test "TARGET_SSE2"))
3320                         (not (match_test "optimize_function_for_size_p (cfun)")))
3321                    (const_string "TI")
3322                    (const_string "V4SF"))
3323                /* For architectures resolving dependencies on
3324                   whole SSE registers use APS move to break dependency
3325                   chains, otherwise use short move to avoid extra work.
3326
3327                   Do the same for architectures resolving dependencies on
3328                   the parts.  While in DF mode it is better to always handle
3329                   just register parts, the SF mode is different due to lack
3330                   of instructions to load just part of the register.  It is
3331                   better to maintain the whole registers in single format
3332                   to avoid problems on using packed logical operations.  */
3333                (eq_attr "alternative" "6")
3334                  (if_then_else
3335                    (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3336                         (match_test "TARGET_SSE_SPLIT_REGS"))
3337                    (const_string "V4SF")
3338                    (const_string "SF"))
3339                (eq_attr "alternative" "11")
3340                  (const_string "DI")]
3341                (const_string "SF")))])
3342
3343 (define_split
3344   [(set (match_operand 0 "any_fp_register_operand" "")
3345         (match_operand 1 "memory_operand" ""))]
3346   "reload_completed
3347    && (GET_MODE (operands[0]) == TFmode
3348        || GET_MODE (operands[0]) == XFmode
3349        || GET_MODE (operands[0]) == DFmode
3350        || GET_MODE (operands[0]) == SFmode)
3351    && (operands[2] = find_constant_src (insn))"
3352   [(set (match_dup 0) (match_dup 2))]
3353 {
3354   rtx c = operands[2];
3355   int r = REGNO (operands[0]);
3356
3357   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3358       || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3359     FAIL;
3360 })
3361
3362 (define_split
3363   [(set (match_operand 0 "any_fp_register_operand" "")
3364         (float_extend (match_operand 1 "memory_operand" "")))]
3365   "reload_completed
3366    && (GET_MODE (operands[0]) == TFmode
3367        || GET_MODE (operands[0]) == XFmode
3368        || GET_MODE (operands[0]) == DFmode)
3369    && (operands[2] = find_constant_src (insn))"
3370   [(set (match_dup 0) (match_dup 2))]
3371 {
3372   rtx c = operands[2];
3373   int r = REGNO (operands[0]);
3374
3375   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3376       || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3377     FAIL;
3378 })
3379
3380 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3381 (define_split
3382   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3383         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3384   "reload_completed
3385    && (standard_80387_constant_p (operands[1]) == 8
3386        || standard_80387_constant_p (operands[1]) == 9)"
3387   [(set (match_dup 0)(match_dup 1))
3388    (set (match_dup 0)
3389         (neg:X87MODEF (match_dup 0)))]
3390 {
3391   REAL_VALUE_TYPE r;
3392
3393   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3394   if (real_isnegzero (&r))
3395     operands[1] = CONST0_RTX (<MODE>mode);
3396   else
3397     operands[1] = CONST1_RTX (<MODE>mode);
3398 })
3399
3400 (define_split
3401   [(set (match_operand 0 "nonimmediate_operand" "")
3402         (match_operand 1 "general_operand" ""))]
3403   "reload_completed
3404    && (GET_MODE (operands[0]) == TFmode
3405        || GET_MODE (operands[0]) == XFmode
3406        || GET_MODE (operands[0]) == DFmode)
3407    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3408   [(const_int 0)]
3409   "ix86_split_long_move (operands); DONE;")
3410
3411 (define_insn "swapxf"
3412   [(set (match_operand:XF 0 "register_operand" "+f")
3413         (match_operand:XF 1 "register_operand" "+f"))
3414    (set (match_dup 1)
3415         (match_dup 0))]
3416   "TARGET_80387"
3417 {
3418   if (STACK_TOP_P (operands[0]))
3419     return "fxch\t%1";
3420   else
3421     return "fxch\t%0";
3422 }
3423   [(set_attr "type" "fxch")
3424    (set_attr "mode" "XF")])
3425
3426 (define_insn "*swap<mode>"
3427   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3428         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3429    (set (match_dup 1)
3430         (match_dup 0))]
3431   "TARGET_80387 || reload_completed"
3432 {
3433   if (STACK_TOP_P (operands[0]))
3434     return "fxch\t%1";
3435   else
3436     return "fxch\t%0";
3437 }
3438   [(set_attr "type" "fxch")
3439    (set_attr "mode" "<MODE>")])
3440 \f
3441 ;; Zero extension instructions
3442
3443 (define_expand "zero_extendsidi2"
3444   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3445         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3446   ""
3447 {
3448   if (!TARGET_64BIT)
3449     {
3450       emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3451       DONE;
3452     }
3453 })
3454
3455 (define_insn "*zero_extendsidi2_rex64"
3456   [(set (match_operand:DI 0 "nonimmediate_operand"  "=r,o,?*Ym,?*y,?*Yi,*x")
3457         (zero_extend:DI
3458          (match_operand:SI 1 "nonimmediate_operand" "rm,0,r   ,m  ,r   ,m")))]
3459   "TARGET_64BIT"
3460   "@
3461    mov\t{%k1, %k0|%k0, %k1}
3462    #
3463    movd\t{%1, %0|%0, %1}
3464    movd\t{%1, %0|%0, %1}
3465    %vmovd\t{%1, %0|%0, %1}
3466    %vmovd\t{%1, %0|%0, %1}"
3467   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3468    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3469    (set_attr "prefix_0f" "0,*,*,*,*,*")
3470    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3471
3472 (define_split
3473   [(set (match_operand:DI 0 "memory_operand" "")
3474         (zero_extend:DI (match_dup 0)))]
3475   "TARGET_64BIT"
3476   [(set (match_dup 4) (const_int 0))]
3477   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3478
3479 ;; %%% Kill me once multi-word ops are sane.
3480 (define_insn "zero_extendsidi2_1"
3481   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*x")
3482         (zero_extend:DI
3483          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3484    (clobber (reg:CC FLAGS_REG))]
3485   "!TARGET_64BIT"
3486   "@
3487    #
3488    #
3489    #
3490    movd\t{%1, %0|%0, %1}
3491    movd\t{%1, %0|%0, %1}
3492    %vmovd\t{%1, %0|%0, %1}
3493    %vmovd\t{%1, %0|%0, %1}"
3494   [(set_attr "isa" "*,*,*,*,*,*,sse2")
3495    (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3496    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3497    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3498
3499 (define_split
3500   [(set (match_operand:DI 0 "register_operand" "")
3501         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3502    (clobber (reg:CC FLAGS_REG))]
3503   "!TARGET_64BIT && reload_completed
3504    && true_regnum (operands[0]) == true_regnum (operands[1])"
3505   [(set (match_dup 4) (const_int 0))]
3506   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3507
3508 (define_split
3509   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3510         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3511    (clobber (reg:CC FLAGS_REG))]
3512   "!TARGET_64BIT && reload_completed
3513    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3514   [(set (match_dup 3) (match_dup 1))
3515    (set (match_dup 4) (const_int 0))]
3516   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3517
3518 (define_insn "zero_extend<mode>di2"
3519   [(set (match_operand:DI 0 "register_operand" "=r")
3520         (zero_extend:DI
3521          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3522   "TARGET_64BIT"
3523   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3524   [(set_attr "type" "imovx")
3525    (set_attr "mode" "SI")])
3526
3527 (define_expand "zero_extendhisi2"
3528   [(set (match_operand:SI 0 "register_operand" "")
3529         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3530   ""
3531 {
3532   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3533     {
3534       operands[1] = force_reg (HImode, operands[1]);
3535       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3536       DONE;
3537     }
3538 })
3539
3540 (define_insn_and_split "zero_extendhisi2_and"
3541   [(set (match_operand:SI 0 "register_operand" "=r")
3542         (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3543    (clobber (reg:CC FLAGS_REG))]
3544   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3545   "#"
3546   "&& reload_completed"
3547   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3548               (clobber (reg:CC FLAGS_REG))])]
3549   ""
3550   [(set_attr "type" "alu1")
3551    (set_attr "mode" "SI")])
3552
3553 (define_insn "*zero_extendhisi2_movzwl"
3554   [(set (match_operand:SI 0 "register_operand" "=r")
3555         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3556   "!TARGET_ZERO_EXTEND_WITH_AND
3557    || optimize_function_for_size_p (cfun)"
3558   "movz{wl|x}\t{%1, %0|%0, %1}"
3559   [(set_attr "type" "imovx")
3560    (set_attr "mode" "SI")])
3561
3562 (define_expand "zero_extendqi<mode>2"
3563   [(parallel
3564     [(set (match_operand:SWI24 0 "register_operand" "")
3565           (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3566      (clobber (reg:CC FLAGS_REG))])])
3567
3568 (define_insn "*zero_extendqi<mode>2_and"
3569   [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3570         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3571    (clobber (reg:CC FLAGS_REG))]
3572   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3573   "#"
3574   [(set_attr "type" "alu1")
3575    (set_attr "mode" "<MODE>")])
3576
3577 ;; When source and destination does not overlap, clear destination
3578 ;; first and then do the movb
3579 (define_split
3580   [(set (match_operand:SWI24 0 "register_operand" "")
3581         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3582    (clobber (reg:CC FLAGS_REG))]
3583   "reload_completed
3584    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3585    && ANY_QI_REG_P (operands[0])
3586    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3587    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3588   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3589 {
3590   operands[2] = gen_lowpart (QImode, operands[0]);
3591   ix86_expand_clear (operands[0]);
3592 })
3593
3594 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3595   [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3596         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3597    (clobber (reg:CC FLAGS_REG))]
3598   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3599   "#"
3600   [(set_attr "type" "imovx,alu1")
3601    (set_attr "mode" "<MODE>")])
3602
3603 ;; For the movzbl case strip only the clobber
3604 (define_split
3605   [(set (match_operand:SWI24 0 "register_operand" "")
3606         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3607    (clobber (reg:CC FLAGS_REG))]
3608   "reload_completed
3609    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3610    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3611   [(set (match_dup 0)
3612         (zero_extend:SWI24 (match_dup 1)))])
3613
3614 ; zero extend to SImode to avoid partial register stalls
3615 (define_insn "*zero_extendqi<mode>2_movzbl"
3616   [(set (match_operand:SWI24 0 "register_operand" "=r")
3617         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3618   "reload_completed
3619    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3620   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3621   [(set_attr "type" "imovx")
3622    (set_attr "mode" "SI")])
3623
3624 ;; Rest is handled by single and.
3625 (define_split
3626   [(set (match_operand:SWI24 0 "register_operand" "")
3627         (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3628    (clobber (reg:CC FLAGS_REG))]
3629   "reload_completed
3630    && true_regnum (operands[0]) == true_regnum (operands[1])"
3631   [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3632               (clobber (reg:CC FLAGS_REG))])])
3633 \f
3634 ;; Sign extension instructions
3635
3636 (define_expand "extendsidi2"
3637   [(set (match_operand:DI 0 "register_operand" "")
3638         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3639   ""
3640 {
3641   if (!TARGET_64BIT)
3642     {
3643       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3644       DONE;
3645     }
3646 })
3647
3648 (define_insn "*extendsidi2_rex64"
3649   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3650         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3651   "TARGET_64BIT"
3652   "@
3653    {cltq|cdqe}
3654    movs{lq|x}\t{%1, %0|%0, %1}"
3655   [(set_attr "type" "imovx")
3656    (set_attr "mode" "DI")
3657    (set_attr "prefix_0f" "0")
3658    (set_attr "modrm" "0,1")])
3659
3660 (define_insn "extendsidi2_1"
3661   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3662         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3663    (clobber (reg:CC FLAGS_REG))
3664    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3665   "!TARGET_64BIT"
3666   "#")
3667
3668 ;; Extend to memory case when source register does die.
3669 (define_split
3670   [(set (match_operand:DI 0 "memory_operand" "")
3671         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3672    (clobber (reg:CC FLAGS_REG))
3673    (clobber (match_operand:SI 2 "register_operand" ""))]
3674   "(reload_completed
3675     && dead_or_set_p (insn, operands[1])
3676     && !reg_mentioned_p (operands[1], operands[0]))"
3677   [(set (match_dup 3) (match_dup 1))
3678    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3679               (clobber (reg:CC FLAGS_REG))])
3680    (set (match_dup 4) (match_dup 1))]
3681   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3682
3683 ;; Extend to memory case when source register does not die.
3684 (define_split
3685   [(set (match_operand:DI 0 "memory_operand" "")
3686         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3687    (clobber (reg:CC FLAGS_REG))
3688    (clobber (match_operand:SI 2 "register_operand" ""))]
3689   "reload_completed"
3690   [(const_int 0)]
3691 {
3692   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3693
3694   emit_move_insn (operands[3], operands[1]);
3695
3696   /* Generate a cltd if possible and doing so it profitable.  */
3697   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3698       && true_regnum (operands[1]) == AX_REG
3699       && true_regnum (operands[2]) == DX_REG)
3700     {
3701       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3702     }
3703   else
3704     {
3705       emit_move_insn (operands[2], operands[1]);
3706       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3707     }
3708   emit_move_insn (operands[4], operands[2]);
3709   DONE;
3710 })
3711
3712 ;; Extend to register case.  Optimize case where source and destination
3713 ;; registers match and cases where we can use cltd.
3714 (define_split
3715   [(set (match_operand:DI 0 "register_operand" "")
3716         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3717    (clobber (reg:CC FLAGS_REG))
3718    (clobber (match_scratch:SI 2 ""))]
3719   "reload_completed"
3720   [(const_int 0)]
3721 {
3722   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3723
3724   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3725     emit_move_insn (operands[3], operands[1]);
3726
3727   /* Generate a cltd if possible and doing so it profitable.  */
3728   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3729       && true_regnum (operands[3]) == AX_REG
3730       && true_regnum (operands[4]) == DX_REG)
3731     {
3732       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3733       DONE;
3734     }
3735
3736   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3737     emit_move_insn (operands[4], operands[1]);
3738
3739   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3740   DONE;
3741 })
3742
3743 (define_insn "extend<mode>di2"
3744   [(set (match_operand:DI 0 "register_operand" "=r")
3745         (sign_extend:DI
3746          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3747   "TARGET_64BIT"
3748   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3749   [(set_attr "type" "imovx")
3750    (set_attr "mode" "DI")])
3751
3752 (define_insn "extendhisi2"
3753   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3754         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3755   ""
3756 {
3757   switch (get_attr_prefix_0f (insn))
3758     {
3759     case 0:
3760       return "{cwtl|cwde}";
3761     default:
3762       return "movs{wl|x}\t{%1, %0|%0, %1}";
3763     }
3764 }
3765   [(set_attr "type" "imovx")
3766    (set_attr "mode" "SI")
3767    (set (attr "prefix_0f")
3768      ;; movsx is short decodable while cwtl is vector decoded.
3769      (if_then_else (and (eq_attr "cpu" "!k6")
3770                         (eq_attr "alternative" "0"))
3771         (const_string "0")
3772         (const_string "1")))
3773    (set (attr "modrm")
3774      (if_then_else (eq_attr "prefix_0f" "0")
3775         (const_string "0")
3776         (const_string "1")))])
3777
3778 (define_insn "*extendhisi2_zext"
3779   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3780         (zero_extend:DI
3781          (sign_extend:SI
3782           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3783   "TARGET_64BIT"
3784 {
3785   switch (get_attr_prefix_0f (insn))
3786     {
3787     case 0:
3788       return "{cwtl|cwde}";
3789     default:
3790       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3791     }
3792 }
3793   [(set_attr "type" "imovx")
3794    (set_attr "mode" "SI")
3795    (set (attr "prefix_0f")
3796      ;; movsx is short decodable while cwtl is vector decoded.
3797      (if_then_else (and (eq_attr "cpu" "!k6")
3798                         (eq_attr "alternative" "0"))
3799         (const_string "0")
3800         (const_string "1")))
3801    (set (attr "modrm")
3802      (if_then_else (eq_attr "prefix_0f" "0")
3803         (const_string "0")
3804         (const_string "1")))])
3805
3806 (define_insn "extendqisi2"
3807   [(set (match_operand:SI 0 "register_operand" "=r")
3808         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3809   ""
3810   "movs{bl|x}\t{%1, %0|%0, %1}"
3811    [(set_attr "type" "imovx")
3812     (set_attr "mode" "SI")])
3813
3814 (define_insn "*extendqisi2_zext"
3815   [(set (match_operand:DI 0 "register_operand" "=r")
3816         (zero_extend:DI
3817           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3818   "TARGET_64BIT"
3819   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3820    [(set_attr "type" "imovx")
3821     (set_attr "mode" "SI")])
3822
3823 (define_insn "extendqihi2"
3824   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3825         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3826   ""
3827 {
3828   switch (get_attr_prefix_0f (insn))
3829     {
3830     case 0:
3831       return "{cbtw|cbw}";
3832     default:
3833       return "movs{bw|x}\t{%1, %0|%0, %1}";
3834     }
3835 }
3836   [(set_attr "type" "imovx")
3837    (set_attr "mode" "HI")
3838    (set (attr "prefix_0f")
3839      ;; movsx is short decodable while cwtl is vector decoded.
3840      (if_then_else (and (eq_attr "cpu" "!k6")
3841                         (eq_attr "alternative" "0"))
3842         (const_string "0")
3843         (const_string "1")))
3844    (set (attr "modrm")
3845      (if_then_else (eq_attr "prefix_0f" "0")
3846         (const_string "0")
3847         (const_string "1")))])
3848 \f
3849 ;; Conversions between float and double.
3850
3851 ;; These are all no-ops in the model used for the 80387.
3852 ;; So just emit moves.
3853
3854 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3855 (define_split
3856   [(set (match_operand:DF 0 "push_operand" "")
3857         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3858   "reload_completed"
3859   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3860    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3861
3862 (define_split
3863   [(set (match_operand:XF 0 "push_operand" "")
3864         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3865   "reload_completed"
3866   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3867    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3868   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3869
3870 (define_expand "extendsfdf2"
3871   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3872         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3873   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3874 {
3875   /* ??? Needed for compress_float_constant since all fp constants
3876      are TARGET_LEGITIMATE_CONSTANT_P.  */
3877   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3878     {
3879       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3880           && standard_80387_constant_p (operands[1]) > 0)
3881         {
3882           operands[1] = simplify_const_unary_operation
3883             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3884           emit_move_insn_1 (operands[0], operands[1]);
3885           DONE;
3886         }
3887       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3888     }
3889 })
3890
3891 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3892    cvtss2sd:
3893       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3894       cvtps2pd xmm2,xmm1
3895    We do the conversion post reload to avoid producing of 128bit spills
3896    that might lead to ICE on 32bit target.  The sequence unlikely combine
3897    anyway.  */
3898 (define_split
3899   [(set (match_operand:DF 0 "register_operand" "")
3900         (float_extend:DF
3901           (match_operand:SF 1 "nonimmediate_operand" "")))]
3902   "TARGET_USE_VECTOR_FP_CONVERTS
3903    && optimize_insn_for_speed_p ()
3904    && reload_completed && SSE_REG_P (operands[0])"
3905    [(set (match_dup 2)
3906          (float_extend:V2DF
3907            (vec_select:V2SF
3908              (match_dup 3)
3909              (parallel [(const_int 0) (const_int 1)]))))]
3910 {
3911   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3912   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3913   /* Use movss for loading from memory, unpcklps reg, reg for registers.
3914      Try to avoid move when unpacking can be done in source.  */
3915   if (REG_P (operands[1]))
3916     {
3917       /* If it is unsafe to overwrite upper half of source, we need
3918          to move to destination and unpack there.  */
3919       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3920            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3921           && true_regnum (operands[0]) != true_regnum (operands[1]))
3922         {
3923           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3924           emit_move_insn (tmp, operands[1]);
3925         }
3926       else
3927         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3928       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3929                                              operands[3]));
3930     }
3931   else
3932     emit_insn (gen_vec_setv4sf_0 (operands[3],
3933                                   CONST0_RTX (V4SFmode), operands[1]));
3934 })
3935
3936 (define_insn "*extendsfdf2_mixed"
3937   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3938         (float_extend:DF
3939           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3940   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3941 {
3942   switch (which_alternative)
3943     {
3944     case 0:
3945     case 1:
3946       return output_387_reg_move (insn, operands);
3947
3948     case 2:
3949       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3950
3951     default:
3952       gcc_unreachable ();
3953     }
3954 }
3955   [(set_attr "type" "fmov,fmov,ssecvt")
3956    (set_attr "prefix" "orig,orig,maybe_vex")
3957    (set_attr "mode" "SF,XF,DF")])
3958
3959 (define_insn "*extendsfdf2_sse"
3960   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3961         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3962   "TARGET_SSE2 && TARGET_SSE_MATH"
3963   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3964   [(set_attr "type" "ssecvt")
3965    (set_attr "prefix" "maybe_vex")
3966    (set_attr "mode" "DF")])
3967
3968 (define_insn "*extendsfdf2_i387"
3969   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3970         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3971   "TARGET_80387"
3972   "* return output_387_reg_move (insn, operands);"
3973   [(set_attr "type" "fmov")
3974    (set_attr "mode" "SF,XF")])
3975
3976 (define_expand "extend<mode>xf2"
3977   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3978         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3979   "TARGET_80387"
3980 {
3981   /* ??? Needed for compress_float_constant since all fp constants
3982      are TARGET_LEGITIMATE_CONSTANT_P.  */
3983   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3984     {
3985       if (standard_80387_constant_p (operands[1]) > 0)
3986         {
3987           operands[1] = simplify_const_unary_operation
3988             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3989           emit_move_insn_1 (operands[0], operands[1]);
3990           DONE;
3991         }
3992       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3993     }
3994 })
3995
3996 (define_insn "*extend<mode>xf2_i387"
3997   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3998         (float_extend:XF
3999           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4000   "TARGET_80387"
4001   "* return output_387_reg_move (insn, operands);"
4002   [(set_attr "type" "fmov")
4003    (set_attr "mode" "<MODE>,XF")])
4004
4005 ;; %%% This seems bad bad news.
4006 ;; This cannot output into an f-reg because there is no way to be sure
4007 ;; of truncating in that case.  Otherwise this is just like a simple move
4008 ;; insn.  So we pretend we can output to a reg in order to get better
4009 ;; register preferencing, but we really use a stack slot.
4010
4011 ;; Conversion from DFmode to SFmode.
4012
4013 (define_expand "truncdfsf2"
4014   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4015         (float_truncate:SF
4016           (match_operand:DF 1 "nonimmediate_operand" "")))]
4017   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4018 {
4019   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4020     ;
4021   else if (flag_unsafe_math_optimizations)
4022     ;
4023   else
4024     {
4025       enum ix86_stack_slot slot = (virtuals_instantiated
4026                                    ? SLOT_TEMP
4027                                    : SLOT_VIRTUAL);
4028       rtx temp = assign_386_stack_local (SFmode, slot);
4029       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4030       DONE;
4031     }
4032 })
4033
4034 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4035    cvtsd2ss:
4036       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4037       cvtpd2ps xmm2,xmm1
4038    We do the conversion post reload to avoid producing of 128bit spills
4039    that might lead to ICE on 32bit target.  The sequence unlikely combine
4040    anyway.  */
4041 (define_split
4042   [(set (match_operand:SF 0 "register_operand" "")
4043         (float_truncate:SF
4044           (match_operand:DF 1 "nonimmediate_operand" "")))]
4045   "TARGET_USE_VECTOR_FP_CONVERTS
4046    && optimize_insn_for_speed_p ()
4047    && reload_completed && SSE_REG_P (operands[0])"
4048    [(set (match_dup 2)
4049          (vec_concat:V4SF
4050            (float_truncate:V2SF
4051              (match_dup 4))
4052            (match_dup 3)))]
4053 {
4054   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4055   operands[3] = CONST0_RTX (V2SFmode);
4056   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4057   /* Use movsd for loading from memory, unpcklpd for registers.
4058      Try to avoid move when unpacking can be done in source, or SSE3
4059      movddup is available.  */
4060   if (REG_P (operands[1]))
4061     {
4062       if (!TARGET_SSE3
4063           && true_regnum (operands[0]) != true_regnum (operands[1])
4064           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4065               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4066         {
4067           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4068           emit_move_insn (tmp, operands[1]);
4069           operands[1] = tmp;
4070         }
4071       else if (!TARGET_SSE3)
4072         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4073       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4074     }
4075   else
4076     emit_insn (gen_sse2_loadlpd (operands[4],
4077                                  CONST0_RTX (V2DFmode), operands[1]));
4078 })
4079
4080 (define_expand "truncdfsf2_with_temp"
4081   [(parallel [(set (match_operand:SF 0 "" "")
4082                    (float_truncate:SF (match_operand:DF 1 "" "")))
4083               (clobber (match_operand:SF 2 "" ""))])])
4084
4085 (define_insn "*truncdfsf_fast_mixed"
4086   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4087         (float_truncate:SF
4088           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4089   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4090 {
4091   switch (which_alternative)
4092     {
4093     case 0:
4094       return output_387_reg_move (insn, operands);
4095     case 1:
4096       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4097     default:
4098       gcc_unreachable ();
4099     }
4100 }
4101   [(set_attr "type" "fmov,ssecvt")
4102    (set_attr "prefix" "orig,maybe_vex")
4103    (set_attr "mode" "SF")])
4104
4105 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4106 ;; because nothing we do here is unsafe.
4107 (define_insn "*truncdfsf_fast_sse"
4108   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4109         (float_truncate:SF
4110           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4111   "TARGET_SSE2 && TARGET_SSE_MATH"
4112   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4113   [(set_attr "type" "ssecvt")
4114    (set_attr "prefix" "maybe_vex")
4115    (set_attr "mode" "SF")])
4116
4117 (define_insn "*truncdfsf_fast_i387"
4118   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4119         (float_truncate:SF
4120           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4121   "TARGET_80387 && flag_unsafe_math_optimizations"
4122   "* return output_387_reg_move (insn, operands);"
4123   [(set_attr "type" "fmov")
4124    (set_attr "mode" "SF")])
4125
4126 (define_insn "*truncdfsf_mixed"
4127   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,x ,?f,?x,?*r")
4128         (float_truncate:SF
4129           (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4130    (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
4131   "TARGET_MIX_SSE_I387"
4132 {
4133   switch (which_alternative)
4134     {
4135     case 0:
4136       return output_387_reg_move (insn, operands);
4137     case 1:
4138       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4139
4140     default:
4141       return "#";
4142     }
4143 }
4144   [(set_attr "isa" "*,sse2,*,*,*")
4145    (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4146    (set_attr "unit" "*,*,i387,i387,i387")
4147    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4148    (set_attr "mode" "SF")])
4149
4150 (define_insn "*truncdfsf_i387"
4151   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4152         (float_truncate:SF
4153           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4154    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4155   "TARGET_80387"
4156 {
4157   switch (which_alternative)
4158     {
4159     case 0:
4160       return output_387_reg_move (insn, operands);
4161
4162     default:
4163       return "#";
4164     }
4165 }
4166   [(set_attr "type" "fmov,multi,multi,multi")
4167    (set_attr "unit" "*,i387,i387,i387")
4168    (set_attr "mode" "SF")])
4169
4170 (define_insn "*truncdfsf2_i387_1"
4171   [(set (match_operand:SF 0 "memory_operand" "=m")
4172         (float_truncate:SF
4173           (match_operand:DF 1 "register_operand" "f")))]
4174   "TARGET_80387
4175    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4176    && !TARGET_MIX_SSE_I387"
4177   "* return output_387_reg_move (insn, operands);"
4178   [(set_attr "type" "fmov")
4179    (set_attr "mode" "SF")])
4180
4181 (define_split
4182   [(set (match_operand:SF 0 "register_operand" "")
4183         (float_truncate:SF
4184          (match_operand:DF 1 "fp_register_operand" "")))
4185    (clobber (match_operand 2 "" ""))]
4186   "reload_completed"
4187   [(set (match_dup 2) (match_dup 1))
4188    (set (match_dup 0) (match_dup 2))]
4189   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4190
4191 ;; Conversion from XFmode to {SF,DF}mode
4192
4193 (define_expand "truncxf<mode>2"
4194   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4195                    (float_truncate:MODEF
4196                      (match_operand:XF 1 "register_operand" "")))
4197               (clobber (match_dup 2))])]
4198   "TARGET_80387"
4199 {
4200   if (flag_unsafe_math_optimizations)
4201     {
4202       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4203       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4204       if (reg != operands[0])
4205         emit_move_insn (operands[0], reg);
4206       DONE;
4207     }
4208   else
4209     {
4210       enum ix86_stack_slot slot = (virtuals_instantiated
4211                                    ? SLOT_TEMP
4212                                    : SLOT_VIRTUAL);
4213       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4214     }
4215 })
4216
4217 (define_insn "*truncxfsf2_mixed"
4218   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4219         (float_truncate:SF
4220           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4221    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4222   "TARGET_80387"
4223 {
4224   gcc_assert (!which_alternative);
4225   return output_387_reg_move (insn, operands);
4226 }
4227   [(set_attr "type" "fmov,multi,multi,multi")
4228    (set_attr "unit" "*,i387,i387,i387")
4229    (set_attr "mode" "SF")])
4230
4231 (define_insn "*truncxfdf2_mixed"
4232   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4233         (float_truncate:DF
4234           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4235    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4236   "TARGET_80387"
4237 {
4238   gcc_assert (!which_alternative);
4239   return output_387_reg_move (insn, operands);
4240 }
4241   [(set_attr "isa" "*,*,sse2,*")
4242    (set_attr "type" "fmov,multi,multi,multi")
4243    (set_attr "unit" "*,i387,i387,i387")
4244    (set_attr "mode" "DF")])
4245
4246 (define_insn "truncxf<mode>2_i387_noop"
4247   [(set (match_operand:MODEF 0 "register_operand" "=f")
4248         (float_truncate:MODEF
4249           (match_operand:XF 1 "register_operand" "f")))]
4250   "TARGET_80387 && flag_unsafe_math_optimizations"
4251   "* return output_387_reg_move (insn, operands);"
4252   [(set_attr "type" "fmov")
4253    (set_attr "mode" "<MODE>")])
4254
4255 (define_insn "*truncxf<mode>2_i387"
4256   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4257         (float_truncate:MODEF
4258           (match_operand:XF 1 "register_operand" "f")))]
4259   "TARGET_80387"
4260   "* return output_387_reg_move (insn, operands);"
4261   [(set_attr "type" "fmov")
4262    (set_attr "mode" "<MODE>")])
4263
4264 (define_split
4265   [(set (match_operand:MODEF 0 "register_operand" "")
4266         (float_truncate:MODEF
4267           (match_operand:XF 1 "register_operand" "")))
4268    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4269   "TARGET_80387 && reload_completed"
4270   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4271    (set (match_dup 0) (match_dup 2))])
4272
4273 (define_split
4274   [(set (match_operand:MODEF 0 "memory_operand" "")
4275         (float_truncate:MODEF
4276           (match_operand:XF 1 "register_operand" "")))
4277    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4278   "TARGET_80387"
4279   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4280 \f
4281 ;; Signed conversion to DImode.
4282
4283 (define_expand "fix_truncxfdi2"
4284   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4285                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4286               (clobber (reg:CC FLAGS_REG))])]
4287   "TARGET_80387"
4288 {
4289   if (TARGET_FISTTP)
4290    {
4291      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4292      DONE;
4293    }
4294 })
4295
4296 (define_expand "fix_trunc<mode>di2"
4297   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4298                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4299               (clobber (reg:CC FLAGS_REG))])]
4300   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4301 {
4302   if (TARGET_FISTTP
4303       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4304    {
4305      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4306      DONE;
4307    }
4308   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4309    {
4310      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4311      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4312      if (out != operands[0])
4313         emit_move_insn (operands[0], out);
4314      DONE;
4315    }
4316 })
4317
4318 ;; Signed conversion to SImode.
4319
4320 (define_expand "fix_truncxfsi2"
4321   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4322                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4323               (clobber (reg:CC FLAGS_REG))])]
4324   "TARGET_80387"
4325 {
4326   if (TARGET_FISTTP)
4327    {
4328      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4329      DONE;
4330    }
4331 })
4332
4333 (define_expand "fix_trunc<mode>si2"
4334   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4335                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4336               (clobber (reg:CC FLAGS_REG))])]
4337   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4338 {
4339   if (TARGET_FISTTP
4340       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4341    {
4342      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4343      DONE;
4344    }
4345   if (SSE_FLOAT_MODE_P (<MODE>mode))
4346    {
4347      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4348      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4349      if (out != operands[0])
4350         emit_move_insn (operands[0], out);
4351      DONE;
4352    }
4353 })
4354
4355 ;; Signed conversion to HImode.
4356
4357 (define_expand "fix_trunc<mode>hi2"
4358   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4359                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4360               (clobber (reg:CC FLAGS_REG))])]
4361   "TARGET_80387
4362    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4363 {
4364   if (TARGET_FISTTP)
4365    {
4366      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4367      DONE;
4368    }
4369 })
4370
4371 ;; Unsigned conversion to SImode.
4372
4373 (define_expand "fixuns_trunc<mode>si2"
4374   [(parallel
4375     [(set (match_operand:SI 0 "register_operand" "")
4376           (unsigned_fix:SI
4377             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4378      (use (match_dup 2))
4379      (clobber (match_scratch:<ssevecmode> 3 ""))
4380      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4381   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4382 {
4383   enum machine_mode mode = <MODE>mode;
4384   enum machine_mode vecmode = <ssevecmode>mode;
4385   REAL_VALUE_TYPE TWO31r;
4386   rtx two31;
4387
4388   if (optimize_insn_for_size_p ())
4389     FAIL;
4390
4391   real_ldexp (&TWO31r, &dconst1, 31);
4392   two31 = const_double_from_real_value (TWO31r, mode);
4393   two31 = ix86_build_const_vector (vecmode, true, two31);
4394   operands[2] = force_reg (vecmode, two31);
4395 })
4396
4397 (define_insn_and_split "*fixuns_trunc<mode>_1"
4398   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4399         (unsigned_fix:SI
4400           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4401    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4402    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4403    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4404   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4405    && optimize_function_for_speed_p (cfun)"
4406   "#"
4407   "&& reload_completed"
4408   [(const_int 0)]
4409 {
4410   ix86_split_convert_uns_si_sse (operands);
4411   DONE;
4412 })
4413
4414 ;; Unsigned conversion to HImode.
4415 ;; Without these patterns, we'll try the unsigned SI conversion which
4416 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4417
4418 (define_expand "fixuns_trunc<mode>hi2"
4419   [(set (match_dup 2)
4420         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4421    (set (match_operand:HI 0 "nonimmediate_operand" "")
4422         (subreg:HI (match_dup 2) 0))]
4423   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4424   "operands[2] = gen_reg_rtx (SImode);")
4425
4426 ;; When SSE is available, it is always faster to use it!
4427 (define_insn "fix_trunc<mode>di_sse"
4428   [(set (match_operand:DI 0 "register_operand" "=r,r")
4429         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4430   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4431    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4432   "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4433   [(set_attr "type" "sseicvt")
4434    (set_attr "prefix" "maybe_vex")
4435    (set_attr "prefix_rex" "1")
4436    (set_attr "mode" "<MODE>")
4437    (set_attr "athlon_decode" "double,vector")
4438    (set_attr "amdfam10_decode" "double,double")
4439    (set_attr "bdver1_decode" "double,double")])
4440
4441 (define_insn "fix_trunc<mode>si_sse"
4442   [(set (match_operand:SI 0 "register_operand" "=r,r")
4443         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4444   "SSE_FLOAT_MODE_P (<MODE>mode)
4445    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4446   "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4447   [(set_attr "type" "sseicvt")
4448    (set_attr "prefix" "maybe_vex")
4449    (set_attr "mode" "<MODE>")
4450    (set_attr "athlon_decode" "double,vector")
4451    (set_attr "amdfam10_decode" "double,double")
4452    (set_attr "bdver1_decode" "double,double")])
4453
4454 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4455 (define_peephole2
4456   [(set (match_operand:MODEF 0 "register_operand" "")
4457         (match_operand:MODEF 1 "memory_operand" ""))
4458    (set (match_operand:SWI48x 2 "register_operand" "")
4459         (fix:SWI48x (match_dup 0)))]
4460   "TARGET_SHORTEN_X87_SSE
4461    && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4462    && peep2_reg_dead_p (2, operands[0])"
4463   [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4464
4465 ;; Avoid vector decoded forms of the instruction.
4466 (define_peephole2
4467   [(match_scratch:DF 2 "x")
4468    (set (match_operand:SWI48x 0 "register_operand" "")
4469         (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4470   "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4471   [(set (match_dup 2) (match_dup 1))
4472    (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4473
4474 (define_peephole2
4475   [(match_scratch:SF 2 "x")
4476    (set (match_operand:SWI48x 0 "register_operand" "")
4477         (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4478   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4479   [(set (match_dup 2) (match_dup 1))
4480    (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4481
4482 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4483   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4484         (fix:SWI248x (match_operand 1 "register_operand" "")))]
4485   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4486    && TARGET_FISTTP
4487    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4488          && (TARGET_64BIT || <MODE>mode != DImode))
4489         && TARGET_SSE_MATH)
4490    && can_create_pseudo_p ()"
4491   "#"
4492   "&& 1"
4493   [(const_int 0)]
4494 {
4495   if (memory_operand (operands[0], VOIDmode))
4496     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4497   else
4498     {
4499       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4500       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4501                                                             operands[1],
4502                                                             operands[2]));
4503     }
4504   DONE;
4505 }
4506   [(set_attr "type" "fisttp")
4507    (set_attr "mode" "<MODE>")])
4508
4509 (define_insn "fix_trunc<mode>_i387_fisttp"
4510   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4511         (fix:SWI248x (match_operand 1 "register_operand" "f")))
4512    (clobber (match_scratch:XF 2 "=&1f"))]
4513   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4514    && TARGET_FISTTP
4515    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4516          && (TARGET_64BIT || <MODE>mode != DImode))
4517         && TARGET_SSE_MATH)"
4518   "* return output_fix_trunc (insn, operands, true);"
4519   [(set_attr "type" "fisttp")
4520    (set_attr "mode" "<MODE>")])
4521
4522 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4523   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4524         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4525    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4526    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4527   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4528    && TARGET_FISTTP
4529    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4530         && (TARGET_64BIT || <MODE>mode != DImode))
4531         && TARGET_SSE_MATH)"
4532   "#"
4533   [(set_attr "type" "fisttp")
4534    (set_attr "mode" "<MODE>")])
4535
4536 (define_split
4537   [(set (match_operand:SWI248x 0 "register_operand" "")
4538         (fix:SWI248x (match_operand 1 "register_operand" "")))
4539    (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4540    (clobber (match_scratch 3 ""))]
4541   "reload_completed"
4542   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4543               (clobber (match_dup 3))])
4544    (set (match_dup 0) (match_dup 2))])
4545
4546 (define_split
4547   [(set (match_operand:SWI248x 0 "memory_operand" "")
4548         (fix:SWI248x (match_operand 1 "register_operand" "")))
4549    (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4550    (clobber (match_scratch 3 ""))]
4551   "reload_completed"
4552   [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4553               (clobber (match_dup 3))])])
4554
4555 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4556 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4557 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4558 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4559 ;; function in i386.c.
4560 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4561   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4562         (fix:SWI248x (match_operand 1 "register_operand" "")))
4563    (clobber (reg:CC FLAGS_REG))]
4564   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4565    && !TARGET_FISTTP
4566    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4567          && (TARGET_64BIT || <MODE>mode != DImode))
4568    && can_create_pseudo_p ()"
4569   "#"
4570   "&& 1"
4571   [(const_int 0)]
4572 {
4573   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4574
4575   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4576   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4577   if (memory_operand (operands[0], VOIDmode))
4578     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4579                                          operands[2], operands[3]));
4580   else
4581     {
4582       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4583       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4584                                                      operands[2], operands[3],
4585                                                      operands[4]));
4586     }
4587   DONE;
4588 }
4589   [(set_attr "type" "fistp")
4590    (set_attr "i387_cw" "trunc")
4591    (set_attr "mode" "<MODE>")])
4592
4593 (define_insn "fix_truncdi_i387"
4594   [(set (match_operand:DI 0 "memory_operand" "=m")
4595         (fix:DI (match_operand 1 "register_operand" "f")))
4596    (use (match_operand:HI 2 "memory_operand" "m"))
4597    (use (match_operand:HI 3 "memory_operand" "m"))
4598    (clobber (match_scratch:XF 4 "=&1f"))]
4599   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4600    && !TARGET_FISTTP
4601    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4602   "* return output_fix_trunc (insn, operands, false);"
4603   [(set_attr "type" "fistp")
4604    (set_attr "i387_cw" "trunc")
4605    (set_attr "mode" "DI")])
4606
4607 (define_insn "fix_truncdi_i387_with_temp"
4608   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4609         (fix:DI (match_operand 1 "register_operand" "f,f")))
4610    (use (match_operand:HI 2 "memory_operand" "m,m"))
4611    (use (match_operand:HI 3 "memory_operand" "m,m"))
4612    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4613    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4614   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4615    && !TARGET_FISTTP
4616    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4617   "#"
4618   [(set_attr "type" "fistp")
4619    (set_attr "i387_cw" "trunc")
4620    (set_attr "mode" "DI")])
4621
4622 (define_split
4623   [(set (match_operand:DI 0 "register_operand" "")
4624         (fix:DI (match_operand 1 "register_operand" "")))
4625    (use (match_operand:HI 2 "memory_operand" ""))
4626    (use (match_operand:HI 3 "memory_operand" ""))
4627    (clobber (match_operand:DI 4 "memory_operand" ""))
4628    (clobber (match_scratch 5 ""))]
4629   "reload_completed"
4630   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4631               (use (match_dup 2))
4632               (use (match_dup 3))
4633               (clobber (match_dup 5))])
4634    (set (match_dup 0) (match_dup 4))])
4635
4636 (define_split
4637   [(set (match_operand:DI 0 "memory_operand" "")
4638         (fix:DI (match_operand 1 "register_operand" "")))
4639    (use (match_operand:HI 2 "memory_operand" ""))
4640    (use (match_operand:HI 3 "memory_operand" ""))
4641    (clobber (match_operand:DI 4 "memory_operand" ""))
4642    (clobber (match_scratch 5 ""))]
4643   "reload_completed"
4644   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4645               (use (match_dup 2))
4646               (use (match_dup 3))
4647               (clobber (match_dup 5))])])
4648
4649 (define_insn "fix_trunc<mode>_i387"
4650   [(set (match_operand:SWI24 0 "memory_operand" "=m")
4651         (fix:SWI24 (match_operand 1 "register_operand" "f")))
4652    (use (match_operand:HI 2 "memory_operand" "m"))
4653    (use (match_operand:HI 3 "memory_operand" "m"))]
4654   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4655    && !TARGET_FISTTP
4656    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4657   "* return output_fix_trunc (insn, operands, false);"
4658   [(set_attr "type" "fistp")
4659    (set_attr "i387_cw" "trunc")
4660    (set_attr "mode" "<MODE>")])
4661
4662 (define_insn "fix_trunc<mode>_i387_with_temp"
4663   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4664         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4665    (use (match_operand:HI 2 "memory_operand" "m,m"))
4666    (use (match_operand:HI 3 "memory_operand" "m,m"))
4667    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4668   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4669    && !TARGET_FISTTP
4670    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4671   "#"
4672   [(set_attr "type" "fistp")
4673    (set_attr "i387_cw" "trunc")
4674    (set_attr "mode" "<MODE>")])
4675
4676 (define_split
4677   [(set (match_operand:SWI24 0 "register_operand" "")
4678         (fix:SWI24 (match_operand 1 "register_operand" "")))
4679    (use (match_operand:HI 2 "memory_operand" ""))
4680    (use (match_operand:HI 3 "memory_operand" ""))
4681    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4682   "reload_completed"
4683   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4684               (use (match_dup 2))
4685               (use (match_dup 3))])
4686    (set (match_dup 0) (match_dup 4))])
4687
4688 (define_split
4689   [(set (match_operand:SWI24 0 "memory_operand" "")
4690         (fix:SWI24 (match_operand 1 "register_operand" "")))
4691    (use (match_operand:HI 2 "memory_operand" ""))
4692    (use (match_operand:HI 3 "memory_operand" ""))
4693    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4694   "reload_completed"
4695   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4696               (use (match_dup 2))
4697               (use (match_dup 3))])])
4698
4699 (define_insn "x86_fnstcw_1"
4700   [(set (match_operand:HI 0 "memory_operand" "=m")
4701         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4702   "TARGET_80387"
4703   "fnstcw\t%0"
4704   [(set (attr "length")
4705         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4706    (set_attr "mode" "HI")
4707    (set_attr "unit" "i387")
4708    (set_attr "bdver1_decode" "vector")])
4709
4710 (define_insn "x86_fldcw_1"
4711   [(set (reg:HI FPCR_REG)
4712         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4713   "TARGET_80387"
4714   "fldcw\t%0"
4715   [(set (attr "length")
4716         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4717    (set_attr "mode" "HI")
4718    (set_attr "unit" "i387")
4719    (set_attr "athlon_decode" "vector")
4720    (set_attr "amdfam10_decode" "vector")
4721    (set_attr "bdver1_decode" "vector")])
4722 \f
4723 ;; Conversion between fixed point and floating point.
4724
4725 ;; Even though we only accept memory inputs, the backend _really_
4726 ;; wants to be able to do this between registers.
4727
4728 (define_expand "floathi<mode>2"
4729   [(set (match_operand:X87MODEF 0 "register_operand" "")
4730         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4731   "TARGET_80387
4732    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4733        || TARGET_MIX_SSE_I387)")
4734
4735 ;; Pre-reload splitter to add memory clobber to the pattern.
4736 (define_insn_and_split "*floathi<mode>2_1"
4737   [(set (match_operand:X87MODEF 0 "register_operand" "")
4738         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4739   "TARGET_80387
4740    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4741        || TARGET_MIX_SSE_I387)
4742    && can_create_pseudo_p ()"
4743   "#"
4744   "&& 1"
4745   [(parallel [(set (match_dup 0)
4746               (float:X87MODEF (match_dup 1)))
4747    (clobber (match_dup 2))])]
4748   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4749
4750 (define_insn "*floathi<mode>2_i387_with_temp"
4751   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4752         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4753   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4754   "TARGET_80387
4755    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4756        || TARGET_MIX_SSE_I387)"
4757   "#"
4758   [(set_attr "type" "fmov,multi")
4759    (set_attr "mode" "<MODE>")
4760    (set_attr "unit" "*,i387")
4761    (set_attr "fp_int_src" "true")])
4762
4763 (define_insn "*floathi<mode>2_i387"
4764   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4765         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4766   "TARGET_80387
4767    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4768        || TARGET_MIX_SSE_I387)"
4769   "fild%Z1\t%1"
4770   [(set_attr "type" "fmov")
4771    (set_attr "mode" "<MODE>")
4772    (set_attr "fp_int_src" "true")])
4773
4774 (define_split
4775   [(set (match_operand:X87MODEF 0 "register_operand" "")
4776         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4777    (clobber (match_operand:HI 2 "memory_operand" ""))]
4778   "TARGET_80387
4779    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4780        || TARGET_MIX_SSE_I387)
4781    && reload_completed"
4782   [(set (match_dup 2) (match_dup 1))
4783    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4784
4785 (define_split
4786   [(set (match_operand:X87MODEF 0 "register_operand" "")
4787         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4788    (clobber (match_operand:HI 2 "memory_operand" ""))]
4789    "TARGET_80387
4790     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4791         || TARGET_MIX_SSE_I387)
4792     && reload_completed"
4793   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4794
4795 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4796   [(set (match_operand:X87MODEF 0 "register_operand" "")
4797         (float:X87MODEF
4798           (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4799   "TARGET_80387
4800    || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4801        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4802 {
4803   if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4804         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4805       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4806     {
4807       rtx reg = gen_reg_rtx (XFmode);
4808       rtx (*insn)(rtx, rtx);
4809
4810       emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4811
4812       if (<X87MODEF:MODE>mode == SFmode)
4813         insn = gen_truncxfsf2;
4814       else if (<X87MODEF:MODE>mode == DFmode)
4815         insn = gen_truncxfdf2;
4816       else
4817         gcc_unreachable ();
4818
4819       emit_insn (insn (operands[0], reg));
4820       DONE;
4821     }
4822 })
4823
4824 ;; Pre-reload splitter to add memory clobber to the pattern.
4825 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4826   [(set (match_operand:X87MODEF 0 "register_operand" "")
4827         (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4828   "((TARGET_80387
4829      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4830      && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4831            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4832          || TARGET_MIX_SSE_I387))
4833     || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4834         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4835         && ((<SWI48x:MODE>mode == SImode
4836              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4837              && optimize_function_for_speed_p (cfun)
4838              && flag_trapping_math)
4839             || !(TARGET_INTER_UNIT_CONVERSIONS
4840                  || optimize_function_for_size_p (cfun)))))
4841    && can_create_pseudo_p ()"
4842   "#"
4843   "&& 1"
4844   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4845               (clobber (match_dup 2))])]
4846 {
4847   operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4848
4849   /* Avoid store forwarding (partial memory) stall penalty
4850      by passing DImode value through XMM registers.  */
4851   if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4852       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4853       && optimize_function_for_speed_p (cfun))
4854     {
4855       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4856                                                             operands[1],
4857                                                             operands[2]));
4858       DONE;
4859     }
4860 })
4861
4862 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4863   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4864         (float:MODEF
4865           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4866    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4867   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4868    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4869   "#"
4870   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4871    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4872    (set_attr "unit" "*,i387,*,*,*")
4873    (set_attr "athlon_decode" "*,*,double,direct,double")
4874    (set_attr "amdfam10_decode" "*,*,vector,double,double")
4875    (set_attr "bdver1_decode" "*,*,double,direct,double")
4876    (set_attr "fp_int_src" "true")])
4877
4878 (define_insn "*floatsi<mode>2_vector_mixed"
4879   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4880         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4881   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4882    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4883   "@
4884    fild%Z1\t%1
4885    #"
4886   [(set_attr "type" "fmov,sseicvt")
4887    (set_attr "mode" "<MODE>,<ssevecmode>")
4888    (set_attr "unit" "i387,*")
4889    (set_attr "athlon_decode" "*,direct")
4890    (set_attr "amdfam10_decode" "*,double")
4891    (set_attr "bdver1_decode" "*,direct")
4892    (set_attr "fp_int_src" "true")])
4893
4894 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4895   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4896         (float:MODEF
4897           (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4898    (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4899   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4900    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4901   "#"
4902   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4903    (set_attr "mode" "<MODEF:MODE>")
4904    (set_attr "unit" "*,i387,*,*")
4905    (set_attr "athlon_decode" "*,*,double,direct")
4906    (set_attr "amdfam10_decode" "*,*,vector,double")
4907    (set_attr "bdver1_decode" "*,*,double,direct")
4908    (set_attr "fp_int_src" "true")])
4909
4910 (define_split
4911   [(set (match_operand:MODEF 0 "register_operand" "")
4912         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4913    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4914   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4915    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4916    && TARGET_INTER_UNIT_CONVERSIONS
4917    && reload_completed
4918    && (SSE_REG_P (operands[0])
4919        || (GET_CODE (operands[0]) == SUBREG
4920            && SSE_REG_P (operands[0])))"
4921   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4922
4923 (define_split
4924   [(set (match_operand:MODEF 0 "register_operand" "")
4925         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4926    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4927   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4928    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4929    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4930    && reload_completed
4931    && (SSE_REG_P (operands[0])
4932        || (GET_CODE (operands[0]) == SUBREG
4933            && SSE_REG_P (operands[0])))"
4934   [(set (match_dup 2) (match_dup 1))
4935    (set (match_dup 0) (float:MODEF (match_dup 2)))])
4936
4937 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4938   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4939         (float:MODEF
4940           (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4941   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4942    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4943    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4944   "@
4945    fild%Z1\t%1
4946    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4947    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4948   [(set_attr "type" "fmov,sseicvt,sseicvt")
4949    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4950    (set_attr "mode" "<MODEF:MODE>")
4951    (set (attr "prefix_rex")
4952      (if_then_else
4953        (and (eq_attr "prefix" "maybe_vex")
4954             (match_test "<SWI48x:MODE>mode == DImode"))
4955        (const_string "1")
4956        (const_string "*")))
4957    (set_attr "unit" "i387,*,*")
4958    (set_attr "athlon_decode" "*,double,direct")
4959    (set_attr "amdfam10_decode" "*,vector,double")
4960    (set_attr "bdver1_decode" "*,double,direct")
4961    (set_attr "fp_int_src" "true")])
4962
4963 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4964   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4965         (float:MODEF
4966           (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4967   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4968    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4969    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4970   "@
4971    fild%Z1\t%1
4972    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4973   [(set_attr "type" "fmov,sseicvt")
4974    (set_attr "prefix" "orig,maybe_vex")
4975    (set_attr "mode" "<MODEF:MODE>")
4976    (set (attr "prefix_rex")
4977      (if_then_else
4978        (and (eq_attr "prefix" "maybe_vex")
4979             (match_test "<SWI48x:MODE>mode == DImode"))
4980        (const_string "1")
4981        (const_string "*")))
4982    (set_attr "athlon_decode" "*,direct")
4983    (set_attr "amdfam10_decode" "*,double")
4984    (set_attr "bdver1_decode" "*,direct")
4985    (set_attr "fp_int_src" "true")])
4986
4987 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4988   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4989         (float:MODEF
4990           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4991    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4992   "TARGET_SSE2 && TARGET_SSE_MATH
4993    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4994   "#"
4995   [(set_attr "type" "sseicvt")
4996    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4997    (set_attr "athlon_decode" "double,direct,double")
4998    (set_attr "amdfam10_decode" "vector,double,double")
4999    (set_attr "bdver1_decode" "double,direct,double")
5000    (set_attr "fp_int_src" "true")])
5001
5002 (define_insn "*floatsi<mode>2_vector_sse"
5003   [(set (match_operand:MODEF 0 "register_operand" "=x")
5004         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5005   "TARGET_SSE2 && TARGET_SSE_MATH
5006    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5007   "#"
5008   [(set_attr "type" "sseicvt")
5009    (set_attr "mode" "<MODE>")
5010    (set_attr "athlon_decode" "direct")
5011    (set_attr "amdfam10_decode" "double")
5012    (set_attr "bdver1_decode" "direct")
5013    (set_attr "fp_int_src" "true")])
5014
5015 (define_split
5016   [(set (match_operand:MODEF 0 "register_operand" "")
5017         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5018    (clobber (match_operand:SI 2 "memory_operand" ""))]
5019   "TARGET_SSE2 && TARGET_SSE_MATH
5020    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5021    && reload_completed
5022    && (SSE_REG_P (operands[0])
5023        || (GET_CODE (operands[0]) == SUBREG
5024            && SSE_REG_P (operands[0])))"
5025   [(const_int 0)]
5026 {
5027   rtx op1 = operands[1];
5028
5029   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5030                                      <MODE>mode, 0);
5031   if (GET_CODE (op1) == SUBREG)
5032     op1 = SUBREG_REG (op1);
5033
5034   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5035     {
5036       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5037       emit_insn (gen_sse2_loadld (operands[4],
5038                                   CONST0_RTX (V4SImode), operands[1]));
5039     }
5040   /* We can ignore possible trapping value in the
5041      high part of SSE register for non-trapping math. */
5042   else if (SSE_REG_P (op1) && !flag_trapping_math)
5043     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5044   else
5045     {
5046       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5047       emit_move_insn (operands[2], operands[1]);
5048       emit_insn (gen_sse2_loadld (operands[4],
5049                                   CONST0_RTX (V4SImode), operands[2]));
5050     }
5051   emit_insn
5052     (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5053   DONE;
5054 })
5055
5056 (define_split
5057   [(set (match_operand:MODEF 0 "register_operand" "")
5058         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5059    (clobber (match_operand:SI 2 "memory_operand" ""))]
5060   "TARGET_SSE2 && TARGET_SSE_MATH
5061    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5062    && reload_completed
5063    && (SSE_REG_P (operands[0])
5064        || (GET_CODE (operands[0]) == SUBREG
5065            && SSE_REG_P (operands[0])))"
5066   [(const_int 0)]
5067 {
5068   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5069                                      <MODE>mode, 0);
5070   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5071
5072   emit_insn (gen_sse2_loadld (operands[4],
5073                               CONST0_RTX (V4SImode), operands[1]));
5074   emit_insn
5075     (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5076   DONE;
5077 })
5078
5079 (define_split
5080   [(set (match_operand:MODEF 0 "register_operand" "")
5081         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5082   "TARGET_SSE2 && TARGET_SSE_MATH
5083    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5084    && reload_completed
5085    && (SSE_REG_P (operands[0])
5086        || (GET_CODE (operands[0]) == SUBREG
5087            && SSE_REG_P (operands[0])))"
5088   [(const_int 0)]
5089 {
5090   rtx op1 = operands[1];
5091
5092   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5093                                      <MODE>mode, 0);
5094   if (GET_CODE (op1) == SUBREG)
5095     op1 = SUBREG_REG (op1);
5096
5097   if (GENERAL_REG_P (op1))
5098     {
5099       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5100       if (TARGET_INTER_UNIT_MOVES)
5101         emit_insn (gen_sse2_loadld (operands[4],
5102                                     CONST0_RTX (V4SImode), operands[1]));
5103       else
5104         {
5105           operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5106                                               operands[1]);
5107           emit_insn (gen_sse2_loadld (operands[4],
5108                                       CONST0_RTX (V4SImode), operands[5]));
5109           ix86_free_from_memory (GET_MODE (operands[1]));
5110         }
5111     }
5112   /* We can ignore possible trapping value in the
5113      high part of SSE register for non-trapping math. */
5114   else if (SSE_REG_P (op1) && !flag_trapping_math)
5115     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5116   else
5117     gcc_unreachable ();
5118   emit_insn
5119     (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5120   DONE;
5121 })
5122
5123 (define_split
5124   [(set (match_operand:MODEF 0 "register_operand" "")
5125         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5126   "TARGET_SSE2 && TARGET_SSE_MATH
5127    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5128    && reload_completed
5129    && (SSE_REG_P (operands[0])
5130        || (GET_CODE (operands[0]) == SUBREG
5131            && SSE_REG_P (operands[0])))"
5132   [(const_int 0)]
5133 {
5134   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5135                                      <MODE>mode, 0);
5136   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5137
5138   emit_insn (gen_sse2_loadld (operands[4],
5139                               CONST0_RTX (V4SImode), operands[1]));
5140   emit_insn
5141     (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5142   DONE;
5143 })
5144
5145 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5146   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5147         (float:MODEF
5148           (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5149   (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5150   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5151    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5152   "#"
5153   [(set_attr "type" "sseicvt")
5154    (set_attr "mode" "<MODEF:MODE>")
5155    (set_attr "athlon_decode" "double,direct")
5156    (set_attr "amdfam10_decode" "vector,double")
5157    (set_attr "bdver1_decode" "double,direct")
5158    (set_attr "fp_int_src" "true")])
5159
5160 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5161   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5162         (float:MODEF
5163           (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5164   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5165    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5166    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5167   "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5168   [(set_attr "type" "sseicvt")
5169    (set_attr "prefix" "maybe_vex")
5170    (set_attr "mode" "<MODEF:MODE>")
5171    (set (attr "prefix_rex")
5172      (if_then_else
5173        (and (eq_attr "prefix" "maybe_vex")
5174             (match_test "<SWI48x:MODE>mode == DImode"))
5175        (const_string "1")
5176        (const_string "*")))
5177    (set_attr "athlon_decode" "double,direct")
5178    (set_attr "amdfam10_decode" "vector,double")
5179    (set_attr "bdver1_decode" "double,direct")
5180    (set_attr "fp_int_src" "true")])
5181
5182 (define_split
5183   [(set (match_operand:MODEF 0 "register_operand" "")
5184         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5185    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5186   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5187    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5188    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5189    && reload_completed
5190    && (SSE_REG_P (operands[0])
5191        || (GET_CODE (operands[0]) == SUBREG
5192            && SSE_REG_P (operands[0])))"
5193   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5194
5195 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5196   [(set (match_operand:MODEF 0 "register_operand" "=x")
5197         (float:MODEF
5198           (match_operand:SWI48x 1 "memory_operand" "m")))]
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   "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5203   [(set_attr "type" "sseicvt")
5204    (set_attr "prefix" "maybe_vex")
5205    (set_attr "mode" "<MODEF:MODE>")
5206    (set (attr "prefix_rex")
5207      (if_then_else
5208        (and (eq_attr "prefix" "maybe_vex")
5209             (match_test "<SWI48x:MODE>mode == DImode"))
5210        (const_string "1")
5211        (const_string "*")))
5212    (set_attr "athlon_decode" "direct")
5213    (set_attr "amdfam10_decode" "double")
5214    (set_attr "bdver1_decode" "direct")
5215    (set_attr "fp_int_src" "true")])
5216
5217 (define_split
5218   [(set (match_operand:MODEF 0 "register_operand" "")
5219         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5220    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5221   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5222    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5223    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5224    && reload_completed
5225    && (SSE_REG_P (operands[0])
5226        || (GET_CODE (operands[0]) == SUBREG
5227            && SSE_REG_P (operands[0])))"
5228   [(set (match_dup 2) (match_dup 1))
5229    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5230
5231 (define_split
5232   [(set (match_operand:MODEF 0 "register_operand" "")
5233         (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5234    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5235   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5236    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
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 0) (float:MODEF (match_dup 1)))])
5242
5243 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5244   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5245         (float:X87MODEF
5246           (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5247   (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5248   "TARGET_80387
5249    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5250   "@
5251    fild%Z1\t%1
5252    #"
5253   [(set_attr "type" "fmov,multi")
5254    (set_attr "mode" "<X87MODEF:MODE>")
5255    (set_attr "unit" "*,i387")
5256    (set_attr "fp_int_src" "true")])
5257
5258 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5259   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5260         (float:X87MODEF
5261           (match_operand:SWI48x 1 "memory_operand" "m")))]
5262   "TARGET_80387
5263    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5264   "fild%Z1\t%1"
5265   [(set_attr "type" "fmov")
5266    (set_attr "mode" "<X87MODEF:MODE>")
5267    (set_attr "fp_int_src" "true")])
5268
5269 (define_split
5270   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5271         (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5272    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5273   "TARGET_80387
5274    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5275    && reload_completed"
5276   [(set (match_dup 2) (match_dup 1))
5277    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5278
5279 (define_split
5280   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5281         (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5282    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5283   "TARGET_80387
5284    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5285    && reload_completed"
5286   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5287
5288 ;; Avoid store forwarding (partial memory) stall penalty
5289 ;; by passing DImode value through XMM registers.  */
5290
5291 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5292   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5293         (float:X87MODEF
5294           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5295    (clobber (match_scratch:V4SI 3 "=X,x"))
5296    (clobber (match_scratch:V4SI 4 "=X,x"))
5297    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5298   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5299    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5300    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5301   "#"
5302   [(set_attr "type" "multi")
5303    (set_attr "mode" "<X87MODEF:MODE>")
5304    (set_attr "unit" "i387")
5305    (set_attr "fp_int_src" "true")])
5306
5307 (define_split
5308   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5309         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5310    (clobber (match_scratch:V4SI 3 ""))
5311    (clobber (match_scratch:V4SI 4 ""))
5312    (clobber (match_operand:DI 2 "memory_operand" ""))]
5313   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5314    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5315    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5316    && reload_completed"
5317   [(set (match_dup 2) (match_dup 3))
5318    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5319 {
5320   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5321      Assemble the 64-bit DImode value in an xmm register.  */
5322   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5323                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5324   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5325                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5326   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5327                                          operands[4]));
5328
5329   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5330 })
5331
5332 (define_split
5333   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5334         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5335    (clobber (match_scratch:V4SI 3 ""))
5336    (clobber (match_scratch:V4SI 4 ""))
5337    (clobber (match_operand:DI 2 "memory_operand" ""))]
5338   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5339    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5340    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5341    && reload_completed"
5342   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5343
5344 ;; Avoid store forwarding (partial memory) stall penalty by extending
5345 ;; SImode value to DImode through XMM register instead of pushing two
5346 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5347 ;; targets benefit from this optimization. Also note that fild
5348 ;; loads from memory only.
5349
5350 (define_insn "*floatunssi<mode>2_1"
5351   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5352         (unsigned_float:X87MODEF
5353           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5354    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5355    (clobber (match_scratch:SI 3 "=X,x"))]
5356   "!TARGET_64BIT
5357    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5358    && TARGET_SSE"
5359   "#"
5360   [(set_attr "type" "multi")
5361    (set_attr "mode" "<MODE>")])
5362
5363 (define_split
5364   [(set (match_operand:X87MODEF 0 "register_operand" "")
5365         (unsigned_float:X87MODEF
5366           (match_operand:SI 1 "register_operand" "")))
5367    (clobber (match_operand:DI 2 "memory_operand" ""))
5368    (clobber (match_scratch:SI 3 ""))]
5369   "!TARGET_64BIT
5370    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5371    && TARGET_SSE
5372    && reload_completed"
5373   [(set (match_dup 2) (match_dup 1))
5374    (set (match_dup 0)
5375         (float:X87MODEF (match_dup 2)))]
5376   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5377
5378 (define_split
5379   [(set (match_operand:X87MODEF 0 "register_operand" "")
5380         (unsigned_float:X87MODEF
5381           (match_operand:SI 1 "memory_operand" "")))
5382    (clobber (match_operand:DI 2 "memory_operand" ""))
5383    (clobber (match_scratch:SI 3 ""))]
5384   "!TARGET_64BIT
5385    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5386    && TARGET_SSE
5387    && reload_completed"
5388   [(set (match_dup 2) (match_dup 3))
5389    (set (match_dup 0)
5390         (float:X87MODEF (match_dup 2)))]
5391 {
5392   emit_move_insn (operands[3], operands[1]);
5393   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5394 })
5395
5396 (define_expand "floatunssi<mode>2"
5397   [(parallel
5398      [(set (match_operand:X87MODEF 0 "register_operand" "")
5399            (unsigned_float:X87MODEF
5400              (match_operand:SI 1 "nonimmediate_operand" "")))
5401       (clobber (match_dup 2))
5402       (clobber (match_scratch:SI 3 ""))])]
5403   "!TARGET_64BIT
5404    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5405         && TARGET_SSE)
5406        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5407 {
5408   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5409     {
5410       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5411       DONE;
5412     }
5413   else
5414     {
5415       enum ix86_stack_slot slot = (virtuals_instantiated
5416                                    ? SLOT_TEMP
5417                                    : SLOT_VIRTUAL);
5418       operands[2] = assign_386_stack_local (DImode, slot);
5419     }
5420 })
5421
5422 (define_expand "floatunsdisf2"
5423   [(use (match_operand:SF 0 "register_operand" ""))
5424    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5425   "TARGET_64BIT && TARGET_SSE_MATH"
5426   "x86_emit_floatuns (operands); DONE;")
5427
5428 (define_expand "floatunsdidf2"
5429   [(use (match_operand:DF 0 "register_operand" ""))
5430    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5431   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5432    && TARGET_SSE2 && TARGET_SSE_MATH"
5433 {
5434   if (TARGET_64BIT)
5435     x86_emit_floatuns (operands);
5436   else
5437     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5438   DONE;
5439 })
5440 \f
5441 ;; Add instructions
5442
5443 (define_expand "add<mode>3"
5444   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5445         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5446                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5447   ""
5448   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5449
5450 (define_insn_and_split "*add<dwi>3_doubleword"
5451   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5452         (plus:<DWI>
5453           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5454           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5455    (clobber (reg:CC FLAGS_REG))]
5456   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5457   "#"
5458   "reload_completed"
5459   [(parallel [(set (reg:CC FLAGS_REG)
5460                    (unspec:CC [(match_dup 1) (match_dup 2)]
5461                               UNSPEC_ADD_CARRY))
5462               (set (match_dup 0)
5463                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5464    (parallel [(set (match_dup 3)
5465                    (plus:DWIH
5466                      (match_dup 4)
5467                      (plus:DWIH
5468                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5469                        (match_dup 5))))
5470               (clobber (reg:CC FLAGS_REG))])]
5471   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5472
5473 (define_insn "*add<mode>3_cc"
5474   [(set (reg:CC FLAGS_REG)
5475         (unspec:CC
5476           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5477            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5478           UNSPEC_ADD_CARRY))
5479    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5480         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5481   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5482   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5483   [(set_attr "type" "alu")
5484    (set_attr "mode" "<MODE>")])
5485
5486 (define_insn "addqi3_cc"
5487   [(set (reg:CC FLAGS_REG)
5488         (unspec:CC
5489           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5490            (match_operand:QI 2 "general_operand" "qn,qm")]
5491           UNSPEC_ADD_CARRY))
5492    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5493         (plus:QI (match_dup 1) (match_dup 2)))]
5494   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5495   "add{b}\t{%2, %0|%0, %2}"
5496   [(set_attr "type" "alu")
5497    (set_attr "mode" "QI")])
5498
5499 (define_insn_and_split "*lea_1"
5500   [(set (match_operand:SI 0 "register_operand" "=r")
5501         (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
5502   "TARGET_64BIT"
5503   "lea{l}\t{%a1, %0|%0, %a1}"
5504   "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5505   [(const_int 0)]
5506 {
5507   ix86_split_lea_for_addr (operands, SImode);
5508   DONE;
5509 }
5510   [(set_attr "type" "lea")
5511    (set_attr "mode" "SI")])
5512
5513 (define_insn_and_split "*lea<mode>_2"
5514   [(set (match_operand:SWI48 0 "register_operand" "=r")
5515         (match_operand:SWI48 1 "lea_address_operand" "p"))]
5516   ""
5517   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5518   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5519   [(const_int 0)]
5520 {
5521   ix86_split_lea_for_addr (operands, <MODE>mode);
5522   DONE;
5523 }
5524   [(set_attr "type" "lea")
5525    (set_attr "mode" "<MODE>")])
5526
5527 (define_insn "*lea_3_zext"
5528   [(set (match_operand:DI 0 "register_operand" "=r")
5529         (zero_extend:DI
5530           (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0)))]
5531   "TARGET_64BIT"
5532   "lea{l}\t{%a1, %k0|%k0, %a1}"
5533   [(set_attr "type" "lea")
5534    (set_attr "mode" "SI")])
5535
5536 (define_insn "*lea_4_zext"
5537   [(set (match_operand:DI 0 "register_operand" "=r")
5538         (zero_extend:DI
5539           (match_operand:SI 1 "lea_address_operand" "p")))]
5540   "TARGET_64BIT"
5541   "lea{l}\t{%a1, %k0|%k0, %a1}"
5542   [(set_attr "type" "lea")
5543    (set_attr "mode" "SI")])
5544
5545 (define_insn "*lea_5_zext"
5546   [(set (match_operand:DI 0 "register_operand" "=r")
5547         (and:DI
5548           (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
5549           (match_operand:DI 2 "const_32bit_mask" "n")))]
5550   "TARGET_64BIT"
5551   "lea{l}\t{%a1, %k0|%k0, %a1}"
5552   [(set_attr "type" "lea")
5553    (set_attr "mode" "SI")])
5554
5555 (define_insn "*lea_6_zext"
5556   [(set (match_operand:DI 0 "register_operand" "=r")
5557         (and:DI
5558           (match_operand:DI 1 "lea_address_operand" "p")
5559           (match_operand:DI 2 "const_32bit_mask" "n")))]
5560   "TARGET_64BIT"
5561   "lea{l}\t{%a1, %k0|%k0, %a1}"
5562   [(set_attr "type" "lea")
5563    (set_attr "mode" "SI")])
5564
5565 (define_insn "*add<mode>_1"
5566   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5567         (plus:SWI48
5568           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5569           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5570    (clobber (reg:CC FLAGS_REG))]
5571   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5572 {
5573   switch (get_attr_type (insn))
5574     {
5575     case TYPE_LEA:
5576       return "#";
5577
5578     case TYPE_INCDEC:
5579       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5580       if (operands[2] == const1_rtx)
5581         return "inc{<imodesuffix>}\t%0";
5582       else
5583         {
5584           gcc_assert (operands[2] == constm1_rtx);
5585           return "dec{<imodesuffix>}\t%0";
5586         }
5587
5588     default:
5589       /* For most processors, ADD is faster than LEA.  This alternative
5590          was added to use ADD as much as possible.  */
5591       if (which_alternative == 2)
5592         {
5593           rtx tmp;
5594           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5595         }
5596         
5597       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5598       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5599         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5600
5601       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5602     }
5603 }
5604   [(set (attr "type")
5605      (cond [(eq_attr "alternative" "3")
5606               (const_string "lea")
5607             (match_operand:SWI48 2 "incdec_operand" "")
5608               (const_string "incdec")
5609            ]
5610            (const_string "alu")))
5611    (set (attr "length_immediate")
5612       (if_then_else
5613         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5614         (const_string "1")
5615         (const_string "*")))
5616    (set_attr "mode" "<MODE>")])
5617
5618 ;; It may seem that nonimmediate operand is proper one for operand 1.
5619 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5620 ;; we take care in ix86_binary_operator_ok to not allow two memory
5621 ;; operands so proper swapping will be done in reload.  This allow
5622 ;; patterns constructed from addsi_1 to match.
5623
5624 (define_insn "addsi_1_zext"
5625   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5626         (zero_extend:DI
5627           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5628                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5629    (clobber (reg:CC FLAGS_REG))]
5630   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5631 {
5632   switch (get_attr_type (insn))
5633     {
5634     case TYPE_LEA:
5635       return "#";
5636
5637     case TYPE_INCDEC:
5638       if (operands[2] == const1_rtx)
5639         return "inc{l}\t%k0";
5640       else
5641         {
5642           gcc_assert (operands[2] == constm1_rtx);
5643           return "dec{l}\t%k0";
5644         }
5645
5646     default:
5647       /* For most processors, ADD is faster than LEA.  This alternative
5648          was added to use ADD as much as possible.  */
5649       if (which_alternative == 1)
5650         {
5651           rtx tmp;
5652           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5653         }
5654
5655       if (x86_maybe_negate_const_int (&operands[2], SImode))
5656         return "sub{l}\t{%2, %k0|%k0, %2}";
5657
5658       return "add{l}\t{%2, %k0|%k0, %2}";
5659     }
5660 }
5661   [(set (attr "type")
5662      (cond [(eq_attr "alternative" "2")
5663               (const_string "lea")
5664             (match_operand:SI 2 "incdec_operand" "")
5665               (const_string "incdec")
5666            ]
5667            (const_string "alu")))
5668    (set (attr "length_immediate")
5669       (if_then_else
5670         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5671         (const_string "1")
5672         (const_string "*")))
5673    (set_attr "mode" "SI")])
5674
5675 (define_insn "*addhi_1"
5676   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5677         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5678                  (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5679    (clobber (reg:CC FLAGS_REG))]
5680   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5681 {
5682   switch (get_attr_type (insn))
5683     {
5684     case TYPE_LEA:
5685       return "#";
5686
5687     case TYPE_INCDEC:
5688       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5689       if (operands[2] == const1_rtx)
5690         return "inc{w}\t%0";
5691       else
5692         {
5693           gcc_assert (operands[2] == constm1_rtx);
5694           return "dec{w}\t%0";
5695         }
5696
5697     default:
5698       /* For most processors, ADD is faster than LEA.  This alternative
5699          was added to use ADD as much as possible.  */
5700       if (which_alternative == 2)
5701         {
5702           rtx tmp;
5703           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5704         }
5705
5706       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5707       if (x86_maybe_negate_const_int (&operands[2], HImode))
5708         return "sub{w}\t{%2, %0|%0, %2}";
5709
5710       return "add{w}\t{%2, %0|%0, %2}";
5711     }
5712 }
5713   [(set (attr "type")
5714      (cond [(eq_attr "alternative" "3")
5715               (const_string "lea")
5716             (match_operand:HI 2 "incdec_operand" "")
5717               (const_string "incdec")
5718            ]
5719            (const_string "alu")))
5720    (set (attr "length_immediate")
5721       (if_then_else
5722         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5723         (const_string "1")
5724         (const_string "*")))
5725    (set_attr "mode" "HI,HI,HI,SI")])
5726
5727 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5728 (define_insn "*addqi_1"
5729   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5730         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5731                  (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5732    (clobber (reg:CC FLAGS_REG))]
5733   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5734 {
5735   bool widen = (which_alternative == 3 || which_alternative == 4);
5736
5737   switch (get_attr_type (insn))
5738     {
5739     case TYPE_LEA:
5740       return "#";
5741
5742     case TYPE_INCDEC:
5743       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5744       if (operands[2] == const1_rtx)
5745         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5746       else
5747         {
5748           gcc_assert (operands[2] == constm1_rtx);
5749           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5750         }
5751
5752     default:
5753       /* For most processors, ADD is faster than LEA.  These alternatives
5754          were added to use ADD as much as possible.  */
5755       if (which_alternative == 2 || which_alternative == 4)
5756         {
5757           rtx tmp;
5758           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5759         }
5760
5761       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5762       if (x86_maybe_negate_const_int (&operands[2], QImode))
5763         {
5764           if (widen)
5765             return "sub{l}\t{%2, %k0|%k0, %2}";
5766           else
5767             return "sub{b}\t{%2, %0|%0, %2}";
5768         }
5769       if (widen)
5770         return "add{l}\t{%k2, %k0|%k0, %k2}";
5771       else
5772         return "add{b}\t{%2, %0|%0, %2}";
5773     }
5774 }
5775   [(set (attr "type")
5776      (cond [(eq_attr "alternative" "5")
5777               (const_string "lea")
5778             (match_operand:QI 2 "incdec_operand" "")
5779               (const_string "incdec")
5780            ]
5781            (const_string "alu")))
5782    (set (attr "length_immediate")
5783       (if_then_else
5784         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5785         (const_string "1")
5786         (const_string "*")))
5787    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5788
5789 (define_insn "*addqi_1_slp"
5790   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5791         (plus:QI (match_dup 0)
5792                  (match_operand:QI 1 "general_operand" "qn,qm")))
5793    (clobber (reg:CC FLAGS_REG))]
5794   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5795    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5796 {
5797   switch (get_attr_type (insn))
5798     {
5799     case TYPE_INCDEC:
5800       if (operands[1] == const1_rtx)
5801         return "inc{b}\t%0";
5802       else
5803         {
5804           gcc_assert (operands[1] == constm1_rtx);
5805           return "dec{b}\t%0";
5806         }
5807
5808     default:
5809       if (x86_maybe_negate_const_int (&operands[1], QImode))
5810         return "sub{b}\t{%1, %0|%0, %1}";
5811
5812       return "add{b}\t{%1, %0|%0, %1}";
5813     }
5814 }
5815   [(set (attr "type")
5816      (if_then_else (match_operand:QI 1 "incdec_operand" "")
5817         (const_string "incdec")
5818         (const_string "alu1")))
5819    (set (attr "memory")
5820      (if_then_else (match_operand 1 "memory_operand" "")
5821         (const_string "load")
5822         (const_string "none")))
5823    (set_attr "mode" "QI")])
5824
5825 ;; Split non destructive adds if we cannot use lea.
5826 (define_split
5827   [(set (match_operand:SWI48 0 "register_operand" "")
5828         (plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5829               (match_operand:SWI48 2 "nonmemory_operand" "")))
5830    (clobber (reg:CC FLAGS_REG))]
5831   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5832   [(set (match_dup 0) (match_dup 1))
5833    (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5834               (clobber (reg:CC FLAGS_REG))])])
5835
5836 ;; Convert add to the lea pattern to avoid flags dependency.
5837 (define_split
5838   [(set (match_operand:SWI 0 "register_operand" "")
5839         (plus:SWI (match_operand:SWI 1 "register_operand" "")
5840                   (match_operand:SWI 2 "<nonmemory_operand>" "")))
5841    (clobber (reg:CC FLAGS_REG))]
5842   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5843   [(const_int 0)]
5844 {
5845   enum machine_mode mode = <MODE>mode;
5846   rtx pat;
5847
5848   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5849     { 
5850       mode = SImode; 
5851       operands[0] = gen_lowpart (mode, operands[0]);
5852       operands[1] = gen_lowpart (mode, operands[1]);
5853       operands[2] = gen_lowpart (mode, operands[2]);
5854     }
5855
5856   pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5857
5858   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5859   DONE;
5860 })
5861
5862 ;; Convert add to the lea pattern to avoid flags dependency.
5863 (define_split
5864   [(set (match_operand:DI 0 "register_operand" "")
5865         (zero_extend:DI
5866           (plus:SI (match_operand:SI 1 "register_operand" "")
5867                    (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5868    (clobber (reg:CC FLAGS_REG))]
5869   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5870   [(set (match_dup 0)
5871         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5872
5873 (define_insn "*add<mode>_2"
5874   [(set (reg FLAGS_REG)
5875         (compare
5876           (plus:SWI
5877             (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5878             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5879           (const_int 0)))
5880    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5881         (plus:SWI (match_dup 1) (match_dup 2)))]
5882   "ix86_match_ccmode (insn, CCGOCmode)
5883    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5884 {
5885   switch (get_attr_type (insn))
5886     {
5887     case TYPE_INCDEC:
5888       if (operands[2] == const1_rtx)
5889         return "inc{<imodesuffix>}\t%0";
5890       else
5891         {
5892           gcc_assert (operands[2] == constm1_rtx);
5893           return "dec{<imodesuffix>}\t%0";
5894         }
5895
5896     default:
5897       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5898         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5899
5900       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5901     }
5902 }
5903   [(set (attr "type")
5904      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5905         (const_string "incdec")
5906         (const_string "alu")))
5907    (set (attr "length_immediate")
5908       (if_then_else
5909         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5910         (const_string "1")
5911         (const_string "*")))
5912    (set_attr "mode" "<MODE>")])
5913
5914 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5915 (define_insn "*addsi_2_zext"
5916   [(set (reg FLAGS_REG)
5917         (compare
5918           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5919                    (match_operand:SI 2 "x86_64_general_operand" "rme"))
5920           (const_int 0)))
5921    (set (match_operand:DI 0 "register_operand" "=r")
5922         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5923   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5924    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5925 {
5926   switch (get_attr_type (insn))
5927     {
5928     case TYPE_INCDEC:
5929       if (operands[2] == const1_rtx)
5930         return "inc{l}\t%k0";
5931       else
5932         {
5933           gcc_assert (operands[2] == constm1_rtx);
5934           return "dec{l}\t%k0";
5935         }
5936
5937     default:
5938       if (x86_maybe_negate_const_int (&operands[2], SImode))
5939         return "sub{l}\t{%2, %k0|%k0, %2}";
5940
5941       return "add{l}\t{%2, %k0|%k0, %2}";
5942     }
5943 }
5944   [(set (attr "type")
5945      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5946         (const_string "incdec")
5947         (const_string "alu")))
5948    (set (attr "length_immediate")
5949       (if_then_else
5950         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5951         (const_string "1")
5952         (const_string "*")))
5953    (set_attr "mode" "SI")])
5954
5955 (define_insn "*add<mode>_3"
5956   [(set (reg FLAGS_REG)
5957         (compare
5958           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5959           (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5960    (clobber (match_scratch:SWI 0 "=<r>"))]
5961   "ix86_match_ccmode (insn, CCZmode)
5962    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5963 {
5964   switch (get_attr_type (insn))
5965     {
5966     case TYPE_INCDEC:
5967       if (operands[2] == const1_rtx)
5968         return "inc{<imodesuffix>}\t%0";
5969       else
5970         {
5971           gcc_assert (operands[2] == constm1_rtx);
5972           return "dec{<imodesuffix>}\t%0";
5973         }
5974
5975     default:
5976       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5977         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5978
5979       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5980     }
5981 }
5982   [(set (attr "type")
5983      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5984         (const_string "incdec")
5985         (const_string "alu")))
5986    (set (attr "length_immediate")
5987       (if_then_else
5988         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5989         (const_string "1")
5990         (const_string "*")))
5991    (set_attr "mode" "<MODE>")])
5992
5993 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5994 (define_insn "*addsi_3_zext"
5995   [(set (reg FLAGS_REG)
5996         (compare
5997           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme"))
5998           (match_operand:SI 1 "nonimmediate_operand" "%0")))
5999    (set (match_operand:DI 0 "register_operand" "=r")
6000         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6001   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6002    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6003 {
6004   switch (get_attr_type (insn))
6005     {
6006     case TYPE_INCDEC:
6007       if (operands[2] == const1_rtx)
6008         return "inc{l}\t%k0";
6009       else
6010         {
6011           gcc_assert (operands[2] == constm1_rtx);
6012           return "dec{l}\t%k0";
6013         }
6014
6015     default:
6016       if (x86_maybe_negate_const_int (&operands[2], SImode))
6017         return "sub{l}\t{%2, %k0|%k0, %2}";
6018
6019       return "add{l}\t{%2, %k0|%k0, %2}";
6020     }
6021 }
6022   [(set (attr "type")
6023      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6024         (const_string "incdec")
6025         (const_string "alu")))
6026    (set (attr "length_immediate")
6027       (if_then_else
6028         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6029         (const_string "1")
6030         (const_string "*")))
6031    (set_attr "mode" "SI")])
6032
6033 ; For comparisons against 1, -1 and 128, we may generate better code
6034 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6035 ; is matched then.  We can't accept general immediate, because for
6036 ; case of overflows,  the result is messed up.
6037 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6038 ; only for comparisons not depending on it.
6039
6040 (define_insn "*adddi_4"
6041   [(set (reg FLAGS_REG)
6042         (compare
6043           (match_operand:DI 1 "nonimmediate_operand" "0")
6044           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6045    (clobber (match_scratch:DI 0 "=rm"))]
6046   "TARGET_64BIT
6047    && ix86_match_ccmode (insn, CCGCmode)"
6048 {
6049   switch (get_attr_type (insn))
6050     {
6051     case TYPE_INCDEC:
6052       if (operands[2] == constm1_rtx)
6053         return "inc{q}\t%0";
6054       else
6055         {
6056           gcc_assert (operands[2] == const1_rtx);
6057           return "dec{q}\t%0";
6058         }
6059
6060     default:
6061       if (x86_maybe_negate_const_int (&operands[2], DImode))
6062         return "add{q}\t{%2, %0|%0, %2}";
6063
6064       return "sub{q}\t{%2, %0|%0, %2}";
6065     }
6066 }
6067   [(set (attr "type")
6068      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6069         (const_string "incdec")
6070         (const_string "alu")))
6071    (set (attr "length_immediate")
6072       (if_then_else
6073         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6074         (const_string "1")
6075         (const_string "*")))
6076    (set_attr "mode" "DI")])
6077
6078 ; For comparisons against 1, -1 and 128, we may generate better code
6079 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6080 ; is matched then.  We can't accept general immediate, because for
6081 ; case of overflows,  the result is messed up.
6082 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6083 ; only for comparisons not depending on it.
6084
6085 (define_insn "*add<mode>_4"
6086   [(set (reg FLAGS_REG)
6087         (compare
6088           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6089           (match_operand:SWI124 2 "const_int_operand" "n")))
6090    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6091   "ix86_match_ccmode (insn, CCGCmode)"
6092 {
6093   switch (get_attr_type (insn))
6094     {
6095     case TYPE_INCDEC:
6096       if (operands[2] == constm1_rtx)
6097         return "inc{<imodesuffix>}\t%0";
6098       else
6099         {
6100           gcc_assert (operands[2] == const1_rtx);
6101           return "dec{<imodesuffix>}\t%0";
6102         }
6103
6104     default:
6105       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6106         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6107
6108       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6109     }
6110 }
6111   [(set (attr "type")
6112      (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6113         (const_string "incdec")
6114         (const_string "alu")))
6115    (set (attr "length_immediate")
6116       (if_then_else
6117         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6118         (const_string "1")
6119         (const_string "*")))
6120    (set_attr "mode" "<MODE>")])
6121
6122 (define_insn "*add<mode>_5"
6123   [(set (reg FLAGS_REG)
6124         (compare
6125           (plus:SWI
6126             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6127             (match_operand:SWI 2 "<general_operand>" "<g>"))
6128           (const_int 0)))
6129    (clobber (match_scratch:SWI 0 "=<r>"))]
6130   "ix86_match_ccmode (insn, CCGOCmode)
6131    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6132 {
6133   switch (get_attr_type (insn))
6134     {
6135     case TYPE_INCDEC:
6136       if (operands[2] == const1_rtx)
6137         return "inc{<imodesuffix>}\t%0";
6138       else
6139         {
6140           gcc_assert (operands[2] == constm1_rtx);
6141           return "dec{<imodesuffix>}\t%0";
6142         }
6143
6144     default:
6145       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6146         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6147
6148       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6149     }
6150 }
6151   [(set (attr "type")
6152      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6153         (const_string "incdec")
6154         (const_string "alu")))
6155    (set (attr "length_immediate")
6156       (if_then_else
6157         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6158         (const_string "1")
6159         (const_string "*")))
6160    (set_attr "mode" "<MODE>")])
6161
6162 (define_insn "*addqi_ext_1_rex64"
6163   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6164                          (const_int 8)
6165                          (const_int 8))
6166         (plus:SI
6167           (zero_extract:SI
6168             (match_operand 1 "ext_register_operand" "0")
6169             (const_int 8)
6170             (const_int 8))
6171           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6172    (clobber (reg:CC FLAGS_REG))]
6173   "TARGET_64BIT"
6174 {
6175   switch (get_attr_type (insn))
6176     {
6177     case TYPE_INCDEC:
6178       if (operands[2] == const1_rtx)
6179         return "inc{b}\t%h0";
6180       else
6181         {
6182           gcc_assert (operands[2] == constm1_rtx);
6183           return "dec{b}\t%h0";
6184         }
6185
6186     default:
6187       return "add{b}\t{%2, %h0|%h0, %2}";
6188     }
6189 }
6190   [(set (attr "type")
6191      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6192         (const_string "incdec")
6193         (const_string "alu")))
6194    (set_attr "modrm" "1")
6195    (set_attr "mode" "QI")])
6196
6197 (define_insn "addqi_ext_1"
6198   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6199                          (const_int 8)
6200                          (const_int 8))
6201         (plus:SI
6202           (zero_extract:SI
6203             (match_operand 1 "ext_register_operand" "0")
6204             (const_int 8)
6205             (const_int 8))
6206           (match_operand:QI 2 "general_operand" "Qmn")))
6207    (clobber (reg:CC FLAGS_REG))]
6208   "!TARGET_64BIT"
6209 {
6210   switch (get_attr_type (insn))
6211     {
6212     case TYPE_INCDEC:
6213       if (operands[2] == const1_rtx)
6214         return "inc{b}\t%h0";
6215       else
6216         {
6217           gcc_assert (operands[2] == constm1_rtx);
6218           return "dec{b}\t%h0";
6219         }
6220
6221     default:
6222       return "add{b}\t{%2, %h0|%h0, %2}";
6223     }
6224 }
6225   [(set (attr "type")
6226      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6227         (const_string "incdec")
6228         (const_string "alu")))
6229    (set_attr "modrm" "1")
6230    (set_attr "mode" "QI")])
6231
6232 (define_insn "*addqi_ext_2"
6233   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6234                          (const_int 8)
6235                          (const_int 8))
6236         (plus:SI
6237           (zero_extract:SI
6238             (match_operand 1 "ext_register_operand" "%0")
6239             (const_int 8)
6240             (const_int 8))
6241           (zero_extract:SI
6242             (match_operand 2 "ext_register_operand" "Q")
6243             (const_int 8)
6244             (const_int 8))))
6245    (clobber (reg:CC FLAGS_REG))]
6246   ""
6247   "add{b}\t{%h2, %h0|%h0, %h2}"
6248   [(set_attr "type" "alu")
6249    (set_attr "mode" "QI")])
6250
6251 ;; The lea patterns for modes less than 32 bits need to be matched by
6252 ;; several insns converted to real lea by splitters.
6253
6254 (define_insn_and_split "*lea_general_1"
6255   [(set (match_operand 0 "register_operand" "=r")
6256         (plus (plus (match_operand 1 "index_register_operand" "l")
6257                     (match_operand 2 "register_operand" "r"))
6258               (match_operand 3 "immediate_operand" "i")))]
6259   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6260    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6261    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6262    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6263    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6264        || GET_MODE (operands[3]) == VOIDmode)"
6265   "#"
6266   "&& reload_completed"
6267   [(const_int 0)]
6268 {
6269   enum machine_mode mode = SImode;
6270   rtx pat;
6271
6272   operands[0] = gen_lowpart (mode, operands[0]);
6273   operands[1] = gen_lowpart (mode, operands[1]);
6274   operands[2] = gen_lowpart (mode, operands[2]);
6275   operands[3] = gen_lowpart (mode, operands[3]);
6276
6277   pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6278                       operands[3]);
6279
6280   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6281   DONE;
6282 }
6283   [(set_attr "type" "lea")
6284    (set_attr "mode" "SI")])
6285
6286 (define_insn_and_split "*lea_general_2"
6287   [(set (match_operand 0 "register_operand" "=r")
6288         (plus (mult (match_operand 1 "index_register_operand" "l")
6289                     (match_operand 2 "const248_operand" "n"))
6290               (match_operand 3 "nonmemory_operand" "ri")))]
6291   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6292    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6293    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6294    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6295        || GET_MODE (operands[3]) == VOIDmode)"
6296   "#"
6297   "&& reload_completed"
6298   [(const_int 0)]
6299 {
6300   enum machine_mode mode = SImode;
6301   rtx pat;
6302
6303   operands[0] = gen_lowpart (mode, operands[0]);
6304   operands[1] = gen_lowpart (mode, operands[1]);
6305   operands[3] = gen_lowpart (mode, operands[3]);
6306
6307   pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6308                       operands[3]);
6309
6310   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6311   DONE;
6312 }
6313   [(set_attr "type" "lea")
6314    (set_attr "mode" "SI")])
6315
6316 (define_insn_and_split "*lea_general_3"
6317   [(set (match_operand 0 "register_operand" "=r")
6318         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6319                           (match_operand 2 "const248_operand" "n"))
6320                     (match_operand 3 "register_operand" "r"))
6321               (match_operand 4 "immediate_operand" "i")))]
6322   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6323    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6324    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6325    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6326   "#"
6327   "&& reload_completed"
6328   [(const_int 0)]
6329 {
6330   enum machine_mode mode = SImode;
6331   rtx pat;
6332
6333   operands[0] = gen_lowpart (mode, operands[0]);
6334   operands[1] = gen_lowpart (mode, operands[1]);
6335   operands[3] = gen_lowpart (mode, operands[3]);
6336   operands[4] = gen_lowpart (mode, operands[4]);
6337
6338   pat = gen_rtx_PLUS (mode,
6339                       gen_rtx_PLUS (mode,
6340                                     gen_rtx_MULT (mode, operands[1],
6341                                                         operands[2]),
6342                                     operands[3]),
6343                       operands[4]);
6344
6345   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6346   DONE;
6347 }
6348   [(set_attr "type" "lea")
6349    (set_attr "mode" "SI")])
6350
6351 (define_insn_and_split "*lea_general_4"
6352   [(set (match_operand 0 "register_operand" "=r")
6353         (any_or (ashift
6354                   (match_operand 1 "index_register_operand" "l")
6355                   (match_operand 2 "const_int_operand" "n"))
6356                 (match_operand 3 "const_int_operand" "n")))]
6357   "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6358       && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6359     || GET_MODE (operands[0]) == SImode
6360     || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6361    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6362    && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6363    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6364        < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6365   "#"
6366   "&& reload_completed"
6367   [(const_int 0)]
6368 {
6369   enum machine_mode mode = GET_MODE (operands[0]);
6370   rtx pat;
6371
6372   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6373     { 
6374       mode = SImode; 
6375       operands[0] = gen_lowpart (mode, operands[0]);
6376       operands[1] = gen_lowpart (mode, operands[1]);
6377     }
6378
6379   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6380
6381   pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6382                        INTVAL (operands[3]));
6383
6384   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6385   DONE;
6386 }
6387   [(set_attr "type" "lea")
6388    (set (attr "mode")
6389       (if_then_else (match_operand:DI 0 "" "")
6390         (const_string "DI")
6391         (const_string "SI")))])
6392 \f
6393 ;; Subtract instructions
6394
6395 (define_expand "sub<mode>3"
6396   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6397         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6398                      (match_operand:SDWIM 2 "<general_operand>" "")))]
6399   ""
6400   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6401
6402 (define_insn_and_split "*sub<dwi>3_doubleword"
6403   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6404         (minus:<DWI>
6405           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6406           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6407    (clobber (reg:CC FLAGS_REG))]
6408   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6409   "#"
6410   "reload_completed"
6411   [(parallel [(set (reg:CC FLAGS_REG)
6412                    (compare:CC (match_dup 1) (match_dup 2)))
6413               (set (match_dup 0)
6414                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6415    (parallel [(set (match_dup 3)
6416                    (minus:DWIH
6417                      (match_dup 4)
6418                      (plus:DWIH
6419                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6420                        (match_dup 5))))
6421               (clobber (reg:CC FLAGS_REG))])]
6422   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6423
6424 (define_insn "*sub<mode>_1"
6425   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6426         (minus:SWI
6427           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6428           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6429    (clobber (reg:CC FLAGS_REG))]
6430   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6431   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6432   [(set_attr "type" "alu")
6433    (set_attr "mode" "<MODE>")])
6434
6435 (define_insn "*subsi_1_zext"
6436   [(set (match_operand:DI 0 "register_operand" "=r")
6437         (zero_extend:DI
6438           (minus:SI (match_operand:SI 1 "register_operand" "0")
6439                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6440    (clobber (reg:CC FLAGS_REG))]
6441   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6442   "sub{l}\t{%2, %k0|%k0, %2}"
6443   [(set_attr "type" "alu")
6444    (set_attr "mode" "SI")])
6445
6446 (define_insn "*subqi_1_slp"
6447   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6448         (minus:QI (match_dup 0)
6449                   (match_operand:QI 1 "general_operand" "qn,qm")))
6450    (clobber (reg:CC FLAGS_REG))]
6451   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6452    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6453   "sub{b}\t{%1, %0|%0, %1}"
6454   [(set_attr "type" "alu1")
6455    (set_attr "mode" "QI")])
6456
6457 (define_insn "*sub<mode>_2"
6458   [(set (reg FLAGS_REG)
6459         (compare
6460           (minus:SWI
6461             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6462             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6463           (const_int 0)))
6464    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6465         (minus:SWI (match_dup 1) (match_dup 2)))]
6466   "ix86_match_ccmode (insn, CCGOCmode)
6467    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6468   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6469   [(set_attr "type" "alu")
6470    (set_attr "mode" "<MODE>")])
6471
6472 (define_insn "*subsi_2_zext"
6473   [(set (reg FLAGS_REG)
6474         (compare
6475           (minus:SI (match_operand:SI 1 "register_operand" "0")
6476                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6477           (const_int 0)))
6478    (set (match_operand:DI 0 "register_operand" "=r")
6479         (zero_extend:DI
6480           (minus:SI (match_dup 1)
6481                     (match_dup 2))))]
6482   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6483    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6484   "sub{l}\t{%2, %k0|%k0, %2}"
6485   [(set_attr "type" "alu")
6486    (set_attr "mode" "SI")])
6487
6488 (define_insn "*sub<mode>_3"
6489   [(set (reg FLAGS_REG)
6490         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6491                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6492    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6493         (minus:SWI (match_dup 1) (match_dup 2)))]
6494   "ix86_match_ccmode (insn, CCmode)
6495    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6496   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6497   [(set_attr "type" "alu")
6498    (set_attr "mode" "<MODE>")])
6499
6500 (define_insn "*subsi_3_zext"
6501   [(set (reg FLAGS_REG)
6502         (compare (match_operand:SI 1 "register_operand" "0")
6503                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6504    (set (match_operand:DI 0 "register_operand" "=r")
6505         (zero_extend:DI
6506           (minus:SI (match_dup 1)
6507                     (match_dup 2))))]
6508   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6509    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6510   "sub{l}\t{%2, %1|%1, %2}"
6511   [(set_attr "type" "alu")
6512    (set_attr "mode" "SI")])
6513 \f
6514 ;; Add with carry and subtract with borrow
6515
6516 (define_expand "<plusminus_insn><mode>3_carry"
6517   [(parallel
6518     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6519           (plusminus:SWI
6520             (match_operand:SWI 1 "nonimmediate_operand" "")
6521             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6522                        [(match_operand 3 "flags_reg_operand" "")
6523                         (const_int 0)])
6524                       (match_operand:SWI 2 "<general_operand>" ""))))
6525      (clobber (reg:CC FLAGS_REG))])]
6526   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6527
6528 (define_insn "*<plusminus_insn><mode>3_carry"
6529   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6530         (plusminus:SWI
6531           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6532           (plus:SWI
6533             (match_operator 3 "ix86_carry_flag_operator"
6534              [(reg FLAGS_REG) (const_int 0)])
6535             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6536    (clobber (reg:CC FLAGS_REG))]
6537   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6538   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6539   [(set_attr "type" "alu")
6540    (set_attr "use_carry" "1")
6541    (set_attr "pent_pair" "pu")
6542    (set_attr "mode" "<MODE>")])
6543
6544 (define_insn "*addsi3_carry_zext"
6545   [(set (match_operand:DI 0 "register_operand" "=r")
6546         (zero_extend:DI
6547           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6548                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6549                              [(reg FLAGS_REG) (const_int 0)])
6550                             (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6551    (clobber (reg:CC FLAGS_REG))]
6552   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6553   "adc{l}\t{%2, %k0|%k0, %2}"
6554   [(set_attr "type" "alu")
6555    (set_attr "use_carry" "1")
6556    (set_attr "pent_pair" "pu")
6557    (set_attr "mode" "SI")])
6558
6559 (define_insn "*subsi3_carry_zext"
6560   [(set (match_operand:DI 0 "register_operand" "=r")
6561         (zero_extend:DI
6562           (minus:SI (match_operand:SI 1 "register_operand" "0")
6563                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6564                               [(reg FLAGS_REG) (const_int 0)])
6565                              (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6566    (clobber (reg:CC FLAGS_REG))]
6567   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6568   "sbb{l}\t{%2, %k0|%k0, %2}"
6569   [(set_attr "type" "alu")
6570    (set_attr "pent_pair" "pu")
6571    (set_attr "mode" "SI")])
6572 \f
6573 ;; Overflow setting add and subtract instructions
6574
6575 (define_insn "*add<mode>3_cconly_overflow"
6576   [(set (reg:CCC FLAGS_REG)
6577         (compare:CCC
6578           (plus:SWI
6579             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6580             (match_operand:SWI 2 "<general_operand>" "<g>"))
6581           (match_dup 1)))
6582    (clobber (match_scratch:SWI 0 "=<r>"))]
6583   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6584   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6585   [(set_attr "type" "alu")
6586    (set_attr "mode" "<MODE>")])
6587
6588 (define_insn "*sub<mode>3_cconly_overflow"
6589   [(set (reg:CCC FLAGS_REG)
6590         (compare:CCC
6591           (minus:SWI
6592             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6593             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6594           (match_dup 0)))]
6595   ""
6596   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6597   [(set_attr "type" "icmp")
6598    (set_attr "mode" "<MODE>")])
6599
6600 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6601   [(set (reg:CCC FLAGS_REG)
6602         (compare:CCC
6603             (plusminus:SWI
6604                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6605                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6606             (match_dup 1)))
6607    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6608         (plusminus:SWI (match_dup 1) (match_dup 2)))]
6609   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6610   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6611   [(set_attr "type" "alu")
6612    (set_attr "mode" "<MODE>")])
6613
6614 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6615   [(set (reg:CCC FLAGS_REG)
6616         (compare:CCC
6617           (plusminus:SI
6618             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6619             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6620           (match_dup 1)))
6621    (set (match_operand:DI 0 "register_operand" "=r")
6622         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6623   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6624   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6625   [(set_attr "type" "alu")
6626    (set_attr "mode" "SI")])
6627
6628 ;; The patterns that match these are at the end of this file.
6629
6630 (define_expand "<plusminus_insn>xf3"
6631   [(set (match_operand:XF 0 "register_operand" "")
6632         (plusminus:XF
6633           (match_operand:XF 1 "register_operand" "")
6634           (match_operand:XF 2 "register_operand" "")))]
6635   "TARGET_80387")
6636
6637 (define_expand "<plusminus_insn><mode>3"
6638   [(set (match_operand:MODEF 0 "register_operand" "")
6639         (plusminus:MODEF
6640           (match_operand:MODEF 1 "register_operand" "")
6641           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6642   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6643     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6644 \f
6645 ;; Multiply instructions
6646
6647 (define_expand "mul<mode>3"
6648   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6649                    (mult:SWIM248
6650                      (match_operand:SWIM248 1 "register_operand" "")
6651                      (match_operand:SWIM248 2 "<general_operand>" "")))
6652               (clobber (reg:CC FLAGS_REG))])])
6653
6654 (define_expand "mulqi3"
6655   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6656                    (mult:QI
6657                      (match_operand:QI 1 "register_operand" "")
6658                      (match_operand:QI 2 "nonimmediate_operand" "")))
6659               (clobber (reg:CC FLAGS_REG))])]
6660   "TARGET_QIMODE_MATH")
6661
6662 ;; On AMDFAM10
6663 ;; IMUL reg32/64, reg32/64, imm8        Direct
6664 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6665 ;; IMUL reg32/64, reg32/64, imm32       Direct
6666 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6667 ;; IMUL reg32/64, reg32/64              Direct
6668 ;; IMUL reg32/64, mem32/64              Direct
6669 ;;
6670 ;; On BDVER1, all above IMULs use DirectPath
6671
6672 (define_insn "*mul<mode>3_1"
6673   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6674         (mult:SWI48
6675           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6676           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6677    (clobber (reg:CC FLAGS_REG))]
6678   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6679   "@
6680    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6681    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6682    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6683   [(set_attr "type" "imul")
6684    (set_attr "prefix_0f" "0,0,1")
6685    (set (attr "athlon_decode")
6686         (cond [(eq_attr "cpu" "athlon")
6687                   (const_string "vector")
6688                (eq_attr "alternative" "1")
6689                   (const_string "vector")
6690                (and (eq_attr "alternative" "2")
6691                     (match_operand 1 "memory_operand" ""))
6692                   (const_string "vector")]
6693               (const_string "direct")))
6694    (set (attr "amdfam10_decode")
6695         (cond [(and (eq_attr "alternative" "0,1")
6696                     (match_operand 1 "memory_operand" ""))
6697                   (const_string "vector")]
6698               (const_string "direct")))
6699    (set_attr "bdver1_decode" "direct")
6700    (set_attr "mode" "<MODE>")])
6701
6702 (define_insn "*mulsi3_1_zext"
6703   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6704         (zero_extend:DI
6705           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6706                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6707    (clobber (reg:CC FLAGS_REG))]
6708   "TARGET_64BIT
6709    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6710   "@
6711    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6712    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6713    imul{l}\t{%2, %k0|%k0, %2}"
6714   [(set_attr "type" "imul")
6715    (set_attr "prefix_0f" "0,0,1")
6716    (set (attr "athlon_decode")
6717         (cond [(eq_attr "cpu" "athlon")
6718                   (const_string "vector")
6719                (eq_attr "alternative" "1")
6720                   (const_string "vector")
6721                (and (eq_attr "alternative" "2")
6722                     (match_operand 1 "memory_operand" ""))
6723                   (const_string "vector")]
6724               (const_string "direct")))
6725    (set (attr "amdfam10_decode")
6726         (cond [(and (eq_attr "alternative" "0,1")
6727                     (match_operand 1 "memory_operand" ""))
6728                   (const_string "vector")]
6729               (const_string "direct")))
6730    (set_attr "bdver1_decode" "direct")
6731    (set_attr "mode" "SI")])
6732
6733 ;; On AMDFAM10
6734 ;; IMUL reg16, reg16, imm8      VectorPath
6735 ;; IMUL reg16, mem16, imm8      VectorPath
6736 ;; IMUL reg16, reg16, imm16     VectorPath
6737 ;; IMUL reg16, mem16, imm16     VectorPath
6738 ;; IMUL reg16, reg16            Direct
6739 ;; IMUL reg16, mem16            Direct
6740 ;;
6741 ;; On BDVER1, all HI MULs use DoublePath
6742
6743 (define_insn "*mulhi3_1"
6744   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6745         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6746                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6747    (clobber (reg:CC FLAGS_REG))]
6748   "TARGET_HIMODE_MATH
6749    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6750   "@
6751    imul{w}\t{%2, %1, %0|%0, %1, %2}
6752    imul{w}\t{%2, %1, %0|%0, %1, %2}
6753    imul{w}\t{%2, %0|%0, %2}"
6754   [(set_attr "type" "imul")
6755    (set_attr "prefix_0f" "0,0,1")
6756    (set (attr "athlon_decode")
6757         (cond [(eq_attr "cpu" "athlon")
6758                   (const_string "vector")
6759                (eq_attr "alternative" "1,2")
6760                   (const_string "vector")]
6761               (const_string "direct")))
6762    (set (attr "amdfam10_decode")
6763         (cond [(eq_attr "alternative" "0,1")
6764                   (const_string "vector")]
6765               (const_string "direct")))
6766    (set_attr "bdver1_decode" "double")
6767    (set_attr "mode" "HI")])
6768
6769 ;;On AMDFAM10 and BDVER1
6770 ;; MUL reg8     Direct
6771 ;; MUL mem8     Direct
6772
6773 (define_insn "*mulqi3_1"
6774   [(set (match_operand:QI 0 "register_operand" "=a")
6775         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6776                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6777    (clobber (reg:CC FLAGS_REG))]
6778   "TARGET_QIMODE_MATH
6779    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6780   "mul{b}\t%2"
6781   [(set_attr "type" "imul")
6782    (set_attr "length_immediate" "0")
6783    (set (attr "athlon_decode")
6784      (if_then_else (eq_attr "cpu" "athlon")
6785         (const_string "vector")
6786         (const_string "direct")))
6787    (set_attr "amdfam10_decode" "direct")
6788    (set_attr "bdver1_decode" "direct")
6789    (set_attr "mode" "QI")])
6790
6791 (define_expand "<u>mul<mode><dwi>3"
6792   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6793                    (mult:<DWI>
6794                      (any_extend:<DWI>
6795                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
6796                      (any_extend:<DWI>
6797                        (match_operand:DWIH 2 "register_operand" ""))))
6798               (clobber (reg:CC FLAGS_REG))])])
6799
6800 (define_expand "<u>mulqihi3"
6801   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6802                    (mult:HI
6803                      (any_extend:HI
6804                        (match_operand:QI 1 "nonimmediate_operand" ""))
6805                      (any_extend:HI
6806                        (match_operand:QI 2 "register_operand" ""))))
6807               (clobber (reg:CC FLAGS_REG))])]
6808   "TARGET_QIMODE_MATH")
6809
6810 (define_insn "*bmi2_umulditi3_1"
6811   [(set (match_operand:DI 0 "register_operand" "=r")
6812         (mult:DI
6813           (match_operand:DI 2 "nonimmediate_operand" "%d")
6814           (match_operand:DI 3 "nonimmediate_operand" "rm")))
6815    (set (match_operand:DI 1 "register_operand" "=r")
6816         (truncate:DI
6817           (lshiftrt:TI
6818             (mult:TI (zero_extend:TI (match_dup 2))
6819                      (zero_extend:TI (match_dup 3)))
6820             (const_int 64))))]
6821   "TARGET_64BIT && TARGET_BMI2
6822    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6823   "mulx\t{%3, %0, %1|%1, %0, %3}"
6824   [(set_attr "type" "imulx")
6825    (set_attr "prefix" "vex")
6826    (set_attr "mode" "DI")])
6827
6828 (define_insn "*bmi2_umulsidi3_1"
6829   [(set (match_operand:SI 0 "register_operand" "=r")
6830         (mult:SI
6831           (match_operand:SI 2 "nonimmediate_operand" "%d")
6832           (match_operand:SI 3 "nonimmediate_operand" "rm")))
6833    (set (match_operand:SI 1 "register_operand" "=r")
6834         (truncate:SI
6835           (lshiftrt:DI
6836             (mult:DI (zero_extend:DI (match_dup 2))
6837                      (zero_extend:DI (match_dup 3)))
6838             (const_int 32))))]
6839   "!TARGET_64BIT && TARGET_BMI2
6840    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6841   "mulx\t{%3, %0, %1|%1, %0, %3}"
6842   [(set_attr "type" "imulx")
6843    (set_attr "prefix" "vex")
6844    (set_attr "mode" "SI")])
6845
6846 (define_insn "*umul<mode><dwi>3_1"
6847   [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6848         (mult:<DWI>
6849           (zero_extend:<DWI>
6850             (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6851           (zero_extend:<DWI>
6852             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6853    (clobber (reg:CC FLAGS_REG))]
6854   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6855   "@
6856    mul{<imodesuffix>}\t%2
6857    #"
6858   [(set_attr "isa" "*,bmi2")
6859    (set_attr "type" "imul,imulx")
6860    (set_attr "length_immediate" "0,*")
6861    (set (attr "athlon_decode")
6862         (cond [(eq_attr "alternative" "0")
6863                  (if_then_else (eq_attr "cpu" "athlon")
6864                    (const_string "vector")
6865                    (const_string "double"))]
6866               (const_string "*")))
6867    (set_attr "amdfam10_decode" "double,*")
6868    (set_attr "bdver1_decode" "direct,*")
6869    (set_attr "prefix" "orig,vex")
6870    (set_attr "mode" "<MODE>")])
6871
6872 ;; Convert mul to the mulx pattern to avoid flags dependency.
6873 (define_split
6874  [(set (match_operand:<DWI> 0 "register_operand" "")
6875        (mult:<DWI>
6876          (zero_extend:<DWI>
6877            (match_operand:DWIH 1 "register_operand" ""))
6878          (zero_extend:<DWI>
6879            (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6880   (clobber (reg:CC FLAGS_REG))]
6881  "TARGET_BMI2 && reload_completed
6882   && true_regnum (operands[1]) == DX_REG"
6883   [(parallel [(set (match_dup 3)
6884                    (mult:DWIH (match_dup 1) (match_dup 2)))
6885               (set (match_dup 4)
6886                    (truncate:DWIH
6887                      (lshiftrt:<DWI>
6888                        (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6889                                    (zero_extend:<DWI> (match_dup 2)))
6890                        (match_dup 5))))])]
6891 {
6892   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6893
6894   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6895 })
6896
6897 (define_insn "*mul<mode><dwi>3_1"
6898   [(set (match_operand:<DWI> 0 "register_operand" "=A")
6899         (mult:<DWI>
6900           (sign_extend:<DWI>
6901             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6902           (sign_extend:<DWI>
6903             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6904    (clobber (reg:CC FLAGS_REG))]
6905   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6906   "imul{<imodesuffix>}\t%2"
6907   [(set_attr "type" "imul")
6908    (set_attr "length_immediate" "0")
6909    (set (attr "athlon_decode")
6910      (if_then_else (eq_attr "cpu" "athlon")
6911         (const_string "vector")
6912         (const_string "double")))
6913    (set_attr "amdfam10_decode" "double")
6914    (set_attr "bdver1_decode" "direct")
6915    (set_attr "mode" "<MODE>")])
6916
6917 (define_insn "*<u>mulqihi3_1"
6918   [(set (match_operand:HI 0 "register_operand" "=a")
6919         (mult:HI
6920           (any_extend:HI
6921             (match_operand:QI 1 "nonimmediate_operand" "%0"))
6922           (any_extend:HI
6923             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6924    (clobber (reg:CC FLAGS_REG))]
6925   "TARGET_QIMODE_MATH
6926    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6927   "<sgnprefix>mul{b}\t%2"
6928   [(set_attr "type" "imul")
6929    (set_attr "length_immediate" "0")
6930    (set (attr "athlon_decode")
6931      (if_then_else (eq_attr "cpu" "athlon")
6932         (const_string "vector")
6933         (const_string "direct")))
6934    (set_attr "amdfam10_decode" "direct")
6935    (set_attr "bdver1_decode" "direct")
6936    (set_attr "mode" "QI")])
6937
6938 (define_expand "<s>mul<mode>3_highpart"
6939   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6940                    (truncate:SWI48
6941                      (lshiftrt:<DWI>
6942                        (mult:<DWI>
6943                          (any_extend:<DWI>
6944                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
6945                          (any_extend:<DWI>
6946                            (match_operand:SWI48 2 "register_operand" "")))
6947                        (match_dup 4))))
6948               (clobber (match_scratch:SWI48 3 ""))
6949               (clobber (reg:CC FLAGS_REG))])]
6950   ""
6951   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6952
6953 (define_insn "*<s>muldi3_highpart_1"
6954   [(set (match_operand:DI 0 "register_operand" "=d")
6955         (truncate:DI
6956           (lshiftrt:TI
6957             (mult:TI
6958               (any_extend:TI
6959                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6960               (any_extend:TI
6961                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6962             (const_int 64))))
6963    (clobber (match_scratch:DI 3 "=1"))
6964    (clobber (reg:CC FLAGS_REG))]
6965   "TARGET_64BIT
6966    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6967   "<sgnprefix>mul{q}\t%2"
6968   [(set_attr "type" "imul")
6969    (set_attr "length_immediate" "0")
6970    (set (attr "athlon_decode")
6971      (if_then_else (eq_attr "cpu" "athlon")
6972         (const_string "vector")
6973         (const_string "double")))
6974    (set_attr "amdfam10_decode" "double")
6975    (set_attr "bdver1_decode" "direct")
6976    (set_attr "mode" "DI")])
6977
6978 (define_insn "*<s>mulsi3_highpart_1"
6979   [(set (match_operand:SI 0 "register_operand" "=d")
6980         (truncate:SI
6981           (lshiftrt:DI
6982             (mult:DI
6983               (any_extend:DI
6984                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6985               (any_extend:DI
6986                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6987             (const_int 32))))
6988    (clobber (match_scratch:SI 3 "=1"))
6989    (clobber (reg:CC FLAGS_REG))]
6990   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6991   "<sgnprefix>mul{l}\t%2"
6992   [(set_attr "type" "imul")
6993    (set_attr "length_immediate" "0")
6994    (set (attr "athlon_decode")
6995      (if_then_else (eq_attr "cpu" "athlon")
6996         (const_string "vector")
6997         (const_string "double")))
6998    (set_attr "amdfam10_decode" "double")
6999    (set_attr "bdver1_decode" "direct")
7000    (set_attr "mode" "SI")])
7001
7002 (define_insn "*<s>mulsi3_highpart_zext"
7003   [(set (match_operand:DI 0 "register_operand" "=d")
7004         (zero_extend:DI (truncate:SI
7005           (lshiftrt:DI
7006             (mult:DI (any_extend:DI
7007                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7008                      (any_extend:DI
7009                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7010             (const_int 32)))))
7011    (clobber (match_scratch:SI 3 "=1"))
7012    (clobber (reg:CC FLAGS_REG))]
7013   "TARGET_64BIT
7014    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7015   "<sgnprefix>mul{l}\t%2"
7016   [(set_attr "type" "imul")
7017    (set_attr "length_immediate" "0")
7018    (set (attr "athlon_decode")
7019      (if_then_else (eq_attr "cpu" "athlon")
7020         (const_string "vector")
7021         (const_string "double")))
7022    (set_attr "amdfam10_decode" "double")
7023    (set_attr "bdver1_decode" "direct")
7024    (set_attr "mode" "SI")])
7025
7026 ;; The patterns that match these are at the end of this file.
7027
7028 (define_expand "mulxf3"
7029   [(set (match_operand:XF 0 "register_operand" "")
7030         (mult:XF (match_operand:XF 1 "register_operand" "")
7031                  (match_operand:XF 2 "register_operand" "")))]
7032   "TARGET_80387")
7033
7034 (define_expand "mul<mode>3"
7035   [(set (match_operand:MODEF 0 "register_operand" "")
7036         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7037                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7038   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7039     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7040 \f
7041 ;; Divide instructions
7042
7043 ;; The patterns that match these are at the end of this file.
7044
7045 (define_expand "divxf3"
7046   [(set (match_operand:XF 0 "register_operand" "")
7047         (div:XF (match_operand:XF 1 "register_operand" "")
7048                 (match_operand:XF 2 "register_operand" "")))]
7049   "TARGET_80387")
7050
7051 (define_expand "divdf3"
7052   [(set (match_operand:DF 0 "register_operand" "")
7053         (div:DF (match_operand:DF 1 "register_operand" "")
7054                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7055    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7056     || (TARGET_SSE2 && TARGET_SSE_MATH)")
7057
7058 (define_expand "divsf3"
7059   [(set (match_operand:SF 0 "register_operand" "")
7060         (div:SF (match_operand:SF 1 "register_operand" "")
7061                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7062   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7063     || TARGET_SSE_MATH"
7064 {
7065   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7066       && flag_finite_math_only && !flag_trapping_math
7067       && flag_unsafe_math_optimizations)
7068     {
7069       ix86_emit_swdivsf (operands[0], operands[1],
7070                          operands[2], SFmode);
7071       DONE;
7072     }
7073 })
7074 \f
7075 ;; Divmod instructions.
7076
7077 (define_expand "divmod<mode>4"
7078   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7079                    (div:SWIM248
7080                      (match_operand:SWIM248 1 "register_operand" "")
7081                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7082               (set (match_operand:SWIM248 3 "register_operand" "")
7083                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7084               (clobber (reg:CC FLAGS_REG))])])
7085
7086 ;; Split with 8bit unsigned divide:
7087 ;;      if (dividend an divisor are in [0-255])
7088 ;;         use 8bit unsigned integer divide
7089 ;;       else
7090 ;;         use original integer divide
7091 (define_split
7092   [(set (match_operand:SWI48 0 "register_operand" "")
7093         (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7094                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7095    (set (match_operand:SWI48 1 "register_operand" "")
7096         (mod:SWI48 (match_dup 2) (match_dup 3)))
7097    (clobber (reg:CC FLAGS_REG))]
7098   "TARGET_USE_8BIT_IDIV
7099    && TARGET_QIMODE_MATH
7100    && can_create_pseudo_p ()
7101    && !optimize_insn_for_size_p ()"
7102   [(const_int 0)]
7103   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7104
7105 (define_insn_and_split "divmod<mode>4_1"
7106   [(set (match_operand:SWI48 0 "register_operand" "=a")
7107         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7108                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7109    (set (match_operand:SWI48 1 "register_operand" "=&d")
7110         (mod:SWI48 (match_dup 2) (match_dup 3)))
7111    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7112    (clobber (reg:CC FLAGS_REG))]
7113   ""
7114   "#"
7115   "reload_completed"
7116   [(parallel [(set (match_dup 1)
7117                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7118               (clobber (reg:CC FLAGS_REG))])
7119    (parallel [(set (match_dup 0)
7120                    (div:SWI48 (match_dup 2) (match_dup 3)))
7121               (set (match_dup 1)
7122                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7123               (use (match_dup 1))
7124               (clobber (reg:CC FLAGS_REG))])]
7125 {
7126   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7127
7128   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7129     operands[4] = operands[2];
7130   else
7131     {
7132       /* Avoid use of cltd in favor of a mov+shift.  */
7133       emit_move_insn (operands[1], operands[2]);
7134       operands[4] = operands[1];
7135     }
7136 }
7137   [(set_attr "type" "multi")
7138    (set_attr "mode" "<MODE>")])
7139
7140 (define_insn_and_split "*divmod<mode>4"
7141   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7142         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7143                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7144    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7145         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7146    (clobber (reg:CC FLAGS_REG))]
7147   ""
7148   "#"
7149   "reload_completed"
7150   [(parallel [(set (match_dup 1)
7151                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7152               (clobber (reg:CC FLAGS_REG))])
7153    (parallel [(set (match_dup 0)
7154                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7155               (set (match_dup 1)
7156                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7157               (use (match_dup 1))
7158               (clobber (reg:CC FLAGS_REG))])]
7159 {
7160   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7161
7162   if (<MODE>mode != HImode
7163       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7164     operands[4] = operands[2];
7165   else
7166     {
7167       /* Avoid use of cltd in favor of a mov+shift.  */
7168       emit_move_insn (operands[1], operands[2]);
7169       operands[4] = operands[1];
7170     }
7171 }
7172   [(set_attr "type" "multi")
7173    (set_attr "mode" "<MODE>")])
7174
7175 (define_insn "*divmod<mode>4_noext"
7176   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7177         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7178                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7179    (set (match_operand:SWIM248 1 "register_operand" "=d")
7180         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7181    (use (match_operand:SWIM248 4 "register_operand" "1"))
7182    (clobber (reg:CC FLAGS_REG))]
7183   ""
7184   "idiv{<imodesuffix>}\t%3"
7185   [(set_attr "type" "idiv")
7186    (set_attr "mode" "<MODE>")])
7187
7188 (define_expand "divmodqi4"
7189   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7190                    (div:QI
7191                      (match_operand:QI 1 "register_operand" "")
7192                      (match_operand:QI 2 "nonimmediate_operand" "")))
7193               (set (match_operand:QI 3 "register_operand" "")
7194                    (mod:QI (match_dup 1) (match_dup 2)))
7195               (clobber (reg:CC FLAGS_REG))])]
7196   "TARGET_QIMODE_MATH"
7197 {
7198   rtx div, mod, insn;
7199   rtx tmp0, tmp1;
7200   
7201   tmp0 = gen_reg_rtx (HImode);
7202   tmp1 = gen_reg_rtx (HImode);
7203
7204   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7205      in AX.  */
7206   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7207   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7208
7209   /* Extract remainder from AH.  */
7210   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7211   insn = emit_move_insn (operands[3], tmp1);
7212
7213   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7214   set_unique_reg_note (insn, REG_EQUAL, mod);
7215
7216   /* Extract quotient from AL.  */
7217   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7218
7219   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7220   set_unique_reg_note (insn, REG_EQUAL, div);
7221
7222   DONE;
7223 })
7224
7225 ;; Divide AX by r/m8, with result stored in
7226 ;; AL <- Quotient
7227 ;; AH <- Remainder
7228 ;; Change div/mod to HImode and extend the second argument to HImode
7229 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7230 ;; combine may fail.
7231 (define_insn "divmodhiqi3"
7232   [(set (match_operand:HI 0 "register_operand" "=a")
7233         (ior:HI
7234           (ashift:HI
7235             (zero_extend:HI
7236               (truncate:QI
7237                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7238                         (sign_extend:HI
7239                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7240             (const_int 8))
7241           (zero_extend:HI
7242             (truncate:QI
7243               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7244    (clobber (reg:CC FLAGS_REG))]
7245   "TARGET_QIMODE_MATH"
7246   "idiv{b}\t%2"
7247   [(set_attr "type" "idiv")
7248    (set_attr "mode" "QI")])
7249
7250 (define_expand "udivmod<mode>4"
7251   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7252                    (udiv:SWIM248
7253                      (match_operand:SWIM248 1 "register_operand" "")
7254                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7255               (set (match_operand:SWIM248 3 "register_operand" "")
7256                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7257               (clobber (reg:CC FLAGS_REG))])])
7258
7259 ;; Split with 8bit unsigned divide:
7260 ;;      if (dividend an divisor are in [0-255])
7261 ;;         use 8bit unsigned integer divide
7262 ;;       else
7263 ;;         use original integer divide
7264 (define_split
7265   [(set (match_operand:SWI48 0 "register_operand" "")
7266         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7267                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7268    (set (match_operand:SWI48 1 "register_operand" "")
7269         (umod:SWI48 (match_dup 2) (match_dup 3)))
7270    (clobber (reg:CC FLAGS_REG))]
7271   "TARGET_USE_8BIT_IDIV
7272    && TARGET_QIMODE_MATH
7273    && can_create_pseudo_p ()
7274    && !optimize_insn_for_size_p ()"
7275   [(const_int 0)]
7276   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7277
7278 (define_insn_and_split "udivmod<mode>4_1"
7279   [(set (match_operand:SWI48 0 "register_operand" "=a")
7280         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7281                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7282    (set (match_operand:SWI48 1 "register_operand" "=&d")
7283         (umod:SWI48 (match_dup 2) (match_dup 3)))
7284    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7285    (clobber (reg:CC FLAGS_REG))]
7286   ""
7287   "#"
7288   "reload_completed"
7289   [(set (match_dup 1) (const_int 0))
7290    (parallel [(set (match_dup 0)
7291                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7292               (set (match_dup 1)
7293                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7294               (use (match_dup 1))
7295               (clobber (reg:CC FLAGS_REG))])]
7296   ""
7297   [(set_attr "type" "multi")
7298    (set_attr "mode" "<MODE>")])
7299
7300 (define_insn_and_split "*udivmod<mode>4"
7301   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7302         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7303                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7304    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7305         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7306    (clobber (reg:CC FLAGS_REG))]
7307   ""
7308   "#"
7309   "reload_completed"
7310   [(set (match_dup 1) (const_int 0))
7311    (parallel [(set (match_dup 0)
7312                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7313               (set (match_dup 1)
7314                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7315               (use (match_dup 1))
7316               (clobber (reg:CC FLAGS_REG))])]
7317   ""
7318   [(set_attr "type" "multi")
7319    (set_attr "mode" "<MODE>")])
7320
7321 (define_insn "*udivmod<mode>4_noext"
7322   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7323         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7324                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7325    (set (match_operand:SWIM248 1 "register_operand" "=d")
7326         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7327    (use (match_operand:SWIM248 4 "register_operand" "1"))
7328    (clobber (reg:CC FLAGS_REG))]
7329   ""
7330   "div{<imodesuffix>}\t%3"
7331   [(set_attr "type" "idiv")
7332    (set_attr "mode" "<MODE>")])
7333
7334 (define_expand "udivmodqi4"
7335   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7336                    (udiv:QI
7337                      (match_operand:QI 1 "register_operand" "")
7338                      (match_operand:QI 2 "nonimmediate_operand" "")))
7339               (set (match_operand:QI 3 "register_operand" "")
7340                    (umod:QI (match_dup 1) (match_dup 2)))
7341               (clobber (reg:CC FLAGS_REG))])]
7342   "TARGET_QIMODE_MATH"
7343 {
7344   rtx div, mod, insn;
7345   rtx tmp0, tmp1;
7346   
7347   tmp0 = gen_reg_rtx (HImode);
7348   tmp1 = gen_reg_rtx (HImode);
7349
7350   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7351      in AX.  */
7352   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7353   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7354
7355   /* Extract remainder from AH.  */
7356   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7357   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7358   insn = emit_move_insn (operands[3], tmp1);
7359
7360   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7361   set_unique_reg_note (insn, REG_EQUAL, mod);
7362
7363   /* Extract quotient from AL.  */
7364   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7365
7366   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7367   set_unique_reg_note (insn, REG_EQUAL, div);
7368
7369   DONE;
7370 })
7371
7372 (define_insn "udivmodhiqi3"
7373   [(set (match_operand:HI 0 "register_operand" "=a")
7374         (ior:HI
7375           (ashift:HI
7376             (zero_extend:HI
7377               (truncate:QI
7378                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7379                         (zero_extend:HI
7380                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7381             (const_int 8))
7382           (zero_extend:HI
7383             (truncate:QI
7384               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7385    (clobber (reg:CC FLAGS_REG))]
7386   "TARGET_QIMODE_MATH"
7387   "div{b}\t%2"
7388   [(set_attr "type" "idiv")
7389    (set_attr "mode" "QI")])
7390
7391 ;; We cannot use div/idiv for double division, because it causes
7392 ;; "division by zero" on the overflow and that's not what we expect
7393 ;; from truncate.  Because true (non truncating) double division is
7394 ;; never generated, we can't create this insn anyway.
7395 ;
7396 ;(define_insn ""
7397 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7398 ;       (truncate:SI
7399 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7400 ;                  (zero_extend:DI
7401 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7402 ;   (set (match_operand:SI 3 "register_operand" "=d")
7403 ;       (truncate:SI
7404 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7405 ;   (clobber (reg:CC FLAGS_REG))]
7406 ;  ""
7407 ;  "div{l}\t{%2, %0|%0, %2}"
7408 ;  [(set_attr "type" "idiv")])
7409 \f
7410 ;;- Logical AND instructions
7411
7412 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7413 ;; Note that this excludes ah.
7414
7415 (define_expand "testsi_ccno_1"
7416   [(set (reg:CCNO FLAGS_REG)
7417         (compare:CCNO
7418           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7419                   (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7420           (const_int 0)))])
7421
7422 (define_expand "testqi_ccz_1"
7423   [(set (reg:CCZ FLAGS_REG)
7424         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7425                              (match_operand:QI 1 "nonmemory_operand" ""))
7426                  (const_int 0)))])
7427
7428 (define_expand "testdi_ccno_1"
7429   [(set (reg:CCNO FLAGS_REG)
7430         (compare:CCNO
7431           (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7432                   (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7433           (const_int 0)))]
7434   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7435
7436 (define_insn "*testdi_1"
7437   [(set (reg FLAGS_REG)
7438         (compare
7439          (and:DI
7440           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7441           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7442          (const_int 0)))]
7443   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7444    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7445   "@
7446    test{l}\t{%k1, %k0|%k0, %k1}
7447    test{l}\t{%k1, %k0|%k0, %k1}
7448    test{q}\t{%1, %0|%0, %1}
7449    test{q}\t{%1, %0|%0, %1}
7450    test{q}\t{%1, %0|%0, %1}"
7451   [(set_attr "type" "test")
7452    (set_attr "modrm" "0,1,0,1,1")
7453    (set_attr "mode" "SI,SI,DI,DI,DI")])
7454
7455 (define_insn "*testqi_1_maybe_si"
7456   [(set (reg FLAGS_REG)
7457         (compare
7458           (and:QI
7459             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7460             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7461           (const_int 0)))]
7462    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7463     && ix86_match_ccmode (insn,
7464                          CONST_INT_P (operands[1])
7465                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7466 {
7467   if (which_alternative == 3)
7468     {
7469       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7470         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7471       return "test{l}\t{%1, %k0|%k0, %1}";
7472     }
7473   return "test{b}\t{%1, %0|%0, %1}";
7474 }
7475   [(set_attr "type" "test")
7476    (set_attr "modrm" "0,1,1,1")
7477    (set_attr "mode" "QI,QI,QI,SI")
7478    (set_attr "pent_pair" "uv,np,uv,np")])
7479
7480 (define_insn "*test<mode>_1"
7481   [(set (reg FLAGS_REG)
7482         (compare
7483          (and:SWI124
7484           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7485           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7486          (const_int 0)))]
7487   "ix86_match_ccmode (insn, CCNOmode)
7488    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7489   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7490   [(set_attr "type" "test")
7491    (set_attr "modrm" "0,1,1")
7492    (set_attr "mode" "<MODE>")
7493    (set_attr "pent_pair" "uv,np,uv")])
7494
7495 (define_expand "testqi_ext_ccno_0"
7496   [(set (reg:CCNO FLAGS_REG)
7497         (compare:CCNO
7498           (and:SI
7499             (zero_extract:SI
7500               (match_operand 0 "ext_register_operand" "")
7501               (const_int 8)
7502               (const_int 8))
7503             (match_operand 1 "const_int_operand" ""))
7504           (const_int 0)))])
7505
7506 (define_insn "*testqi_ext_0"
7507   [(set (reg FLAGS_REG)
7508         (compare
7509           (and:SI
7510             (zero_extract:SI
7511               (match_operand 0 "ext_register_operand" "Q")
7512               (const_int 8)
7513               (const_int 8))
7514             (match_operand 1 "const_int_operand" "n"))
7515           (const_int 0)))]
7516   "ix86_match_ccmode (insn, CCNOmode)"
7517   "test{b}\t{%1, %h0|%h0, %1}"
7518   [(set_attr "type" "test")
7519    (set_attr "mode" "QI")
7520    (set_attr "length_immediate" "1")
7521    (set_attr "modrm" "1")
7522    (set_attr "pent_pair" "np")])
7523
7524 (define_insn "*testqi_ext_1_rex64"
7525   [(set (reg FLAGS_REG)
7526         (compare
7527           (and:SI
7528             (zero_extract:SI
7529               (match_operand 0 "ext_register_operand" "Q")
7530               (const_int 8)
7531               (const_int 8))
7532             (zero_extend:SI
7533               (match_operand:QI 1 "register_operand" "Q")))
7534           (const_int 0)))]
7535   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7536   "test{b}\t{%1, %h0|%h0, %1}"
7537   [(set_attr "type" "test")
7538    (set_attr "mode" "QI")])
7539
7540 (define_insn "*testqi_ext_1"
7541   [(set (reg FLAGS_REG)
7542         (compare
7543           (and:SI
7544             (zero_extract:SI
7545               (match_operand 0 "ext_register_operand" "Q")
7546               (const_int 8)
7547               (const_int 8))
7548             (zero_extend:SI
7549               (match_operand:QI 1 "general_operand" "Qm")))
7550           (const_int 0)))]
7551   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7552   "test{b}\t{%1, %h0|%h0, %1}"
7553   [(set_attr "type" "test")
7554    (set_attr "mode" "QI")])
7555
7556 (define_insn "*testqi_ext_2"
7557   [(set (reg FLAGS_REG)
7558         (compare
7559           (and:SI
7560             (zero_extract:SI
7561               (match_operand 0 "ext_register_operand" "Q")
7562               (const_int 8)
7563               (const_int 8))
7564             (zero_extract:SI
7565               (match_operand 1 "ext_register_operand" "Q")
7566               (const_int 8)
7567               (const_int 8)))
7568           (const_int 0)))]
7569   "ix86_match_ccmode (insn, CCNOmode)"
7570   "test{b}\t{%h1, %h0|%h0, %h1}"
7571   [(set_attr "type" "test")
7572    (set_attr "mode" "QI")])
7573
7574 (define_insn "*testqi_ext_3_rex64"
7575   [(set (reg FLAGS_REG)
7576         (compare (zero_extract:DI
7577                    (match_operand 0 "nonimmediate_operand" "rm")
7578                    (match_operand:DI 1 "const_int_operand" "")
7579                    (match_operand:DI 2 "const_int_operand" ""))
7580                  (const_int 0)))]
7581   "TARGET_64BIT
7582    && ix86_match_ccmode (insn, CCNOmode)
7583    && INTVAL (operands[1]) > 0
7584    && INTVAL (operands[2]) >= 0
7585    /* Ensure that resulting mask is zero or sign extended operand.  */
7586    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7587        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7588            && INTVAL (operands[1]) > 32))
7589    && (GET_MODE (operands[0]) == SImode
7590        || GET_MODE (operands[0]) == DImode
7591        || GET_MODE (operands[0]) == HImode
7592        || GET_MODE (operands[0]) == QImode)"
7593   "#")
7594
7595 ;; Combine likes to form bit extractions for some tests.  Humor it.
7596 (define_insn "*testqi_ext_3"
7597   [(set (reg FLAGS_REG)
7598         (compare (zero_extract:SI
7599                    (match_operand 0 "nonimmediate_operand" "rm")
7600                    (match_operand:SI 1 "const_int_operand" "")
7601                    (match_operand:SI 2 "const_int_operand" ""))
7602                  (const_int 0)))]
7603   "ix86_match_ccmode (insn, CCNOmode)
7604    && INTVAL (operands[1]) > 0
7605    && INTVAL (operands[2]) >= 0
7606    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7607    && (GET_MODE (operands[0]) == SImode
7608        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7609        || GET_MODE (operands[0]) == HImode
7610        || GET_MODE (operands[0]) == QImode)"
7611   "#")
7612
7613 (define_split
7614   [(set (match_operand 0 "flags_reg_operand" "")
7615         (match_operator 1 "compare_operator"
7616           [(zero_extract
7617              (match_operand 2 "nonimmediate_operand" "")
7618              (match_operand 3 "const_int_operand" "")
7619              (match_operand 4 "const_int_operand" ""))
7620            (const_int 0)]))]
7621   "ix86_match_ccmode (insn, CCNOmode)"
7622   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7623 {
7624   rtx val = operands[2];
7625   HOST_WIDE_INT len = INTVAL (operands[3]);
7626   HOST_WIDE_INT pos = INTVAL (operands[4]);
7627   HOST_WIDE_INT mask;
7628   enum machine_mode mode, submode;
7629
7630   mode = GET_MODE (val);
7631   if (MEM_P (val))
7632     {
7633       /* ??? Combine likes to put non-volatile mem extractions in QImode
7634          no matter the size of the test.  So find a mode that works.  */
7635       if (! MEM_VOLATILE_P (val))
7636         {
7637           mode = smallest_mode_for_size (pos + len, MODE_INT);
7638           val = adjust_address (val, mode, 0);
7639         }
7640     }
7641   else if (GET_CODE (val) == SUBREG
7642            && (submode = GET_MODE (SUBREG_REG (val)),
7643                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7644            && pos + len <= GET_MODE_BITSIZE (submode)
7645            && GET_MODE_CLASS (submode) == MODE_INT)
7646     {
7647       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7648       mode = submode;
7649       val = SUBREG_REG (val);
7650     }
7651   else if (mode == HImode && pos + len <= 8)
7652     {
7653       /* Small HImode tests can be converted to QImode.  */
7654       mode = QImode;
7655       val = gen_lowpart (QImode, val);
7656     }
7657
7658   if (len == HOST_BITS_PER_WIDE_INT)
7659     mask = -1;
7660   else
7661     mask = ((HOST_WIDE_INT)1 << len) - 1;
7662   mask <<= pos;
7663
7664   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7665 })
7666
7667 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7668 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7669 ;; this is relatively important trick.
7670 ;; Do the conversion only post-reload to avoid limiting of the register class
7671 ;; to QI regs.
7672 (define_split
7673   [(set (match_operand 0 "flags_reg_operand" "")
7674         (match_operator 1 "compare_operator"
7675           [(and (match_operand 2 "register_operand" "")
7676                 (match_operand 3 "const_int_operand" ""))
7677            (const_int 0)]))]
7678    "reload_completed
7679     && QI_REG_P (operands[2])
7680     && GET_MODE (operands[2]) != QImode
7681     && ((ix86_match_ccmode (insn, CCZmode)
7682          && !(INTVAL (operands[3]) & ~(255 << 8)))
7683         || (ix86_match_ccmode (insn, CCNOmode)
7684             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7685   [(set (match_dup 0)
7686         (match_op_dup 1
7687           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7688                    (match_dup 3))
7689            (const_int 0)]))]
7690   "operands[2] = gen_lowpart (SImode, operands[2]);
7691    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7692
7693 (define_split
7694   [(set (match_operand 0 "flags_reg_operand" "")
7695         (match_operator 1 "compare_operator"
7696           [(and (match_operand 2 "nonimmediate_operand" "")
7697                 (match_operand 3 "const_int_operand" ""))
7698            (const_int 0)]))]
7699    "reload_completed
7700     && GET_MODE (operands[2]) != QImode
7701     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7702     && ((ix86_match_ccmode (insn, CCZmode)
7703          && !(INTVAL (operands[3]) & ~255))
7704         || (ix86_match_ccmode (insn, CCNOmode)
7705             && !(INTVAL (operands[3]) & ~127)))"
7706   [(set (match_dup 0)
7707         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7708                          (const_int 0)]))]
7709   "operands[2] = gen_lowpart (QImode, operands[2]);
7710    operands[3] = gen_lowpart (QImode, operands[3]);")
7711
7712 ;; %%% This used to optimize known byte-wide and operations to memory,
7713 ;; and sometimes to QImode registers.  If this is considered useful,
7714 ;; it should be done with splitters.
7715
7716 (define_expand "and<mode>3"
7717   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7718         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7719                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7720   ""
7721   "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7722
7723 (define_insn "*anddi_1"
7724   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7725         (and:DI
7726          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7727          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7728    (clobber (reg:CC FLAGS_REG))]
7729   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7730 {
7731   switch (get_attr_type (insn))
7732     {
7733     case TYPE_IMOVX:
7734       {
7735         enum machine_mode mode;
7736
7737         gcc_assert (CONST_INT_P (operands[2]));
7738         if (INTVAL (operands[2]) == 0xff)
7739           mode = QImode;
7740         else
7741           {
7742             gcc_assert (INTVAL (operands[2]) == 0xffff);
7743             mode = HImode;
7744           }
7745
7746         operands[1] = gen_lowpart (mode, operands[1]);
7747         if (mode == QImode)
7748           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7749         else
7750           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7751       }
7752
7753     default:
7754       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7755       if (get_attr_mode (insn) == MODE_SI)
7756         return "and{l}\t{%k2, %k0|%k0, %k2}";
7757       else
7758         return "and{q}\t{%2, %0|%0, %2}";
7759     }
7760 }
7761   [(set_attr "type" "alu,alu,alu,imovx")
7762    (set_attr "length_immediate" "*,*,*,0")
7763    (set (attr "prefix_rex")
7764      (if_then_else
7765        (and (eq_attr "type" "imovx")
7766             (and (match_test "INTVAL (operands[2]) == 0xff")
7767                  (match_operand 1 "ext_QIreg_operand" "")))
7768        (const_string "1")
7769        (const_string "*")))
7770    (set_attr "mode" "SI,DI,DI,SI")])
7771
7772 (define_insn "*andsi_1"
7773   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7774         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7775                 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7776    (clobber (reg:CC FLAGS_REG))]
7777   "ix86_binary_operator_ok (AND, SImode, operands)"
7778 {
7779   switch (get_attr_type (insn))
7780     {
7781     case TYPE_IMOVX:
7782       {
7783         enum machine_mode mode;
7784
7785         gcc_assert (CONST_INT_P (operands[2]));
7786         if (INTVAL (operands[2]) == 0xff)
7787           mode = QImode;
7788         else
7789           {
7790             gcc_assert (INTVAL (operands[2]) == 0xffff);
7791             mode = HImode;
7792           }
7793
7794         operands[1] = gen_lowpart (mode, operands[1]);
7795         if (mode == QImode)
7796           return "movz{bl|x}\t{%1, %0|%0, %1}";
7797         else
7798           return "movz{wl|x}\t{%1, %0|%0, %1}";
7799       }
7800
7801     default:
7802       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7803       return "and{l}\t{%2, %0|%0, %2}";
7804     }
7805 }
7806   [(set_attr "type" "alu,alu,imovx")
7807    (set (attr "prefix_rex")
7808      (if_then_else
7809        (and (eq_attr "type" "imovx")
7810             (and (match_test "INTVAL (operands[2]) == 0xff")
7811                  (match_operand 1 "ext_QIreg_operand" "")))
7812        (const_string "1")
7813        (const_string "*")))
7814    (set_attr "length_immediate" "*,*,0")
7815    (set_attr "mode" "SI")])
7816
7817 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7818 (define_insn "*andsi_1_zext"
7819   [(set (match_operand:DI 0 "register_operand" "=r")
7820         (zero_extend:DI
7821           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7822                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7823    (clobber (reg:CC FLAGS_REG))]
7824   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7825   "and{l}\t{%2, %k0|%k0, %2}"
7826   [(set_attr "type" "alu")
7827    (set_attr "mode" "SI")])
7828
7829 (define_insn "*andhi_1"
7830   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7831         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7832                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7833    (clobber (reg:CC FLAGS_REG))]
7834   "ix86_binary_operator_ok (AND, HImode, operands)"
7835 {
7836   switch (get_attr_type (insn))
7837     {
7838     case TYPE_IMOVX:
7839       gcc_assert (CONST_INT_P (operands[2]));
7840       gcc_assert (INTVAL (operands[2]) == 0xff);
7841       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7842
7843     default:
7844       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7845
7846       return "and{w}\t{%2, %0|%0, %2}";
7847     }
7848 }
7849   [(set_attr "type" "alu,alu,imovx")
7850    (set_attr "length_immediate" "*,*,0")
7851    (set (attr "prefix_rex")
7852      (if_then_else
7853        (and (eq_attr "type" "imovx")
7854             (match_operand 1 "ext_QIreg_operand" ""))
7855        (const_string "1")
7856        (const_string "*")))
7857    (set_attr "mode" "HI,HI,SI")])
7858
7859 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7860 (define_insn "*andqi_1"
7861   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7862         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7863                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7864    (clobber (reg:CC FLAGS_REG))]
7865   "ix86_binary_operator_ok (AND, QImode, operands)"
7866   "@
7867    and{b}\t{%2, %0|%0, %2}
7868    and{b}\t{%2, %0|%0, %2}
7869    and{l}\t{%k2, %k0|%k0, %k2}"
7870   [(set_attr "type" "alu")
7871    (set_attr "mode" "QI,QI,SI")])
7872
7873 (define_insn "*andqi_1_slp"
7874   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7875         (and:QI (match_dup 0)
7876                 (match_operand:QI 1 "general_operand" "qn,qmn")))
7877    (clobber (reg:CC FLAGS_REG))]
7878   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7879    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7880   "and{b}\t{%1, %0|%0, %1}"
7881   [(set_attr "type" "alu1")
7882    (set_attr "mode" "QI")])
7883
7884 (define_split
7885   [(set (match_operand 0 "register_operand" "")
7886         (and (match_dup 0)
7887              (const_int -65536)))
7888    (clobber (reg:CC FLAGS_REG))]
7889   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7890     || optimize_function_for_size_p (cfun)"
7891   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7892   "operands[1] = gen_lowpart (HImode, operands[0]);")
7893
7894 (define_split
7895   [(set (match_operand 0 "ext_register_operand" "")
7896         (and (match_dup 0)
7897              (const_int -256)))
7898    (clobber (reg:CC FLAGS_REG))]
7899   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7900    && reload_completed"
7901   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7902   "operands[1] = gen_lowpart (QImode, operands[0]);")
7903
7904 (define_split
7905   [(set (match_operand 0 "ext_register_operand" "")
7906         (and (match_dup 0)
7907              (const_int -65281)))
7908    (clobber (reg:CC FLAGS_REG))]
7909   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7910    && reload_completed"
7911   [(parallel [(set (zero_extract:SI (match_dup 0)
7912                                     (const_int 8)
7913                                     (const_int 8))
7914                    (xor:SI
7915                      (zero_extract:SI (match_dup 0)
7916                                       (const_int 8)
7917                                       (const_int 8))
7918                      (zero_extract:SI (match_dup 0)
7919                                       (const_int 8)
7920                                       (const_int 8))))
7921               (clobber (reg:CC FLAGS_REG))])]
7922   "operands[0] = gen_lowpart (SImode, operands[0]);")
7923
7924 (define_insn "*anddi_2"
7925   [(set (reg FLAGS_REG)
7926         (compare
7927          (and:DI
7928           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7929           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7930          (const_int 0)))
7931    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7932         (and:DI (match_dup 1) (match_dup 2)))]
7933   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7934    && ix86_binary_operator_ok (AND, DImode, operands)"
7935   "@
7936    and{l}\t{%k2, %k0|%k0, %k2}
7937    and{q}\t{%2, %0|%0, %2}
7938    and{q}\t{%2, %0|%0, %2}"
7939   [(set_attr "type" "alu")
7940    (set_attr "mode" "SI,DI,DI")])
7941
7942 (define_insn "*andqi_2_maybe_si"
7943   [(set (reg FLAGS_REG)
7944         (compare (and:QI
7945                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7946                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7947                  (const_int 0)))
7948    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7949         (and:QI (match_dup 1) (match_dup 2)))]
7950   "ix86_binary_operator_ok (AND, QImode, operands)
7951    && ix86_match_ccmode (insn,
7952                          CONST_INT_P (operands[2])
7953                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7954 {
7955   if (which_alternative == 2)
7956     {
7957       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7958         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7959       return "and{l}\t{%2, %k0|%k0, %2}";
7960     }
7961   return "and{b}\t{%2, %0|%0, %2}";
7962 }
7963   [(set_attr "type" "alu")
7964    (set_attr "mode" "QI,QI,SI")])
7965
7966 (define_insn "*and<mode>_2"
7967   [(set (reg FLAGS_REG)
7968         (compare (and:SWI124
7969                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7970                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7971                  (const_int 0)))
7972    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7973         (and:SWI124 (match_dup 1) (match_dup 2)))]
7974   "ix86_match_ccmode (insn, CCNOmode)
7975    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7976   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7977   [(set_attr "type" "alu")
7978    (set_attr "mode" "<MODE>")])
7979
7980 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7981 (define_insn "*andsi_2_zext"
7982   [(set (reg FLAGS_REG)
7983         (compare (and:SI
7984                   (match_operand:SI 1 "nonimmediate_operand" "%0")
7985                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
7986                  (const_int 0)))
7987    (set (match_operand:DI 0 "register_operand" "=r")
7988         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7989   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7990    && ix86_binary_operator_ok (AND, SImode, operands)"
7991   "and{l}\t{%2, %k0|%k0, %2}"
7992   [(set_attr "type" "alu")
7993    (set_attr "mode" "SI")])
7994
7995 (define_insn "*andqi_2_slp"
7996   [(set (reg FLAGS_REG)
7997         (compare (and:QI
7998                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7999                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8000                  (const_int 0)))
8001    (set (strict_low_part (match_dup 0))
8002         (and:QI (match_dup 0) (match_dup 1)))]
8003   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8004    && ix86_match_ccmode (insn, CCNOmode)
8005    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8006   "and{b}\t{%1, %0|%0, %1}"
8007   [(set_attr "type" "alu1")
8008    (set_attr "mode" "QI")])
8009
8010 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8011 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8012 ;; for a QImode operand, which of course failed.
8013 (define_insn "andqi_ext_0"
8014   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8015                          (const_int 8)
8016                          (const_int 8))
8017         (and:SI
8018           (zero_extract:SI
8019             (match_operand 1 "ext_register_operand" "0")
8020             (const_int 8)
8021             (const_int 8))
8022           (match_operand 2 "const_int_operand" "n")))
8023    (clobber (reg:CC FLAGS_REG))]
8024   ""
8025   "and{b}\t{%2, %h0|%h0, %2}"
8026   [(set_attr "type" "alu")
8027    (set_attr "length_immediate" "1")
8028    (set_attr "modrm" "1")
8029    (set_attr "mode" "QI")])
8030
8031 ;; Generated by peephole translating test to and.  This shows up
8032 ;; often in fp comparisons.
8033 (define_insn "*andqi_ext_0_cc"
8034   [(set (reg FLAGS_REG)
8035         (compare
8036           (and:SI
8037             (zero_extract:SI
8038               (match_operand 1 "ext_register_operand" "0")
8039               (const_int 8)
8040               (const_int 8))
8041             (match_operand 2 "const_int_operand" "n"))
8042           (const_int 0)))
8043    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8044                          (const_int 8)
8045                          (const_int 8))
8046         (and:SI
8047           (zero_extract:SI
8048             (match_dup 1)
8049             (const_int 8)
8050             (const_int 8))
8051           (match_dup 2)))]
8052   "ix86_match_ccmode (insn, CCNOmode)"
8053   "and{b}\t{%2, %h0|%h0, %2}"
8054   [(set_attr "type" "alu")
8055    (set_attr "length_immediate" "1")
8056    (set_attr "modrm" "1")
8057    (set_attr "mode" "QI")])
8058
8059 (define_insn "*andqi_ext_1_rex64"
8060   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8061                          (const_int 8)
8062                          (const_int 8))
8063         (and:SI
8064           (zero_extract:SI
8065             (match_operand 1 "ext_register_operand" "0")
8066             (const_int 8)
8067             (const_int 8))
8068           (zero_extend:SI
8069             (match_operand 2 "ext_register_operand" "Q"))))
8070    (clobber (reg:CC FLAGS_REG))]
8071   "TARGET_64BIT"
8072   "and{b}\t{%2, %h0|%h0, %2}"
8073   [(set_attr "type" "alu")
8074    (set_attr "length_immediate" "0")
8075    (set_attr "mode" "QI")])
8076
8077 (define_insn "*andqi_ext_1"
8078   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8079                          (const_int 8)
8080                          (const_int 8))
8081         (and:SI
8082           (zero_extract:SI
8083             (match_operand 1 "ext_register_operand" "0")
8084             (const_int 8)
8085             (const_int 8))
8086           (zero_extend:SI
8087             (match_operand:QI 2 "general_operand" "Qm"))))
8088    (clobber (reg:CC FLAGS_REG))]
8089   "!TARGET_64BIT"
8090   "and{b}\t{%2, %h0|%h0, %2}"
8091   [(set_attr "type" "alu")
8092    (set_attr "length_immediate" "0")
8093    (set_attr "mode" "QI")])
8094
8095 (define_insn "*andqi_ext_2"
8096   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8097                          (const_int 8)
8098                          (const_int 8))
8099         (and:SI
8100           (zero_extract:SI
8101             (match_operand 1 "ext_register_operand" "%0")
8102             (const_int 8)
8103             (const_int 8))
8104           (zero_extract:SI
8105             (match_operand 2 "ext_register_operand" "Q")
8106             (const_int 8)
8107             (const_int 8))))
8108    (clobber (reg:CC FLAGS_REG))]
8109   ""
8110   "and{b}\t{%h2, %h0|%h0, %h2}"
8111   [(set_attr "type" "alu")
8112    (set_attr "length_immediate" "0")
8113    (set_attr "mode" "QI")])
8114
8115 ;; Convert wide AND instructions with immediate operand to shorter QImode
8116 ;; equivalents when possible.
8117 ;; Don't do the splitting with memory operands, since it introduces risk
8118 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8119 ;; for size, but that can (should?) be handled by generic code instead.
8120 (define_split
8121   [(set (match_operand 0 "register_operand" "")
8122         (and (match_operand 1 "register_operand" "")
8123              (match_operand 2 "const_int_operand" "")))
8124    (clobber (reg:CC FLAGS_REG))]
8125    "reload_completed
8126     && QI_REG_P (operands[0])
8127     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8128     && !(~INTVAL (operands[2]) & ~(255 << 8))
8129     && GET_MODE (operands[0]) != QImode"
8130   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8131                    (and:SI (zero_extract:SI (match_dup 1)
8132                                             (const_int 8) (const_int 8))
8133                            (match_dup 2)))
8134               (clobber (reg:CC FLAGS_REG))])]
8135   "operands[0] = gen_lowpart (SImode, operands[0]);
8136    operands[1] = gen_lowpart (SImode, operands[1]);
8137    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8138
8139 ;; Since AND can be encoded with sign extended immediate, this is only
8140 ;; profitable when 7th bit is not set.
8141 (define_split
8142   [(set (match_operand 0 "register_operand" "")
8143         (and (match_operand 1 "general_operand" "")
8144              (match_operand 2 "const_int_operand" "")))
8145    (clobber (reg:CC FLAGS_REG))]
8146    "reload_completed
8147     && ANY_QI_REG_P (operands[0])
8148     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8149     && !(~INTVAL (operands[2]) & ~255)
8150     && !(INTVAL (operands[2]) & 128)
8151     && GET_MODE (operands[0]) != QImode"
8152   [(parallel [(set (strict_low_part (match_dup 0))
8153                    (and:QI (match_dup 1)
8154                            (match_dup 2)))
8155               (clobber (reg:CC FLAGS_REG))])]
8156   "operands[0] = gen_lowpart (QImode, operands[0]);
8157    operands[1] = gen_lowpart (QImode, operands[1]);
8158    operands[2] = gen_lowpart (QImode, operands[2]);")
8159 \f
8160 ;; Logical inclusive and exclusive OR instructions
8161
8162 ;; %%% This used to optimize known byte-wide and operations to memory.
8163 ;; If this is considered useful, it should be done with splitters.
8164
8165 (define_expand "<code><mode>3"
8166   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8167         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8168                      (match_operand:SWIM 2 "<general_operand>" "")))]
8169   ""
8170   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8171
8172 (define_insn "*<code><mode>_1"
8173   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8174         (any_or:SWI248
8175          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8176          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8177    (clobber (reg:CC FLAGS_REG))]
8178   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8179   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8180   [(set_attr "type" "alu")
8181    (set_attr "mode" "<MODE>")])
8182
8183 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8184 (define_insn "*<code>qi_1"
8185   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8186         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8187                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8188    (clobber (reg:CC FLAGS_REG))]
8189   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8190   "@
8191    <logic>{b}\t{%2, %0|%0, %2}
8192    <logic>{b}\t{%2, %0|%0, %2}
8193    <logic>{l}\t{%k2, %k0|%k0, %k2}"
8194   [(set_attr "type" "alu")
8195    (set_attr "mode" "QI,QI,SI")])
8196
8197 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8198 (define_insn "*<code>si_1_zext"
8199   [(set (match_operand:DI 0 "register_operand" "=r")
8200         (zero_extend:DI
8201          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8202                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8203    (clobber (reg:CC FLAGS_REG))]
8204   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8205   "<logic>{l}\t{%2, %k0|%k0, %2}"
8206   [(set_attr "type" "alu")
8207    (set_attr "mode" "SI")])
8208
8209 (define_insn "*<code>si_1_zext_imm"
8210   [(set (match_operand:DI 0 "register_operand" "=r")
8211         (any_or:DI
8212          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8213          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8214    (clobber (reg:CC FLAGS_REG))]
8215   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8216   "<logic>{l}\t{%2, %k0|%k0, %2}"
8217   [(set_attr "type" "alu")
8218    (set_attr "mode" "SI")])
8219
8220 (define_insn "*<code>qi_1_slp"
8221   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8222         (any_or:QI (match_dup 0)
8223                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8224    (clobber (reg:CC FLAGS_REG))]
8225   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8226    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8227   "<logic>{b}\t{%1, %0|%0, %1}"
8228   [(set_attr "type" "alu1")
8229    (set_attr "mode" "QI")])
8230
8231 (define_insn "*<code><mode>_2"
8232   [(set (reg FLAGS_REG)
8233         (compare (any_or:SWI
8234                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8235                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8236                  (const_int 0)))
8237    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8238         (any_or:SWI (match_dup 1) (match_dup 2)))]
8239   "ix86_match_ccmode (insn, CCNOmode)
8240    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8241   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8242   [(set_attr "type" "alu")
8243    (set_attr "mode" "<MODE>")])
8244
8245 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8246 ;; ??? Special case for immediate operand is missing - it is tricky.
8247 (define_insn "*<code>si_2_zext"
8248   [(set (reg FLAGS_REG)
8249         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8250                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
8251                  (const_int 0)))
8252    (set (match_operand:DI 0 "register_operand" "=r")
8253         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8254   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8255    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8256   "<logic>{l}\t{%2, %k0|%k0, %2}"
8257   [(set_attr "type" "alu")
8258    (set_attr "mode" "SI")])
8259
8260 (define_insn "*<code>si_2_zext_imm"
8261   [(set (reg FLAGS_REG)
8262         (compare (any_or:SI
8263                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8264                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8265                  (const_int 0)))
8266    (set (match_operand:DI 0 "register_operand" "=r")
8267         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8268   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8269    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8270   "<logic>{l}\t{%2, %k0|%k0, %2}"
8271   [(set_attr "type" "alu")
8272    (set_attr "mode" "SI")])
8273
8274 (define_insn "*<code>qi_2_slp"
8275   [(set (reg FLAGS_REG)
8276         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8277                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8278                  (const_int 0)))
8279    (set (strict_low_part (match_dup 0))
8280         (any_or:QI (match_dup 0) (match_dup 1)))]
8281   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8282    && ix86_match_ccmode (insn, CCNOmode)
8283    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8284   "<logic>{b}\t{%1, %0|%0, %1}"
8285   [(set_attr "type" "alu1")
8286    (set_attr "mode" "QI")])
8287
8288 (define_insn "*<code><mode>_3"
8289   [(set (reg FLAGS_REG)
8290         (compare (any_or:SWI
8291                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8292                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8293                  (const_int 0)))
8294    (clobber (match_scratch:SWI 0 "=<r>"))]
8295   "ix86_match_ccmode (insn, CCNOmode)
8296    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8297   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8298   [(set_attr "type" "alu")
8299    (set_attr "mode" "<MODE>")])
8300
8301 (define_insn "*<code>qi_ext_0"
8302   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8303                          (const_int 8)
8304                          (const_int 8))
8305         (any_or:SI
8306           (zero_extract:SI
8307             (match_operand 1 "ext_register_operand" "0")
8308             (const_int 8)
8309             (const_int 8))
8310           (match_operand 2 "const_int_operand" "n")))
8311    (clobber (reg:CC FLAGS_REG))]
8312   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8313   "<logic>{b}\t{%2, %h0|%h0, %2}"
8314   [(set_attr "type" "alu")
8315    (set_attr "length_immediate" "1")
8316    (set_attr "modrm" "1")
8317    (set_attr "mode" "QI")])
8318
8319 (define_insn "*<code>qi_ext_1_rex64"
8320   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8321                          (const_int 8)
8322                          (const_int 8))
8323         (any_or:SI
8324           (zero_extract:SI
8325             (match_operand 1 "ext_register_operand" "0")
8326             (const_int 8)
8327             (const_int 8))
8328           (zero_extend:SI
8329             (match_operand 2 "ext_register_operand" "Q"))))
8330    (clobber (reg:CC FLAGS_REG))]
8331   "TARGET_64BIT
8332    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8333   "<logic>{b}\t{%2, %h0|%h0, %2}"
8334   [(set_attr "type" "alu")
8335    (set_attr "length_immediate" "0")
8336    (set_attr "mode" "QI")])
8337
8338 (define_insn "*<code>qi_ext_1"
8339   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8340                          (const_int 8)
8341                          (const_int 8))
8342         (any_or:SI
8343           (zero_extract:SI
8344             (match_operand 1 "ext_register_operand" "0")
8345             (const_int 8)
8346             (const_int 8))
8347           (zero_extend:SI
8348             (match_operand:QI 2 "general_operand" "Qm"))))
8349    (clobber (reg:CC FLAGS_REG))]
8350   "!TARGET_64BIT
8351    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8352   "<logic>{b}\t{%2, %h0|%h0, %2}"
8353   [(set_attr "type" "alu")
8354    (set_attr "length_immediate" "0")
8355    (set_attr "mode" "QI")])
8356
8357 (define_insn "*<code>qi_ext_2"
8358   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8359                          (const_int 8)
8360                          (const_int 8))
8361         (any_or:SI
8362           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8363                            (const_int 8)
8364                            (const_int 8))
8365           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8366                            (const_int 8)
8367                            (const_int 8))))
8368    (clobber (reg:CC FLAGS_REG))]
8369   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8370   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8371   [(set_attr "type" "alu")
8372    (set_attr "length_immediate" "0")
8373    (set_attr "mode" "QI")])
8374
8375 (define_split
8376   [(set (match_operand 0 "register_operand" "")
8377         (any_or (match_operand 1 "register_operand" "")
8378                 (match_operand 2 "const_int_operand" "")))
8379    (clobber (reg:CC FLAGS_REG))]
8380    "reload_completed
8381     && QI_REG_P (operands[0])
8382     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8383     && !(INTVAL (operands[2]) & ~(255 << 8))
8384     && GET_MODE (operands[0]) != QImode"
8385   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8386                    (any_or:SI (zero_extract:SI (match_dup 1)
8387                                                (const_int 8) (const_int 8))
8388                               (match_dup 2)))
8389               (clobber (reg:CC FLAGS_REG))])]
8390   "operands[0] = gen_lowpart (SImode, operands[0]);
8391    operands[1] = gen_lowpart (SImode, operands[1]);
8392    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8393
8394 ;; Since OR can be encoded with sign extended immediate, this is only
8395 ;; profitable when 7th bit is set.
8396 (define_split
8397   [(set (match_operand 0 "register_operand" "")
8398         (any_or (match_operand 1 "general_operand" "")
8399                 (match_operand 2 "const_int_operand" "")))
8400    (clobber (reg:CC FLAGS_REG))]
8401    "reload_completed
8402     && ANY_QI_REG_P (operands[0])
8403     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8404     && !(INTVAL (operands[2]) & ~255)
8405     && (INTVAL (operands[2]) & 128)
8406     && GET_MODE (operands[0]) != QImode"
8407   [(parallel [(set (strict_low_part (match_dup 0))
8408                    (any_or:QI (match_dup 1)
8409                               (match_dup 2)))
8410               (clobber (reg:CC FLAGS_REG))])]
8411   "operands[0] = gen_lowpart (QImode, operands[0]);
8412    operands[1] = gen_lowpart (QImode, operands[1]);
8413    operands[2] = gen_lowpart (QImode, operands[2]);")
8414
8415 (define_expand "xorqi_cc_ext_1"
8416   [(parallel [
8417      (set (reg:CCNO FLAGS_REG)
8418           (compare:CCNO
8419             (xor:SI
8420               (zero_extract:SI
8421                 (match_operand 1 "ext_register_operand" "")
8422                 (const_int 8)
8423                 (const_int 8))
8424               (match_operand:QI 2 "general_operand" ""))
8425             (const_int 0)))
8426      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8427                            (const_int 8)
8428                            (const_int 8))
8429           (xor:SI
8430             (zero_extract:SI
8431              (match_dup 1)
8432              (const_int 8)
8433              (const_int 8))
8434             (match_dup 2)))])])
8435
8436 (define_insn "*xorqi_cc_ext_1_rex64"
8437   [(set (reg FLAGS_REG)
8438         (compare
8439           (xor:SI
8440             (zero_extract:SI
8441               (match_operand 1 "ext_register_operand" "0")
8442               (const_int 8)
8443               (const_int 8))
8444             (match_operand:QI 2 "nonmemory_operand" "Qn"))
8445           (const_int 0)))
8446    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8447                          (const_int 8)
8448                          (const_int 8))
8449         (xor:SI
8450           (zero_extract:SI
8451            (match_dup 1)
8452            (const_int 8)
8453            (const_int 8))
8454           (match_dup 2)))]
8455   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8456   "xor{b}\t{%2, %h0|%h0, %2}"
8457   [(set_attr "type" "alu")
8458    (set_attr "modrm" "1")
8459    (set_attr "mode" "QI")])
8460
8461 (define_insn "*xorqi_cc_ext_1"
8462   [(set (reg FLAGS_REG)
8463         (compare
8464           (xor:SI
8465             (zero_extract:SI
8466               (match_operand 1 "ext_register_operand" "0")
8467               (const_int 8)
8468               (const_int 8))
8469             (match_operand:QI 2 "general_operand" "qmn"))
8470           (const_int 0)))
8471    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8472                          (const_int 8)
8473                          (const_int 8))
8474         (xor:SI
8475           (zero_extract:SI
8476            (match_dup 1)
8477            (const_int 8)
8478            (const_int 8))
8479           (match_dup 2)))]
8480   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8481   "xor{b}\t{%2, %h0|%h0, %2}"
8482   [(set_attr "type" "alu")
8483    (set_attr "modrm" "1")
8484    (set_attr "mode" "QI")])
8485 \f
8486 ;; Negation instructions
8487
8488 (define_expand "neg<mode>2"
8489   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8490         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8491   ""
8492   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8493
8494 (define_insn_and_split "*neg<dwi>2_doubleword"
8495   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8496         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8497    (clobber (reg:CC FLAGS_REG))]
8498   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8499   "#"
8500   "reload_completed"
8501   [(parallel
8502     [(set (reg:CCZ FLAGS_REG)
8503           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8504      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8505    (parallel
8506     [(set (match_dup 2)
8507           (plus:DWIH (match_dup 3)
8508                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8509                                 (const_int 0))))
8510      (clobber (reg:CC FLAGS_REG))])
8511    (parallel
8512     [(set (match_dup 2)
8513           (neg:DWIH (match_dup 2)))
8514      (clobber (reg:CC FLAGS_REG))])]
8515   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8516
8517 (define_insn "*neg<mode>2_1"
8518   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8519         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8520    (clobber (reg:CC FLAGS_REG))]
8521   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8522   "neg{<imodesuffix>}\t%0"
8523   [(set_attr "type" "negnot")
8524    (set_attr "mode" "<MODE>")])
8525
8526 ;; Combine is quite creative about this pattern.
8527 (define_insn "*negsi2_1_zext"
8528   [(set (match_operand:DI 0 "register_operand" "=r")
8529         (lshiftrt:DI
8530           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8531                              (const_int 32)))
8532         (const_int 32)))
8533    (clobber (reg:CC FLAGS_REG))]
8534   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8535   "neg{l}\t%k0"
8536   [(set_attr "type" "negnot")
8537    (set_attr "mode" "SI")])
8538
8539 ;; The problem with neg is that it does not perform (compare x 0),
8540 ;; it really performs (compare 0 x), which leaves us with the zero
8541 ;; flag being the only useful item.
8542
8543 (define_insn "*neg<mode>2_cmpz"
8544   [(set (reg:CCZ FLAGS_REG)
8545         (compare:CCZ
8546           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8547                    (const_int 0)))
8548    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8549         (neg:SWI (match_dup 1)))]
8550   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8551   "neg{<imodesuffix>}\t%0"
8552   [(set_attr "type" "negnot")
8553    (set_attr "mode" "<MODE>")])
8554
8555 (define_insn "*negsi2_cmpz_zext"
8556   [(set (reg:CCZ FLAGS_REG)
8557         (compare:CCZ
8558           (lshiftrt:DI
8559             (neg:DI (ashift:DI
8560                       (match_operand:DI 1 "register_operand" "0")
8561                       (const_int 32)))
8562             (const_int 32))
8563           (const_int 0)))
8564    (set (match_operand:DI 0 "register_operand" "=r")
8565         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8566                                         (const_int 32)))
8567                      (const_int 32)))]
8568   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8569   "neg{l}\t%k0"
8570   [(set_attr "type" "negnot")
8571    (set_attr "mode" "SI")])
8572
8573 ;; Changing of sign for FP values is doable using integer unit too.
8574
8575 (define_expand "<code><mode>2"
8576   [(set (match_operand:X87MODEF 0 "register_operand" "")
8577         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8578   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8579   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8580
8581 (define_insn "*absneg<mode>2_mixed"
8582   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8583         (match_operator:MODEF 3 "absneg_operator"
8584           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8585    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8586    (clobber (reg:CC FLAGS_REG))]
8587   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8588   "#")
8589
8590 (define_insn "*absneg<mode>2_sse"
8591   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8592         (match_operator:MODEF 3 "absneg_operator"
8593           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8594    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8595    (clobber (reg:CC FLAGS_REG))]
8596   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8597   "#")
8598
8599 (define_insn "*absneg<mode>2_i387"
8600   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8601         (match_operator:X87MODEF 3 "absneg_operator"
8602           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8603    (use (match_operand 2 "" ""))
8604    (clobber (reg:CC FLAGS_REG))]
8605   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8606   "#")
8607
8608 (define_expand "<code>tf2"
8609   [(set (match_operand:TF 0 "register_operand" "")
8610         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8611   "TARGET_SSE2"
8612   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8613
8614 (define_insn "*absnegtf2_sse"
8615   [(set (match_operand:TF 0 "register_operand" "=x,x")
8616         (match_operator:TF 3 "absneg_operator"
8617           [(match_operand:TF 1 "register_operand" "0,x")]))
8618    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8619    (clobber (reg:CC FLAGS_REG))]
8620   "TARGET_SSE2"
8621   "#")
8622
8623 ;; Splitters for fp abs and neg.
8624
8625 (define_split
8626   [(set (match_operand 0 "fp_register_operand" "")
8627         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8628    (use (match_operand 2 "" ""))
8629    (clobber (reg:CC FLAGS_REG))]
8630   "reload_completed"
8631   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8632
8633 (define_split
8634   [(set (match_operand 0 "register_operand" "")
8635         (match_operator 3 "absneg_operator"
8636           [(match_operand 1 "register_operand" "")]))
8637    (use (match_operand 2 "nonimmediate_operand" ""))
8638    (clobber (reg:CC FLAGS_REG))]
8639   "reload_completed && SSE_REG_P (operands[0])"
8640   [(set (match_dup 0) (match_dup 3))]
8641 {
8642   enum machine_mode mode = GET_MODE (operands[0]);
8643   enum machine_mode vmode = GET_MODE (operands[2]);
8644   rtx tmp;
8645
8646   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8647   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8648   if (operands_match_p (operands[0], operands[2]))
8649     {
8650       tmp = operands[1];
8651       operands[1] = operands[2];
8652       operands[2] = tmp;
8653     }
8654   if (GET_CODE (operands[3]) == ABS)
8655     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8656   else
8657     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8658   operands[3] = tmp;
8659 })
8660
8661 (define_split
8662   [(set (match_operand:SF 0 "register_operand" "")
8663         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8664    (use (match_operand:V4SF 2 "" ""))
8665    (clobber (reg:CC FLAGS_REG))]
8666   "reload_completed"
8667   [(parallel [(set (match_dup 0) (match_dup 1))
8668               (clobber (reg:CC FLAGS_REG))])]
8669 {
8670   rtx tmp;
8671   operands[0] = gen_lowpart (SImode, operands[0]);
8672   if (GET_CODE (operands[1]) == ABS)
8673     {
8674       tmp = gen_int_mode (0x7fffffff, SImode);
8675       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8676     }
8677   else
8678     {
8679       tmp = gen_int_mode (0x80000000, SImode);
8680       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8681     }
8682   operands[1] = tmp;
8683 })
8684
8685 (define_split
8686   [(set (match_operand:DF 0 "register_operand" "")
8687         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8688    (use (match_operand 2 "" ""))
8689    (clobber (reg:CC FLAGS_REG))]
8690   "reload_completed"
8691   [(parallel [(set (match_dup 0) (match_dup 1))
8692               (clobber (reg:CC FLAGS_REG))])]
8693 {
8694   rtx tmp;
8695   if (TARGET_64BIT)
8696     {
8697       tmp = gen_lowpart (DImode, operands[0]);
8698       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8699       operands[0] = tmp;
8700
8701       if (GET_CODE (operands[1]) == ABS)
8702         tmp = const0_rtx;
8703       else
8704         tmp = gen_rtx_NOT (DImode, tmp);
8705     }
8706   else
8707     {
8708       operands[0] = gen_highpart (SImode, operands[0]);
8709       if (GET_CODE (operands[1]) == ABS)
8710         {
8711           tmp = gen_int_mode (0x7fffffff, SImode);
8712           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8713         }
8714       else
8715         {
8716           tmp = gen_int_mode (0x80000000, SImode);
8717           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8718         }
8719     }
8720   operands[1] = tmp;
8721 })
8722
8723 (define_split
8724   [(set (match_operand:XF 0 "register_operand" "")
8725         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8726    (use (match_operand 2 "" ""))
8727    (clobber (reg:CC FLAGS_REG))]
8728   "reload_completed"
8729   [(parallel [(set (match_dup 0) (match_dup 1))
8730               (clobber (reg:CC FLAGS_REG))])]
8731 {
8732   rtx tmp;
8733   operands[0] = gen_rtx_REG (SImode,
8734                              true_regnum (operands[0])
8735                              + (TARGET_64BIT ? 1 : 2));
8736   if (GET_CODE (operands[1]) == ABS)
8737     {
8738       tmp = GEN_INT (0x7fff);
8739       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8740     }
8741   else
8742     {
8743       tmp = GEN_INT (0x8000);
8744       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8745     }
8746   operands[1] = tmp;
8747 })
8748
8749 ;; Conditionalize these after reload. If they match before reload, we
8750 ;; lose the clobber and ability to use integer instructions.
8751
8752 (define_insn "*<code><mode>2_1"
8753   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8754         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8755   "TARGET_80387
8756    && (reload_completed
8757        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8758   "f<absneg_mnemonic>"
8759   [(set_attr "type" "fsgn")
8760    (set_attr "mode" "<MODE>")])
8761
8762 (define_insn "*<code>extendsfdf2"
8763   [(set (match_operand:DF 0 "register_operand" "=f")
8764         (absneg:DF (float_extend:DF
8765                      (match_operand:SF 1 "register_operand" "0"))))]
8766   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8767   "f<absneg_mnemonic>"
8768   [(set_attr "type" "fsgn")
8769    (set_attr "mode" "DF")])
8770
8771 (define_insn "*<code>extendsfxf2"
8772   [(set (match_operand:XF 0 "register_operand" "=f")
8773         (absneg:XF (float_extend:XF
8774                      (match_operand:SF 1 "register_operand" "0"))))]
8775   "TARGET_80387"
8776   "f<absneg_mnemonic>"
8777   [(set_attr "type" "fsgn")
8778    (set_attr "mode" "XF")])
8779
8780 (define_insn "*<code>extenddfxf2"
8781   [(set (match_operand:XF 0 "register_operand" "=f")
8782         (absneg:XF (float_extend:XF
8783                      (match_operand:DF 1 "register_operand" "0"))))]
8784   "TARGET_80387"
8785   "f<absneg_mnemonic>"
8786   [(set_attr "type" "fsgn")
8787    (set_attr "mode" "XF")])
8788
8789 ;; Copysign instructions
8790
8791 (define_mode_iterator CSGNMODE [SF DF TF])
8792 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8793
8794 (define_expand "copysign<mode>3"
8795   [(match_operand:CSGNMODE 0 "register_operand" "")
8796    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8797    (match_operand:CSGNMODE 2 "register_operand" "")]
8798   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8799    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8800   "ix86_expand_copysign (operands); DONE;")
8801
8802 (define_insn_and_split "copysign<mode>3_const"
8803   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8804         (unspec:CSGNMODE
8805           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8806            (match_operand:CSGNMODE 2 "register_operand" "0")
8807            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8808           UNSPEC_COPYSIGN))]
8809   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8810    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8811   "#"
8812   "&& reload_completed"
8813   [(const_int 0)]
8814   "ix86_split_copysign_const (operands); DONE;")
8815
8816 (define_insn "copysign<mode>3_var"
8817   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8818         (unspec:CSGNMODE
8819           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8820            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8821            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8822            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8823           UNSPEC_COPYSIGN))
8824    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8825   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8826    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8827   "#")
8828
8829 (define_split
8830   [(set (match_operand:CSGNMODE 0 "register_operand" "")
8831         (unspec:CSGNMODE
8832           [(match_operand:CSGNMODE 2 "register_operand" "")
8833            (match_operand:CSGNMODE 3 "register_operand" "")
8834            (match_operand:<CSGNVMODE> 4 "" "")
8835            (match_operand:<CSGNVMODE> 5 "" "")]
8836           UNSPEC_COPYSIGN))
8837    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8838   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8839     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8840    && reload_completed"
8841   [(const_int 0)]
8842   "ix86_split_copysign_var (operands); DONE;")
8843 \f
8844 ;; One complement instructions
8845
8846 (define_expand "one_cmpl<mode>2"
8847   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8848         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8849   ""
8850   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8851
8852 (define_insn "*one_cmpl<mode>2_1"
8853   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8854         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8855   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8856   "not{<imodesuffix>}\t%0"
8857   [(set_attr "type" "negnot")
8858    (set_attr "mode" "<MODE>")])
8859
8860 ;; %%% Potential partial reg stall on alternative 1.  What to do?
8861 (define_insn "*one_cmplqi2_1"
8862   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8863         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8864   "ix86_unary_operator_ok (NOT, QImode, operands)"
8865   "@
8866    not{b}\t%0
8867    not{l}\t%k0"
8868   [(set_attr "type" "negnot")
8869    (set_attr "mode" "QI,SI")])
8870
8871 ;; ??? Currently never generated - xor is used instead.
8872 (define_insn "*one_cmplsi2_1_zext"
8873   [(set (match_operand:DI 0 "register_operand" "=r")
8874         (zero_extend:DI
8875           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8876   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8877   "not{l}\t%k0"
8878   [(set_attr "type" "negnot")
8879    (set_attr "mode" "SI")])
8880
8881 (define_insn "*one_cmpl<mode>2_2"
8882   [(set (reg FLAGS_REG)
8883         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8884                  (const_int 0)))
8885    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8886         (not:SWI (match_dup 1)))]
8887   "ix86_match_ccmode (insn, CCNOmode)
8888    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8889   "#"
8890   [(set_attr "type" "alu1")
8891    (set_attr "mode" "<MODE>")])
8892
8893 (define_split
8894   [(set (match_operand 0 "flags_reg_operand" "")
8895         (match_operator 2 "compare_operator"
8896           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8897            (const_int 0)]))
8898    (set (match_operand:SWI 1 "nonimmediate_operand" "")
8899         (not:SWI (match_dup 3)))]
8900   "ix86_match_ccmode (insn, CCNOmode)"
8901   [(parallel [(set (match_dup 0)
8902                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8903                                     (const_int 0)]))
8904               (set (match_dup 1)
8905                    (xor:SWI (match_dup 3) (const_int -1)))])])
8906
8907 ;; ??? Currently never generated - xor is used instead.
8908 (define_insn "*one_cmplsi2_2_zext"
8909   [(set (reg FLAGS_REG)
8910         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8911                  (const_int 0)))
8912    (set (match_operand:DI 0 "register_operand" "=r")
8913         (zero_extend:DI (not:SI (match_dup 1))))]
8914   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8915    && ix86_unary_operator_ok (NOT, SImode, operands)"
8916   "#"
8917   [(set_attr "type" "alu1")
8918    (set_attr "mode" "SI")])
8919
8920 (define_split
8921   [(set (match_operand 0 "flags_reg_operand" "")
8922         (match_operator 2 "compare_operator"
8923           [(not:SI (match_operand:SI 3 "register_operand" ""))
8924            (const_int 0)]))
8925    (set (match_operand:DI 1 "register_operand" "")
8926         (zero_extend:DI (not:SI (match_dup 3))))]
8927   "ix86_match_ccmode (insn, CCNOmode)"
8928   [(parallel [(set (match_dup 0)
8929                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8930                                     (const_int 0)]))
8931               (set (match_dup 1)
8932                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8933 \f
8934 ;; Shift instructions
8935
8936 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8937 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
8938 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8939 ;; from the assembler input.
8940 ;;
8941 ;; This instruction shifts the target reg/mem as usual, but instead of
8942 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
8943 ;; is a left shift double, bits are taken from the high order bits of
8944 ;; reg, else if the insn is a shift right double, bits are taken from the
8945 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
8946 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8947 ;;
8948 ;; Since sh[lr]d does not change the `reg' operand, that is done
8949 ;; separately, making all shifts emit pairs of shift double and normal
8950 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
8951 ;; support a 63 bit shift, each shift where the count is in a reg expands
8952 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8953 ;;
8954 ;; If the shift count is a constant, we need never emit more than one
8955 ;; shift pair, instead using moves and sign extension for counts greater
8956 ;; than 31.
8957
8958 (define_expand "ashl<mode>3"
8959   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8960         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8961                       (match_operand:QI 2 "nonmemory_operand" "")))]
8962   ""
8963   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8964
8965 (define_insn "*ashl<mode>3_doubleword"
8966   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8967         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8968                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8969    (clobber (reg:CC FLAGS_REG))]
8970   ""
8971   "#"
8972   [(set_attr "type" "multi")])
8973
8974 (define_split
8975   [(set (match_operand:DWI 0 "register_operand" "")
8976         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8977                     (match_operand:QI 2 "nonmemory_operand" "")))
8978    (clobber (reg:CC FLAGS_REG))]
8979   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8980   [(const_int 0)]
8981   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8982
8983 ;; By default we don't ask for a scratch register, because when DWImode
8984 ;; values are manipulated, registers are already at a premium.  But if
8985 ;; we have one handy, we won't turn it away.
8986
8987 (define_peephole2
8988   [(match_scratch:DWIH 3 "r")
8989    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8990                    (ashift:<DWI>
8991                      (match_operand:<DWI> 1 "nonmemory_operand" "")
8992                      (match_operand:QI 2 "nonmemory_operand" "")))
8993               (clobber (reg:CC FLAGS_REG))])
8994    (match_dup 3)]
8995   "TARGET_CMOVE"
8996   [(const_int 0)]
8997   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8998
8999 (define_insn "x86_64_shld"
9000   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9001         (ior:DI (ashift:DI (match_dup 0)
9002                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9003                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9004                   (minus:QI (const_int 64) (match_dup 2)))))
9005    (clobber (reg:CC FLAGS_REG))]
9006   "TARGET_64BIT"
9007   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9008   [(set_attr "type" "ishift")
9009    (set_attr "prefix_0f" "1")
9010    (set_attr "mode" "DI")
9011    (set_attr "athlon_decode" "vector")
9012    (set_attr "amdfam10_decode" "vector")
9013    (set_attr "bdver1_decode" "vector")])
9014
9015 (define_insn "x86_shld"
9016   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9017         (ior:SI (ashift:SI (match_dup 0)
9018                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9019                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9020                   (minus:QI (const_int 32) (match_dup 2)))))
9021    (clobber (reg:CC FLAGS_REG))]
9022   ""
9023   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9024   [(set_attr "type" "ishift")
9025    (set_attr "prefix_0f" "1")
9026    (set_attr "mode" "SI")
9027    (set_attr "pent_pair" "np")
9028    (set_attr "athlon_decode" "vector")
9029    (set_attr "amdfam10_decode" "vector")
9030    (set_attr "bdver1_decode" "vector")])
9031
9032 (define_expand "x86_shift<mode>_adj_1"
9033   [(set (reg:CCZ FLAGS_REG)
9034         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9035                              (match_dup 4))
9036                      (const_int 0)))
9037    (set (match_operand:SWI48 0 "register_operand" "")
9038         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9039                             (match_operand:SWI48 1 "register_operand" "")
9040                             (match_dup 0)))
9041    (set (match_dup 1)
9042         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9043                             (match_operand:SWI48 3 "register_operand" "r")
9044                             (match_dup 1)))]
9045   "TARGET_CMOVE"
9046   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9047
9048 (define_expand "x86_shift<mode>_adj_2"
9049   [(use (match_operand:SWI48 0 "register_operand" ""))
9050    (use (match_operand:SWI48 1 "register_operand" ""))
9051    (use (match_operand:QI 2 "register_operand" ""))]
9052   ""
9053 {
9054   rtx label = gen_label_rtx ();
9055   rtx tmp;
9056
9057   emit_insn (gen_testqi_ccz_1 (operands[2],
9058                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9059
9060   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9061   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9062   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9063                               gen_rtx_LABEL_REF (VOIDmode, label),
9064                               pc_rtx);
9065   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9066   JUMP_LABEL (tmp) = label;
9067
9068   emit_move_insn (operands[0], operands[1]);
9069   ix86_expand_clear (operands[1]);
9070
9071   emit_label (label);
9072   LABEL_NUSES (label) = 1;
9073
9074   DONE;
9075 })
9076
9077 ;; Avoid useless masking of count operand.
9078 (define_insn_and_split "*ashl<mode>3_mask"
9079   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9080         (ashift:SWI48
9081           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9082           (subreg:QI
9083             (and:SI
9084               (match_operand:SI 2 "nonimmediate_operand" "c")
9085               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9086    (clobber (reg:CC FLAGS_REG))]
9087   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9088    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9089       == GET_MODE_BITSIZE (<MODE>mode)-1"
9090   "#"
9091   "&& 1"
9092   [(parallel [(set (match_dup 0)
9093                    (ashift:SWI48 (match_dup 1) (match_dup 2)))
9094               (clobber (reg:CC FLAGS_REG))])]
9095 {
9096   if (can_create_pseudo_p ())
9097     operands [2] = force_reg (SImode, operands[2]);
9098
9099   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9100 }
9101   [(set_attr "type" "ishift")
9102    (set_attr "mode" "<MODE>")])
9103
9104 (define_insn "*bmi2_ashl<mode>3_1"
9105   [(set (match_operand:SWI48 0 "register_operand" "=r")
9106         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9107                       (match_operand:SWI48 2 "register_operand" "r")))]
9108   "TARGET_BMI2"
9109   "shlx\t{%2, %1, %0|%0, %1, %2}"
9110   [(set_attr "type" "ishiftx")
9111    (set_attr "mode" "<MODE>")])
9112
9113 (define_insn "*ashl<mode>3_1"
9114   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9115         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9116                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9117    (clobber (reg:CC FLAGS_REG))]
9118   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9119 {
9120   switch (get_attr_type (insn))
9121     {
9122     case TYPE_LEA:
9123     case TYPE_ISHIFTX:
9124       return "#";
9125
9126     case TYPE_ALU:
9127       gcc_assert (operands[2] == const1_rtx);
9128       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9129       return "add{<imodesuffix>}\t%0, %0";
9130
9131     default:
9132       if (operands[2] == const1_rtx
9133           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9134         return "sal{<imodesuffix>}\t%0";
9135       else
9136         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9137     }
9138 }
9139   [(set_attr "isa" "*,*,bmi2")
9140    (set (attr "type")
9141      (cond [(eq_attr "alternative" "1")
9142               (const_string "lea")
9143             (eq_attr "alternative" "2")
9144               (const_string "ishiftx")
9145             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9146                       (match_operand 0 "register_operand" ""))
9147                  (match_operand 2 "const1_operand" ""))
9148               (const_string "alu")
9149            ]
9150            (const_string "ishift")))
9151    (set (attr "length_immediate")
9152      (if_then_else
9153        (ior (eq_attr "type" "alu")
9154             (and (eq_attr "type" "ishift")
9155                  (and (match_operand 2 "const1_operand" "")
9156                       (ior (match_test "TARGET_SHIFT1")
9157                            (match_test "optimize_function_for_size_p (cfun)")))))
9158        (const_string "0")
9159        (const_string "*")))
9160    (set_attr "mode" "<MODE>")])
9161
9162 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9163 (define_split
9164   [(set (match_operand:SWI48 0 "register_operand" "")
9165         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9166                       (match_operand:QI 2 "register_operand" "")))
9167    (clobber (reg:CC FLAGS_REG))]
9168   "TARGET_BMI2 && reload_completed"
9169   [(set (match_dup 0)
9170         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9171   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9172
9173 (define_insn "*bmi2_ashlsi3_1_zext"
9174   [(set (match_operand:DI 0 "register_operand" "=r")
9175         (zero_extend:DI
9176           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9177                      (match_operand:SI 2 "register_operand" "r"))))]
9178   "TARGET_64BIT && TARGET_BMI2"
9179   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9180   [(set_attr "type" "ishiftx")
9181    (set_attr "mode" "SI")])
9182
9183 (define_insn "*ashlsi3_1_zext"
9184   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9185         (zero_extend:DI
9186           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9187                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9188    (clobber (reg:CC FLAGS_REG))]
9189   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9190 {
9191   switch (get_attr_type (insn))
9192     {
9193     case TYPE_LEA:
9194     case TYPE_ISHIFTX:
9195       return "#";
9196
9197     case TYPE_ALU:
9198       gcc_assert (operands[2] == const1_rtx);
9199       return "add{l}\t%k0, %k0";
9200
9201     default:
9202       if (operands[2] == const1_rtx
9203           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9204         return "sal{l}\t%k0";
9205       else
9206         return "sal{l}\t{%2, %k0|%k0, %2}";
9207     }
9208 }
9209   [(set_attr "isa" "*,*,bmi2")
9210    (set (attr "type")
9211      (cond [(eq_attr "alternative" "1")
9212               (const_string "lea")
9213             (eq_attr "alternative" "2")
9214               (const_string "ishiftx")
9215             (and (match_test "TARGET_DOUBLE_WITH_ADD")
9216                  (match_operand 2 "const1_operand" ""))
9217               (const_string "alu")
9218            ]
9219            (const_string "ishift")))
9220    (set (attr "length_immediate")
9221      (if_then_else
9222        (ior (eq_attr "type" "alu")
9223             (and (eq_attr "type" "ishift")
9224                  (and (match_operand 2 "const1_operand" "")
9225                       (ior (match_test "TARGET_SHIFT1")
9226                            (match_test "optimize_function_for_size_p (cfun)")))))
9227        (const_string "0")
9228        (const_string "*")))
9229    (set_attr "mode" "SI")])
9230
9231 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9232 (define_split
9233   [(set (match_operand:DI 0 "register_operand" "")
9234         (zero_extend:DI
9235           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9236                      (match_operand:QI 2 "register_operand" ""))))
9237    (clobber (reg:CC FLAGS_REG))]
9238   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9239   [(set (match_dup 0)
9240         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9241   "operands[2] = gen_lowpart (SImode, operands[2]);")
9242
9243 (define_insn "*ashlhi3_1"
9244   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9245         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9246                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9247    (clobber (reg:CC FLAGS_REG))]
9248   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9249 {
9250   switch (get_attr_type (insn))
9251     {
9252     case TYPE_LEA:
9253       return "#";
9254
9255     case TYPE_ALU:
9256       gcc_assert (operands[2] == const1_rtx);
9257       return "add{w}\t%0, %0";
9258
9259     default:
9260       if (operands[2] == const1_rtx
9261           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9262         return "sal{w}\t%0";
9263       else
9264         return "sal{w}\t{%2, %0|%0, %2}";
9265     }
9266 }
9267   [(set (attr "type")
9268      (cond [(eq_attr "alternative" "1")
9269               (const_string "lea")
9270             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9271                       (match_operand 0 "register_operand" ""))
9272                  (match_operand 2 "const1_operand" ""))
9273               (const_string "alu")
9274            ]
9275            (const_string "ishift")))
9276    (set (attr "length_immediate")
9277      (if_then_else
9278        (ior (eq_attr "type" "alu")
9279             (and (eq_attr "type" "ishift")
9280                  (and (match_operand 2 "const1_operand" "")
9281                       (ior (match_test "TARGET_SHIFT1")
9282                            (match_test "optimize_function_for_size_p (cfun)")))))
9283        (const_string "0")
9284        (const_string "*")))
9285    (set_attr "mode" "HI,SI")])
9286
9287 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9288 (define_insn "*ashlqi3_1"
9289   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9290         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9291                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9292    (clobber (reg:CC FLAGS_REG))]
9293   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9294 {
9295   switch (get_attr_type (insn))
9296     {
9297     case TYPE_LEA:
9298       return "#";
9299
9300     case TYPE_ALU:
9301       gcc_assert (operands[2] == const1_rtx);
9302       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9303         return "add{l}\t%k0, %k0";
9304       else
9305         return "add{b}\t%0, %0";
9306
9307     default:
9308       if (operands[2] == const1_rtx
9309           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9310         {
9311           if (get_attr_mode (insn) == MODE_SI)
9312             return "sal{l}\t%k0";
9313           else
9314             return "sal{b}\t%0";
9315         }
9316       else
9317         {
9318           if (get_attr_mode (insn) == MODE_SI)
9319             return "sal{l}\t{%2, %k0|%k0, %2}";
9320           else
9321             return "sal{b}\t{%2, %0|%0, %2}";
9322         }
9323     }
9324 }
9325   [(set (attr "type")
9326      (cond [(eq_attr "alternative" "2")
9327               (const_string "lea")
9328             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9329                       (match_operand 0 "register_operand" ""))
9330                  (match_operand 2 "const1_operand" ""))
9331               (const_string "alu")
9332            ]
9333            (const_string "ishift")))
9334    (set (attr "length_immediate")
9335      (if_then_else
9336        (ior (eq_attr "type" "alu")
9337             (and (eq_attr "type" "ishift")
9338                  (and (match_operand 2 "const1_operand" "")
9339                       (ior (match_test "TARGET_SHIFT1")
9340                            (match_test "optimize_function_for_size_p (cfun)")))))
9341        (const_string "0")
9342        (const_string "*")))
9343    (set_attr "mode" "QI,SI,SI")])
9344
9345 (define_insn "*ashlqi3_1_slp"
9346   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9347         (ashift:QI (match_dup 0)
9348                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9349    (clobber (reg:CC FLAGS_REG))]
9350   "(optimize_function_for_size_p (cfun)
9351     || !TARGET_PARTIAL_FLAG_REG_STALL
9352     || (operands[1] == const1_rtx
9353         && (TARGET_SHIFT1
9354             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9355 {
9356   switch (get_attr_type (insn))
9357     {
9358     case TYPE_ALU:
9359       gcc_assert (operands[1] == const1_rtx);
9360       return "add{b}\t%0, %0";
9361
9362     default:
9363       if (operands[1] == const1_rtx
9364           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9365         return "sal{b}\t%0";
9366       else
9367         return "sal{b}\t{%1, %0|%0, %1}";
9368     }
9369 }
9370   [(set (attr "type")
9371      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9372                       (match_operand 0 "register_operand" ""))
9373                  (match_operand 1 "const1_operand" ""))
9374               (const_string "alu")
9375            ]
9376            (const_string "ishift1")))
9377    (set (attr "length_immediate")
9378      (if_then_else
9379        (ior (eq_attr "type" "alu")
9380             (and (eq_attr "type" "ishift1")
9381                  (and (match_operand 1 "const1_operand" "")
9382                       (ior (match_test "TARGET_SHIFT1")
9383                            (match_test "optimize_function_for_size_p (cfun)")))))
9384        (const_string "0")
9385        (const_string "*")))
9386    (set_attr "mode" "QI")])
9387
9388 ;; Convert ashift to the lea pattern to avoid flags dependency.
9389 (define_split
9390   [(set (match_operand 0 "register_operand" "")
9391         (ashift (match_operand 1 "index_register_operand" "")
9392                 (match_operand:QI 2 "const_int_operand" "")))
9393    (clobber (reg:CC FLAGS_REG))]
9394   "GET_MODE (operands[0]) == GET_MODE (operands[1])
9395    && reload_completed
9396    && true_regnum (operands[0]) != true_regnum (operands[1])"
9397   [(const_int 0)]
9398 {
9399   enum machine_mode mode = GET_MODE (operands[0]);
9400   rtx pat;
9401
9402   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9403     { 
9404       mode = SImode; 
9405       operands[0] = gen_lowpart (mode, operands[0]);
9406       operands[1] = gen_lowpart (mode, operands[1]);
9407     }
9408
9409   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9410
9411   pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9412
9413   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9414   DONE;
9415 })
9416
9417 ;; Convert ashift to the lea pattern to avoid flags dependency.
9418 (define_split
9419   [(set (match_operand:DI 0 "register_operand" "")
9420         (zero_extend:DI
9421           (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9422                      (match_operand:QI 2 "const_int_operand" ""))))
9423    (clobber (reg:CC FLAGS_REG))]
9424   "TARGET_64BIT && reload_completed
9425    && true_regnum (operands[0]) != true_regnum (operands[1])"
9426   [(set (match_dup 0)
9427         (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9428 {
9429   operands[1] = gen_lowpart (DImode, operands[1]);
9430   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9431 })
9432
9433 ;; This pattern can't accept a variable shift count, since shifts by
9434 ;; zero don't affect the flags.  We assume that shifts by constant
9435 ;; zero are optimized away.
9436 (define_insn "*ashl<mode>3_cmp"
9437   [(set (reg FLAGS_REG)
9438         (compare
9439           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9440                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9441           (const_int 0)))
9442    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9443         (ashift:SWI (match_dup 1) (match_dup 2)))]
9444   "(optimize_function_for_size_p (cfun)
9445     || !TARGET_PARTIAL_FLAG_REG_STALL
9446     || (operands[2] == const1_rtx
9447         && (TARGET_SHIFT1
9448             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9449    && ix86_match_ccmode (insn, CCGOCmode)
9450    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9451 {
9452   switch (get_attr_type (insn))
9453     {
9454     case TYPE_ALU:
9455       gcc_assert (operands[2] == const1_rtx);
9456       return "add{<imodesuffix>}\t%0, %0";
9457
9458     default:
9459       if (operands[2] == const1_rtx
9460           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9461         return "sal{<imodesuffix>}\t%0";
9462       else
9463         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9464     }
9465 }
9466   [(set (attr "type")
9467      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9468                       (match_operand 0 "register_operand" ""))
9469                  (match_operand 2 "const1_operand" ""))
9470               (const_string "alu")
9471            ]
9472            (const_string "ishift")))
9473    (set (attr "length_immediate")
9474      (if_then_else
9475        (ior (eq_attr "type" "alu")
9476             (and (eq_attr "type" "ishift")
9477                  (and (match_operand 2 "const1_operand" "")
9478                       (ior (match_test "TARGET_SHIFT1")
9479                            (match_test "optimize_function_for_size_p (cfun)")))))
9480        (const_string "0")
9481        (const_string "*")))
9482    (set_attr "mode" "<MODE>")])
9483
9484 (define_insn "*ashlsi3_cmp_zext"
9485   [(set (reg FLAGS_REG)
9486         (compare
9487           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9488                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9489           (const_int 0)))
9490    (set (match_operand:DI 0 "register_operand" "=r")
9491         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9492   "TARGET_64BIT
9493    && (optimize_function_for_size_p (cfun)
9494        || !TARGET_PARTIAL_FLAG_REG_STALL
9495        || (operands[2] == const1_rtx
9496            && (TARGET_SHIFT1
9497                || TARGET_DOUBLE_WITH_ADD)))
9498    && ix86_match_ccmode (insn, CCGOCmode)
9499    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9500 {
9501   switch (get_attr_type (insn))
9502     {
9503     case TYPE_ALU:
9504       gcc_assert (operands[2] == const1_rtx);
9505       return "add{l}\t%k0, %k0";
9506
9507     default:
9508       if (operands[2] == const1_rtx
9509           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9510         return "sal{l}\t%k0";
9511       else
9512         return "sal{l}\t{%2, %k0|%k0, %2}";
9513     }
9514 }
9515   [(set (attr "type")
9516      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9517                  (match_operand 2 "const1_operand" ""))
9518               (const_string "alu")
9519            ]
9520            (const_string "ishift")))
9521    (set (attr "length_immediate")
9522      (if_then_else
9523        (ior (eq_attr "type" "alu")
9524             (and (eq_attr "type" "ishift")
9525                  (and (match_operand 2 "const1_operand" "")
9526                       (ior (match_test "TARGET_SHIFT1")
9527                            (match_test "optimize_function_for_size_p (cfun)")))))
9528        (const_string "0")
9529        (const_string "*")))
9530    (set_attr "mode" "SI")])
9531
9532 (define_insn "*ashl<mode>3_cconly"
9533   [(set (reg FLAGS_REG)
9534         (compare
9535           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9536                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9537           (const_int 0)))
9538    (clobber (match_scratch:SWI 0 "=<r>"))]
9539   "(optimize_function_for_size_p (cfun)
9540     || !TARGET_PARTIAL_FLAG_REG_STALL
9541     || (operands[2] == const1_rtx
9542         && (TARGET_SHIFT1
9543             || TARGET_DOUBLE_WITH_ADD)))
9544    && ix86_match_ccmode (insn, CCGOCmode)"
9545 {
9546   switch (get_attr_type (insn))
9547     {
9548     case TYPE_ALU:
9549       gcc_assert (operands[2] == const1_rtx);
9550       return "add{<imodesuffix>}\t%0, %0";
9551
9552     default:
9553       if (operands[2] == const1_rtx
9554           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9555         return "sal{<imodesuffix>}\t%0";
9556       else
9557         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9558     }
9559 }
9560   [(set (attr "type")
9561      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9562                       (match_operand 0 "register_operand" ""))
9563                  (match_operand 2 "const1_operand" ""))
9564               (const_string "alu")
9565            ]
9566            (const_string "ishift")))
9567    (set (attr "length_immediate")
9568      (if_then_else
9569        (ior (eq_attr "type" "alu")
9570             (and (eq_attr "type" "ishift")
9571                  (and (match_operand 2 "const1_operand" "")
9572                       (ior (match_test "TARGET_SHIFT1")
9573                            (match_test "optimize_function_for_size_p (cfun)")))))
9574        (const_string "0")
9575        (const_string "*")))
9576    (set_attr "mode" "<MODE>")])
9577
9578 ;; See comment above `ashl<mode>3' about how this works.
9579
9580 (define_expand "<shiftrt_insn><mode>3"
9581   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9582         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9583                            (match_operand:QI 2 "nonmemory_operand" "")))]
9584   ""
9585   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9586
9587 ;; Avoid useless masking of count operand.
9588 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9589   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9590         (any_shiftrt:SWI48
9591           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9592           (subreg:QI
9593             (and:SI
9594               (match_operand:SI 2 "nonimmediate_operand" "c")
9595               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9596    (clobber (reg:CC FLAGS_REG))]
9597   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9598    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9599       == GET_MODE_BITSIZE (<MODE>mode)-1"
9600   "#"
9601   "&& 1"
9602   [(parallel [(set (match_dup 0)
9603                    (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9604               (clobber (reg:CC FLAGS_REG))])]
9605 {
9606   if (can_create_pseudo_p ())
9607     operands [2] = force_reg (SImode, operands[2]);
9608
9609   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9610 }
9611   [(set_attr "type" "ishift")
9612    (set_attr "mode" "<MODE>")])
9613
9614 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9615   [(set (match_operand:DWI 0 "register_operand" "=r")
9616         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9617                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9618    (clobber (reg:CC FLAGS_REG))]
9619   ""
9620   "#"
9621   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9622   [(const_int 0)]
9623   "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9624   [(set_attr "type" "multi")])
9625
9626 ;; By default we don't ask for a scratch register, because when DWImode
9627 ;; values are manipulated, registers are already at a premium.  But if
9628 ;; we have one handy, we won't turn it away.
9629
9630 (define_peephole2
9631   [(match_scratch:DWIH 3 "r")
9632    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9633                    (any_shiftrt:<DWI>
9634                      (match_operand:<DWI> 1 "register_operand" "")
9635                      (match_operand:QI 2 "nonmemory_operand" "")))
9636               (clobber (reg:CC FLAGS_REG))])
9637    (match_dup 3)]
9638   "TARGET_CMOVE"
9639   [(const_int 0)]
9640   "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9641
9642 (define_insn "x86_64_shrd"
9643   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9644         (ior:DI (ashiftrt:DI (match_dup 0)
9645                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9646                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9647                   (minus:QI (const_int 64) (match_dup 2)))))
9648    (clobber (reg:CC FLAGS_REG))]
9649   "TARGET_64BIT"
9650   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9651   [(set_attr "type" "ishift")
9652    (set_attr "prefix_0f" "1")
9653    (set_attr "mode" "DI")
9654    (set_attr "athlon_decode" "vector")
9655    (set_attr "amdfam10_decode" "vector")
9656    (set_attr "bdver1_decode" "vector")])
9657
9658 (define_insn "x86_shrd"
9659   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9660         (ior:SI (ashiftrt:SI (match_dup 0)
9661                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9662                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9663                   (minus:QI (const_int 32) (match_dup 2)))))
9664    (clobber (reg:CC FLAGS_REG))]
9665   ""
9666   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9667   [(set_attr "type" "ishift")
9668    (set_attr "prefix_0f" "1")
9669    (set_attr "mode" "SI")
9670    (set_attr "pent_pair" "np")
9671    (set_attr "athlon_decode" "vector")
9672    (set_attr "amdfam10_decode" "vector")
9673    (set_attr "bdver1_decode" "vector")])
9674
9675 (define_insn "ashrdi3_cvt"
9676   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9677         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9678                      (match_operand:QI 2 "const_int_operand" "")))
9679    (clobber (reg:CC FLAGS_REG))]
9680   "TARGET_64BIT && INTVAL (operands[2]) == 63
9681    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9682    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9683   "@
9684    {cqto|cqo}
9685    sar{q}\t{%2, %0|%0, %2}"
9686   [(set_attr "type" "imovx,ishift")
9687    (set_attr "prefix_0f" "0,*")
9688    (set_attr "length_immediate" "0,*")
9689    (set_attr "modrm" "0,1")
9690    (set_attr "mode" "DI")])
9691
9692 (define_insn "ashrsi3_cvt"
9693   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9694         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9695                      (match_operand:QI 2 "const_int_operand" "")))
9696    (clobber (reg:CC FLAGS_REG))]
9697   "INTVAL (operands[2]) == 31
9698    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9699    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9700   "@
9701    {cltd|cdq}
9702    sar{l}\t{%2, %0|%0, %2}"
9703   [(set_attr "type" "imovx,ishift")
9704    (set_attr "prefix_0f" "0,*")
9705    (set_attr "length_immediate" "0,*")
9706    (set_attr "modrm" "0,1")
9707    (set_attr "mode" "SI")])
9708
9709 (define_insn "*ashrsi3_cvt_zext"
9710   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9711         (zero_extend:DI
9712           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9713                        (match_operand:QI 2 "const_int_operand" ""))))
9714    (clobber (reg:CC FLAGS_REG))]
9715   "TARGET_64BIT && INTVAL (operands[2]) == 31
9716    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9717    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9718   "@
9719    {cltd|cdq}
9720    sar{l}\t{%2, %k0|%k0, %2}"
9721   [(set_attr "type" "imovx,ishift")
9722    (set_attr "prefix_0f" "0,*")
9723    (set_attr "length_immediate" "0,*")
9724    (set_attr "modrm" "0,1")
9725    (set_attr "mode" "SI")])
9726
9727 (define_expand "x86_shift<mode>_adj_3"
9728   [(use (match_operand:SWI48 0 "register_operand" ""))
9729    (use (match_operand:SWI48 1 "register_operand" ""))
9730    (use (match_operand:QI 2 "register_operand" ""))]
9731   ""
9732 {
9733   rtx label = gen_label_rtx ();
9734   rtx tmp;
9735
9736   emit_insn (gen_testqi_ccz_1 (operands[2],
9737                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9738
9739   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9740   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9741   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9742                               gen_rtx_LABEL_REF (VOIDmode, label),
9743                               pc_rtx);
9744   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9745   JUMP_LABEL (tmp) = label;
9746
9747   emit_move_insn (operands[0], operands[1]);
9748   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9749                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9750   emit_label (label);
9751   LABEL_NUSES (label) = 1;
9752
9753   DONE;
9754 })
9755
9756 (define_insn "*bmi2_<shiftrt_insn><mode>3_1"
9757   [(set (match_operand:SWI48 0 "register_operand" "=r")
9758         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9759                            (match_operand:SWI48 2 "register_operand" "r")))]
9760   "TARGET_BMI2"
9761   "<shiftrt>x\t{%2, %1, %0|%0, %1, %2}"
9762   [(set_attr "type" "ishiftx")
9763    (set_attr "mode" "<MODE>")])
9764
9765 (define_insn "*<shiftrt_insn><mode>3_1"
9766   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9767         (any_shiftrt:SWI48
9768           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9769           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9770    (clobber (reg:CC FLAGS_REG))]
9771   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9772 {
9773   switch (get_attr_type (insn))
9774     {
9775     case TYPE_ISHIFTX:
9776       return "#";
9777
9778     default:
9779       if (operands[2] == const1_rtx
9780           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9781         return "<shiftrt>{<imodesuffix>}\t%0";
9782       else
9783         return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9784     }
9785 }
9786   [(set_attr "isa" "*,bmi2")
9787    (set_attr "type" "ishift,ishiftx")
9788    (set (attr "length_immediate")
9789      (if_then_else
9790        (and (match_operand 2 "const1_operand" "")
9791             (ior (match_test "TARGET_SHIFT1")
9792                  (match_test "optimize_function_for_size_p (cfun)")))
9793        (const_string "0")
9794        (const_string "*")))
9795    (set_attr "mode" "<MODE>")])
9796
9797 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9798 (define_split
9799   [(set (match_operand:SWI48 0 "register_operand" "")
9800         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9801                            (match_operand:QI 2 "register_operand" "")))
9802    (clobber (reg:CC FLAGS_REG))]
9803   "TARGET_BMI2 && reload_completed"
9804   [(set (match_dup 0)
9805         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9806   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9807
9808 (define_insn "*bmi2_<shiftrt_insn>si3_1_zext"
9809   [(set (match_operand:DI 0 "register_operand" "=r")
9810         (zero_extend:DI
9811           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9812                           (match_operand:SI 2 "register_operand" "r"))))]
9813   "TARGET_64BIT && TARGET_BMI2"
9814   "<shiftrt>x\t{%2, %1, %k0|%k0, %1, %2}"
9815   [(set_attr "type" "ishiftx")
9816    (set_attr "mode" "SI")])
9817
9818 (define_insn "*<shiftrt_insn>si3_1_zext"
9819   [(set (match_operand:DI 0 "register_operand" "=r,r")
9820         (zero_extend:DI
9821           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9822                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9823    (clobber (reg:CC FLAGS_REG))]
9824   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9825 {
9826   switch (get_attr_type (insn))
9827     {
9828     case TYPE_ISHIFTX:
9829       return "#";
9830
9831     default:
9832       if (operands[2] == const1_rtx
9833           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9834         return "<shiftrt>{l}\t%k0";
9835       else
9836         return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9837     }
9838 }
9839   [(set_attr "isa" "*,bmi2")
9840    (set_attr "type" "ishift,ishiftx")
9841    (set (attr "length_immediate")
9842      (if_then_else
9843        (and (match_operand 2 "const1_operand" "")
9844             (ior (match_test "TARGET_SHIFT1")
9845                  (match_test "optimize_function_for_size_p (cfun)")))
9846        (const_string "0")
9847        (const_string "*")))
9848    (set_attr "mode" "SI")])
9849
9850 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9851 (define_split
9852   [(set (match_operand:DI 0 "register_operand" "")
9853         (zero_extend:DI
9854           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9855                           (match_operand:QI 2 "register_operand" ""))))
9856    (clobber (reg:CC FLAGS_REG))]
9857   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9858   [(set (match_dup 0)
9859         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9860   "operands[2] = gen_lowpart (SImode, operands[2]);")
9861
9862 (define_insn "*<shiftrt_insn><mode>3_1"
9863   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9864         (any_shiftrt:SWI12
9865           (match_operand:SWI12 1 "nonimmediate_operand" "0")
9866           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9867    (clobber (reg:CC FLAGS_REG))]
9868   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9869 {
9870   if (operands[2] == const1_rtx
9871       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9872     return "<shiftrt>{<imodesuffix>}\t%0";
9873   else
9874     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9875 }
9876   [(set_attr "type" "ishift")
9877    (set (attr "length_immediate")
9878      (if_then_else
9879        (and (match_operand 2 "const1_operand" "")
9880             (ior (match_test "TARGET_SHIFT1")
9881                  (match_test "optimize_function_for_size_p (cfun)")))
9882        (const_string "0")
9883        (const_string "*")))
9884    (set_attr "mode" "<MODE>")])
9885
9886 (define_insn "*<shiftrt_insn>qi3_1_slp"
9887   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9888         (any_shiftrt:QI (match_dup 0)
9889                         (match_operand:QI 1 "nonmemory_operand" "cI")))
9890    (clobber (reg:CC FLAGS_REG))]
9891   "(optimize_function_for_size_p (cfun)
9892     || !TARGET_PARTIAL_REG_STALL
9893     || (operands[1] == const1_rtx
9894         && TARGET_SHIFT1))"
9895 {
9896   if (operands[1] == const1_rtx
9897       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9898     return "<shiftrt>{b}\t%0";
9899   else
9900     return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9901 }
9902   [(set_attr "type" "ishift1")
9903    (set (attr "length_immediate")
9904      (if_then_else
9905        (and (match_operand 1 "const1_operand" "")
9906             (ior (match_test "TARGET_SHIFT1")
9907                  (match_test "optimize_function_for_size_p (cfun)")))
9908        (const_string "0")
9909        (const_string "*")))
9910    (set_attr "mode" "QI")])
9911
9912 ;; This pattern can't accept a variable shift count, since shifts by
9913 ;; zero don't affect the flags.  We assume that shifts by constant
9914 ;; zero are optimized away.
9915 (define_insn "*<shiftrt_insn><mode>3_cmp"
9916   [(set (reg FLAGS_REG)
9917         (compare
9918           (any_shiftrt:SWI
9919             (match_operand:SWI 1 "nonimmediate_operand" "0")
9920             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9921           (const_int 0)))
9922    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9923         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9924   "(optimize_function_for_size_p (cfun)
9925     || !TARGET_PARTIAL_FLAG_REG_STALL
9926     || (operands[2] == const1_rtx
9927         && TARGET_SHIFT1))
9928    && ix86_match_ccmode (insn, CCGOCmode)
9929    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9930 {
9931   if (operands[2] == const1_rtx
9932       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9933     return "<shiftrt>{<imodesuffix>}\t%0";
9934   else
9935     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9936 }
9937   [(set_attr "type" "ishift")
9938    (set (attr "length_immediate")
9939      (if_then_else
9940        (and (match_operand 2 "const1_operand" "")
9941             (ior (match_test "TARGET_SHIFT1")
9942                  (match_test "optimize_function_for_size_p (cfun)")))
9943        (const_string "0")
9944        (const_string "*")))
9945    (set_attr "mode" "<MODE>")])
9946
9947 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9948   [(set (reg FLAGS_REG)
9949         (compare
9950           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9951                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
9952           (const_int 0)))
9953    (set (match_operand:DI 0 "register_operand" "=r")
9954         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9955   "TARGET_64BIT
9956    && (optimize_function_for_size_p (cfun)
9957        || !TARGET_PARTIAL_FLAG_REG_STALL
9958        || (operands[2] == const1_rtx
9959            && TARGET_SHIFT1))
9960    && ix86_match_ccmode (insn, CCGOCmode)
9961    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9962 {
9963   if (operands[2] == const1_rtx
9964       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9965     return "<shiftrt>{l}\t%k0";
9966   else
9967     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9968 }
9969   [(set_attr "type" "ishift")
9970    (set (attr "length_immediate")
9971      (if_then_else
9972        (and (match_operand 2 "const1_operand" "")
9973             (ior (match_test "TARGET_SHIFT1")
9974                  (match_test "optimize_function_for_size_p (cfun)")))
9975        (const_string "0")
9976        (const_string "*")))
9977    (set_attr "mode" "SI")])
9978
9979 (define_insn "*<shiftrt_insn><mode>3_cconly"
9980   [(set (reg FLAGS_REG)
9981         (compare
9982           (any_shiftrt:SWI
9983             (match_operand:SWI 1 "register_operand" "0")
9984             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9985           (const_int 0)))
9986    (clobber (match_scratch:SWI 0 "=<r>"))]
9987   "(optimize_function_for_size_p (cfun)
9988     || !TARGET_PARTIAL_FLAG_REG_STALL
9989     || (operands[2] == const1_rtx
9990         && TARGET_SHIFT1))
9991    && ix86_match_ccmode (insn, CCGOCmode)"
9992 {
9993   if (operands[2] == const1_rtx
9994       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9995     return "<shiftrt>{<imodesuffix>}\t%0";
9996   else
9997     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9998 }
9999   [(set_attr "type" "ishift")
10000    (set (attr "length_immediate")
10001      (if_then_else
10002        (and (match_operand 2 "const1_operand" "")
10003             (ior (match_test "TARGET_SHIFT1")
10004                  (match_test "optimize_function_for_size_p (cfun)")))
10005        (const_string "0")
10006        (const_string "*")))
10007    (set_attr "mode" "<MODE>")])
10008 \f
10009 ;; Rotate instructions
10010
10011 (define_expand "<rotate_insn>ti3"
10012   [(set (match_operand:TI 0 "register_operand" "")
10013         (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10014                        (match_operand:QI 2 "nonmemory_operand" "")))]
10015   "TARGET_64BIT"
10016 {
10017   if (const_1_to_63_operand (operands[2], VOIDmode))
10018     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10019                 (operands[0], operands[1], operands[2]));
10020   else
10021     FAIL;
10022
10023   DONE;
10024 })
10025
10026 (define_expand "<rotate_insn>di3"
10027   [(set (match_operand:DI 0 "shiftdi_operand" "")
10028         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10029                        (match_operand:QI 2 "nonmemory_operand" "")))]
10030  ""
10031 {
10032   if (TARGET_64BIT)
10033     ix86_expand_binary_operator (<CODE>, DImode, operands);
10034   else if (const_1_to_31_operand (operands[2], VOIDmode))
10035     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10036                 (operands[0], operands[1], operands[2]));
10037   else
10038     FAIL;
10039
10040   DONE;
10041 })
10042
10043 (define_expand "<rotate_insn><mode>3"
10044   [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10045         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10046                             (match_operand:QI 2 "nonmemory_operand" "")))]
10047   ""
10048   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10049
10050 ;; Avoid useless masking of count operand.
10051 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10052   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10053         (any_rotate:SWI48
10054           (match_operand:SWI48 1 "nonimmediate_operand" "0")
10055           (subreg:QI
10056             (and:SI
10057               (match_operand:SI 2 "nonimmediate_operand" "c")
10058               (match_operand:SI 3 "const_int_operand" "n")) 0)))
10059    (clobber (reg:CC FLAGS_REG))]
10060   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10061    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10062       == GET_MODE_BITSIZE (<MODE>mode)-1"
10063   "#"
10064   "&& 1"
10065   [(parallel [(set (match_dup 0)
10066                    (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10067               (clobber (reg:CC FLAGS_REG))])]
10068 {
10069   if (can_create_pseudo_p ())
10070     operands [2] = force_reg (SImode, operands[2]);
10071
10072   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10073 }
10074   [(set_attr "type" "rotate")
10075    (set_attr "mode" "<MODE>")])
10076
10077 ;; Implement rotation using two double-precision
10078 ;; shift instructions and a scratch register.
10079
10080 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10081  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10082        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10083                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10084   (clobber (reg:CC FLAGS_REG))
10085   (clobber (match_scratch:DWIH 3 "=&r"))]
10086  ""
10087  "#"
10088  "reload_completed"
10089  [(set (match_dup 3) (match_dup 4))
10090   (parallel
10091    [(set (match_dup 4)
10092          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10093                    (lshiftrt:DWIH (match_dup 5)
10094                                   (minus:QI (match_dup 6) (match_dup 2)))))
10095     (clobber (reg:CC FLAGS_REG))])
10096   (parallel
10097    [(set (match_dup 5)
10098          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10099                    (lshiftrt:DWIH (match_dup 3)
10100                                   (minus:QI (match_dup 6) (match_dup 2)))))
10101     (clobber (reg:CC FLAGS_REG))])]
10102 {
10103   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10104
10105   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10106 })
10107
10108 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10109  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10110        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10111                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10112   (clobber (reg:CC FLAGS_REG))
10113   (clobber (match_scratch:DWIH 3 "=&r"))]
10114  ""
10115  "#"
10116  "reload_completed"
10117  [(set (match_dup 3) (match_dup 4))
10118   (parallel
10119    [(set (match_dup 4)
10120          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10121                    (ashift:DWIH (match_dup 5)
10122                                 (minus:QI (match_dup 6) (match_dup 2)))))
10123     (clobber (reg:CC FLAGS_REG))])
10124   (parallel
10125    [(set (match_dup 5)
10126          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10127                    (ashift:DWIH (match_dup 3)
10128                                 (minus:QI (match_dup 6) (match_dup 2)))))
10129     (clobber (reg:CC FLAGS_REG))])]
10130 {
10131   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10132
10133   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10134 })
10135
10136 (define_insn "*bmi2_rorx<mode>3_1"
10137   [(set (match_operand:SWI48 0 "register_operand" "=r")
10138         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10139                         (match_operand:QI 2 "immediate_operand" "<S>")))]
10140   "TARGET_BMI2"
10141   "rorx\t{%2, %1, %0|%0, %1, %2}"
10142   [(set_attr "type" "rotatex")
10143    (set_attr "mode" "<MODE>")])
10144
10145 (define_insn "*<rotate_insn><mode>3_1"
10146   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10147         (any_rotate:SWI48
10148           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10149           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10150    (clobber (reg:CC FLAGS_REG))]
10151   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10152 {
10153   switch (get_attr_type (insn))
10154     {
10155     case TYPE_ROTATEX:
10156       return "#";
10157
10158     default:
10159       if (operands[2] == const1_rtx
10160           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10161         return "<rotate>{<imodesuffix>}\t%0";
10162       else
10163         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10164     }
10165 }
10166   [(set_attr "isa" "*,bmi2")
10167    (set_attr "type" "rotate,rotatex")
10168    (set (attr "length_immediate")
10169      (if_then_else
10170        (and (eq_attr "type" "rotate")
10171             (and (match_operand 2 "const1_operand" "")
10172                  (ior (match_test "TARGET_SHIFT1")
10173                       (match_test "optimize_function_for_size_p (cfun)"))))
10174        (const_string "0")
10175        (const_string "*")))
10176    (set_attr "mode" "<MODE>")])
10177
10178 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10179 (define_split
10180   [(set (match_operand:SWI48 0 "register_operand" "")
10181         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10182                       (match_operand:QI 2 "immediate_operand" "")))
10183    (clobber (reg:CC FLAGS_REG))]
10184   "TARGET_BMI2 && reload_completed"
10185   [(set (match_dup 0)
10186         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10187 {
10188   operands[2]
10189     = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10190 })
10191
10192 (define_split
10193   [(set (match_operand:SWI48 0 "register_operand" "")
10194         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10195                         (match_operand:QI 2 "immediate_operand" "")))
10196    (clobber (reg:CC FLAGS_REG))]
10197   "TARGET_BMI2 && reload_completed"
10198   [(set (match_dup 0)
10199         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10200
10201 (define_insn "*bmi2_rorxsi3_1_zext"
10202   [(set (match_operand:DI 0 "register_operand" "=r")
10203         (zero_extend:DI
10204           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10205                        (match_operand:QI 2 "immediate_operand" "I"))))]
10206   "TARGET_64BIT && TARGET_BMI2"
10207   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10208   [(set_attr "type" "rotatex")
10209    (set_attr "mode" "SI")])
10210
10211 (define_insn "*<rotate_insn>si3_1_zext"
10212   [(set (match_operand:DI 0 "register_operand" "=r,r")
10213         (zero_extend:DI
10214           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10215                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10216    (clobber (reg:CC FLAGS_REG))]
10217   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10218 {
10219   switch (get_attr_type (insn))
10220     {
10221     case TYPE_ROTATEX:
10222       return "#";
10223
10224     default:
10225       if (operands[2] == const1_rtx
10226           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10227         return "<rotate>{l}\t%k0";
10228       else
10229         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10230     }
10231 }
10232   [(set_attr "isa" "*,bmi2")
10233    (set_attr "type" "rotate,rotatex")
10234    (set (attr "length_immediate")
10235      (if_then_else
10236        (and (eq_attr "type" "rotate")
10237             (and (match_operand 2 "const1_operand" "")
10238                  (ior (match_test "TARGET_SHIFT1")
10239                       (match_test "optimize_function_for_size_p (cfun)"))))
10240        (const_string "0")
10241        (const_string "*")))
10242    (set_attr "mode" "SI")])
10243
10244 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10245 (define_split
10246   [(set (match_operand:DI 0 "register_operand" "")
10247         (zero_extend:DI
10248           (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10249                      (match_operand:QI 2 "immediate_operand" ""))))
10250    (clobber (reg:CC FLAGS_REG))]
10251   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10252   [(set (match_dup 0)
10253         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10254 {
10255   operands[2]
10256     = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10257 })
10258
10259 (define_split
10260   [(set (match_operand:DI 0 "register_operand" "")
10261         (zero_extend:DI
10262           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10263                        (match_operand:QI 2 "immediate_operand" ""))))
10264    (clobber (reg:CC FLAGS_REG))]
10265   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10266   [(set (match_dup 0)
10267         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10268
10269 (define_insn "*<rotate_insn><mode>3_1"
10270   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10271         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10272                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10273    (clobber (reg:CC FLAGS_REG))]
10274   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10275 {
10276   if (operands[2] == const1_rtx
10277       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10278     return "<rotate>{<imodesuffix>}\t%0";
10279   else
10280     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10281 }
10282   [(set_attr "type" "rotate")
10283    (set (attr "length_immediate")
10284      (if_then_else
10285        (and (match_operand 2 "const1_operand" "")
10286             (ior (match_test "TARGET_SHIFT1")
10287                  (match_test "optimize_function_for_size_p (cfun)")))
10288        (const_string "0")
10289        (const_string "*")))
10290    (set_attr "mode" "<MODE>")])
10291
10292 (define_insn "*<rotate_insn>qi3_1_slp"
10293   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10294         (any_rotate:QI (match_dup 0)
10295                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10296    (clobber (reg:CC FLAGS_REG))]
10297   "(optimize_function_for_size_p (cfun)
10298     || !TARGET_PARTIAL_REG_STALL
10299     || (operands[1] == const1_rtx
10300         && TARGET_SHIFT1))"
10301 {
10302   if (operands[1] == const1_rtx
10303       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10304     return "<rotate>{b}\t%0";
10305   else
10306     return "<rotate>{b}\t{%1, %0|%0, %1}";
10307 }
10308   [(set_attr "type" "rotate1")
10309    (set (attr "length_immediate")
10310      (if_then_else
10311        (and (match_operand 1 "const1_operand" "")
10312             (ior (match_test "TARGET_SHIFT1")
10313                  (match_test "optimize_function_for_size_p (cfun)")))
10314        (const_string "0")
10315        (const_string "*")))
10316    (set_attr "mode" "QI")])
10317
10318 (define_split
10319  [(set (match_operand:HI 0 "register_operand" "")
10320        (any_rotate:HI (match_dup 0) (const_int 8)))
10321   (clobber (reg:CC FLAGS_REG))]
10322  "reload_completed
10323   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10324  [(parallel [(set (strict_low_part (match_dup 0))
10325                   (bswap:HI (match_dup 0)))
10326              (clobber (reg:CC FLAGS_REG))])])
10327 \f
10328 ;; Bit set / bit test instructions
10329
10330 (define_expand "extv"
10331   [(set (match_operand:SI 0 "register_operand" "")
10332         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10333                          (match_operand:SI 2 "const8_operand" "")
10334                          (match_operand:SI 3 "const8_operand" "")))]
10335   ""
10336 {
10337   /* Handle extractions from %ah et al.  */
10338   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10339     FAIL;
10340
10341   /* From mips.md: extract_bit_field doesn't verify that our source
10342      matches the predicate, so check it again here.  */
10343   if (! ext_register_operand (operands[1], VOIDmode))
10344     FAIL;
10345 })
10346
10347 (define_expand "extzv"
10348   [(set (match_operand:SI 0 "register_operand" "")
10349         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10350                          (match_operand:SI 2 "const8_operand" "")
10351                          (match_operand:SI 3 "const8_operand" "")))]
10352   ""
10353 {
10354   /* Handle extractions from %ah et al.  */
10355   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10356     FAIL;
10357
10358   /* From mips.md: extract_bit_field doesn't verify that our source
10359      matches the predicate, so check it again here.  */
10360   if (! ext_register_operand (operands[1], VOIDmode))
10361     FAIL;
10362 })
10363
10364 (define_expand "insv"
10365   [(set (zero_extract (match_operand 0 "register_operand" "")
10366                       (match_operand 1 "const_int_operand" "")
10367                       (match_operand 2 "const_int_operand" ""))
10368         (match_operand 3 "register_operand" ""))]
10369   ""
10370 {
10371   rtx (*gen_mov_insv_1) (rtx, rtx);
10372
10373   if (ix86_expand_pinsr (operands))
10374     DONE;
10375
10376   /* Handle insertions to %ah et al.  */
10377   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10378     FAIL;
10379
10380   /* From mips.md: insert_bit_field doesn't verify that our source
10381      matches the predicate, so check it again here.  */
10382   if (! ext_register_operand (operands[0], VOIDmode))
10383     FAIL;
10384
10385   gen_mov_insv_1 = (TARGET_64BIT
10386                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10387
10388   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10389   DONE;
10390 })
10391
10392 ;; %%% bts, btr, btc, bt.
10393 ;; In general these instructions are *slow* when applied to memory,
10394 ;; since they enforce atomic operation.  When applied to registers,
10395 ;; it depends on the cpu implementation.  They're never faster than
10396 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10397 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10398 ;; within the instruction itself, so operating on bits in the high
10399 ;; 32-bits of a register becomes easier.
10400 ;;
10401 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10402 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10403 ;; negdf respectively, so they can never be disabled entirely.
10404
10405 (define_insn "*btsq"
10406   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10407                          (const_int 1)
10408                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10409         (const_int 1))
10410    (clobber (reg:CC FLAGS_REG))]
10411   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10412   "bts{q}\t{%1, %0|%0, %1}"
10413   [(set_attr "type" "alu1")
10414    (set_attr "prefix_0f" "1")
10415    (set_attr "mode" "DI")])
10416
10417 (define_insn "*btrq"
10418   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10419                          (const_int 1)
10420                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10421         (const_int 0))
10422    (clobber (reg:CC FLAGS_REG))]
10423   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10424   "btr{q}\t{%1, %0|%0, %1}"
10425   [(set_attr "type" "alu1")
10426    (set_attr "prefix_0f" "1")
10427    (set_attr "mode" "DI")])
10428
10429 (define_insn "*btcq"
10430   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10431                          (const_int 1)
10432                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10433         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10434    (clobber (reg:CC FLAGS_REG))]
10435   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10436   "btc{q}\t{%1, %0|%0, %1}"
10437   [(set_attr "type" "alu1")
10438    (set_attr "prefix_0f" "1")
10439    (set_attr "mode" "DI")])
10440
10441 ;; Allow Nocona to avoid these instructions if a register is available.
10442
10443 (define_peephole2
10444   [(match_scratch:DI 2 "r")
10445    (parallel [(set (zero_extract:DI
10446                      (match_operand:DI 0 "register_operand" "")
10447                      (const_int 1)
10448                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10449                    (const_int 1))
10450               (clobber (reg:CC FLAGS_REG))])]
10451   "TARGET_64BIT && !TARGET_USE_BT"
10452   [(const_int 0)]
10453 {
10454   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10455   rtx op1;
10456
10457   if (HOST_BITS_PER_WIDE_INT >= 64)
10458     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10459   else if (i < HOST_BITS_PER_WIDE_INT)
10460     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10461   else
10462     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10463
10464   op1 = immed_double_const (lo, hi, DImode);
10465   if (i >= 31)
10466     {
10467       emit_move_insn (operands[2], op1);
10468       op1 = operands[2];
10469     }
10470
10471   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10472   DONE;
10473 })
10474
10475 (define_peephole2
10476   [(match_scratch:DI 2 "r")
10477    (parallel [(set (zero_extract:DI
10478                      (match_operand:DI 0 "register_operand" "")
10479                      (const_int 1)
10480                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10481                    (const_int 0))
10482               (clobber (reg:CC FLAGS_REG))])]
10483   "TARGET_64BIT && !TARGET_USE_BT"
10484   [(const_int 0)]
10485 {
10486   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10487   rtx op1;
10488
10489   if (HOST_BITS_PER_WIDE_INT >= 64)
10490     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10491   else if (i < HOST_BITS_PER_WIDE_INT)
10492     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10493   else
10494     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10495
10496   op1 = immed_double_const (~lo, ~hi, DImode);
10497   if (i >= 32)
10498     {
10499       emit_move_insn (operands[2], op1);
10500       op1 = operands[2];
10501     }
10502
10503   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10504   DONE;
10505 })
10506
10507 (define_peephole2
10508   [(match_scratch:DI 2 "r")
10509    (parallel [(set (zero_extract:DI
10510                      (match_operand:DI 0 "register_operand" "")
10511                      (const_int 1)
10512                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10513               (not:DI (zero_extract:DI
10514                         (match_dup 0) (const_int 1) (match_dup 1))))
10515               (clobber (reg:CC FLAGS_REG))])]
10516   "TARGET_64BIT && !TARGET_USE_BT"
10517   [(const_int 0)]
10518 {
10519   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10520   rtx op1;
10521
10522   if (HOST_BITS_PER_WIDE_INT >= 64)
10523     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10524   else if (i < HOST_BITS_PER_WIDE_INT)
10525     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10526   else
10527     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10528
10529   op1 = immed_double_const (lo, hi, DImode);
10530   if (i >= 31)
10531     {
10532       emit_move_insn (operands[2], op1);
10533       op1 = operands[2];
10534     }
10535
10536   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10537   DONE;
10538 })
10539
10540 (define_insn "*bt<mode>"
10541   [(set (reg:CCC FLAGS_REG)
10542         (compare:CCC
10543           (zero_extract:SWI48
10544             (match_operand:SWI48 0 "register_operand" "r")
10545             (const_int 1)
10546             (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10547           (const_int 0)))]
10548   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10549   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10550   [(set_attr "type" "alu1")
10551    (set_attr "prefix_0f" "1")
10552    (set_attr "mode" "<MODE>")])
10553 \f
10554 ;; Store-flag instructions.
10555
10556 ;; For all sCOND expanders, also expand the compare or test insn that
10557 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10558
10559 (define_insn_and_split "*setcc_di_1"
10560   [(set (match_operand:DI 0 "register_operand" "=q")
10561         (match_operator:DI 1 "ix86_comparison_operator"
10562           [(reg FLAGS_REG) (const_int 0)]))]
10563   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10564   "#"
10565   "&& reload_completed"
10566   [(set (match_dup 2) (match_dup 1))
10567    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10568 {
10569   PUT_MODE (operands[1], QImode);
10570   operands[2] = gen_lowpart (QImode, operands[0]);
10571 })
10572
10573 (define_insn_and_split "*setcc_si_1_and"
10574   [(set (match_operand:SI 0 "register_operand" "=q")
10575         (match_operator:SI 1 "ix86_comparison_operator"
10576           [(reg FLAGS_REG) (const_int 0)]))
10577    (clobber (reg:CC FLAGS_REG))]
10578   "!TARGET_PARTIAL_REG_STALL
10579    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10580   "#"
10581   "&& reload_completed"
10582   [(set (match_dup 2) (match_dup 1))
10583    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10584               (clobber (reg:CC FLAGS_REG))])]
10585 {
10586   PUT_MODE (operands[1], QImode);
10587   operands[2] = gen_lowpart (QImode, operands[0]);
10588 })
10589
10590 (define_insn_and_split "*setcc_si_1_movzbl"
10591   [(set (match_operand:SI 0 "register_operand" "=q")
10592         (match_operator:SI 1 "ix86_comparison_operator"
10593           [(reg FLAGS_REG) (const_int 0)]))]
10594   "!TARGET_PARTIAL_REG_STALL
10595    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10596   "#"
10597   "&& reload_completed"
10598   [(set (match_dup 2) (match_dup 1))
10599    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10600 {
10601   PUT_MODE (operands[1], QImode);
10602   operands[2] = gen_lowpart (QImode, operands[0]);
10603 })
10604
10605 (define_insn "*setcc_qi"
10606   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10607         (match_operator:QI 1 "ix86_comparison_operator"
10608           [(reg FLAGS_REG) (const_int 0)]))]
10609   ""
10610   "set%C1\t%0"
10611   [(set_attr "type" "setcc")
10612    (set_attr "mode" "QI")])
10613
10614 (define_insn "*setcc_qi_slp"
10615   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10616         (match_operator:QI 1 "ix86_comparison_operator"
10617           [(reg FLAGS_REG) (const_int 0)]))]
10618   ""
10619   "set%C1\t%0"
10620   [(set_attr "type" "setcc")
10621    (set_attr "mode" "QI")])
10622
10623 ;; In general it is not safe to assume too much about CCmode registers,
10624 ;; so simplify-rtx stops when it sees a second one.  Under certain
10625 ;; conditions this is safe on x86, so help combine not create
10626 ;;
10627 ;;      seta    %al
10628 ;;      testb   %al, %al
10629 ;;      sete    %al
10630
10631 (define_split
10632   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10633         (ne:QI (match_operator 1 "ix86_comparison_operator"
10634                  [(reg FLAGS_REG) (const_int 0)])
10635             (const_int 0)))]
10636   ""
10637   [(set (match_dup 0) (match_dup 1))]
10638   "PUT_MODE (operands[1], QImode);")
10639
10640 (define_split
10641   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10642         (ne:QI (match_operator 1 "ix86_comparison_operator"
10643                  [(reg FLAGS_REG) (const_int 0)])
10644             (const_int 0)))]
10645   ""
10646   [(set (match_dup 0) (match_dup 1))]
10647   "PUT_MODE (operands[1], QImode);")
10648
10649 (define_split
10650   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10651         (eq:QI (match_operator 1 "ix86_comparison_operator"
10652                  [(reg FLAGS_REG) (const_int 0)])
10653             (const_int 0)))]
10654   ""
10655   [(set (match_dup 0) (match_dup 1))]
10656 {
10657   rtx new_op1 = copy_rtx (operands[1]);
10658   operands[1] = new_op1;
10659   PUT_MODE (new_op1, QImode);
10660   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10661                                              GET_MODE (XEXP (new_op1, 0))));
10662
10663   /* Make sure that (a) the CCmode we have for the flags is strong
10664      enough for the reversed compare or (b) we have a valid FP compare.  */
10665   if (! ix86_comparison_operator (new_op1, VOIDmode))
10666     FAIL;
10667 })
10668
10669 (define_split
10670   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10671         (eq:QI (match_operator 1 "ix86_comparison_operator"
10672                  [(reg FLAGS_REG) (const_int 0)])
10673             (const_int 0)))]
10674   ""
10675   [(set (match_dup 0) (match_dup 1))]
10676 {
10677   rtx new_op1 = copy_rtx (operands[1]);
10678   operands[1] = new_op1;
10679   PUT_MODE (new_op1, QImode);
10680   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10681                                              GET_MODE (XEXP (new_op1, 0))));
10682
10683   /* Make sure that (a) the CCmode we have for the flags is strong
10684      enough for the reversed compare or (b) we have a valid FP compare.  */
10685   if (! ix86_comparison_operator (new_op1, VOIDmode))
10686     FAIL;
10687 })
10688
10689 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10690 ;; subsequent logical operations are used to imitate conditional moves.
10691 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10692 ;; it directly.
10693
10694 (define_insn "setcc_<mode>_sse"
10695   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10696         (match_operator:MODEF 3 "sse_comparison_operator"
10697           [(match_operand:MODEF 1 "register_operand" "0,x")
10698            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10699   "SSE_FLOAT_MODE_P (<MODE>mode)"
10700   "@
10701    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10702    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10703   [(set_attr "isa" "noavx,avx")
10704    (set_attr "type" "ssecmp")
10705    (set_attr "length_immediate" "1")
10706    (set_attr "prefix" "orig,vex")
10707    (set_attr "mode" "<MODE>")])
10708 \f
10709 ;; Basic conditional jump instructions.
10710 ;; We ignore the overflow flag for signed branch instructions.
10711
10712 (define_insn "*jcc_1"
10713   [(set (pc)
10714         (if_then_else (match_operator 1 "ix86_comparison_operator"
10715                                       [(reg FLAGS_REG) (const_int 0)])
10716                       (label_ref (match_operand 0 "" ""))
10717                       (pc)))]
10718   ""
10719   "%+j%C1\t%l0"
10720   [(set_attr "type" "ibr")
10721    (set_attr "modrm" "0")
10722    (set (attr "length")
10723            (if_then_else (and (ge (minus (match_dup 0) (pc))
10724                                   (const_int -126))
10725                               (lt (minus (match_dup 0) (pc))
10726                                   (const_int 128)))
10727              (const_int 2)
10728              (const_int 6)))])
10729
10730 (define_insn "*jcc_2"
10731   [(set (pc)
10732         (if_then_else (match_operator 1 "ix86_comparison_operator"
10733                                       [(reg FLAGS_REG) (const_int 0)])
10734                       (pc)
10735                       (label_ref (match_operand 0 "" ""))))]
10736   ""
10737   "%+j%c1\t%l0"
10738   [(set_attr "type" "ibr")
10739    (set_attr "modrm" "0")
10740    (set (attr "length")
10741            (if_then_else (and (ge (minus (match_dup 0) (pc))
10742                                   (const_int -126))
10743                               (lt (minus (match_dup 0) (pc))
10744                                   (const_int 128)))
10745              (const_int 2)
10746              (const_int 6)))])
10747
10748 ;; In general it is not safe to assume too much about CCmode registers,
10749 ;; so simplify-rtx stops when it sees a second one.  Under certain
10750 ;; conditions this is safe on x86, so help combine not create
10751 ;;
10752 ;;      seta    %al
10753 ;;      testb   %al, %al
10754 ;;      je      Lfoo
10755
10756 (define_split
10757   [(set (pc)
10758         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10759                                       [(reg FLAGS_REG) (const_int 0)])
10760                           (const_int 0))
10761                       (label_ref (match_operand 1 "" ""))
10762                       (pc)))]
10763   ""
10764   [(set (pc)
10765         (if_then_else (match_dup 0)
10766                       (label_ref (match_dup 1))
10767                       (pc)))]
10768   "PUT_MODE (operands[0], VOIDmode);")
10769
10770 (define_split
10771   [(set (pc)
10772         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10773                                       [(reg FLAGS_REG) (const_int 0)])
10774                           (const_int 0))
10775                       (label_ref (match_operand 1 "" ""))
10776                       (pc)))]
10777   ""
10778   [(set (pc)
10779         (if_then_else (match_dup 0)
10780                       (label_ref (match_dup 1))
10781                       (pc)))]
10782 {
10783   rtx new_op0 = copy_rtx (operands[0]);
10784   operands[0] = new_op0;
10785   PUT_MODE (new_op0, VOIDmode);
10786   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10787                                              GET_MODE (XEXP (new_op0, 0))));
10788
10789   /* Make sure that (a) the CCmode we have for the flags is strong
10790      enough for the reversed compare or (b) we have a valid FP compare.  */
10791   if (! ix86_comparison_operator (new_op0, VOIDmode))
10792     FAIL;
10793 })
10794
10795 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10796 ;; pass generates from shift insn with QImode operand.  Actually, the mode
10797 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10798 ;; appropriate modulo of the bit offset value.
10799
10800 (define_insn_and_split "*jcc_bt<mode>"
10801   [(set (pc)
10802         (if_then_else (match_operator 0 "bt_comparison_operator"
10803                         [(zero_extract:SWI48
10804                            (match_operand:SWI48 1 "register_operand" "r")
10805                            (const_int 1)
10806                            (zero_extend:SI
10807                              (match_operand:QI 2 "register_operand" "r")))
10808                          (const_int 0)])
10809                       (label_ref (match_operand 3 "" ""))
10810                       (pc)))
10811    (clobber (reg:CC FLAGS_REG))]
10812   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10813   "#"
10814   "&& 1"
10815   [(set (reg:CCC FLAGS_REG)
10816         (compare:CCC
10817           (zero_extract:SWI48
10818             (match_dup 1)
10819             (const_int 1)
10820             (match_dup 2))
10821           (const_int 0)))
10822    (set (pc)
10823         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10824                       (label_ref (match_dup 3))
10825                       (pc)))]
10826 {
10827   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10828
10829   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10830 })
10831
10832 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10833 ;; also for DImode, this is what combine produces.
10834 (define_insn_and_split "*jcc_bt<mode>_mask"
10835   [(set (pc)
10836         (if_then_else (match_operator 0 "bt_comparison_operator"
10837                         [(zero_extract:SWI48
10838                            (match_operand:SWI48 1 "register_operand" "r")
10839                            (const_int 1)
10840                            (and:SI
10841                              (match_operand:SI 2 "register_operand" "r")
10842                              (match_operand:SI 3 "const_int_operand" "n")))])
10843                       (label_ref (match_operand 4 "" ""))
10844                       (pc)))
10845    (clobber (reg:CC FLAGS_REG))]
10846   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10847    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10848       == GET_MODE_BITSIZE (<MODE>mode)-1"
10849   "#"
10850   "&& 1"
10851   [(set (reg:CCC FLAGS_REG)
10852         (compare:CCC
10853           (zero_extract:SWI48
10854             (match_dup 1)
10855             (const_int 1)
10856             (match_dup 2))
10857           (const_int 0)))
10858    (set (pc)
10859         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10860                       (label_ref (match_dup 4))
10861                       (pc)))]
10862 {
10863   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10864
10865   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10866 })
10867
10868 (define_insn_and_split "*jcc_btsi_1"
10869   [(set (pc)
10870         (if_then_else (match_operator 0 "bt_comparison_operator"
10871                         [(and:SI
10872                            (lshiftrt:SI
10873                              (match_operand:SI 1 "register_operand" "r")
10874                              (match_operand:QI 2 "register_operand" "r"))
10875                            (const_int 1))
10876                          (const_int 0)])
10877                       (label_ref (match_operand 3 "" ""))
10878                       (pc)))
10879    (clobber (reg:CC FLAGS_REG))]
10880   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10881   "#"
10882   "&& 1"
10883   [(set (reg:CCC FLAGS_REG)
10884         (compare:CCC
10885           (zero_extract:SI
10886             (match_dup 1)
10887             (const_int 1)
10888             (match_dup 2))
10889           (const_int 0)))
10890    (set (pc)
10891         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10892                       (label_ref (match_dup 3))
10893                       (pc)))]
10894 {
10895   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10896
10897   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10898 })
10899
10900 ;; avoid useless masking of bit offset operand
10901 (define_insn_and_split "*jcc_btsi_mask_1"
10902   [(set (pc)
10903         (if_then_else
10904           (match_operator 0 "bt_comparison_operator"
10905             [(and:SI
10906                (lshiftrt:SI
10907                  (match_operand:SI 1 "register_operand" "r")
10908                  (subreg:QI
10909                    (and:SI
10910                      (match_operand:SI 2 "register_operand" "r")
10911                      (match_operand:SI 3 "const_int_operand" "n")) 0))
10912                (const_int 1))
10913              (const_int 0)])
10914           (label_ref (match_operand 4 "" ""))
10915           (pc)))
10916    (clobber (reg:CC FLAGS_REG))]
10917   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10918    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10919   "#"
10920   "&& 1"
10921   [(set (reg:CCC FLAGS_REG)
10922         (compare:CCC
10923           (zero_extract:SI
10924             (match_dup 1)
10925             (const_int 1)
10926             (match_dup 2))
10927           (const_int 0)))
10928    (set (pc)
10929         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10930                       (label_ref (match_dup 4))
10931                       (pc)))]
10932   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10933
10934 ;; Define combination compare-and-branch fp compare instructions to help
10935 ;; combine.
10936
10937 (define_insn "*fp_jcc_1_387"
10938   [(set (pc)
10939         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10940                         [(match_operand 1 "register_operand" "f")
10941                          (match_operand 2 "nonimmediate_operand" "fm")])
10942           (label_ref (match_operand 3 "" ""))
10943           (pc)))
10944    (clobber (reg:CCFP FPSR_REG))
10945    (clobber (reg:CCFP FLAGS_REG))
10946    (clobber (match_scratch:HI 4 "=a"))]
10947   "TARGET_80387
10948    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10949    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10950    && SELECT_CC_MODE (GET_CODE (operands[0]),
10951                       operands[1], operands[2]) == CCFPmode
10952    && !TARGET_CMOVE"
10953   "#")
10954
10955 (define_insn "*fp_jcc_1r_387"
10956   [(set (pc)
10957         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10958                         [(match_operand 1 "register_operand" "f")
10959                          (match_operand 2 "nonimmediate_operand" "fm")])
10960           (pc)
10961           (label_ref (match_operand 3 "" ""))))
10962    (clobber (reg:CCFP FPSR_REG))
10963    (clobber (reg:CCFP FLAGS_REG))
10964    (clobber (match_scratch:HI 4 "=a"))]
10965   "TARGET_80387
10966    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10967    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10968    && SELECT_CC_MODE (GET_CODE (operands[0]),
10969                       operands[1], operands[2]) == CCFPmode
10970    && !TARGET_CMOVE"
10971   "#")
10972
10973 (define_insn "*fp_jcc_2_387"
10974   [(set (pc)
10975         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10976                         [(match_operand 1 "register_operand" "f")
10977                          (match_operand 2 "register_operand" "f")])
10978           (label_ref (match_operand 3 "" ""))
10979           (pc)))
10980    (clobber (reg:CCFP FPSR_REG))
10981    (clobber (reg:CCFP FLAGS_REG))
10982    (clobber (match_scratch:HI 4 "=a"))]
10983   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10984    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10985    && !TARGET_CMOVE"
10986   "#")
10987
10988 (define_insn "*fp_jcc_2r_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           (pc)
10994           (label_ref (match_operand 3 "" ""))))
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   "#")
11002
11003 (define_insn "*fp_jcc_3_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 "const0_operand" "")])
11008           (label_ref (match_operand 3 "" ""))
11009           (pc)))
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    && SELECT_CC_MODE (GET_CODE (operands[0]),
11016                       operands[1], operands[2]) == CCFPmode
11017    && !TARGET_CMOVE"
11018   "#")
11019
11020 (define_split
11021   [(set (pc)
11022         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11023                         [(match_operand 1 "register_operand" "")
11024                          (match_operand 2 "nonimmediate_operand" "")])
11025           (match_operand 3 "" "")
11026           (match_operand 4 "" "")))
11027    (clobber (reg:CCFP FPSR_REG))
11028    (clobber (reg:CCFP FLAGS_REG))]
11029   "reload_completed"
11030   [(const_int 0)]
11031 {
11032   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11033                         operands[3], operands[4], NULL_RTX, NULL_RTX);
11034   DONE;
11035 })
11036
11037 (define_split
11038   [(set (pc)
11039         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11040                         [(match_operand 1 "register_operand" "")
11041                          (match_operand 2 "general_operand" "")])
11042           (match_operand 3 "" "")
11043           (match_operand 4 "" "")))
11044    (clobber (reg:CCFP FPSR_REG))
11045    (clobber (reg:CCFP FLAGS_REG))
11046    (clobber (match_scratch:HI 5 "=a"))]
11047   "reload_completed"
11048   [(const_int 0)]
11049 {
11050   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11051                         operands[3], operands[4], operands[5], NULL_RTX);
11052   DONE;
11053 })
11054
11055 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11056 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11057 ;; with a precedence over other operators and is always put in the first
11058 ;; place. Swap condition and operands to match ficom instruction.
11059
11060 (define_insn "*fp_jcc_4_<mode>_387"
11061   [(set (pc)
11062         (if_then_else
11063           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11064             [(match_operator 1 "float_operator"
11065               [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11066              (match_operand 3 "register_operand" "f,f")])
11067           (label_ref (match_operand 4 "" ""))
11068           (pc)))
11069    (clobber (reg:CCFP FPSR_REG))
11070    (clobber (reg:CCFP FLAGS_REG))
11071    (clobber (match_scratch:HI 5 "=a,a"))]
11072   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11073    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11074    && GET_MODE (operands[1]) == GET_MODE (operands[3])
11075    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11076    && !TARGET_CMOVE"
11077   "#")
11078
11079 (define_split
11080   [(set (pc)
11081         (if_then_else
11082           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11083             [(match_operator 1 "float_operator"
11084               [(match_operand:SWI24 2 "memory_operand" "")])
11085              (match_operand 3 "register_operand" "")])
11086           (match_operand 4 "" "")
11087           (match_operand 5 "" "")))
11088    (clobber (reg:CCFP FPSR_REG))
11089    (clobber (reg:CCFP FLAGS_REG))
11090    (clobber (match_scratch:HI 6 "=a"))]
11091   "reload_completed"
11092   [(const_int 0)]
11093 {
11094   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11095
11096   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11097                         operands[3], operands[7],
11098                         operands[4], operands[5], operands[6], NULL_RTX);
11099   DONE;
11100 })
11101
11102 ;; %%% Kill this when reload knows how to do it.
11103 (define_split
11104   [(set (pc)
11105         (if_then_else
11106           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11107             [(match_operator 1 "float_operator"
11108               [(match_operand:SWI24 2 "register_operand" "")])
11109              (match_operand 3 "register_operand" "")])
11110           (match_operand 4 "" "")
11111           (match_operand 5 "" "")))
11112    (clobber (reg:CCFP FPSR_REG))
11113    (clobber (reg:CCFP FLAGS_REG))
11114    (clobber (match_scratch:HI 6 "=a"))]
11115   "reload_completed"
11116   [(const_int 0)]
11117 {
11118   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11119   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11120
11121   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11122                         operands[3], operands[7],
11123                         operands[4], operands[5], operands[6], operands[2]);
11124   DONE;
11125 })
11126 \f
11127 ;; Unconditional and other jump instructions
11128
11129 (define_insn "jump"
11130   [(set (pc)
11131         (label_ref (match_operand 0 "" "")))]
11132   ""
11133   "jmp\t%l0"
11134   [(set_attr "type" "ibr")
11135    (set (attr "length")
11136            (if_then_else (and (ge (minus (match_dup 0) (pc))
11137                                   (const_int -126))
11138                               (lt (minus (match_dup 0) (pc))
11139                                   (const_int 128)))
11140              (const_int 2)
11141              (const_int 5)))
11142    (set_attr "modrm" "0")])
11143
11144 (define_expand "indirect_jump"
11145   [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11146
11147 (define_insn "*indirect_jump"
11148   [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11149   ""
11150   "jmp\t%A0"
11151   [(set_attr "type" "ibr")
11152    (set_attr "length_immediate" "0")])
11153
11154 (define_expand "tablejump"
11155   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11156               (use (label_ref (match_operand 1 "" "")))])]
11157   ""
11158 {
11159   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11160      relative.  Convert the relative address to an absolute address.  */
11161   if (flag_pic)
11162     {
11163       rtx op0, op1;
11164       enum rtx_code code;
11165
11166       /* We can't use @GOTOFF for text labels on VxWorks;
11167          see gotoff_operand.  */
11168       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11169         {
11170           code = PLUS;
11171           op0 = operands[0];
11172           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11173         }
11174       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11175         {
11176           code = PLUS;
11177           op0 = operands[0];
11178           op1 = pic_offset_table_rtx;
11179         }
11180       else
11181         {
11182           code = MINUS;
11183           op0 = pic_offset_table_rtx;
11184           op1 = operands[0];
11185         }
11186
11187       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11188                                          OPTAB_DIRECT);
11189     }
11190   else if (TARGET_X32)
11191     operands[0] = convert_memory_address (Pmode, operands[0]);
11192 })
11193
11194 (define_insn "*tablejump_1"
11195   [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11196    (use (label_ref (match_operand 1 "" "")))]
11197   ""
11198   "jmp\t%A0"
11199   [(set_attr "type" "ibr")
11200    (set_attr "length_immediate" "0")])
11201 \f
11202 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11203
11204 (define_peephole2
11205   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11206    (set (match_operand:QI 1 "register_operand" "")
11207         (match_operator:QI 2 "ix86_comparison_operator"
11208           [(reg FLAGS_REG) (const_int 0)]))
11209    (set (match_operand 3 "q_regs_operand" "")
11210         (zero_extend (match_dup 1)))]
11211   "(peep2_reg_dead_p (3, operands[1])
11212     || operands_match_p (operands[1], operands[3]))
11213    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11214   [(set (match_dup 4) (match_dup 0))
11215    (set (strict_low_part (match_dup 5))
11216         (match_dup 2))]
11217 {
11218   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11219   operands[5] = gen_lowpart (QImode, operands[3]);
11220   ix86_expand_clear (operands[3]);
11221 })
11222
11223 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11224
11225 (define_peephole2
11226   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11227    (set (match_operand:QI 1 "register_operand" "")
11228         (match_operator:QI 2 "ix86_comparison_operator"
11229           [(reg FLAGS_REG) (const_int 0)]))
11230    (parallel [(set (match_operand 3 "q_regs_operand" "")
11231                    (zero_extend (match_dup 1)))
11232               (clobber (reg:CC FLAGS_REG))])]
11233   "(peep2_reg_dead_p (3, operands[1])
11234     || operands_match_p (operands[1], operands[3]))
11235    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11236   [(set (match_dup 4) (match_dup 0))
11237    (set (strict_low_part (match_dup 5))
11238         (match_dup 2))]
11239 {
11240   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11241   operands[5] = gen_lowpart (QImode, operands[3]);
11242   ix86_expand_clear (operands[3]);
11243 })
11244 \f
11245 ;; Call instructions.
11246
11247 ;; The predicates normally associated with named expanders are not properly
11248 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11249 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11250
11251 ;; P6 processors will jump to the address after the decrement when %esp
11252 ;; is used as a call operand, so they will execute return address as a code.
11253 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11254
11255 ;; Register constraint for call instruction.
11256 (define_mode_attr c [(SI "l") (DI "r")])
11257
11258 ;; Call subroutine returning no value.
11259
11260 (define_expand "call"
11261   [(call (match_operand:QI 0 "" "")
11262          (match_operand 1 "" ""))
11263    (use (match_operand 2 "" ""))]
11264   ""
11265 {
11266   ix86_expand_call (NULL, operands[0], operands[1],
11267                     operands[2], NULL, false);
11268   DONE;
11269 })
11270
11271 (define_expand "sibcall"
11272   [(call (match_operand:QI 0 "" "")
11273          (match_operand 1 "" ""))
11274    (use (match_operand 2 "" ""))]
11275   ""
11276 {
11277   ix86_expand_call (NULL, operands[0], operands[1],
11278                     operands[2], NULL, true);
11279   DONE;
11280 })
11281
11282 (define_insn_and_split "*call_vzeroupper"
11283   [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11284          (match_operand 1 "" ""))
11285    (unspec [(match_operand 2 "const_int_operand" "")]
11286            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11287   "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11288   "#"
11289   "&& reload_completed"
11290   [(const_int 0)]
11291   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11292   [(set_attr "type" "call")])
11293
11294 (define_insn "*call"
11295   [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11296          (match_operand 1 "" ""))]
11297   "!SIBLING_CALL_P (insn)"
11298   "* return ix86_output_call_insn (insn, operands[0]);"
11299   [(set_attr "type" "call")])
11300
11301 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11302   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11303          (match_operand 1 "" ""))
11304    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11305    (clobber (reg:TI XMM6_REG))
11306    (clobber (reg:TI XMM7_REG))
11307    (clobber (reg:TI XMM8_REG))
11308    (clobber (reg:TI XMM9_REG))
11309    (clobber (reg:TI XMM10_REG))
11310    (clobber (reg:TI XMM11_REG))
11311    (clobber (reg:TI XMM12_REG))
11312    (clobber (reg:TI XMM13_REG))
11313    (clobber (reg:TI XMM14_REG))
11314    (clobber (reg:TI XMM15_REG))
11315    (clobber (reg:DI SI_REG))
11316    (clobber (reg:DI DI_REG))
11317    (unspec [(match_operand 2 "const_int_operand" "")]
11318            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11319   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11320   "#"
11321   "&& reload_completed"
11322   [(const_int 0)]
11323   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11324   [(set_attr "type" "call")])
11325
11326 (define_insn "*call_rex64_ms_sysv"
11327   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11328          (match_operand 1 "" ""))
11329    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11330    (clobber (reg:TI XMM6_REG))
11331    (clobber (reg:TI XMM7_REG))
11332    (clobber (reg:TI XMM8_REG))
11333    (clobber (reg:TI XMM9_REG))
11334    (clobber (reg:TI XMM10_REG))
11335    (clobber (reg:TI XMM11_REG))
11336    (clobber (reg:TI XMM12_REG))
11337    (clobber (reg:TI XMM13_REG))
11338    (clobber (reg:TI XMM14_REG))
11339    (clobber (reg:TI XMM15_REG))
11340    (clobber (reg:DI SI_REG))
11341    (clobber (reg:DI DI_REG))]
11342   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11343   "* return ix86_output_call_insn (insn, operands[0]);"
11344   [(set_attr "type" "call")])
11345
11346 (define_insn_and_split "*sibcall_vzeroupper"
11347   [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11348          (match_operand 1 "" ""))
11349    (unspec [(match_operand 2 "const_int_operand" "")]
11350            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11351   "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11352   "#"
11353   "&& reload_completed"
11354   [(const_int 0)]
11355   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11356   [(set_attr "type" "call")])
11357
11358 (define_insn "*sibcall"
11359   [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11360          (match_operand 1 "" ""))]
11361   "SIBLING_CALL_P (insn)"
11362   "* return ix86_output_call_insn (insn, operands[0]);"
11363   [(set_attr "type" "call")])
11364
11365 (define_expand "call_pop"
11366   [(parallel [(call (match_operand:QI 0 "" "")
11367                     (match_operand:SI 1 "" ""))
11368               (set (reg:SI SP_REG)
11369                    (plus:SI (reg:SI SP_REG)
11370                             (match_operand:SI 3 "" "")))])]
11371   "!TARGET_64BIT"
11372 {
11373   ix86_expand_call (NULL, operands[0], operands[1],
11374                     operands[2], operands[3], false);
11375   DONE;
11376 })
11377
11378 (define_insn_and_split "*call_pop_vzeroupper"
11379   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11380          (match_operand:SI 1 "" ""))
11381    (set (reg:SI SP_REG)
11382         (plus:SI (reg:SI SP_REG)
11383                  (match_operand:SI 2 "immediate_operand" "i")))
11384    (unspec [(match_operand 3 "const_int_operand" "")]
11385            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11386   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11387   "#"
11388   "&& reload_completed"
11389   [(const_int 0)]
11390   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11391   [(set_attr "type" "call")])
11392
11393 (define_insn "*call_pop"
11394   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11395          (match_operand 1 "" ""))
11396    (set (reg:SI SP_REG)
11397         (plus:SI (reg:SI SP_REG)
11398                  (match_operand:SI 2 "immediate_operand" "i")))]
11399   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11400   "* return ix86_output_call_insn (insn, operands[0]);"
11401   [(set_attr "type" "call")])
11402
11403 (define_insn_and_split "*sibcall_pop_vzeroupper"
11404   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11405          (match_operand 1 "" ""))
11406    (set (reg:SI SP_REG)
11407         (plus:SI (reg:SI SP_REG)
11408                  (match_operand:SI 2 "immediate_operand" "i")))
11409    (unspec [(match_operand 3 "const_int_operand" "")]
11410            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11411   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11412   "#"
11413   "&& reload_completed"
11414   [(const_int 0)]
11415   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11416   [(set_attr "type" "call")])
11417
11418 (define_insn "*sibcall_pop"
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   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11425   "* return ix86_output_call_insn (insn, operands[0]);"
11426   [(set_attr "type" "call")])
11427
11428 ;; Call subroutine, returning value in operand 0
11429
11430 (define_expand "call_value"
11431   [(set (match_operand 0 "" "")
11432         (call (match_operand:QI 1 "" "")
11433               (match_operand 2 "" "")))
11434    (use (match_operand 3 "" ""))]
11435   ""
11436 {
11437   ix86_expand_call (operands[0], operands[1], operands[2],
11438                     operands[3], NULL, false);
11439   DONE;
11440 })
11441
11442 (define_expand "sibcall_value"
11443   [(set (match_operand 0 "" "")
11444         (call (match_operand:QI 1 "" "")
11445               (match_operand 2 "" "")))
11446    (use (match_operand 3 "" ""))]
11447   ""
11448 {
11449   ix86_expand_call (operands[0], operands[1], operands[2],
11450                     operands[3], NULL, true);
11451   DONE;
11452 })
11453
11454 (define_insn_and_split "*call_value_vzeroupper"
11455   [(set (match_operand 0 "" "")
11456         (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11457               (match_operand 2 "" "")))
11458    (unspec [(match_operand 3 "const_int_operand" "")]
11459            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11460   "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11461   "#"
11462   "&& reload_completed"
11463   [(const_int 0)]
11464   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11465   [(set_attr "type" "callv")])
11466
11467 (define_insn "*call_value"
11468   [(set (match_operand 0 "" "")
11469         (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11470               (match_operand 2 "" "")))]
11471   "!SIBLING_CALL_P (insn)"
11472   "* return ix86_output_call_insn (insn, operands[1]);"
11473   [(set_attr "type" "callv")])
11474
11475 (define_insn_and_split "*sibcall_value_vzeroupper"
11476   [(set (match_operand 0 "" "")
11477         (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11478               (match_operand 2 "" "")))
11479    (unspec [(match_operand 3 "const_int_operand" "")]
11480            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11481   "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11482   "#"
11483   "&& reload_completed"
11484   [(const_int 0)]
11485   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11486   [(set_attr "type" "callv")])
11487
11488 (define_insn "*sibcall_value"
11489   [(set (match_operand 0 "" "")
11490         (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11491               (match_operand 2 "" "")))]
11492   "SIBLING_CALL_P (insn)"
11493   "* return ix86_output_call_insn (insn, operands[1]);"
11494   [(set_attr "type" "callv")])
11495
11496 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11497   [(set (match_operand 0 "" "")
11498         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11499               (match_operand 2 "" "")))
11500    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11501    (clobber (reg:TI XMM6_REG))
11502    (clobber (reg:TI XMM7_REG))
11503    (clobber (reg:TI XMM8_REG))
11504    (clobber (reg:TI XMM9_REG))
11505    (clobber (reg:TI XMM10_REG))
11506    (clobber (reg:TI XMM11_REG))
11507    (clobber (reg:TI XMM12_REG))
11508    (clobber (reg:TI XMM13_REG))
11509    (clobber (reg:TI XMM14_REG))
11510    (clobber (reg:TI XMM15_REG))
11511    (clobber (reg:DI SI_REG))
11512    (clobber (reg:DI DI_REG))
11513    (unspec [(match_operand 3 "const_int_operand" "")]
11514            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11515   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11516   "#"
11517   "&& reload_completed"
11518   [(const_int 0)]
11519   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11520   [(set_attr "type" "callv")])
11521
11522 (define_insn "*call_value_rex64_ms_sysv"
11523   [(set (match_operand 0 "" "")
11524         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11525               (match_operand 2 "" "")))
11526    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11527    (clobber (reg:TI XMM6_REG))
11528    (clobber (reg:TI XMM7_REG))
11529    (clobber (reg:TI XMM8_REG))
11530    (clobber (reg:TI XMM9_REG))
11531    (clobber (reg:TI XMM10_REG))
11532    (clobber (reg:TI XMM11_REG))
11533    (clobber (reg:TI XMM12_REG))
11534    (clobber (reg:TI XMM13_REG))
11535    (clobber (reg:TI XMM14_REG))
11536    (clobber (reg:TI XMM15_REG))
11537    (clobber (reg:DI SI_REG))
11538    (clobber (reg:DI DI_REG))]
11539   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11540   "* return ix86_output_call_insn (insn, operands[1]);"
11541   [(set_attr "type" "callv")])
11542
11543 (define_expand "call_value_pop"
11544   [(parallel [(set (match_operand 0 "" "")
11545                    (call (match_operand:QI 1 "" "")
11546                          (match_operand:SI 2 "" "")))
11547               (set (reg:SI SP_REG)
11548                    (plus:SI (reg:SI SP_REG)
11549                             (match_operand:SI 4 "" "")))])]
11550   "!TARGET_64BIT"
11551 {
11552   ix86_expand_call (operands[0], operands[1], operands[2],
11553                     operands[3], operands[4], false);
11554   DONE;
11555 })
11556
11557 (define_insn_and_split "*call_value_pop_vzeroupper"
11558   [(set (match_operand 0 "" "")
11559         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11560               (match_operand 2 "" "")))
11561    (set (reg:SI SP_REG)
11562         (plus:SI (reg:SI SP_REG)
11563                  (match_operand:SI 3 "immediate_operand" "i")))
11564    (unspec [(match_operand 4 "const_int_operand" "")]
11565            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11566   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11567   "#"
11568   "&& reload_completed"
11569   [(const_int 0)]
11570   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11571   [(set_attr "type" "callv")])
11572
11573 (define_insn "*call_value_pop"
11574   [(set (match_operand 0 "" "")
11575         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11576               (match_operand 2 "" "")))
11577    (set (reg:SI SP_REG)
11578         (plus:SI (reg:SI SP_REG)
11579                  (match_operand:SI 3 "immediate_operand" "i")))]
11580   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11581   "* return ix86_output_call_insn (insn, operands[1]);"
11582   [(set_attr "type" "callv")])
11583
11584 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11585   [(set (match_operand 0 "" "")
11586         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11587               (match_operand 2 "" "")))
11588    (set (reg:SI SP_REG)
11589         (plus:SI (reg:SI SP_REG)
11590                  (match_operand:SI 3 "immediate_operand" "i")))
11591    (unspec [(match_operand 4 "const_int_operand" "")]
11592            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11593   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11594   "#"
11595   "&& reload_completed"
11596   [(const_int 0)]
11597   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11598   [(set_attr "type" "callv")])
11599
11600 (define_insn "*sibcall_value_pop"
11601   [(set (match_operand 0 "" "")
11602         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11603               (match_operand 2 "" "")))
11604    (set (reg:SI SP_REG)
11605         (plus:SI (reg:SI SP_REG)
11606                  (match_operand:SI 3 "immediate_operand" "i")))]
11607   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11608   "* return ix86_output_call_insn (insn, operands[1]);"
11609   [(set_attr "type" "callv")])
11610
11611 ;; Call subroutine returning any type.
11612
11613 (define_expand "untyped_call"
11614   [(parallel [(call (match_operand 0 "" "")
11615                     (const_int 0))
11616               (match_operand 1 "" "")
11617               (match_operand 2 "" "")])]
11618   ""
11619 {
11620   int i;
11621
11622   /* In order to give reg-stack an easier job in validating two
11623      coprocessor registers as containing a possible return value,
11624      simply pretend the untyped call returns a complex long double
11625      value. 
11626
11627      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11628      and should have the default ABI.  */
11629
11630   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11631                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11632                     operands[0], const0_rtx,
11633                     GEN_INT ((TARGET_64BIT
11634                               ? (ix86_abi == SYSV_ABI
11635                                  ? X86_64_SSE_REGPARM_MAX
11636                                  : X86_64_MS_SSE_REGPARM_MAX)
11637                               : X86_32_SSE_REGPARM_MAX)
11638                              - 1),
11639                     NULL, false);
11640
11641   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11642     {
11643       rtx set = XVECEXP (operands[2], 0, i);
11644       emit_move_insn (SET_DEST (set), SET_SRC (set));
11645     }
11646
11647   /* The optimizer does not know that the call sets the function value
11648      registers we stored in the result block.  We avoid problems by
11649      claiming that all hard registers are used and clobbered at this
11650      point.  */
11651   emit_insn (gen_blockage ());
11652
11653   DONE;
11654 })
11655 \f
11656 ;; Prologue and epilogue instructions
11657
11658 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11659 ;; all of memory.  This blocks insns from being moved across this point.
11660
11661 (define_insn "blockage"
11662   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11663   ""
11664   ""
11665   [(set_attr "length" "0")])
11666
11667 ;; Do not schedule instructions accessing memory across this point.
11668
11669 (define_expand "memory_blockage"
11670   [(set (match_dup 0)
11671         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11672   ""
11673 {
11674   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11675   MEM_VOLATILE_P (operands[0]) = 1;
11676 })
11677
11678 (define_insn "*memory_blockage"
11679   [(set (match_operand:BLK 0 "" "")
11680         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11681   ""
11682   ""
11683   [(set_attr "length" "0")])
11684
11685 ;; As USE insns aren't meaningful after reload, this is used instead
11686 ;; to prevent deleting instructions setting registers for PIC code
11687 (define_insn "prologue_use"
11688   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11689   ""
11690   ""
11691   [(set_attr "length" "0")])
11692
11693 ;; Insn emitted into the body of a function to return from a function.
11694 ;; This is only done if the function's epilogue is known to be simple.
11695 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11696
11697 (define_expand "return"
11698   [(return)]
11699   "ix86_can_use_return_insn_p ()"
11700 {
11701   if (crtl->args.pops_args)
11702     {
11703       rtx popc = GEN_INT (crtl->args.pops_args);
11704       emit_jump_insn (gen_return_pop_internal (popc));
11705       DONE;
11706     }
11707 })
11708
11709 (define_insn "return_internal"
11710   [(return)]
11711   "reload_completed"
11712   "ret"
11713   [(set_attr "length" "1")
11714    (set_attr "atom_unit" "jeu")
11715    (set_attr "length_immediate" "0")
11716    (set_attr "modrm" "0")])
11717
11718 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11719 ;; instruction Athlon and K8 have.
11720
11721 (define_insn "return_internal_long"
11722   [(return)
11723    (unspec [(const_int 0)] UNSPEC_REP)]
11724   "reload_completed"
11725   "rep\;ret"
11726   [(set_attr "length" "2")
11727    (set_attr "atom_unit" "jeu")
11728    (set_attr "length_immediate" "0")
11729    (set_attr "prefix_rep" "1")
11730    (set_attr "modrm" "0")])
11731
11732 (define_insn "return_pop_internal"
11733   [(return)
11734    (use (match_operand:SI 0 "const_int_operand" ""))]
11735   "reload_completed"
11736   "ret\t%0"
11737   [(set_attr "length" "3")
11738    (set_attr "atom_unit" "jeu")
11739    (set_attr "length_immediate" "2")
11740    (set_attr "modrm" "0")])
11741
11742 (define_insn "return_indirect_internal"
11743   [(return)
11744    (use (match_operand:SI 0 "register_operand" "r"))]
11745   "reload_completed"
11746   "jmp\t%A0"
11747   [(set_attr "type" "ibr")
11748    (set_attr "length_immediate" "0")])
11749
11750 (define_insn "nop"
11751   [(const_int 0)]
11752   ""
11753   "nop"
11754   [(set_attr "length" "1")
11755    (set_attr "length_immediate" "0")
11756    (set_attr "modrm" "0")])
11757
11758 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
11759 (define_insn "nops"
11760   [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11761                     UNSPECV_NOPS)]
11762   "reload_completed"
11763 {
11764   int num = INTVAL (operands[0]);
11765
11766   gcc_assert (num >= 1 && num <= 8);
11767
11768   while (num--)
11769     fputs ("\tnop\n", asm_out_file);
11770
11771   return "";
11772 }
11773   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11774    (set_attr "length_immediate" "0")
11775    (set_attr "modrm" "0")])
11776
11777 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11778 ;; branch prediction penalty for the third jump in a 16-byte
11779 ;; block on K8.
11780
11781 (define_insn "pad"
11782   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11783   ""
11784 {
11785 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11786   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11787 #else
11788   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11789      The align insn is used to avoid 3 jump instructions in the row to improve
11790      branch prediction and the benefits hardly outweigh the cost of extra 8
11791      nops on the average inserted by full alignment pseudo operation.  */
11792 #endif
11793   return "";
11794 }
11795   [(set_attr "length" "16")])
11796
11797 (define_expand "prologue"
11798   [(const_int 0)]
11799   ""
11800   "ix86_expand_prologue (); DONE;")
11801
11802 (define_insn "set_got"
11803   [(set (match_operand:SI 0 "register_operand" "=r")
11804         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11805    (clobber (reg:CC FLAGS_REG))]
11806   "!TARGET_64BIT"
11807   "* return output_set_got (operands[0], NULL_RTX);"
11808   [(set_attr "type" "multi")
11809    (set_attr "length" "12")])
11810
11811 (define_insn "set_got_labelled"
11812   [(set (match_operand:SI 0 "register_operand" "=r")
11813         (unspec:SI [(label_ref (match_operand 1 "" ""))]
11814          UNSPEC_SET_GOT))
11815    (clobber (reg:CC FLAGS_REG))]
11816   "!TARGET_64BIT"
11817   "* return output_set_got (operands[0], operands[1]);"
11818   [(set_attr "type" "multi")
11819    (set_attr "length" "12")])
11820
11821 (define_insn "set_got_rex64"
11822   [(set (match_operand:DI 0 "register_operand" "=r")
11823         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11824   "TARGET_64BIT"
11825   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11826   [(set_attr "type" "lea")
11827    (set_attr "length_address" "4")
11828    (set_attr "mode" "DI")])
11829
11830 (define_insn "set_rip_rex64"
11831   [(set (match_operand:DI 0 "register_operand" "=r")
11832         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11833   "TARGET_64BIT"
11834   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11835   [(set_attr "type" "lea")
11836    (set_attr "length_address" "4")
11837    (set_attr "mode" "DI")])
11838
11839 (define_insn "set_got_offset_rex64"
11840   [(set (match_operand:DI 0 "register_operand" "=r")
11841         (unspec:DI
11842           [(label_ref (match_operand 1 "" ""))]
11843           UNSPEC_SET_GOT_OFFSET))]
11844   "TARGET_LP64"
11845   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11846   [(set_attr "type" "imov")
11847    (set_attr "length_immediate" "0")
11848    (set_attr "length_address" "8")
11849    (set_attr "mode" "DI")])
11850
11851 (define_expand "epilogue"
11852   [(const_int 0)]
11853   ""
11854   "ix86_expand_epilogue (1); DONE;")
11855
11856 (define_expand "sibcall_epilogue"
11857   [(const_int 0)]
11858   ""
11859   "ix86_expand_epilogue (0); DONE;")
11860
11861 (define_expand "eh_return"
11862   [(use (match_operand 0 "register_operand" ""))]
11863   ""
11864 {
11865   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11866
11867   /* Tricky bit: we write the address of the handler to which we will
11868      be returning into someone else's stack frame, one word below the
11869      stack address we wish to restore.  */
11870   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11871   tmp = plus_constant (tmp, -UNITS_PER_WORD);
11872   tmp = gen_rtx_MEM (Pmode, tmp);
11873   emit_move_insn (tmp, ra);
11874
11875   emit_jump_insn (gen_eh_return_internal ());
11876   emit_barrier ();
11877   DONE;
11878 })
11879
11880 (define_insn_and_split "eh_return_internal"
11881   [(eh_return)]
11882   ""
11883   "#"
11884   "epilogue_completed"
11885   [(const_int 0)]
11886   "ix86_expand_epilogue (2); DONE;")
11887
11888 (define_insn "leave"
11889   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11890    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11891    (clobber (mem:BLK (scratch)))]
11892   "!TARGET_64BIT"
11893   "leave"
11894   [(set_attr "type" "leave")])
11895
11896 (define_insn "leave_rex64"
11897   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11898    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11899    (clobber (mem:BLK (scratch)))]
11900   "TARGET_64BIT"
11901   "leave"
11902   [(set_attr "type" "leave")])
11903 \f
11904 ;; Handle -fsplit-stack.
11905
11906 (define_expand "split_stack_prologue"
11907   [(const_int 0)]
11908   ""
11909 {
11910   ix86_expand_split_stack_prologue ();
11911   DONE;
11912 })
11913
11914 ;; In order to support the call/return predictor, we use a return
11915 ;; instruction which the middle-end doesn't see.
11916 (define_insn "split_stack_return"
11917   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11918                      UNSPECV_SPLIT_STACK_RETURN)]
11919   ""
11920 {
11921   if (operands[0] == const0_rtx)
11922     return "ret";
11923   else
11924     return "ret\t%0";
11925 }
11926   [(set_attr "atom_unit" "jeu")
11927    (set_attr "modrm" "0")
11928    (set (attr "length")
11929         (if_then_else (match_operand:SI 0 "const0_operand" "")
11930                       (const_int 1)
11931                       (const_int 3)))
11932    (set (attr "length_immediate")
11933         (if_then_else (match_operand:SI 0 "const0_operand" "")
11934                       (const_int 0)
11935                       (const_int 2)))])
11936
11937 ;; If there are operand 0 bytes available on the stack, jump to
11938 ;; operand 1.
11939
11940 (define_expand "split_stack_space_check"
11941   [(set (pc) (if_then_else
11942               (ltu (minus (reg SP_REG)
11943                           (match_operand 0 "register_operand" ""))
11944                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11945               (label_ref (match_operand 1 "" ""))
11946               (pc)))]
11947   ""
11948 {
11949   rtx reg, size, limit;
11950
11951   reg = gen_reg_rtx (Pmode);
11952   size = force_reg (Pmode, operands[0]);
11953   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11954   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11955                           UNSPEC_STACK_CHECK);
11956   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11957   ix86_expand_branch (GEU, reg, limit, operands[1]);
11958
11959   DONE;
11960 })
11961 \f
11962 ;; Bit manipulation instructions.
11963
11964 (define_expand "ffs<mode>2"
11965   [(set (match_dup 2) (const_int -1))
11966    (parallel [(set (reg:CCZ FLAGS_REG)
11967                    (compare:CCZ
11968                      (match_operand:SWI48 1 "nonimmediate_operand" "")
11969                      (const_int 0)))
11970               (set (match_operand:SWI48 0 "register_operand" "")
11971                    (ctz:SWI48 (match_dup 1)))])
11972    (set (match_dup 0) (if_then_else:SWI48
11973                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
11974                         (match_dup 2)
11975                         (match_dup 0)))
11976    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11977               (clobber (reg:CC FLAGS_REG))])]
11978   ""
11979 {
11980   if (<MODE>mode == SImode && !TARGET_CMOVE)
11981     {
11982       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11983       DONE;
11984     }
11985   operands[2] = gen_reg_rtx (<MODE>mode);
11986 })
11987
11988 (define_insn_and_split "ffssi2_no_cmove"
11989   [(set (match_operand:SI 0 "register_operand" "=r")
11990         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11991    (clobber (match_scratch:SI 2 "=&q"))
11992    (clobber (reg:CC FLAGS_REG))]
11993   "!TARGET_CMOVE"
11994   "#"
11995   "&& reload_completed"
11996   [(parallel [(set (reg:CCZ FLAGS_REG)
11997                    (compare:CCZ (match_dup 1) (const_int 0)))
11998               (set (match_dup 0) (ctz:SI (match_dup 1)))])
11999    (set (strict_low_part (match_dup 3))
12000         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12001    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12002               (clobber (reg:CC FLAGS_REG))])
12003    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12004               (clobber (reg:CC FLAGS_REG))])
12005    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12006               (clobber (reg:CC FLAGS_REG))])]
12007 {
12008   operands[3] = gen_lowpart (QImode, operands[2]);
12009   ix86_expand_clear (operands[2]);
12010 })
12011
12012 (define_insn "*ffs<mode>_1"
12013   [(set (reg:CCZ FLAGS_REG)
12014         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12015                      (const_int 0)))
12016    (set (match_operand:SWI48 0 "register_operand" "=r")
12017         (ctz:SWI48 (match_dup 1)))]
12018   ""
12019   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12020   [(set_attr "type" "alu1")
12021    (set_attr "prefix_0f" "1")
12022    (set_attr "mode" "<MODE>")])
12023
12024 (define_insn "ctz<mode>2"
12025   [(set (match_operand:SWI248 0 "register_operand" "=r")
12026         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12027    (clobber (reg:CC FLAGS_REG))]
12028   ""
12029 {
12030   if (TARGET_BMI)
12031     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12032   else
12033     return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12034 }
12035   [(set_attr "type" "alu1")
12036    (set_attr "prefix_0f" "1")
12037    (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12038    (set_attr "mode" "<MODE>")])
12039
12040 (define_expand "clz<mode>2"
12041   [(parallel
12042      [(set (match_operand:SWI248 0 "register_operand" "")
12043            (minus:SWI248
12044              (match_dup 2)
12045              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12046       (clobber (reg:CC FLAGS_REG))])
12047    (parallel
12048      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12049       (clobber (reg:CC FLAGS_REG))])]
12050   ""
12051 {
12052   if (TARGET_LZCNT)
12053     {
12054       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12055       DONE;
12056     }
12057   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12058 })
12059
12060 (define_insn "clz<mode>2_lzcnt"
12061   [(set (match_operand:SWI248 0 "register_operand" "=r")
12062         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12063    (clobber (reg:CC FLAGS_REG))]
12064   "TARGET_LZCNT"
12065   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12066   [(set_attr "prefix_rep" "1")
12067    (set_attr "type" "bitmanip")
12068    (set_attr "mode" "<MODE>")])
12069
12070 ;; BMI instructions.
12071 (define_insn "*bmi_andn_<mode>"
12072   [(set (match_operand:SWI48 0 "register_operand" "=r")
12073         (and:SWI48
12074           (not:SWI48
12075             (match_operand:SWI48 1 "register_operand" "r"))
12076             (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12077    (clobber (reg:CC FLAGS_REG))]
12078   "TARGET_BMI"
12079   "andn\t{%2, %1, %0|%0, %1, %2}"
12080   [(set_attr "type" "bitmanip")
12081    (set_attr "mode" "<MODE>")])
12082
12083 (define_insn "bmi_bextr_<mode>"
12084   [(set (match_operand:SWI48 0 "register_operand" "=r")
12085         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
12086                        (match_operand:SWI48 2 "register_operand" "r")]
12087                        UNSPEC_BEXTR))
12088    (clobber (reg:CC FLAGS_REG))]
12089   "TARGET_BMI"
12090   "bextr\t{%2, %1, %0|%0, %1, %2}"
12091   [(set_attr "type" "bitmanip")
12092    (set_attr "mode" "<MODE>")])
12093
12094 (define_insn "*bmi_blsi_<mode>"
12095   [(set (match_operand:SWI48 0 "register_operand" "=r")
12096         (and:SWI48
12097           (neg:SWI48
12098             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12099           (match_dup 1)))
12100    (clobber (reg:CC FLAGS_REG))]
12101   "TARGET_BMI"
12102   "blsi\t{%1, %0|%0, %1}"
12103   [(set_attr "type" "bitmanip")
12104    (set_attr "mode" "<MODE>")])
12105
12106 (define_insn "*bmi_blsmsk_<mode>"
12107   [(set (match_operand:SWI48 0 "register_operand" "=r")
12108         (xor:SWI48
12109           (plus:SWI48
12110             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12111             (const_int -1))
12112           (match_dup 1)))
12113    (clobber (reg:CC FLAGS_REG))]
12114   "TARGET_BMI"
12115   "blsmsk\t{%1, %0|%0, %1}"
12116   [(set_attr "type" "bitmanip")
12117    (set_attr "mode" "<MODE>")])
12118
12119 (define_insn "*bmi_blsr_<mode>"
12120   [(set (match_operand:SWI48 0 "register_operand" "=r")
12121         (and:SWI48
12122           (plus:SWI48
12123             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12124             (const_int -1))
12125           (match_dup 1)))
12126    (clobber (reg:CC FLAGS_REG))]
12127    "TARGET_BMI"
12128    "blsr\t{%1, %0|%0, %1}"
12129   [(set_attr "type" "bitmanip")
12130    (set_attr "mode" "<MODE>")])
12131
12132 ;; BMI2 instructions.
12133 (define_insn "bmi2_bzhi_<mode>3"
12134   [(set (match_operand:SWI48 0 "register_operand" "=r")
12135         (and:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12136                    (lshiftrt:SWI48 (const_int -1)
12137                                    (match_operand:SWI48 2 "register_operand" "r"))))
12138    (clobber (reg:CC FLAGS_REG))]
12139   "TARGET_BMI2"
12140   "bzhi\t{%2, %1, %0|%0, %1, %2}"
12141   [(set_attr "type" "bitmanip")
12142    (set_attr "prefix" "vex")
12143    (set_attr "mode" "<MODE>")])
12144
12145 (define_insn "bmi2_pdep_<mode>3"
12146   [(set (match_operand:SWI48 0 "register_operand" "=r")
12147         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
12148                        (match_operand:SWI48 2 "register_operand" "r")]
12149                        UNSPEC_PDEP))]
12150   "TARGET_BMI2"
12151   "pdep\t{%2, %1, %0|%0, %1, %2}"
12152   [(set_attr "type" "bitmanip")
12153    (set_attr "prefix" "vex")
12154    (set_attr "mode" "<MODE>")])
12155
12156 (define_insn "bmi2_pext_<mode>3"
12157   [(set (match_operand:SWI48 0 "register_operand" "=r")
12158         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
12159                        (match_operand:SWI48 2 "register_operand" "r")]
12160                        UNSPEC_PEXT))]
12161   "TARGET_BMI2"
12162   "pext\t{%2, %1, %0|%0, %1, %2}"
12163   [(set_attr "type" "bitmanip")
12164    (set_attr "prefix" "vex")
12165    (set_attr "mode" "<MODE>")])
12166
12167 ;; TBM instructions.
12168 (define_insn "tbm_bextri_<mode>"
12169   [(set (match_operand:SWI48 0 "register_operand" "=r")
12170         (zero_extract:SWI48
12171           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12172           (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12173           (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12174    (clobber (reg:CC FLAGS_REG))]
12175    "TARGET_TBM"
12176 {
12177   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12178   return "bextr\t{%2, %1, %0|%0, %1, %2}";
12179 }
12180   [(set_attr "type" "bitmanip")
12181    (set_attr "mode" "<MODE>")])
12182
12183 (define_insn "*tbm_blcfill_<mode>"
12184   [(set (match_operand:SWI48 0 "register_operand" "=r")
12185         (and:SWI48
12186           (plus:SWI48
12187             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12188             (const_int 1))
12189           (match_dup 1)))
12190    (clobber (reg:CC FLAGS_REG))]
12191    "TARGET_TBM"
12192    "blcfill\t{%1, %0|%0, %1}"
12193   [(set_attr "type" "bitmanip")
12194    (set_attr "mode" "<MODE>")])
12195
12196 (define_insn "*tbm_blci_<mode>"
12197   [(set (match_operand:SWI48 0 "register_operand" "=r")
12198         (ior:SWI48
12199           (not:SWI48
12200             (plus:SWI48
12201               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12202               (const_int 1)))
12203           (match_dup 1)))
12204    (clobber (reg:CC FLAGS_REG))]
12205    "TARGET_TBM"
12206    "blci\t{%1, %0|%0, %1}"
12207   [(set_attr "type" "bitmanip")
12208    (set_attr "mode" "<MODE>")])
12209
12210 (define_insn "*tbm_blcic_<mode>"
12211   [(set (match_operand:SWI48 0 "register_operand" "=r")
12212         (and:SWI48
12213           (plus:SWI48
12214             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12215             (const_int 1))
12216           (not:SWI48
12217             (match_dup 1))))
12218    (clobber (reg:CC FLAGS_REG))]
12219    "TARGET_TBM"
12220    "blcic\t{%1, %0|%0, %1}"
12221   [(set_attr "type" "bitmanip")
12222    (set_attr "mode" "<MODE>")])
12223
12224 (define_insn "*tbm_blcmsk_<mode>"
12225   [(set (match_operand:SWI48 0 "register_operand" "=r")
12226         (xor:SWI48
12227           (plus:SWI48
12228             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12229             (const_int 1))
12230           (match_dup 1)))
12231    (clobber (reg:CC FLAGS_REG))]
12232    "TARGET_TBM"
12233    "blcmsk\t{%1, %0|%0, %1}"
12234   [(set_attr "type" "bitmanip")
12235    (set_attr "mode" "<MODE>")])
12236
12237 (define_insn "*tbm_blcs_<mode>"
12238   [(set (match_operand:SWI48 0 "register_operand" "=r")
12239         (ior:SWI48
12240           (plus:SWI48
12241             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12242             (const_int 1))
12243           (match_dup 1)))
12244    (clobber (reg:CC FLAGS_REG))]
12245    "TARGET_TBM"
12246    "blcs\t{%1, %0|%0, %1}"
12247   [(set_attr "type" "bitmanip")
12248    (set_attr "mode" "<MODE>")])
12249
12250 (define_insn "*tbm_blsfill_<mode>"
12251   [(set (match_operand:SWI48 0 "register_operand" "=r")
12252         (ior:SWI48
12253           (plus:SWI48
12254             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12255             (const_int -1))
12256           (match_dup 1)))
12257    (clobber (reg:CC FLAGS_REG))]
12258    "TARGET_TBM"
12259    "blsfill\t{%1, %0|%0, %1}"
12260   [(set_attr "type" "bitmanip")
12261    (set_attr "mode" "<MODE>")])
12262
12263 (define_insn "*tbm_blsic_<mode>"
12264   [(set (match_operand:SWI48 0 "register_operand" "=r")
12265         (ior:SWI48
12266           (plus:SWI48
12267             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12268             (const_int -1))
12269           (not:SWI48
12270             (match_dup 1))))
12271    (clobber (reg:CC FLAGS_REG))]
12272    "TARGET_TBM"
12273    "blsic\t{%1, %0|%0, %1}"
12274   [(set_attr "type" "bitmanip")
12275    (set_attr "mode" "<MODE>")])
12276
12277 (define_insn "*tbm_t1mskc_<mode>"
12278   [(set (match_operand:SWI48 0 "register_operand" "=r")
12279         (ior:SWI48
12280           (plus:SWI48
12281             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12282             (const_int 1))
12283           (not:SWI48
12284             (match_dup 1))))
12285    (clobber (reg:CC FLAGS_REG))]
12286    "TARGET_TBM"
12287    "t1mskc\t{%1, %0|%0, %1}"
12288   [(set_attr "type" "bitmanip")
12289    (set_attr "mode" "<MODE>")])
12290
12291 (define_insn "*tbm_tzmsk_<mode>"
12292   [(set (match_operand:SWI48 0 "register_operand" "=r")
12293         (and:SWI48
12294           (plus:SWI48
12295             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12296             (const_int -1))
12297           (not:SWI48
12298             (match_dup 1))))
12299    (clobber (reg:CC FLAGS_REG))]
12300    "TARGET_TBM"
12301    "tzmsk\t{%1, %0|%0, %1}"
12302   [(set_attr "type" "bitmanip")
12303    (set_attr "mode" "<MODE>")])
12304
12305 (define_insn "bsr_rex64"
12306   [(set (match_operand:DI 0 "register_operand" "=r")
12307         (minus:DI (const_int 63)
12308                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12309    (clobber (reg:CC FLAGS_REG))]
12310   "TARGET_64BIT"
12311   "bsr{q}\t{%1, %0|%0, %1}"
12312   [(set_attr "type" "alu1")
12313    (set_attr "prefix_0f" "1")
12314    (set_attr "mode" "DI")])
12315
12316 (define_insn "bsr"
12317   [(set (match_operand:SI 0 "register_operand" "=r")
12318         (minus:SI (const_int 31)
12319                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12320    (clobber (reg:CC FLAGS_REG))]
12321   ""
12322   "bsr{l}\t{%1, %0|%0, %1}"
12323   [(set_attr "type" "alu1")
12324    (set_attr "prefix_0f" "1")
12325    (set_attr "mode" "SI")])
12326
12327 (define_insn "*bsrhi"
12328   [(set (match_operand:HI 0 "register_operand" "=r")
12329         (minus:HI (const_int 15)
12330                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12331    (clobber (reg:CC FLAGS_REG))]
12332   ""
12333   "bsr{w}\t{%1, %0|%0, %1}"
12334   [(set_attr "type" "alu1")
12335    (set_attr "prefix_0f" "1")
12336    (set_attr "mode" "HI")])
12337
12338 (define_insn "popcount<mode>2"
12339   [(set (match_operand:SWI248 0 "register_operand" "=r")
12340         (popcount:SWI248
12341           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12342    (clobber (reg:CC FLAGS_REG))]
12343   "TARGET_POPCNT"
12344 {
12345 #if TARGET_MACHO
12346   return "popcnt\t{%1, %0|%0, %1}";
12347 #else
12348   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12349 #endif
12350 }
12351   [(set_attr "prefix_rep" "1")
12352    (set_attr "type" "bitmanip")
12353    (set_attr "mode" "<MODE>")])
12354
12355 (define_insn "*popcount<mode>2_cmp"
12356   [(set (reg FLAGS_REG)
12357         (compare
12358           (popcount:SWI248
12359             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12360           (const_int 0)))
12361    (set (match_operand:SWI248 0 "register_operand" "=r")
12362         (popcount:SWI248 (match_dup 1)))]
12363   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12364 {
12365 #if TARGET_MACHO
12366   return "popcnt\t{%1, %0|%0, %1}";
12367 #else
12368   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12369 #endif
12370 }
12371   [(set_attr "prefix_rep" "1")
12372    (set_attr "type" "bitmanip")
12373    (set_attr "mode" "<MODE>")])
12374
12375 (define_insn "*popcountsi2_cmp_zext"
12376   [(set (reg FLAGS_REG)
12377         (compare
12378           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12379           (const_int 0)))
12380    (set (match_operand:DI 0 "register_operand" "=r")
12381         (zero_extend:DI(popcount:SI (match_dup 1))))]
12382   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12383 {
12384 #if TARGET_MACHO
12385   return "popcnt\t{%1, %0|%0, %1}";
12386 #else
12387   return "popcnt{l}\t{%1, %0|%0, %1}";
12388 #endif
12389 }
12390   [(set_attr "prefix_rep" "1")
12391    (set_attr "type" "bitmanip")
12392    (set_attr "mode" "SI")])
12393
12394 (define_expand "bswap<mode>2"
12395   [(set (match_operand:SWI48 0 "register_operand" "")
12396         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12397   ""
12398 {
12399   if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12400     {
12401       rtx x = operands[0];
12402
12403       emit_move_insn (x, operands[1]);
12404       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12405       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12406       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12407       DONE;
12408     }
12409 })
12410
12411 (define_insn "*bswap<mode>2_movbe"
12412   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12413         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12414   "TARGET_MOVBE
12415    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12416   "@
12417     bswap\t%0
12418     movbe\t{%1, %0|%0, %1}
12419     movbe\t{%1, %0|%0, %1}"
12420   [(set_attr "type" "bitmanip,imov,imov")
12421    (set_attr "modrm" "0,1,1")
12422    (set_attr "prefix_0f" "*,1,1")
12423    (set_attr "prefix_extra" "*,1,1")
12424    (set_attr "mode" "<MODE>")])
12425
12426 (define_insn "*bswap<mode>2_1"
12427   [(set (match_operand:SWI48 0 "register_operand" "=r")
12428         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12429   "TARGET_BSWAP"
12430   "bswap\t%0"
12431   [(set_attr "type" "bitmanip")
12432    (set_attr "modrm" "0")
12433    (set_attr "mode" "<MODE>")])
12434
12435 (define_insn "*bswaphi_lowpart_1"
12436   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12437         (bswap:HI (match_dup 0)))
12438    (clobber (reg:CC FLAGS_REG))]
12439   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12440   "@
12441     xchg{b}\t{%h0, %b0|%b0, %h0}
12442     rol{w}\t{$8, %0|%0, 8}"
12443   [(set_attr "length" "2,4")
12444    (set_attr "mode" "QI,HI")])
12445
12446 (define_insn "bswaphi_lowpart"
12447   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12448         (bswap:HI (match_dup 0)))
12449    (clobber (reg:CC FLAGS_REG))]
12450   ""
12451   "rol{w}\t{$8, %0|%0, 8}"
12452   [(set_attr "length" "4")
12453    (set_attr "mode" "HI")])
12454
12455 (define_expand "paritydi2"
12456   [(set (match_operand:DI 0 "register_operand" "")
12457         (parity:DI (match_operand:DI 1 "register_operand" "")))]
12458   "! TARGET_POPCNT"
12459 {
12460   rtx scratch = gen_reg_rtx (QImode);
12461   rtx cond;
12462
12463   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12464                                 NULL_RTX, operands[1]));
12465
12466   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12467                          gen_rtx_REG (CCmode, FLAGS_REG),
12468                          const0_rtx);
12469   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12470
12471   if (TARGET_64BIT)
12472     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12473   else
12474     {
12475       rtx tmp = gen_reg_rtx (SImode);
12476
12477       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12478       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12479     }
12480   DONE;
12481 })
12482
12483 (define_expand "paritysi2"
12484   [(set (match_operand:SI 0 "register_operand" "")
12485         (parity:SI (match_operand:SI 1 "register_operand" "")))]
12486   "! TARGET_POPCNT"
12487 {
12488   rtx scratch = gen_reg_rtx (QImode);
12489   rtx cond;
12490
12491   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12492
12493   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12494                          gen_rtx_REG (CCmode, FLAGS_REG),
12495                          const0_rtx);
12496   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12497
12498   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12499   DONE;
12500 })
12501
12502 (define_insn_and_split "paritydi2_cmp"
12503   [(set (reg:CC FLAGS_REG)
12504         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12505                    UNSPEC_PARITY))
12506    (clobber (match_scratch:DI 0 "=r"))
12507    (clobber (match_scratch:SI 1 "=&r"))
12508    (clobber (match_scratch:HI 2 "=Q"))]
12509   "! TARGET_POPCNT"
12510   "#"
12511   "&& reload_completed"
12512   [(parallel
12513      [(set (match_dup 1)
12514            (xor:SI (match_dup 1) (match_dup 4)))
12515       (clobber (reg:CC FLAGS_REG))])
12516    (parallel
12517      [(set (reg:CC FLAGS_REG)
12518            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12519       (clobber (match_dup 1))
12520       (clobber (match_dup 2))])]
12521 {
12522   operands[4] = gen_lowpart (SImode, operands[3]);
12523
12524   if (TARGET_64BIT)
12525     {
12526       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12527       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12528     }
12529   else
12530     operands[1] = gen_highpart (SImode, operands[3]);
12531 })
12532
12533 (define_insn_and_split "paritysi2_cmp"
12534   [(set (reg:CC FLAGS_REG)
12535         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12536                    UNSPEC_PARITY))
12537    (clobber (match_scratch:SI 0 "=r"))
12538    (clobber (match_scratch:HI 1 "=&Q"))]
12539   "! TARGET_POPCNT"
12540   "#"
12541   "&& reload_completed"
12542   [(parallel
12543      [(set (match_dup 1)
12544            (xor:HI (match_dup 1) (match_dup 3)))
12545       (clobber (reg:CC FLAGS_REG))])
12546    (parallel
12547      [(set (reg:CC FLAGS_REG)
12548            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12549       (clobber (match_dup 1))])]
12550 {
12551   operands[3] = gen_lowpart (HImode, operands[2]);
12552
12553   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12554   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12555 })
12556
12557 (define_insn "*parityhi2_cmp"
12558   [(set (reg:CC FLAGS_REG)
12559         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12560                    UNSPEC_PARITY))
12561    (clobber (match_scratch:HI 0 "=Q"))]
12562   "! TARGET_POPCNT"
12563   "xor{b}\t{%h0, %b0|%b0, %h0}"
12564   [(set_attr "length" "2")
12565    (set_attr "mode" "HI")])
12566
12567 \f
12568 ;; Thread-local storage patterns for ELF.
12569 ;;
12570 ;; Note that these code sequences must appear exactly as shown
12571 ;; in order to allow linker relaxation.
12572
12573 (define_insn "*tls_global_dynamic_32_gnu"
12574   [(set (match_operand:SI 0 "register_operand" "=a")
12575         (unspec:SI
12576          [(match_operand:SI 1 "register_operand" "b")
12577           (match_operand:SI 2 "tls_symbolic_operand" "")
12578           (match_operand:SI 3 "constant_call_address_operand" "z")]
12579          UNSPEC_TLS_GD))
12580    (clobber (match_scratch:SI 4 "=d"))
12581    (clobber (match_scratch:SI 5 "=c"))
12582    (clobber (reg:CC FLAGS_REG))]
12583   "!TARGET_64BIT && TARGET_GNU_TLS"
12584 {
12585   output_asm_insn
12586     ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12587   if (TARGET_SUN_TLS)
12588 #ifdef HAVE_AS_IX86_TLSGDPLT
12589     return "call\t%a2@tlsgdplt";
12590 #else
12591     return "call\t%p3@plt";
12592 #endif
12593   return "call\t%P3";
12594 }
12595   [(set_attr "type" "multi")
12596    (set_attr "length" "12")])
12597
12598 (define_expand "tls_global_dynamic_32"
12599   [(parallel
12600     [(set (match_operand:SI 0 "register_operand" "")
12601           (unspec:SI [(match_operand:SI 2 "register_operand" "")
12602                       (match_operand:SI 1 "tls_symbolic_operand" "")
12603                       (match_operand:SI 3 "constant_call_address_operand" "")]
12604                      UNSPEC_TLS_GD))
12605      (clobber (match_scratch:SI 4 ""))
12606      (clobber (match_scratch:SI 5 ""))
12607      (clobber (reg:CC FLAGS_REG))])])
12608
12609 (define_insn "*tls_global_dynamic_64"
12610   [(set (match_operand:DI 0 "register_operand" "=a")
12611         (call:DI
12612          (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12613          (match_operand:DI 3 "" "")))
12614    (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12615               UNSPEC_TLS_GD)]
12616   "TARGET_64BIT"
12617 {
12618   if (!TARGET_X32)
12619     fputs (ASM_BYTE "0x66\n", asm_out_file);
12620   output_asm_insn
12621     ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12622   fputs (ASM_SHORT "0x6666\n", asm_out_file);
12623   fputs ("\trex64\n", asm_out_file);
12624   if (TARGET_SUN_TLS)
12625     return "call\t%p2@plt";
12626   return "call\t%P2";
12627 }
12628   [(set_attr "type" "multi")
12629    (set (attr "length")
12630         (symbol_ref "TARGET_X32 ? 15 : 16"))])
12631
12632 (define_expand "tls_global_dynamic_64"
12633   [(parallel
12634     [(set (match_operand:DI 0 "register_operand" "")
12635           (call:DI
12636            (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12637            (const_int 0)))
12638      (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12639                 UNSPEC_TLS_GD)])])
12640
12641 (define_insn "*tls_local_dynamic_base_32_gnu"
12642   [(set (match_operand:SI 0 "register_operand" "=a")
12643         (unspec:SI
12644          [(match_operand:SI 1 "register_operand" "b")
12645           (match_operand:SI 2 "constant_call_address_operand" "z")]
12646          UNSPEC_TLS_LD_BASE))
12647    (clobber (match_scratch:SI 3 "=d"))
12648    (clobber (match_scratch:SI 4 "=c"))
12649    (clobber (reg:CC FLAGS_REG))]
12650   "!TARGET_64BIT && TARGET_GNU_TLS"
12651 {
12652   output_asm_insn
12653     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12654   if (TARGET_SUN_TLS)
12655 #ifdef HAVE_AS_IX86_TLSLDMPLT
12656     return "call\t%&@tlsldmplt";
12657 #else
12658     return "call\t%p2@plt";
12659 #endif
12660   return "call\t%P2";
12661 }
12662   [(set_attr "type" "multi")
12663    (set_attr "length" "11")])
12664
12665 (define_expand "tls_local_dynamic_base_32"
12666   [(parallel
12667      [(set (match_operand:SI 0 "register_operand" "")
12668            (unspec:SI
12669             [(match_operand:SI 1 "register_operand" "")
12670              (match_operand:SI 2 "constant_call_address_operand" "")]
12671             UNSPEC_TLS_LD_BASE))
12672       (clobber (match_scratch:SI 3 ""))
12673       (clobber (match_scratch:SI 4 ""))
12674       (clobber (reg:CC FLAGS_REG))])])
12675
12676 (define_insn "*tls_local_dynamic_base_64"
12677   [(set (match_operand:DI 0 "register_operand" "=a")
12678         (call:DI
12679          (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12680          (match_operand:DI 2 "" "")))
12681    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12682   "TARGET_64BIT"
12683 {
12684   output_asm_insn
12685     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12686   if (TARGET_SUN_TLS)
12687     return "call\t%p1@plt";
12688   return "call\t%P1";
12689 }
12690   [(set_attr "type" "multi")
12691    (set_attr "length" "12")])
12692
12693 (define_expand "tls_local_dynamic_base_64"
12694   [(parallel
12695      [(set (match_operand:DI 0 "register_operand" "")
12696            (call:DI
12697             (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12698             (const_int 0)))
12699       (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12700
12701 ;; Local dynamic of a single variable is a lose.  Show combine how
12702 ;; to convert that back to global dynamic.
12703
12704 (define_insn_and_split "*tls_local_dynamic_32_once"
12705   [(set (match_operand:SI 0 "register_operand" "=a")
12706         (plus:SI
12707          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12708                      (match_operand:SI 2 "constant_call_address_operand" "z")]
12709                     UNSPEC_TLS_LD_BASE)
12710          (const:SI (unspec:SI
12711                     [(match_operand:SI 3 "tls_symbolic_operand" "")]
12712                     UNSPEC_DTPOFF))))
12713    (clobber (match_scratch:SI 4 "=d"))
12714    (clobber (match_scratch:SI 5 "=c"))
12715    (clobber (reg:CC FLAGS_REG))]
12716   ""
12717   "#"
12718   ""
12719   [(parallel
12720      [(set (match_dup 0)
12721            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12722                       UNSPEC_TLS_GD))
12723       (clobber (match_dup 4))
12724       (clobber (match_dup 5))
12725       (clobber (reg:CC FLAGS_REG))])])
12726
12727 ;; Segment register for the thread base ptr load
12728 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12729
12730 ;; Load and add the thread base pointer from %<tp_seg>:0.
12731 (define_insn "*load_tp_x32"
12732   [(set (match_operand:SI 0 "register_operand" "=r")
12733         (unspec:SI [(const_int 0)] UNSPEC_TP))]
12734   "TARGET_X32"
12735   "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12736   [(set_attr "type" "imov")
12737    (set_attr "modrm" "0")
12738    (set_attr "length" "7")
12739    (set_attr "memory" "load")
12740    (set_attr "imm_disp" "false")])
12741
12742 (define_insn "*load_tp_x32_zext"
12743   [(set (match_operand:DI 0 "register_operand" "=r")
12744         (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12745   "TARGET_X32"
12746   "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12747   [(set_attr "type" "imov")
12748    (set_attr "modrm" "0")
12749    (set_attr "length" "7")
12750    (set_attr "memory" "load")
12751    (set_attr "imm_disp" "false")])
12752
12753 (define_insn "*load_tp_<mode>"
12754   [(set (match_operand:P 0 "register_operand" "=r")
12755         (unspec:P [(const_int 0)] UNSPEC_TP))]
12756   "!TARGET_X32"
12757   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12758   [(set_attr "type" "imov")
12759    (set_attr "modrm" "0")
12760    (set_attr "length" "7")
12761    (set_attr "memory" "load")
12762    (set_attr "imm_disp" "false")])
12763
12764 (define_insn "*add_tp_x32"
12765   [(set (match_operand:SI 0 "register_operand" "=r")
12766         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12767                  (match_operand:SI 1 "register_operand" "0")))
12768    (clobber (reg:CC FLAGS_REG))]
12769   "TARGET_X32"
12770   "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12771   [(set_attr "type" "alu")
12772    (set_attr "modrm" "0")
12773    (set_attr "length" "7")
12774    (set_attr "memory" "load")
12775    (set_attr "imm_disp" "false")])
12776
12777 (define_insn "*add_tp_x32_zext"
12778   [(set (match_operand:DI 0 "register_operand" "=r")
12779         (zero_extend:DI
12780           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12781                    (match_operand:SI 1 "register_operand" "0"))))
12782    (clobber (reg:CC FLAGS_REG))]
12783   "TARGET_X32"
12784   "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12785   [(set_attr "type" "alu")
12786    (set_attr "modrm" "0")
12787    (set_attr "length" "7")
12788    (set_attr "memory" "load")
12789    (set_attr "imm_disp" "false")])
12790
12791 (define_insn "*add_tp_<mode>"
12792   [(set (match_operand:P 0 "register_operand" "=r")
12793         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12794                 (match_operand:P 1 "register_operand" "0")))
12795    (clobber (reg:CC FLAGS_REG))]
12796   "!TARGET_X32"
12797   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12798   [(set_attr "type" "alu")
12799    (set_attr "modrm" "0")
12800    (set_attr "length" "7")
12801    (set_attr "memory" "load")
12802    (set_attr "imm_disp" "false")])
12803
12804 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12805 ;; %rax as destination of the initial executable code sequence.
12806 (define_insn "tls_initial_exec_64_sun"
12807   [(set (match_operand:DI 0 "register_operand" "=a")
12808         (unspec:DI
12809          [(match_operand:DI 1 "tls_symbolic_operand" "")]
12810          UNSPEC_TLS_IE_SUN))
12811    (clobber (reg:CC FLAGS_REG))]
12812   "TARGET_64BIT && TARGET_SUN_TLS"
12813 {
12814   output_asm_insn
12815     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12816   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12817 }
12818   [(set_attr "type" "multi")])
12819
12820 ;; GNU2 TLS patterns can be split.
12821
12822 (define_expand "tls_dynamic_gnu2_32"
12823   [(set (match_dup 3)
12824         (plus:SI (match_operand:SI 2 "register_operand" "")
12825                  (const:SI
12826                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12827                              UNSPEC_TLSDESC))))
12828    (parallel
12829     [(set (match_operand:SI 0 "register_operand" "")
12830           (unspec:SI [(match_dup 1) (match_dup 3)
12831                       (match_dup 2) (reg:SI SP_REG)]
12832                       UNSPEC_TLSDESC))
12833      (clobber (reg:CC FLAGS_REG))])]
12834   "!TARGET_64BIT && TARGET_GNU2_TLS"
12835 {
12836   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12837   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12838 })
12839
12840 (define_insn "*tls_dynamic_gnu2_lea_32"
12841   [(set (match_operand:SI 0 "register_operand" "=r")
12842         (plus:SI (match_operand:SI 1 "register_operand" "b")
12843                  (const:SI
12844                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12845                               UNSPEC_TLSDESC))))]
12846   "!TARGET_64BIT && TARGET_GNU2_TLS"
12847   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12848   [(set_attr "type" "lea")
12849    (set_attr "mode" "SI")
12850    (set_attr "length" "6")
12851    (set_attr "length_address" "4")])
12852
12853 (define_insn "*tls_dynamic_gnu2_call_32"
12854   [(set (match_operand:SI 0 "register_operand" "=a")
12855         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12856                     (match_operand:SI 2 "register_operand" "0")
12857                     ;; we have to make sure %ebx still points to the GOT
12858                     (match_operand:SI 3 "register_operand" "b")
12859                     (reg:SI SP_REG)]
12860                    UNSPEC_TLSDESC))
12861    (clobber (reg:CC FLAGS_REG))]
12862   "!TARGET_64BIT && TARGET_GNU2_TLS"
12863   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12864   [(set_attr "type" "call")
12865    (set_attr "length" "2")
12866    (set_attr "length_address" "0")])
12867
12868 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12869   [(set (match_operand:SI 0 "register_operand" "=&a")
12870         (plus:SI
12871          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12872                      (match_operand:SI 4 "" "")
12873                      (match_operand:SI 2 "register_operand" "b")
12874                      (reg:SI SP_REG)]
12875                     UNSPEC_TLSDESC)
12876          (const:SI (unspec:SI
12877                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
12878                     UNSPEC_DTPOFF))))
12879    (clobber (reg:CC FLAGS_REG))]
12880   "!TARGET_64BIT && TARGET_GNU2_TLS"
12881   "#"
12882   ""
12883   [(set (match_dup 0) (match_dup 5))]
12884 {
12885   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12886   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12887 })
12888
12889 (define_expand "tls_dynamic_gnu2_64"
12890   [(set (match_dup 2)
12891         (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12892                    UNSPEC_TLSDESC))
12893    (parallel
12894     [(set (match_operand:DI 0 "register_operand" "")
12895           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12896                      UNSPEC_TLSDESC))
12897      (clobber (reg:CC FLAGS_REG))])]
12898   "TARGET_64BIT && TARGET_GNU2_TLS"
12899 {
12900   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12901   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12902 })
12903
12904 (define_insn "*tls_dynamic_gnu2_lea_64"
12905   [(set (match_operand:DI 0 "register_operand" "=r")
12906         (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12907                    UNSPEC_TLSDESC))]
12908   "TARGET_64BIT && TARGET_GNU2_TLS"
12909   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12910   [(set_attr "type" "lea")
12911    (set_attr "mode" "DI")
12912    (set_attr "length" "7")
12913    (set_attr "length_address" "4")])
12914
12915 (define_insn "*tls_dynamic_gnu2_call_64"
12916   [(set (match_operand:DI 0 "register_operand" "=a")
12917         (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12918                     (match_operand:DI 2 "register_operand" "0")
12919                     (reg:DI SP_REG)]
12920                    UNSPEC_TLSDESC))
12921    (clobber (reg:CC FLAGS_REG))]
12922   "TARGET_64BIT && TARGET_GNU2_TLS"
12923   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12924   [(set_attr "type" "call")
12925    (set_attr "length" "2")
12926    (set_attr "length_address" "0")])
12927
12928 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12929   [(set (match_operand:DI 0 "register_operand" "=&a")
12930         (plus:DI
12931          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12932                      (match_operand:DI 3 "" "")
12933                      (reg:DI SP_REG)]
12934                     UNSPEC_TLSDESC)
12935          (const:DI (unspec:DI
12936                     [(match_operand 1 "tls_symbolic_operand" "")]
12937                     UNSPEC_DTPOFF))))
12938    (clobber (reg:CC FLAGS_REG))]
12939   "TARGET_64BIT && TARGET_GNU2_TLS"
12940   "#"
12941   ""
12942   [(set (match_dup 0) (match_dup 4))]
12943 {
12944   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12945   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12946 })
12947 \f
12948 ;; These patterns match the binary 387 instructions for addM3, subM3,
12949 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
12950 ;; SFmode.  The first is the normal insn, the second the same insn but
12951 ;; with one operand a conversion, and the third the same insn but with
12952 ;; the other operand a conversion.  The conversion may be SFmode or
12953 ;; SImode if the target mode DFmode, but only SImode if the target mode
12954 ;; is SFmode.
12955
12956 ;; Gcc is slightly more smart about handling normal two address instructions
12957 ;; so use special patterns for add and mull.
12958
12959 (define_insn "*fop_<mode>_comm_mixed"
12960   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12961         (match_operator:MODEF 3 "binary_fp_operator"
12962           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12963            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12964   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12965    && COMMUTATIVE_ARITH_P (operands[3])
12966    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12967   "* return output_387_binary_op (insn, operands);"
12968   [(set (attr "type")
12969         (if_then_else (eq_attr "alternative" "1,2")
12970            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12971               (const_string "ssemul")
12972               (const_string "sseadd"))
12973            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12974               (const_string "fmul")
12975               (const_string "fop"))))
12976    (set_attr "isa" "*,noavx,avx")
12977    (set_attr "prefix" "orig,orig,vex")
12978    (set_attr "mode" "<MODE>")])
12979
12980 (define_insn "*fop_<mode>_comm_sse"
12981   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12982         (match_operator:MODEF 3 "binary_fp_operator"
12983           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12984            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12985   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12986    && COMMUTATIVE_ARITH_P (operands[3])
12987    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12988   "* return output_387_binary_op (insn, operands);"
12989   [(set (attr "type")
12990         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12991            (const_string "ssemul")
12992            (const_string "sseadd")))
12993    (set_attr "isa" "noavx,avx")
12994    (set_attr "prefix" "orig,vex")
12995    (set_attr "mode" "<MODE>")])
12996
12997 (define_insn "*fop_<mode>_comm_i387"
12998   [(set (match_operand:MODEF 0 "register_operand" "=f")
12999         (match_operator:MODEF 3 "binary_fp_operator"
13000           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13001            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13002   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13003    && COMMUTATIVE_ARITH_P (operands[3])
13004    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13005   "* return output_387_binary_op (insn, operands);"
13006   [(set (attr "type")
13007         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13008            (const_string "fmul")
13009            (const_string "fop")))
13010    (set_attr "mode" "<MODE>")])
13011
13012 (define_insn "*fop_<mode>_1_mixed"
13013   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13014         (match_operator:MODEF 3 "binary_fp_operator"
13015           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13016            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13017   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13018    && !COMMUTATIVE_ARITH_P (operands[3])
13019    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13020   "* return output_387_binary_op (insn, operands);"
13021   [(set (attr "type")
13022         (cond [(and (eq_attr "alternative" "2,3")
13023                     (match_operand:MODEF 3 "mult_operator" ""))
13024                  (const_string "ssemul")
13025                (and (eq_attr "alternative" "2,3")
13026                     (match_operand:MODEF 3 "div_operator" ""))
13027                  (const_string "ssediv")
13028                (eq_attr "alternative" "2,3")
13029                  (const_string "sseadd")
13030                (match_operand:MODEF 3 "mult_operator" "")
13031                  (const_string "fmul")
13032                (match_operand:MODEF 3 "div_operator" "")
13033                  (const_string "fdiv")
13034               ]
13035               (const_string "fop")))
13036    (set_attr "isa" "*,*,noavx,avx")
13037    (set_attr "prefix" "orig,orig,orig,vex")
13038    (set_attr "mode" "<MODE>")])
13039
13040 (define_insn "*rcpsf2_sse"
13041   [(set (match_operand:SF 0 "register_operand" "=x")
13042         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13043                    UNSPEC_RCP))]
13044   "TARGET_SSE_MATH"
13045   "%vrcpss\t{%1, %d0|%d0, %1}"
13046   [(set_attr "type" "sse")
13047    (set_attr "atom_sse_attr" "rcp")
13048    (set_attr "prefix" "maybe_vex")
13049    (set_attr "mode" "SF")])
13050
13051 (define_insn "*fop_<mode>_1_sse"
13052   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13053         (match_operator:MODEF 3 "binary_fp_operator"
13054           [(match_operand:MODEF 1 "register_operand" "0,x")
13055            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13056   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13057    && !COMMUTATIVE_ARITH_P (operands[3])"
13058   "* return output_387_binary_op (insn, operands);"
13059   [(set (attr "type")
13060         (cond [(match_operand:MODEF 3 "mult_operator" "")
13061                  (const_string "ssemul")
13062                (match_operand:MODEF 3 "div_operator" "")
13063                  (const_string "ssediv")
13064               ]
13065               (const_string "sseadd")))
13066    (set_attr "isa" "noavx,avx")
13067    (set_attr "prefix" "orig,vex")
13068    (set_attr "mode" "<MODE>")])
13069
13070 ;; This pattern is not fully shadowed by the pattern above.
13071 (define_insn "*fop_<mode>_1_i387"
13072   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13073         (match_operator:MODEF 3 "binary_fp_operator"
13074           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13075            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13076   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13077    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13078    && !COMMUTATIVE_ARITH_P (operands[3])
13079    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13080   "* return output_387_binary_op (insn, operands);"
13081   [(set (attr "type")
13082         (cond [(match_operand:MODEF 3 "mult_operator" "")
13083                  (const_string "fmul")
13084                (match_operand:MODEF 3 "div_operator" "")
13085                  (const_string "fdiv")
13086               ]
13087               (const_string "fop")))
13088    (set_attr "mode" "<MODE>")])
13089
13090 ;; ??? Add SSE splitters for these!
13091 (define_insn "*fop_<MODEF:mode>_2_i387"
13092   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13093         (match_operator:MODEF 3 "binary_fp_operator"
13094           [(float:MODEF
13095              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13096            (match_operand:MODEF 2 "register_operand" "0,0")]))]
13097   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13098    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13099    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13100   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13101   [(set (attr "type")
13102         (cond [(match_operand:MODEF 3 "mult_operator" "")
13103                  (const_string "fmul")
13104                (match_operand:MODEF 3 "div_operator" "")
13105                  (const_string "fdiv")
13106               ]
13107               (const_string "fop")))
13108    (set_attr "fp_int_src" "true")
13109    (set_attr "mode" "<SWI24:MODE>")])
13110
13111 (define_insn "*fop_<MODEF:mode>_3_i387"
13112   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13113         (match_operator:MODEF 3 "binary_fp_operator"
13114           [(match_operand:MODEF 1 "register_operand" "0,0")
13115            (float:MODEF
13116              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13117   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13118    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13119    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13120   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13121   [(set (attr "type")
13122         (cond [(match_operand:MODEF 3 "mult_operator" "")
13123                  (const_string "fmul")
13124                (match_operand:MODEF 3 "div_operator" "")
13125                  (const_string "fdiv")
13126               ]
13127               (const_string "fop")))
13128    (set_attr "fp_int_src" "true")
13129    (set_attr "mode" "<MODE>")])
13130
13131 (define_insn "*fop_df_4_i387"
13132   [(set (match_operand:DF 0 "register_operand" "=f,f")
13133         (match_operator:DF 3 "binary_fp_operator"
13134            [(float_extend:DF
13135              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13136             (match_operand:DF 2 "register_operand" "0,f")]))]
13137   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13138    && !(TARGET_SSE2 && TARGET_SSE_MATH)
13139    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13140   "* return output_387_binary_op (insn, operands);"
13141   [(set (attr "type")
13142         (cond [(match_operand:DF 3 "mult_operator" "")
13143                  (const_string "fmul")
13144                (match_operand:DF 3 "div_operator" "")
13145                  (const_string "fdiv")
13146               ]
13147               (const_string "fop")))
13148    (set_attr "mode" "SF")])
13149
13150 (define_insn "*fop_df_5_i387"
13151   [(set (match_operand:DF 0 "register_operand" "=f,f")
13152         (match_operator:DF 3 "binary_fp_operator"
13153           [(match_operand:DF 1 "register_operand" "0,f")
13154            (float_extend:DF
13155             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13156   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13157    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13158   "* return output_387_binary_op (insn, operands);"
13159   [(set (attr "type")
13160         (cond [(match_operand:DF 3 "mult_operator" "")
13161                  (const_string "fmul")
13162                (match_operand:DF 3 "div_operator" "")
13163                  (const_string "fdiv")
13164               ]
13165               (const_string "fop")))
13166    (set_attr "mode" "SF")])
13167
13168 (define_insn "*fop_df_6_i387"
13169   [(set (match_operand:DF 0 "register_operand" "=f,f")
13170         (match_operator:DF 3 "binary_fp_operator"
13171           [(float_extend:DF
13172             (match_operand:SF 1 "register_operand" "0,f"))
13173            (float_extend:DF
13174             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13175   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13176    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13177   "* return output_387_binary_op (insn, operands);"
13178   [(set (attr "type")
13179         (cond [(match_operand:DF 3 "mult_operator" "")
13180                  (const_string "fmul")
13181                (match_operand:DF 3 "div_operator" "")
13182                  (const_string "fdiv")
13183               ]
13184               (const_string "fop")))
13185    (set_attr "mode" "SF")])
13186
13187 (define_insn "*fop_xf_comm_i387"
13188   [(set (match_operand:XF 0 "register_operand" "=f")
13189         (match_operator:XF 3 "binary_fp_operator"
13190                         [(match_operand:XF 1 "register_operand" "%0")
13191                          (match_operand:XF 2 "register_operand" "f")]))]
13192   "TARGET_80387
13193    && COMMUTATIVE_ARITH_P (operands[3])"
13194   "* return output_387_binary_op (insn, operands);"
13195   [(set (attr "type")
13196         (if_then_else (match_operand:XF 3 "mult_operator" "")
13197            (const_string "fmul")
13198            (const_string "fop")))
13199    (set_attr "mode" "XF")])
13200
13201 (define_insn "*fop_xf_1_i387"
13202   [(set (match_operand:XF 0 "register_operand" "=f,f")
13203         (match_operator:XF 3 "binary_fp_operator"
13204                         [(match_operand:XF 1 "register_operand" "0,f")
13205                          (match_operand:XF 2 "register_operand" "f,0")]))]
13206   "TARGET_80387
13207    && !COMMUTATIVE_ARITH_P (operands[3])"
13208   "* return output_387_binary_op (insn, operands);"
13209   [(set (attr "type")
13210         (cond [(match_operand:XF 3 "mult_operator" "")
13211                  (const_string "fmul")
13212                (match_operand:XF 3 "div_operator" "")
13213                  (const_string "fdiv")
13214               ]
13215               (const_string "fop")))
13216    (set_attr "mode" "XF")])
13217
13218 (define_insn "*fop_xf_2_i387"
13219   [(set (match_operand:XF 0 "register_operand" "=f,f")
13220         (match_operator:XF 3 "binary_fp_operator"
13221           [(float:XF
13222              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13223            (match_operand:XF 2 "register_operand" "0,0")]))]
13224   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13225   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13226   [(set (attr "type")
13227         (cond [(match_operand:XF 3 "mult_operator" "")
13228                  (const_string "fmul")
13229                (match_operand:XF 3 "div_operator" "")
13230                  (const_string "fdiv")
13231               ]
13232               (const_string "fop")))
13233    (set_attr "fp_int_src" "true")
13234    (set_attr "mode" "<MODE>")])
13235
13236 (define_insn "*fop_xf_3_i387"
13237   [(set (match_operand:XF 0 "register_operand" "=f,f")
13238         (match_operator:XF 3 "binary_fp_operator"
13239           [(match_operand:XF 1 "register_operand" "0,0")
13240            (float:XF
13241              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13242   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13243   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13244   [(set (attr "type")
13245         (cond [(match_operand:XF 3 "mult_operator" "")
13246                  (const_string "fmul")
13247                (match_operand:XF 3 "div_operator" "")
13248                  (const_string "fdiv")
13249               ]
13250               (const_string "fop")))
13251    (set_attr "fp_int_src" "true")
13252    (set_attr "mode" "<MODE>")])
13253
13254 (define_insn "*fop_xf_4_i387"
13255   [(set (match_operand:XF 0 "register_operand" "=f,f")
13256         (match_operator:XF 3 "binary_fp_operator"
13257            [(float_extend:XF
13258               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13259             (match_operand:XF 2 "register_operand" "0,f")]))]
13260   "TARGET_80387"
13261   "* return output_387_binary_op (insn, operands);"
13262   [(set (attr "type")
13263         (cond [(match_operand:XF 3 "mult_operator" "")
13264                  (const_string "fmul")
13265                (match_operand:XF 3 "div_operator" "")
13266                  (const_string "fdiv")
13267               ]
13268               (const_string "fop")))
13269    (set_attr "mode" "<MODE>")])
13270
13271 (define_insn "*fop_xf_5_i387"
13272   [(set (match_operand:XF 0 "register_operand" "=f,f")
13273         (match_operator:XF 3 "binary_fp_operator"
13274           [(match_operand:XF 1 "register_operand" "0,f")
13275            (float_extend:XF
13276              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13277   "TARGET_80387"
13278   "* return output_387_binary_op (insn, operands);"
13279   [(set (attr "type")
13280         (cond [(match_operand:XF 3 "mult_operator" "")
13281                  (const_string "fmul")
13282                (match_operand:XF 3 "div_operator" "")
13283                  (const_string "fdiv")
13284               ]
13285               (const_string "fop")))
13286    (set_attr "mode" "<MODE>")])
13287
13288 (define_insn "*fop_xf_6_i387"
13289   [(set (match_operand:XF 0 "register_operand" "=f,f")
13290         (match_operator:XF 3 "binary_fp_operator"
13291           [(float_extend:XF
13292              (match_operand:MODEF 1 "register_operand" "0,f"))
13293            (float_extend:XF
13294              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13295   "TARGET_80387"
13296   "* return output_387_binary_op (insn, operands);"
13297   [(set (attr "type")
13298         (cond [(match_operand:XF 3 "mult_operator" "")
13299                  (const_string "fmul")
13300                (match_operand:XF 3 "div_operator" "")
13301                  (const_string "fdiv")
13302               ]
13303               (const_string "fop")))
13304    (set_attr "mode" "<MODE>")])
13305
13306 (define_split
13307   [(set (match_operand 0 "register_operand" "")
13308         (match_operator 3 "binary_fp_operator"
13309            [(float (match_operand:SWI24 1 "register_operand" ""))
13310             (match_operand 2 "register_operand" "")]))]
13311   "reload_completed
13312    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13313    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13314   [(const_int 0)]
13315 {
13316   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13317   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13318   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13319                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13320                                           GET_MODE (operands[3]),
13321                                           operands[4],
13322                                           operands[2])));
13323   ix86_free_from_memory (GET_MODE (operands[1]));
13324   DONE;
13325 })
13326
13327 (define_split
13328   [(set (match_operand 0 "register_operand" "")
13329         (match_operator 3 "binary_fp_operator"
13330            [(match_operand 1 "register_operand" "")
13331             (float (match_operand:SWI24 2 "register_operand" ""))]))]
13332   "reload_completed
13333    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13334    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13335   [(const_int 0)]
13336 {
13337   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13338   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13339   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13340                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13341                                           GET_MODE (operands[3]),
13342                                           operands[1],
13343                                           operands[4])));
13344   ix86_free_from_memory (GET_MODE (operands[2]));
13345   DONE;
13346 })
13347 \f
13348 ;; FPU special functions.
13349
13350 ;; This pattern implements a no-op XFmode truncation for
13351 ;; all fancy i386 XFmode math functions.
13352
13353 (define_insn "truncxf<mode>2_i387_noop_unspec"
13354   [(set (match_operand:MODEF 0 "register_operand" "=f")
13355         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13356         UNSPEC_TRUNC_NOOP))]
13357   "TARGET_USE_FANCY_MATH_387"
13358   "* return output_387_reg_move (insn, operands);"
13359   [(set_attr "type" "fmov")
13360    (set_attr "mode" "<MODE>")])
13361
13362 (define_insn "sqrtxf2"
13363   [(set (match_operand:XF 0 "register_operand" "=f")
13364         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13365   "TARGET_USE_FANCY_MATH_387"
13366   "fsqrt"
13367   [(set_attr "type" "fpspc")
13368    (set_attr "mode" "XF")
13369    (set_attr "athlon_decode" "direct")
13370    (set_attr "amdfam10_decode" "direct")
13371    (set_attr "bdver1_decode" "direct")])
13372
13373 (define_insn "sqrt_extend<mode>xf2_i387"
13374   [(set (match_operand:XF 0 "register_operand" "=f")
13375         (sqrt:XF
13376           (float_extend:XF
13377             (match_operand:MODEF 1 "register_operand" "0"))))]
13378   "TARGET_USE_FANCY_MATH_387"
13379   "fsqrt"
13380   [(set_attr "type" "fpspc")
13381    (set_attr "mode" "XF")
13382    (set_attr "athlon_decode" "direct")
13383    (set_attr "amdfam10_decode" "direct")
13384    (set_attr "bdver1_decode" "direct")])
13385
13386 (define_insn "*rsqrtsf2_sse"
13387   [(set (match_operand:SF 0 "register_operand" "=x")
13388         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13389                    UNSPEC_RSQRT))]
13390   "TARGET_SSE_MATH"
13391   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13392   [(set_attr "type" "sse")
13393    (set_attr "atom_sse_attr" "rcp")
13394    (set_attr "prefix" "maybe_vex")
13395    (set_attr "mode" "SF")])
13396
13397 (define_expand "rsqrtsf2"
13398   [(set (match_operand:SF 0 "register_operand" "")
13399         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13400                    UNSPEC_RSQRT))]
13401   "TARGET_SSE_MATH"
13402 {
13403   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13404   DONE;
13405 })
13406
13407 (define_insn "*sqrt<mode>2_sse"
13408   [(set (match_operand:MODEF 0 "register_operand" "=x")
13409         (sqrt:MODEF
13410           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13411   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13412   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13413   [(set_attr "type" "sse")
13414    (set_attr "atom_sse_attr" "sqrt")
13415    (set_attr "prefix" "maybe_vex")
13416    (set_attr "mode" "<MODE>")
13417    (set_attr "athlon_decode" "*")
13418    (set_attr "amdfam10_decode" "*")
13419    (set_attr "bdver1_decode" "*")])
13420
13421 (define_expand "sqrt<mode>2"
13422   [(set (match_operand:MODEF 0 "register_operand" "")
13423         (sqrt:MODEF
13424           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13425   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13426    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13427 {
13428   if (<MODE>mode == SFmode
13429       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13430       && flag_finite_math_only && !flag_trapping_math
13431       && flag_unsafe_math_optimizations)
13432     {
13433       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13434       DONE;
13435     }
13436
13437   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13438     {
13439       rtx op0 = gen_reg_rtx (XFmode);
13440       rtx op1 = force_reg (<MODE>mode, operands[1]);
13441
13442       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13443       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13444       DONE;
13445    }
13446 })
13447
13448 (define_insn "fpremxf4_i387"
13449   [(set (match_operand:XF 0 "register_operand" "=f")
13450         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13451                     (match_operand:XF 3 "register_operand" "1")]
13452                    UNSPEC_FPREM_F))
13453    (set (match_operand:XF 1 "register_operand" "=u")
13454         (unspec:XF [(match_dup 2) (match_dup 3)]
13455                    UNSPEC_FPREM_U))
13456    (set (reg:CCFP FPSR_REG)
13457         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13458                      UNSPEC_C2_FLAG))]
13459   "TARGET_USE_FANCY_MATH_387"
13460   "fprem"
13461   [(set_attr "type" "fpspc")
13462    (set_attr "mode" "XF")])
13463
13464 (define_expand "fmodxf3"
13465   [(use (match_operand:XF 0 "register_operand" ""))
13466    (use (match_operand:XF 1 "general_operand" ""))
13467    (use (match_operand:XF 2 "general_operand" ""))]
13468   "TARGET_USE_FANCY_MATH_387"
13469 {
13470   rtx label = gen_label_rtx ();
13471
13472   rtx op1 = gen_reg_rtx (XFmode);
13473   rtx op2 = gen_reg_rtx (XFmode);
13474
13475   emit_move_insn (op2, operands[2]);
13476   emit_move_insn (op1, operands[1]);
13477
13478   emit_label (label);
13479   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13480   ix86_emit_fp_unordered_jump (label);
13481   LABEL_NUSES (label) = 1;
13482
13483   emit_move_insn (operands[0], op1);
13484   DONE;
13485 })
13486
13487 (define_expand "fmod<mode>3"
13488   [(use (match_operand:MODEF 0 "register_operand" ""))
13489    (use (match_operand:MODEF 1 "general_operand" ""))
13490    (use (match_operand:MODEF 2 "general_operand" ""))]
13491   "TARGET_USE_FANCY_MATH_387"
13492 {
13493   rtx (*gen_truncxf) (rtx, rtx);
13494
13495   rtx label = gen_label_rtx ();
13496
13497   rtx op1 = gen_reg_rtx (XFmode);
13498   rtx op2 = gen_reg_rtx (XFmode);
13499
13500   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13501   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13502
13503   emit_label (label);
13504   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13505   ix86_emit_fp_unordered_jump (label);
13506   LABEL_NUSES (label) = 1;
13507
13508   /* Truncate the result properly for strict SSE math.  */
13509   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13510       && !TARGET_MIX_SSE_I387)
13511     gen_truncxf = gen_truncxf<mode>2;
13512   else
13513     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13514
13515   emit_insn (gen_truncxf (operands[0], op1));
13516   DONE;
13517 })
13518
13519 (define_insn "fprem1xf4_i387"
13520   [(set (match_operand:XF 0 "register_operand" "=f")
13521         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13522                     (match_operand:XF 3 "register_operand" "1")]
13523                    UNSPEC_FPREM1_F))
13524    (set (match_operand:XF 1 "register_operand" "=u")
13525         (unspec:XF [(match_dup 2) (match_dup 3)]
13526                    UNSPEC_FPREM1_U))
13527    (set (reg:CCFP FPSR_REG)
13528         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13529                      UNSPEC_C2_FLAG))]
13530   "TARGET_USE_FANCY_MATH_387"
13531   "fprem1"
13532   [(set_attr "type" "fpspc")
13533    (set_attr "mode" "XF")])
13534
13535 (define_expand "remainderxf3"
13536   [(use (match_operand:XF 0 "register_operand" ""))
13537    (use (match_operand:XF 1 "general_operand" ""))
13538    (use (match_operand:XF 2 "general_operand" ""))]
13539   "TARGET_USE_FANCY_MATH_387"
13540 {
13541   rtx label = gen_label_rtx ();
13542
13543   rtx op1 = gen_reg_rtx (XFmode);
13544   rtx op2 = gen_reg_rtx (XFmode);
13545
13546   emit_move_insn (op2, operands[2]);
13547   emit_move_insn (op1, operands[1]);
13548
13549   emit_label (label);
13550   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13551   ix86_emit_fp_unordered_jump (label);
13552   LABEL_NUSES (label) = 1;
13553
13554   emit_move_insn (operands[0], op1);
13555   DONE;
13556 })
13557
13558 (define_expand "remainder<mode>3"
13559   [(use (match_operand:MODEF 0 "register_operand" ""))
13560    (use (match_operand:MODEF 1 "general_operand" ""))
13561    (use (match_operand:MODEF 2 "general_operand" ""))]
13562   "TARGET_USE_FANCY_MATH_387"
13563 {
13564   rtx (*gen_truncxf) (rtx, rtx);
13565
13566   rtx label = gen_label_rtx ();
13567
13568   rtx op1 = gen_reg_rtx (XFmode);
13569   rtx op2 = gen_reg_rtx (XFmode);
13570
13571   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13572   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13573
13574   emit_label (label);
13575
13576   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13577   ix86_emit_fp_unordered_jump (label);
13578   LABEL_NUSES (label) = 1;
13579
13580   /* Truncate the result properly for strict SSE math.  */
13581   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13582       && !TARGET_MIX_SSE_I387)
13583     gen_truncxf = gen_truncxf<mode>2;
13584   else
13585     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13586
13587   emit_insn (gen_truncxf (operands[0], op1));
13588   DONE;
13589 })
13590
13591 (define_insn "*sinxf2_i387"
13592   [(set (match_operand:XF 0 "register_operand" "=f")
13593         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13594   "TARGET_USE_FANCY_MATH_387
13595    && flag_unsafe_math_optimizations"
13596   "fsin"
13597   [(set_attr "type" "fpspc")
13598    (set_attr "mode" "XF")])
13599
13600 (define_insn "*sin_extend<mode>xf2_i387"
13601   [(set (match_operand:XF 0 "register_operand" "=f")
13602         (unspec:XF [(float_extend:XF
13603                       (match_operand:MODEF 1 "register_operand" "0"))]
13604                    UNSPEC_SIN))]
13605   "TARGET_USE_FANCY_MATH_387
13606    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13607        || TARGET_MIX_SSE_I387)
13608    && flag_unsafe_math_optimizations"
13609   "fsin"
13610   [(set_attr "type" "fpspc")
13611    (set_attr "mode" "XF")])
13612
13613 (define_insn "*cosxf2_i387"
13614   [(set (match_operand:XF 0 "register_operand" "=f")
13615         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13616   "TARGET_USE_FANCY_MATH_387
13617    && flag_unsafe_math_optimizations"
13618   "fcos"
13619   [(set_attr "type" "fpspc")
13620    (set_attr "mode" "XF")])
13621
13622 (define_insn "*cos_extend<mode>xf2_i387"
13623   [(set (match_operand:XF 0 "register_operand" "=f")
13624         (unspec:XF [(float_extend:XF
13625                       (match_operand:MODEF 1 "register_operand" "0"))]
13626                    UNSPEC_COS))]
13627   "TARGET_USE_FANCY_MATH_387
13628    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13629        || TARGET_MIX_SSE_I387)
13630    && flag_unsafe_math_optimizations"
13631   "fcos"
13632   [(set_attr "type" "fpspc")
13633    (set_attr "mode" "XF")])
13634
13635 ;; When sincos pattern is defined, sin and cos builtin functions will be
13636 ;; expanded to sincos pattern with one of its outputs left unused.
13637 ;; CSE pass will figure out if two sincos patterns can be combined,
13638 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13639 ;; depending on the unused output.
13640
13641 (define_insn "sincosxf3"
13642   [(set (match_operand:XF 0 "register_operand" "=f")
13643         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13644                    UNSPEC_SINCOS_COS))
13645    (set (match_operand:XF 1 "register_operand" "=u")
13646         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13647   "TARGET_USE_FANCY_MATH_387
13648    && flag_unsafe_math_optimizations"
13649   "fsincos"
13650   [(set_attr "type" "fpspc")
13651    (set_attr "mode" "XF")])
13652
13653 (define_split
13654   [(set (match_operand:XF 0 "register_operand" "")
13655         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13656                    UNSPEC_SINCOS_COS))
13657    (set (match_operand:XF 1 "register_operand" "")
13658         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13659   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13660    && can_create_pseudo_p ()"
13661   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13662
13663 (define_split
13664   [(set (match_operand:XF 0 "register_operand" "")
13665         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13666                    UNSPEC_SINCOS_COS))
13667    (set (match_operand:XF 1 "register_operand" "")
13668         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13669   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13670    && can_create_pseudo_p ()"
13671   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13672
13673 (define_insn "sincos_extend<mode>xf3_i387"
13674   [(set (match_operand:XF 0 "register_operand" "=f")
13675         (unspec:XF [(float_extend:XF
13676                       (match_operand:MODEF 2 "register_operand" "0"))]
13677                    UNSPEC_SINCOS_COS))
13678    (set (match_operand:XF 1 "register_operand" "=u")
13679         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13680   "TARGET_USE_FANCY_MATH_387
13681    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13682        || TARGET_MIX_SSE_I387)
13683    && flag_unsafe_math_optimizations"
13684   "fsincos"
13685   [(set_attr "type" "fpspc")
13686    (set_attr "mode" "XF")])
13687
13688 (define_split
13689   [(set (match_operand:XF 0 "register_operand" "")
13690         (unspec:XF [(float_extend:XF
13691                       (match_operand:MODEF 2 "register_operand" ""))]
13692                    UNSPEC_SINCOS_COS))
13693    (set (match_operand:XF 1 "register_operand" "")
13694         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13695   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13696    && can_create_pseudo_p ()"
13697   [(set (match_dup 1)
13698         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13699
13700 (define_split
13701   [(set (match_operand:XF 0 "register_operand" "")
13702         (unspec:XF [(float_extend:XF
13703                       (match_operand:MODEF 2 "register_operand" ""))]
13704                    UNSPEC_SINCOS_COS))
13705    (set (match_operand:XF 1 "register_operand" "")
13706         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13707   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13708    && can_create_pseudo_p ()"
13709   [(set (match_dup 0)
13710         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13711
13712 (define_expand "sincos<mode>3"
13713   [(use (match_operand:MODEF 0 "register_operand" ""))
13714    (use (match_operand:MODEF 1 "register_operand" ""))
13715    (use (match_operand:MODEF 2 "register_operand" ""))]
13716   "TARGET_USE_FANCY_MATH_387
13717    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13718        || TARGET_MIX_SSE_I387)
13719    && flag_unsafe_math_optimizations"
13720 {
13721   rtx op0 = gen_reg_rtx (XFmode);
13722   rtx op1 = gen_reg_rtx (XFmode);
13723
13724   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13725   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13726   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13727   DONE;
13728 })
13729
13730 (define_insn "fptanxf4_i387"
13731   [(set (match_operand:XF 0 "register_operand" "=f")
13732         (match_operand:XF 3 "const_double_operand" "F"))
13733    (set (match_operand:XF 1 "register_operand" "=u")
13734         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13735                    UNSPEC_TAN))]
13736   "TARGET_USE_FANCY_MATH_387
13737    && flag_unsafe_math_optimizations
13738    && standard_80387_constant_p (operands[3]) == 2"
13739   "fptan"
13740   [(set_attr "type" "fpspc")
13741    (set_attr "mode" "XF")])
13742
13743 (define_insn "fptan_extend<mode>xf4_i387"
13744   [(set (match_operand:MODEF 0 "register_operand" "=f")
13745         (match_operand:MODEF 3 "const_double_operand" "F"))
13746    (set (match_operand:XF 1 "register_operand" "=u")
13747         (unspec:XF [(float_extend:XF
13748                       (match_operand:MODEF 2 "register_operand" "0"))]
13749                    UNSPEC_TAN))]
13750   "TARGET_USE_FANCY_MATH_387
13751    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13752        || TARGET_MIX_SSE_I387)
13753    && flag_unsafe_math_optimizations
13754    && standard_80387_constant_p (operands[3]) == 2"
13755   "fptan"
13756   [(set_attr "type" "fpspc")
13757    (set_attr "mode" "XF")])
13758
13759 (define_expand "tanxf2"
13760   [(use (match_operand:XF 0 "register_operand" ""))
13761    (use (match_operand:XF 1 "register_operand" ""))]
13762   "TARGET_USE_FANCY_MATH_387
13763    && flag_unsafe_math_optimizations"
13764 {
13765   rtx one = gen_reg_rtx (XFmode);
13766   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13767
13768   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13769   DONE;
13770 })
13771
13772 (define_expand "tan<mode>2"
13773   [(use (match_operand:MODEF 0 "register_operand" ""))
13774    (use (match_operand:MODEF 1 "register_operand" ""))]
13775   "TARGET_USE_FANCY_MATH_387
13776    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13777        || TARGET_MIX_SSE_I387)
13778    && flag_unsafe_math_optimizations"
13779 {
13780   rtx op0 = gen_reg_rtx (XFmode);
13781
13782   rtx one = gen_reg_rtx (<MODE>mode);
13783   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13784
13785   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13786                                              operands[1], op2));
13787   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13788   DONE;
13789 })
13790
13791 (define_insn "*fpatanxf3_i387"
13792   [(set (match_operand:XF 0 "register_operand" "=f")
13793         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13794                     (match_operand:XF 2 "register_operand" "u")]
13795                    UNSPEC_FPATAN))
13796    (clobber (match_scratch:XF 3 "=2"))]
13797   "TARGET_USE_FANCY_MATH_387
13798    && flag_unsafe_math_optimizations"
13799   "fpatan"
13800   [(set_attr "type" "fpspc")
13801    (set_attr "mode" "XF")])
13802
13803 (define_insn "fpatan_extend<mode>xf3_i387"
13804   [(set (match_operand:XF 0 "register_operand" "=f")
13805         (unspec:XF [(float_extend:XF
13806                       (match_operand:MODEF 1 "register_operand" "0"))
13807                     (float_extend:XF
13808                       (match_operand:MODEF 2 "register_operand" "u"))]
13809                    UNSPEC_FPATAN))
13810    (clobber (match_scratch:XF 3 "=2"))]
13811   "TARGET_USE_FANCY_MATH_387
13812    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13813        || TARGET_MIX_SSE_I387)
13814    && flag_unsafe_math_optimizations"
13815   "fpatan"
13816   [(set_attr "type" "fpspc")
13817    (set_attr "mode" "XF")])
13818
13819 (define_expand "atan2xf3"
13820   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13821                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
13822                                (match_operand:XF 1 "register_operand" "")]
13823                               UNSPEC_FPATAN))
13824               (clobber (match_scratch:XF 3 ""))])]
13825   "TARGET_USE_FANCY_MATH_387
13826    && flag_unsafe_math_optimizations")
13827
13828 (define_expand "atan2<mode>3"
13829   [(use (match_operand:MODEF 0 "register_operand" ""))
13830    (use (match_operand:MODEF 1 "register_operand" ""))
13831    (use (match_operand:MODEF 2 "register_operand" ""))]
13832   "TARGET_USE_FANCY_MATH_387
13833    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13834        || TARGET_MIX_SSE_I387)
13835    && flag_unsafe_math_optimizations"
13836 {
13837   rtx op0 = gen_reg_rtx (XFmode);
13838
13839   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13840   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13841   DONE;
13842 })
13843
13844 (define_expand "atanxf2"
13845   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13846                    (unspec:XF [(match_dup 2)
13847                                (match_operand:XF 1 "register_operand" "")]
13848                               UNSPEC_FPATAN))
13849               (clobber (match_scratch:XF 3 ""))])]
13850   "TARGET_USE_FANCY_MATH_387
13851    && flag_unsafe_math_optimizations"
13852 {
13853   operands[2] = gen_reg_rtx (XFmode);
13854   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13855 })
13856
13857 (define_expand "atan<mode>2"
13858   [(use (match_operand:MODEF 0 "register_operand" ""))
13859    (use (match_operand:MODEF 1 "register_operand" ""))]
13860   "TARGET_USE_FANCY_MATH_387
13861    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13862        || TARGET_MIX_SSE_I387)
13863    && flag_unsafe_math_optimizations"
13864 {
13865   rtx op0 = gen_reg_rtx (XFmode);
13866
13867   rtx op2 = gen_reg_rtx (<MODE>mode);
13868   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13869
13870   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13871   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13872   DONE;
13873 })
13874
13875 (define_expand "asinxf2"
13876   [(set (match_dup 2)
13877         (mult:XF (match_operand:XF 1 "register_operand" "")
13878                  (match_dup 1)))
13879    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13880    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13881    (parallel [(set (match_operand:XF 0 "register_operand" "")
13882                    (unspec:XF [(match_dup 5) (match_dup 1)]
13883                               UNSPEC_FPATAN))
13884               (clobber (match_scratch:XF 6 ""))])]
13885   "TARGET_USE_FANCY_MATH_387
13886    && flag_unsafe_math_optimizations"
13887 {
13888   int i;
13889
13890   if (optimize_insn_for_size_p ())
13891     FAIL;
13892
13893   for (i = 2; i < 6; i++)
13894     operands[i] = gen_reg_rtx (XFmode);
13895
13896   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13897 })
13898
13899 (define_expand "asin<mode>2"
13900   [(use (match_operand:MODEF 0 "register_operand" ""))
13901    (use (match_operand:MODEF 1 "general_operand" ""))]
13902  "TARGET_USE_FANCY_MATH_387
13903    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13904        || TARGET_MIX_SSE_I387)
13905    && flag_unsafe_math_optimizations"
13906 {
13907   rtx op0 = gen_reg_rtx (XFmode);
13908   rtx op1 = gen_reg_rtx (XFmode);
13909
13910   if (optimize_insn_for_size_p ())
13911     FAIL;
13912
13913   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13914   emit_insn (gen_asinxf2 (op0, op1));
13915   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13916   DONE;
13917 })
13918
13919 (define_expand "acosxf2"
13920   [(set (match_dup 2)
13921         (mult:XF (match_operand:XF 1 "register_operand" "")
13922                  (match_dup 1)))
13923    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13924    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13925    (parallel [(set (match_operand:XF 0 "register_operand" "")
13926                    (unspec:XF [(match_dup 1) (match_dup 5)]
13927                               UNSPEC_FPATAN))
13928               (clobber (match_scratch:XF 6 ""))])]
13929   "TARGET_USE_FANCY_MATH_387
13930    && flag_unsafe_math_optimizations"
13931 {
13932   int i;
13933
13934   if (optimize_insn_for_size_p ())
13935     FAIL;
13936
13937   for (i = 2; i < 6; i++)
13938     operands[i] = gen_reg_rtx (XFmode);
13939
13940   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13941 })
13942
13943 (define_expand "acos<mode>2"
13944   [(use (match_operand:MODEF 0 "register_operand" ""))
13945    (use (match_operand:MODEF 1 "general_operand" ""))]
13946  "TARGET_USE_FANCY_MATH_387
13947    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13948        || TARGET_MIX_SSE_I387)
13949    && flag_unsafe_math_optimizations"
13950 {
13951   rtx op0 = gen_reg_rtx (XFmode);
13952   rtx op1 = gen_reg_rtx (XFmode);
13953
13954   if (optimize_insn_for_size_p ())
13955     FAIL;
13956
13957   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13958   emit_insn (gen_acosxf2 (op0, op1));
13959   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13960   DONE;
13961 })
13962
13963 (define_insn "fyl2xxf3_i387"
13964   [(set (match_operand:XF 0 "register_operand" "=f")
13965         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13966                     (match_operand:XF 2 "register_operand" "u")]
13967                    UNSPEC_FYL2X))
13968    (clobber (match_scratch:XF 3 "=2"))]
13969   "TARGET_USE_FANCY_MATH_387
13970    && flag_unsafe_math_optimizations"
13971   "fyl2x"
13972   [(set_attr "type" "fpspc")
13973    (set_attr "mode" "XF")])
13974
13975 (define_insn "fyl2x_extend<mode>xf3_i387"
13976   [(set (match_operand:XF 0 "register_operand" "=f")
13977         (unspec:XF [(float_extend:XF
13978                       (match_operand:MODEF 1 "register_operand" "0"))
13979                     (match_operand:XF 2 "register_operand" "u")]
13980                    UNSPEC_FYL2X))
13981    (clobber (match_scratch:XF 3 "=2"))]
13982   "TARGET_USE_FANCY_MATH_387
13983    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13984        || TARGET_MIX_SSE_I387)
13985    && flag_unsafe_math_optimizations"
13986   "fyl2x"
13987   [(set_attr "type" "fpspc")
13988    (set_attr "mode" "XF")])
13989
13990 (define_expand "logxf2"
13991   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13992                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13993                                (match_dup 2)] UNSPEC_FYL2X))
13994               (clobber (match_scratch:XF 3 ""))])]
13995   "TARGET_USE_FANCY_MATH_387
13996    && flag_unsafe_math_optimizations"
13997 {
13998   operands[2] = gen_reg_rtx (XFmode);
13999   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14000 })
14001
14002 (define_expand "log<mode>2"
14003   [(use (match_operand:MODEF 0 "register_operand" ""))
14004    (use (match_operand:MODEF 1 "register_operand" ""))]
14005   "TARGET_USE_FANCY_MATH_387
14006    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14007        || TARGET_MIX_SSE_I387)
14008    && flag_unsafe_math_optimizations"
14009 {
14010   rtx op0 = gen_reg_rtx (XFmode);
14011
14012   rtx op2 = gen_reg_rtx (XFmode);
14013   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14014
14015   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14016   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14017   DONE;
14018 })
14019
14020 (define_expand "log10xf2"
14021   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14022                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14023                                (match_dup 2)] UNSPEC_FYL2X))
14024               (clobber (match_scratch:XF 3 ""))])]
14025   "TARGET_USE_FANCY_MATH_387
14026    && flag_unsafe_math_optimizations"
14027 {
14028   operands[2] = gen_reg_rtx (XFmode);
14029   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14030 })
14031
14032 (define_expand "log10<mode>2"
14033   [(use (match_operand:MODEF 0 "register_operand" ""))
14034    (use (match_operand:MODEF 1 "register_operand" ""))]
14035   "TARGET_USE_FANCY_MATH_387
14036    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14037        || TARGET_MIX_SSE_I387)
14038    && flag_unsafe_math_optimizations"
14039 {
14040   rtx op0 = gen_reg_rtx (XFmode);
14041
14042   rtx op2 = gen_reg_rtx (XFmode);
14043   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14044
14045   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14046   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14047   DONE;
14048 })
14049
14050 (define_expand "log2xf2"
14051   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14052                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14053                                (match_dup 2)] UNSPEC_FYL2X))
14054               (clobber (match_scratch:XF 3 ""))])]
14055   "TARGET_USE_FANCY_MATH_387
14056    && flag_unsafe_math_optimizations"
14057 {
14058   operands[2] = gen_reg_rtx (XFmode);
14059   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14060 })
14061
14062 (define_expand "log2<mode>2"
14063   [(use (match_operand:MODEF 0 "register_operand" ""))
14064    (use (match_operand:MODEF 1 "register_operand" ""))]
14065   "TARGET_USE_FANCY_MATH_387
14066    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14067        || TARGET_MIX_SSE_I387)
14068    && flag_unsafe_math_optimizations"
14069 {
14070   rtx op0 = gen_reg_rtx (XFmode);
14071
14072   rtx op2 = gen_reg_rtx (XFmode);
14073   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14074
14075   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14076   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14077   DONE;
14078 })
14079
14080 (define_insn "fyl2xp1xf3_i387"
14081   [(set (match_operand:XF 0 "register_operand" "=f")
14082         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14083                     (match_operand:XF 2 "register_operand" "u")]
14084                    UNSPEC_FYL2XP1))
14085    (clobber (match_scratch:XF 3 "=2"))]
14086   "TARGET_USE_FANCY_MATH_387
14087    && flag_unsafe_math_optimizations"
14088   "fyl2xp1"
14089   [(set_attr "type" "fpspc")
14090    (set_attr "mode" "XF")])
14091
14092 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14093   [(set (match_operand:XF 0 "register_operand" "=f")
14094         (unspec:XF [(float_extend:XF
14095                       (match_operand:MODEF 1 "register_operand" "0"))
14096                     (match_operand:XF 2 "register_operand" "u")]
14097                    UNSPEC_FYL2XP1))
14098    (clobber (match_scratch:XF 3 "=2"))]
14099   "TARGET_USE_FANCY_MATH_387
14100    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14101        || TARGET_MIX_SSE_I387)
14102    && flag_unsafe_math_optimizations"
14103   "fyl2xp1"
14104   [(set_attr "type" "fpspc")
14105    (set_attr "mode" "XF")])
14106
14107 (define_expand "log1pxf2"
14108   [(use (match_operand:XF 0 "register_operand" ""))
14109    (use (match_operand:XF 1 "register_operand" ""))]
14110   "TARGET_USE_FANCY_MATH_387
14111    && flag_unsafe_math_optimizations"
14112 {
14113   if (optimize_insn_for_size_p ())
14114     FAIL;
14115
14116   ix86_emit_i387_log1p (operands[0], operands[1]);
14117   DONE;
14118 })
14119
14120 (define_expand "log1p<mode>2"
14121   [(use (match_operand:MODEF 0 "register_operand" ""))
14122    (use (match_operand:MODEF 1 "register_operand" ""))]
14123   "TARGET_USE_FANCY_MATH_387
14124    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14125        || TARGET_MIX_SSE_I387)
14126    && flag_unsafe_math_optimizations"
14127 {
14128   rtx op0;
14129
14130   if (optimize_insn_for_size_p ())
14131     FAIL;
14132
14133   op0 = gen_reg_rtx (XFmode);
14134
14135   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14136
14137   ix86_emit_i387_log1p (op0, operands[1]);
14138   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14139   DONE;
14140 })
14141
14142 (define_insn "fxtractxf3_i387"
14143   [(set (match_operand:XF 0 "register_operand" "=f")
14144         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14145                    UNSPEC_XTRACT_FRACT))
14146    (set (match_operand:XF 1 "register_operand" "=u")
14147         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14148   "TARGET_USE_FANCY_MATH_387
14149    && flag_unsafe_math_optimizations"
14150   "fxtract"
14151   [(set_attr "type" "fpspc")
14152    (set_attr "mode" "XF")])
14153
14154 (define_insn "fxtract_extend<mode>xf3_i387"
14155   [(set (match_operand:XF 0 "register_operand" "=f")
14156         (unspec:XF [(float_extend:XF
14157                       (match_operand:MODEF 2 "register_operand" "0"))]
14158                    UNSPEC_XTRACT_FRACT))
14159    (set (match_operand:XF 1 "register_operand" "=u")
14160         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14161   "TARGET_USE_FANCY_MATH_387
14162    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14163        || TARGET_MIX_SSE_I387)
14164    && flag_unsafe_math_optimizations"
14165   "fxtract"
14166   [(set_attr "type" "fpspc")
14167    (set_attr "mode" "XF")])
14168
14169 (define_expand "logbxf2"
14170   [(parallel [(set (match_dup 2)
14171                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14172                               UNSPEC_XTRACT_FRACT))
14173               (set (match_operand:XF 0 "register_operand" "")
14174                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14175   "TARGET_USE_FANCY_MATH_387
14176    && flag_unsafe_math_optimizations"
14177   "operands[2] = gen_reg_rtx (XFmode);")
14178
14179 (define_expand "logb<mode>2"
14180   [(use (match_operand:MODEF 0 "register_operand" ""))
14181    (use (match_operand:MODEF 1 "register_operand" ""))]
14182   "TARGET_USE_FANCY_MATH_387
14183    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14184        || TARGET_MIX_SSE_I387)
14185    && flag_unsafe_math_optimizations"
14186 {
14187   rtx op0 = gen_reg_rtx (XFmode);
14188   rtx op1 = gen_reg_rtx (XFmode);
14189
14190   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14191   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14192   DONE;
14193 })
14194
14195 (define_expand "ilogbxf2"
14196   [(use (match_operand:SI 0 "register_operand" ""))
14197    (use (match_operand:XF 1 "register_operand" ""))]
14198   "TARGET_USE_FANCY_MATH_387
14199    && flag_unsafe_math_optimizations"
14200 {
14201   rtx op0, op1;
14202
14203   if (optimize_insn_for_size_p ())
14204     FAIL;
14205
14206   op0 = gen_reg_rtx (XFmode);
14207   op1 = gen_reg_rtx (XFmode);
14208
14209   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14210   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14211   DONE;
14212 })
14213
14214 (define_expand "ilogb<mode>2"
14215   [(use (match_operand:SI 0 "register_operand" ""))
14216    (use (match_operand:MODEF 1 "register_operand" ""))]
14217   "TARGET_USE_FANCY_MATH_387
14218    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14219        || TARGET_MIX_SSE_I387)
14220    && flag_unsafe_math_optimizations"
14221 {
14222   rtx op0, op1;
14223
14224   if (optimize_insn_for_size_p ())
14225     FAIL;
14226
14227   op0 = gen_reg_rtx (XFmode);
14228   op1 = gen_reg_rtx (XFmode);
14229
14230   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14231   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14232   DONE;
14233 })
14234
14235 (define_insn "*f2xm1xf2_i387"
14236   [(set (match_operand:XF 0 "register_operand" "=f")
14237         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14238                    UNSPEC_F2XM1))]
14239   "TARGET_USE_FANCY_MATH_387
14240    && flag_unsafe_math_optimizations"
14241   "f2xm1"
14242   [(set_attr "type" "fpspc")
14243    (set_attr "mode" "XF")])
14244
14245 (define_insn "*fscalexf4_i387"
14246   [(set (match_operand:XF 0 "register_operand" "=f")
14247         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14248                     (match_operand:XF 3 "register_operand" "1")]
14249                    UNSPEC_FSCALE_FRACT))
14250    (set (match_operand:XF 1 "register_operand" "=u")
14251         (unspec:XF [(match_dup 2) (match_dup 3)]
14252                    UNSPEC_FSCALE_EXP))]
14253   "TARGET_USE_FANCY_MATH_387
14254    && flag_unsafe_math_optimizations"
14255   "fscale"
14256   [(set_attr "type" "fpspc")
14257    (set_attr "mode" "XF")])
14258
14259 (define_expand "expNcorexf3"
14260   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14261                                (match_operand:XF 2 "register_operand" "")))
14262    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14263    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14264    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14265    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14266    (parallel [(set (match_operand:XF 0 "register_operand" "")
14267                    (unspec:XF [(match_dup 8) (match_dup 4)]
14268                               UNSPEC_FSCALE_FRACT))
14269               (set (match_dup 9)
14270                    (unspec:XF [(match_dup 8) (match_dup 4)]
14271                               UNSPEC_FSCALE_EXP))])]
14272   "TARGET_USE_FANCY_MATH_387
14273    && flag_unsafe_math_optimizations"
14274 {
14275   int i;
14276
14277   if (optimize_insn_for_size_p ())
14278     FAIL;
14279
14280   for (i = 3; i < 10; i++)
14281     operands[i] = gen_reg_rtx (XFmode);
14282
14283   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14284 })
14285
14286 (define_expand "expxf2"
14287   [(use (match_operand:XF 0 "register_operand" ""))
14288    (use (match_operand:XF 1 "register_operand" ""))]
14289   "TARGET_USE_FANCY_MATH_387
14290    && flag_unsafe_math_optimizations"
14291 {
14292   rtx op2;
14293
14294   if (optimize_insn_for_size_p ())
14295     FAIL;
14296
14297   op2 = gen_reg_rtx (XFmode);
14298   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14299
14300   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14301   DONE;
14302 })
14303
14304 (define_expand "exp<mode>2"
14305   [(use (match_operand:MODEF 0 "register_operand" ""))
14306    (use (match_operand:MODEF 1 "general_operand" ""))]
14307  "TARGET_USE_FANCY_MATH_387
14308    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14309        || TARGET_MIX_SSE_I387)
14310    && flag_unsafe_math_optimizations"
14311 {
14312   rtx op0, op1;
14313
14314   if (optimize_insn_for_size_p ())
14315     FAIL;
14316
14317   op0 = gen_reg_rtx (XFmode);
14318   op1 = gen_reg_rtx (XFmode);
14319
14320   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14321   emit_insn (gen_expxf2 (op0, op1));
14322   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14323   DONE;
14324 })
14325
14326 (define_expand "exp10xf2"
14327   [(use (match_operand:XF 0 "register_operand" ""))
14328    (use (match_operand:XF 1 "register_operand" ""))]
14329   "TARGET_USE_FANCY_MATH_387
14330    && flag_unsafe_math_optimizations"
14331 {
14332   rtx op2;
14333
14334   if (optimize_insn_for_size_p ())
14335     FAIL;
14336
14337   op2 = gen_reg_rtx (XFmode);
14338   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14339
14340   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14341   DONE;
14342 })
14343
14344 (define_expand "exp10<mode>2"
14345   [(use (match_operand:MODEF 0 "register_operand" ""))
14346    (use (match_operand:MODEF 1 "general_operand" ""))]
14347  "TARGET_USE_FANCY_MATH_387
14348    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14349        || TARGET_MIX_SSE_I387)
14350    && flag_unsafe_math_optimizations"
14351 {
14352   rtx op0, op1;
14353
14354   if (optimize_insn_for_size_p ())
14355     FAIL;
14356
14357   op0 = gen_reg_rtx (XFmode);
14358   op1 = gen_reg_rtx (XFmode);
14359
14360   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14361   emit_insn (gen_exp10xf2 (op0, op1));
14362   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14363   DONE;
14364 })
14365
14366 (define_expand "exp2xf2"
14367   [(use (match_operand:XF 0 "register_operand" ""))
14368    (use (match_operand:XF 1 "register_operand" ""))]
14369   "TARGET_USE_FANCY_MATH_387
14370    && flag_unsafe_math_optimizations"
14371 {
14372   rtx op2;
14373
14374   if (optimize_insn_for_size_p ())
14375     FAIL;
14376
14377   op2 = gen_reg_rtx (XFmode);
14378   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14379
14380   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14381   DONE;
14382 })
14383
14384 (define_expand "exp2<mode>2"
14385   [(use (match_operand:MODEF 0 "register_operand" ""))
14386    (use (match_operand:MODEF 1 "general_operand" ""))]
14387  "TARGET_USE_FANCY_MATH_387
14388    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14389        || TARGET_MIX_SSE_I387)
14390    && flag_unsafe_math_optimizations"
14391 {
14392   rtx op0, op1;
14393
14394   if (optimize_insn_for_size_p ())
14395     FAIL;
14396
14397   op0 = gen_reg_rtx (XFmode);
14398   op1 = gen_reg_rtx (XFmode);
14399
14400   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14401   emit_insn (gen_exp2xf2 (op0, op1));
14402   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14403   DONE;
14404 })
14405
14406 (define_expand "expm1xf2"
14407   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14408                                (match_dup 2)))
14409    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14410    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14411    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14412    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14413    (parallel [(set (match_dup 7)
14414                    (unspec:XF [(match_dup 6) (match_dup 4)]
14415                               UNSPEC_FSCALE_FRACT))
14416               (set (match_dup 8)
14417                    (unspec:XF [(match_dup 6) (match_dup 4)]
14418                               UNSPEC_FSCALE_EXP))])
14419    (parallel [(set (match_dup 10)
14420                    (unspec:XF [(match_dup 9) (match_dup 8)]
14421                               UNSPEC_FSCALE_FRACT))
14422               (set (match_dup 11)
14423                    (unspec:XF [(match_dup 9) (match_dup 8)]
14424                               UNSPEC_FSCALE_EXP))])
14425    (set (match_dup 12) (minus:XF (match_dup 10)
14426                                  (float_extend:XF (match_dup 13))))
14427    (set (match_operand:XF 0 "register_operand" "")
14428         (plus:XF (match_dup 12) (match_dup 7)))]
14429   "TARGET_USE_FANCY_MATH_387
14430    && flag_unsafe_math_optimizations"
14431 {
14432   int i;
14433
14434   if (optimize_insn_for_size_p ())
14435     FAIL;
14436
14437   for (i = 2; i < 13; i++)
14438     operands[i] = gen_reg_rtx (XFmode);
14439
14440   operands[13]
14441     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14442
14443   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14444 })
14445
14446 (define_expand "expm1<mode>2"
14447   [(use (match_operand:MODEF 0 "register_operand" ""))
14448    (use (match_operand:MODEF 1 "general_operand" ""))]
14449  "TARGET_USE_FANCY_MATH_387
14450    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14451        || TARGET_MIX_SSE_I387)
14452    && flag_unsafe_math_optimizations"
14453 {
14454   rtx op0, op1;
14455
14456   if (optimize_insn_for_size_p ())
14457     FAIL;
14458
14459   op0 = gen_reg_rtx (XFmode);
14460   op1 = gen_reg_rtx (XFmode);
14461
14462   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14463   emit_insn (gen_expm1xf2 (op0, op1));
14464   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14465   DONE;
14466 })
14467
14468 (define_expand "ldexpxf3"
14469   [(set (match_dup 3)
14470         (float:XF (match_operand:SI 2 "register_operand" "")))
14471    (parallel [(set (match_operand:XF 0 " register_operand" "")
14472                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14473                                (match_dup 3)]
14474                               UNSPEC_FSCALE_FRACT))
14475               (set (match_dup 4)
14476                    (unspec:XF [(match_dup 1) (match_dup 3)]
14477                               UNSPEC_FSCALE_EXP))])]
14478   "TARGET_USE_FANCY_MATH_387
14479    && flag_unsafe_math_optimizations"
14480 {
14481   if (optimize_insn_for_size_p ())
14482     FAIL;
14483
14484   operands[3] = gen_reg_rtx (XFmode);
14485   operands[4] = gen_reg_rtx (XFmode);
14486 })
14487
14488 (define_expand "ldexp<mode>3"
14489   [(use (match_operand:MODEF 0 "register_operand" ""))
14490    (use (match_operand:MODEF 1 "general_operand" ""))
14491    (use (match_operand:SI 2 "register_operand" ""))]
14492  "TARGET_USE_FANCY_MATH_387
14493    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14494        || TARGET_MIX_SSE_I387)
14495    && flag_unsafe_math_optimizations"
14496 {
14497   rtx op0, op1;
14498
14499   if (optimize_insn_for_size_p ())
14500     FAIL;
14501
14502   op0 = gen_reg_rtx (XFmode);
14503   op1 = gen_reg_rtx (XFmode);
14504
14505   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14506   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14507   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14508   DONE;
14509 })
14510
14511 (define_expand "scalbxf3"
14512   [(parallel [(set (match_operand:XF 0 " register_operand" "")
14513                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14514                                (match_operand:XF 2 "register_operand" "")]
14515                               UNSPEC_FSCALE_FRACT))
14516               (set (match_dup 3)
14517                    (unspec:XF [(match_dup 1) (match_dup 2)]
14518                               UNSPEC_FSCALE_EXP))])]
14519   "TARGET_USE_FANCY_MATH_387
14520    && flag_unsafe_math_optimizations"
14521 {
14522   if (optimize_insn_for_size_p ())
14523     FAIL;
14524
14525   operands[3] = gen_reg_rtx (XFmode);
14526 })
14527
14528 (define_expand "scalb<mode>3"
14529   [(use (match_operand:MODEF 0 "register_operand" ""))
14530    (use (match_operand:MODEF 1 "general_operand" ""))
14531    (use (match_operand:MODEF 2 "general_operand" ""))]
14532  "TARGET_USE_FANCY_MATH_387
14533    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14534        || TARGET_MIX_SSE_I387)
14535    && flag_unsafe_math_optimizations"
14536 {
14537   rtx op0, op1, op2;
14538
14539   if (optimize_insn_for_size_p ())
14540     FAIL;
14541
14542   op0 = gen_reg_rtx (XFmode);
14543   op1 = gen_reg_rtx (XFmode);
14544   op2 = gen_reg_rtx (XFmode);
14545
14546   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14547   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14548   emit_insn (gen_scalbxf3 (op0, op1, op2));
14549   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14550   DONE;
14551 })
14552
14553 (define_expand "significandxf2"
14554   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14555                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14556                               UNSPEC_XTRACT_FRACT))
14557               (set (match_dup 2)
14558                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14559   "TARGET_USE_FANCY_MATH_387
14560    && flag_unsafe_math_optimizations"
14561   "operands[2] = gen_reg_rtx (XFmode);")
14562
14563 (define_expand "significand<mode>2"
14564   [(use (match_operand:MODEF 0 "register_operand" ""))
14565    (use (match_operand:MODEF 1 "register_operand" ""))]
14566   "TARGET_USE_FANCY_MATH_387
14567    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14568        || TARGET_MIX_SSE_I387)
14569    && flag_unsafe_math_optimizations"
14570 {
14571   rtx op0 = gen_reg_rtx (XFmode);
14572   rtx op1 = gen_reg_rtx (XFmode);
14573
14574   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14575   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14576   DONE;
14577 })
14578 \f
14579
14580 (define_insn "sse4_1_round<mode>2"
14581   [(set (match_operand:MODEF 0 "register_operand" "=x")
14582         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14583                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14584                       UNSPEC_ROUND))]
14585   "TARGET_ROUND"
14586   "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14587   [(set_attr "type" "ssecvt")
14588    (set_attr "prefix_extra" "1")
14589    (set_attr "prefix" "maybe_vex")
14590    (set_attr "mode" "<MODE>")])
14591
14592 (define_insn "rintxf2"
14593   [(set (match_operand:XF 0 "register_operand" "=f")
14594         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14595                    UNSPEC_FRNDINT))]
14596   "TARGET_USE_FANCY_MATH_387
14597    && flag_unsafe_math_optimizations"
14598   "frndint"
14599   [(set_attr "type" "fpspc")
14600    (set_attr "mode" "XF")])
14601
14602 (define_expand "rint<mode>2"
14603   [(use (match_operand:MODEF 0 "register_operand" ""))
14604    (use (match_operand:MODEF 1 "register_operand" ""))]
14605   "(TARGET_USE_FANCY_MATH_387
14606     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14607         || TARGET_MIX_SSE_I387)
14608     && flag_unsafe_math_optimizations)
14609    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14610        && !flag_trapping_math)"
14611 {
14612   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14613       && !flag_trapping_math)
14614     {
14615       if (TARGET_ROUND)
14616         emit_insn (gen_sse4_1_round<mode>2
14617                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14618       else if (optimize_insn_for_size_p ())
14619         FAIL;
14620       else
14621         ix86_expand_rint (operand0, operand1);
14622     }
14623   else
14624     {
14625       rtx op0 = gen_reg_rtx (XFmode);
14626       rtx op1 = gen_reg_rtx (XFmode);
14627
14628       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14629       emit_insn (gen_rintxf2 (op0, op1));
14630
14631       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14632     }
14633   DONE;
14634 })
14635
14636 (define_expand "round<mode>2"
14637   [(match_operand:X87MODEF 0 "register_operand" "")
14638    (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14639   "(TARGET_USE_FANCY_MATH_387
14640     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14641         || TARGET_MIX_SSE_I387)
14642     && flag_unsafe_math_optimizations)
14643    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14644        && !flag_trapping_math && !flag_rounding_math)"
14645 {
14646   if (optimize_insn_for_size_p ())
14647     FAIL;
14648
14649   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14650       && !flag_trapping_math && !flag_rounding_math)
14651     {
14652       if (TARGET_ROUND)
14653         {
14654           operands[1] = force_reg (<MODE>mode, operands[1]);
14655           ix86_expand_round_sse4 (operands[0], operands[1]);
14656         }
14657       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14658         ix86_expand_round (operands[0], operands[1]);
14659       else
14660         ix86_expand_rounddf_32 (operands[0], operands[1]);
14661     }
14662   else
14663     {
14664       operands[1] = force_reg (<MODE>mode, operands[1]);
14665       ix86_emit_i387_round (operands[0], operands[1]);
14666     }
14667   DONE;
14668 })
14669
14670 (define_insn_and_split "*fistdi2_1"
14671   [(set (match_operand:DI 0 "nonimmediate_operand" "")
14672         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14673                    UNSPEC_FIST))]
14674   "TARGET_USE_FANCY_MATH_387
14675    && can_create_pseudo_p ()"
14676   "#"
14677   "&& 1"
14678   [(const_int 0)]
14679 {
14680   if (memory_operand (operands[0], VOIDmode))
14681     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14682   else
14683     {
14684       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14685       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14686                                          operands[2]));
14687     }
14688   DONE;
14689 }
14690   [(set_attr "type" "fpspc")
14691    (set_attr "mode" "DI")])
14692
14693 (define_insn "fistdi2"
14694   [(set (match_operand:DI 0 "memory_operand" "=m")
14695         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14696                    UNSPEC_FIST))
14697    (clobber (match_scratch:XF 2 "=&1f"))]
14698   "TARGET_USE_FANCY_MATH_387"
14699   "* return output_fix_trunc (insn, operands, false);"
14700   [(set_attr "type" "fpspc")
14701    (set_attr "mode" "DI")])
14702
14703 (define_insn "fistdi2_with_temp"
14704   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14705         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14706                    UNSPEC_FIST))
14707    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14708    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14709   "TARGET_USE_FANCY_MATH_387"
14710   "#"
14711   [(set_attr "type" "fpspc")
14712    (set_attr "mode" "DI")])
14713
14714 (define_split
14715   [(set (match_operand:DI 0 "register_operand" "")
14716         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14717                    UNSPEC_FIST))
14718    (clobber (match_operand:DI 2 "memory_operand" ""))
14719    (clobber (match_scratch 3 ""))]
14720   "reload_completed"
14721   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14722               (clobber (match_dup 3))])
14723    (set (match_dup 0) (match_dup 2))])
14724
14725 (define_split
14726   [(set (match_operand:DI 0 "memory_operand" "")
14727         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14728                    UNSPEC_FIST))
14729    (clobber (match_operand:DI 2 "memory_operand" ""))
14730    (clobber (match_scratch 3 ""))]
14731   "reload_completed"
14732   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14733               (clobber (match_dup 3))])])
14734
14735 (define_insn_and_split "*fist<mode>2_1"
14736   [(set (match_operand:SWI24 0 "register_operand" "")
14737         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14738                       UNSPEC_FIST))]
14739   "TARGET_USE_FANCY_MATH_387
14740    && can_create_pseudo_p ()"
14741   "#"
14742   "&& 1"
14743   [(const_int 0)]
14744 {
14745   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14746   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14747                                         operands[2]));
14748   DONE;
14749 }
14750   [(set_attr "type" "fpspc")
14751    (set_attr "mode" "<MODE>")])
14752
14753 (define_insn "fist<mode>2"
14754   [(set (match_operand:SWI24 0 "memory_operand" "=m")
14755         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14756                       UNSPEC_FIST))]
14757   "TARGET_USE_FANCY_MATH_387"
14758   "* return output_fix_trunc (insn, operands, false);"
14759   [(set_attr "type" "fpspc")
14760    (set_attr "mode" "<MODE>")])
14761
14762 (define_insn "fist<mode>2_with_temp"
14763   [(set (match_operand:SWI24 0 "register_operand" "=r")
14764         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14765                       UNSPEC_FIST))
14766    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14767   "TARGET_USE_FANCY_MATH_387"
14768   "#"
14769   [(set_attr "type" "fpspc")
14770    (set_attr "mode" "<MODE>")])
14771
14772 (define_split
14773   [(set (match_operand:SWI24 0 "register_operand" "")
14774         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14775                       UNSPEC_FIST))
14776    (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14777   "reload_completed"
14778   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14779    (set (match_dup 0) (match_dup 2))])
14780
14781 (define_split
14782   [(set (match_operand:SWI24 0 "memory_operand" "")
14783         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14784                       UNSPEC_FIST))
14785    (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14786   "reload_completed"
14787   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14788
14789 (define_expand "lrintxf<mode>2"
14790   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14791      (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14792                      UNSPEC_FIST))]
14793   "TARGET_USE_FANCY_MATH_387")
14794
14795 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14796   [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14797      (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14798                         UNSPEC_FIX_NOTRUNC))]
14799   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14800    && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14801
14802 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14803   [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14804    (match_operand:X87MODEF 1 "register_operand" "")]
14805   "(TARGET_USE_FANCY_MATH_387
14806     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14807         || TARGET_MIX_SSE_I387)
14808     && flag_unsafe_math_optimizations)
14809    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14810        && <SWI248x:MODE>mode != HImode 
14811        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14812        && !flag_trapping_math && !flag_rounding_math)"
14813 {
14814   if (optimize_insn_for_size_p ())
14815     FAIL;
14816
14817   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14818       && <SWI248x:MODE>mode != HImode
14819       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14820       && !flag_trapping_math && !flag_rounding_math)
14821     ix86_expand_lround (operand0, operand1);
14822   else
14823     ix86_emit_i387_round (operands[0], operands[1]);
14824   DONE;
14825 })
14826
14827 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14828 (define_insn_and_split "frndintxf2_floor"
14829   [(set (match_operand:XF 0 "register_operand" "")
14830         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14831          UNSPEC_FRNDINT_FLOOR))
14832    (clobber (reg:CC FLAGS_REG))]
14833   "TARGET_USE_FANCY_MATH_387
14834    && flag_unsafe_math_optimizations
14835    && can_create_pseudo_p ()"
14836   "#"
14837   "&& 1"
14838   [(const_int 0)]
14839 {
14840   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14841
14842   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14843   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14844
14845   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14846                                         operands[2], operands[3]));
14847   DONE;
14848 }
14849   [(set_attr "type" "frndint")
14850    (set_attr "i387_cw" "floor")
14851    (set_attr "mode" "XF")])
14852
14853 (define_insn "frndintxf2_floor_i387"
14854   [(set (match_operand:XF 0 "register_operand" "=f")
14855         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14856          UNSPEC_FRNDINT_FLOOR))
14857    (use (match_operand:HI 2 "memory_operand" "m"))
14858    (use (match_operand:HI 3 "memory_operand" "m"))]
14859   "TARGET_USE_FANCY_MATH_387
14860    && flag_unsafe_math_optimizations"
14861   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14862   [(set_attr "type" "frndint")
14863    (set_attr "i387_cw" "floor")
14864    (set_attr "mode" "XF")])
14865
14866 (define_expand "floorxf2"
14867   [(use (match_operand:XF 0 "register_operand" ""))
14868    (use (match_operand:XF 1 "register_operand" ""))]
14869   "TARGET_USE_FANCY_MATH_387
14870    && flag_unsafe_math_optimizations"
14871 {
14872   if (optimize_insn_for_size_p ())
14873     FAIL;
14874   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14875   DONE;
14876 })
14877
14878 (define_expand "floor<mode>2"
14879   [(use (match_operand:MODEF 0 "register_operand" ""))
14880    (use (match_operand:MODEF 1 "register_operand" ""))]
14881   "(TARGET_USE_FANCY_MATH_387
14882     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14883         || TARGET_MIX_SSE_I387)
14884     && flag_unsafe_math_optimizations)
14885    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14886        && !flag_trapping_math)"
14887 {
14888   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14889       && !flag_trapping_math)
14890     {
14891       if (TARGET_ROUND)
14892         emit_insn (gen_sse4_1_round<mode>2
14893                    (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14894       else if (optimize_insn_for_size_p ())
14895         FAIL;
14896       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14897         ix86_expand_floorceil (operand0, operand1, true);
14898       else
14899         ix86_expand_floorceildf_32 (operand0, operand1, true);
14900     }
14901   else
14902     {
14903       rtx op0, op1;
14904
14905       if (optimize_insn_for_size_p ())
14906         FAIL;
14907
14908       op0 = gen_reg_rtx (XFmode);
14909       op1 = gen_reg_rtx (XFmode);
14910       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14911       emit_insn (gen_frndintxf2_floor (op0, op1));
14912
14913       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14914     }
14915   DONE;
14916 })
14917
14918 (define_insn_and_split "*fist<mode>2_floor_1"
14919   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14920         (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14921                         UNSPEC_FIST_FLOOR))
14922    (clobber (reg:CC FLAGS_REG))]
14923   "TARGET_USE_FANCY_MATH_387
14924    && flag_unsafe_math_optimizations
14925    && can_create_pseudo_p ()"
14926   "#"
14927   "&& 1"
14928   [(const_int 0)]
14929 {
14930   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14931
14932   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14933   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14934   if (memory_operand (operands[0], VOIDmode))
14935     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14936                                       operands[2], operands[3]));
14937   else
14938     {
14939       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14940       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14941                                                   operands[2], operands[3],
14942                                                   operands[4]));
14943     }
14944   DONE;
14945 }
14946   [(set_attr "type" "fistp")
14947    (set_attr "i387_cw" "floor")
14948    (set_attr "mode" "<MODE>")])
14949
14950 (define_insn "fistdi2_floor"
14951   [(set (match_operand:DI 0 "memory_operand" "=m")
14952         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14953                    UNSPEC_FIST_FLOOR))
14954    (use (match_operand:HI 2 "memory_operand" "m"))
14955    (use (match_operand:HI 3 "memory_operand" "m"))
14956    (clobber (match_scratch:XF 4 "=&1f"))]
14957   "TARGET_USE_FANCY_MATH_387
14958    && flag_unsafe_math_optimizations"
14959   "* return output_fix_trunc (insn, operands, false);"
14960   [(set_attr "type" "fistp")
14961    (set_attr "i387_cw" "floor")
14962    (set_attr "mode" "DI")])
14963
14964 (define_insn "fistdi2_floor_with_temp"
14965   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14966         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14967                    UNSPEC_FIST_FLOOR))
14968    (use (match_operand:HI 2 "memory_operand" "m,m"))
14969    (use (match_operand:HI 3 "memory_operand" "m,m"))
14970    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14971    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14972   "TARGET_USE_FANCY_MATH_387
14973    && flag_unsafe_math_optimizations"
14974   "#"
14975   [(set_attr "type" "fistp")
14976    (set_attr "i387_cw" "floor")
14977    (set_attr "mode" "DI")])
14978
14979 (define_split
14980   [(set (match_operand:DI 0 "register_operand" "")
14981         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14982                    UNSPEC_FIST_FLOOR))
14983    (use (match_operand:HI 2 "memory_operand" ""))
14984    (use (match_operand:HI 3 "memory_operand" ""))
14985    (clobber (match_operand:DI 4 "memory_operand" ""))
14986    (clobber (match_scratch 5 ""))]
14987   "reload_completed"
14988   [(parallel [(set (match_dup 4)
14989                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14990               (use (match_dup 2))
14991               (use (match_dup 3))
14992               (clobber (match_dup 5))])
14993    (set (match_dup 0) (match_dup 4))])
14994
14995 (define_split
14996   [(set (match_operand:DI 0 "memory_operand" "")
14997         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14998                    UNSPEC_FIST_FLOOR))
14999    (use (match_operand:HI 2 "memory_operand" ""))
15000    (use (match_operand:HI 3 "memory_operand" ""))
15001    (clobber (match_operand:DI 4 "memory_operand" ""))
15002    (clobber (match_scratch 5 ""))]
15003   "reload_completed"
15004   [(parallel [(set (match_dup 0)
15005                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15006               (use (match_dup 2))
15007               (use (match_dup 3))
15008               (clobber (match_dup 5))])])
15009
15010 (define_insn "fist<mode>2_floor"
15011   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15012         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15013                       UNSPEC_FIST_FLOOR))
15014    (use (match_operand:HI 2 "memory_operand" "m"))
15015    (use (match_operand:HI 3 "memory_operand" "m"))]
15016   "TARGET_USE_FANCY_MATH_387
15017    && flag_unsafe_math_optimizations"
15018   "* return output_fix_trunc (insn, operands, false);"
15019   [(set_attr "type" "fistp")
15020    (set_attr "i387_cw" "floor")
15021    (set_attr "mode" "<MODE>")])
15022
15023 (define_insn "fist<mode>2_floor_with_temp"
15024   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15025         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15026                       UNSPEC_FIST_FLOOR))
15027    (use (match_operand:HI 2 "memory_operand" "m,m"))
15028    (use (match_operand:HI 3 "memory_operand" "m,m"))
15029    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15030   "TARGET_USE_FANCY_MATH_387
15031    && flag_unsafe_math_optimizations"
15032   "#"
15033   [(set_attr "type" "fistp")
15034    (set_attr "i387_cw" "floor")
15035    (set_attr "mode" "<MODE>")])
15036
15037 (define_split
15038   [(set (match_operand:SWI24 0 "register_operand" "")
15039         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15040                       UNSPEC_FIST_FLOOR))
15041    (use (match_operand:HI 2 "memory_operand" ""))
15042    (use (match_operand:HI 3 "memory_operand" ""))
15043    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15044   "reload_completed"
15045   [(parallel [(set (match_dup 4)
15046                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15047               (use (match_dup 2))
15048               (use (match_dup 3))])
15049    (set (match_dup 0) (match_dup 4))])
15050
15051 (define_split
15052   [(set (match_operand:SWI24 0 "memory_operand" "")
15053         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15054                       UNSPEC_FIST_FLOOR))
15055    (use (match_operand:HI 2 "memory_operand" ""))
15056    (use (match_operand:HI 3 "memory_operand" ""))
15057    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15058   "reload_completed"
15059   [(parallel [(set (match_dup 0)
15060                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15061               (use (match_dup 2))
15062               (use (match_dup 3))])])
15063
15064 (define_expand "lfloorxf<mode>2"
15065   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15066                    (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15067                                    UNSPEC_FIST_FLOOR))
15068               (clobber (reg:CC FLAGS_REG))])]
15069   "TARGET_USE_FANCY_MATH_387
15070    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15071    && flag_unsafe_math_optimizations")
15072
15073 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15074   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15075    (match_operand:MODEF 1 "register_operand" "")]
15076   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15077    && !flag_trapping_math"
15078 {
15079   if (TARGET_64BIT && optimize_insn_for_size_p ())
15080     FAIL;
15081   ix86_expand_lfloorceil (operand0, operand1, true);
15082   DONE;
15083 })
15084
15085 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15086 (define_insn_and_split "frndintxf2_ceil"
15087   [(set (match_operand:XF 0 "register_operand" "")
15088         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15089          UNSPEC_FRNDINT_CEIL))
15090    (clobber (reg:CC FLAGS_REG))]
15091   "TARGET_USE_FANCY_MATH_387
15092    && flag_unsafe_math_optimizations
15093    && can_create_pseudo_p ()"
15094   "#"
15095   "&& 1"
15096   [(const_int 0)]
15097 {
15098   ix86_optimize_mode_switching[I387_CEIL] = 1;
15099
15100   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15101   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15102
15103   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15104                                        operands[2], operands[3]));
15105   DONE;
15106 }
15107   [(set_attr "type" "frndint")
15108    (set_attr "i387_cw" "ceil")
15109    (set_attr "mode" "XF")])
15110
15111 (define_insn "frndintxf2_ceil_i387"
15112   [(set (match_operand:XF 0 "register_operand" "=f")
15113         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15114          UNSPEC_FRNDINT_CEIL))
15115    (use (match_operand:HI 2 "memory_operand" "m"))
15116    (use (match_operand:HI 3 "memory_operand" "m"))]
15117   "TARGET_USE_FANCY_MATH_387
15118    && flag_unsafe_math_optimizations"
15119   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15120   [(set_attr "type" "frndint")
15121    (set_attr "i387_cw" "ceil")
15122    (set_attr "mode" "XF")])
15123
15124 (define_expand "ceilxf2"
15125   [(use (match_operand:XF 0 "register_operand" ""))
15126    (use (match_operand:XF 1 "register_operand" ""))]
15127   "TARGET_USE_FANCY_MATH_387
15128    && flag_unsafe_math_optimizations"
15129 {
15130   if (optimize_insn_for_size_p ())
15131     FAIL;
15132   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15133   DONE;
15134 })
15135
15136 (define_expand "ceil<mode>2"
15137   [(use (match_operand:MODEF 0 "register_operand" ""))
15138    (use (match_operand:MODEF 1 "register_operand" ""))]
15139   "(TARGET_USE_FANCY_MATH_387
15140     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15141         || TARGET_MIX_SSE_I387)
15142     && flag_unsafe_math_optimizations)
15143    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15144        && !flag_trapping_math)"
15145 {
15146   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15147       && !flag_trapping_math)
15148     {
15149       if (TARGET_ROUND)
15150         emit_insn (gen_sse4_1_round<mode>2
15151                    (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15152       else if (optimize_insn_for_size_p ())
15153         FAIL;
15154       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15155         ix86_expand_floorceil (operand0, operand1, false);
15156       else
15157         ix86_expand_floorceildf_32 (operand0, operand1, false);
15158     }
15159   else
15160     {
15161       rtx op0, op1;
15162
15163       if (optimize_insn_for_size_p ())
15164         FAIL;
15165
15166       op0 = gen_reg_rtx (XFmode);
15167       op1 = gen_reg_rtx (XFmode);
15168       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15169       emit_insn (gen_frndintxf2_ceil (op0, op1));
15170
15171       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15172     }
15173   DONE;
15174 })
15175
15176 (define_insn_and_split "*fist<mode>2_ceil_1"
15177   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15178         (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15179                         UNSPEC_FIST_CEIL))
15180    (clobber (reg:CC FLAGS_REG))]
15181   "TARGET_USE_FANCY_MATH_387
15182    && flag_unsafe_math_optimizations
15183    && can_create_pseudo_p ()"
15184   "#"
15185   "&& 1"
15186   [(const_int 0)]
15187 {
15188   ix86_optimize_mode_switching[I387_CEIL] = 1;
15189
15190   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15191   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15192   if (memory_operand (operands[0], VOIDmode))
15193     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15194                                      operands[2], operands[3]));
15195   else
15196     {
15197       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15198       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15199                                                  operands[2], operands[3],
15200                                                  operands[4]));
15201     }
15202   DONE;
15203 }
15204   [(set_attr "type" "fistp")
15205    (set_attr "i387_cw" "ceil")
15206    (set_attr "mode" "<MODE>")])
15207
15208 (define_insn "fistdi2_ceil"
15209   [(set (match_operand:DI 0 "memory_operand" "=m")
15210         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15211                    UNSPEC_FIST_CEIL))
15212    (use (match_operand:HI 2 "memory_operand" "m"))
15213    (use (match_operand:HI 3 "memory_operand" "m"))
15214    (clobber (match_scratch:XF 4 "=&1f"))]
15215   "TARGET_USE_FANCY_MATH_387
15216    && flag_unsafe_math_optimizations"
15217   "* return output_fix_trunc (insn, operands, false);"
15218   [(set_attr "type" "fistp")
15219    (set_attr "i387_cw" "ceil")
15220    (set_attr "mode" "DI")])
15221
15222 (define_insn "fistdi2_ceil_with_temp"
15223   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15224         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15225                    UNSPEC_FIST_CEIL))
15226    (use (match_operand:HI 2 "memory_operand" "m,m"))
15227    (use (match_operand:HI 3 "memory_operand" "m,m"))
15228    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15229    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15230   "TARGET_USE_FANCY_MATH_387
15231    && flag_unsafe_math_optimizations"
15232   "#"
15233   [(set_attr "type" "fistp")
15234    (set_attr "i387_cw" "ceil")
15235    (set_attr "mode" "DI")])
15236
15237 (define_split
15238   [(set (match_operand:DI 0 "register_operand" "")
15239         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15240                    UNSPEC_FIST_CEIL))
15241    (use (match_operand:HI 2 "memory_operand" ""))
15242    (use (match_operand:HI 3 "memory_operand" ""))
15243    (clobber (match_operand:DI 4 "memory_operand" ""))
15244    (clobber (match_scratch 5 ""))]
15245   "reload_completed"
15246   [(parallel [(set (match_dup 4)
15247                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15248               (use (match_dup 2))
15249               (use (match_dup 3))
15250               (clobber (match_dup 5))])
15251    (set (match_dup 0) (match_dup 4))])
15252
15253 (define_split
15254   [(set (match_operand:DI 0 "memory_operand" "")
15255         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15256                    UNSPEC_FIST_CEIL))
15257    (use (match_operand:HI 2 "memory_operand" ""))
15258    (use (match_operand:HI 3 "memory_operand" ""))
15259    (clobber (match_operand:DI 4 "memory_operand" ""))
15260    (clobber (match_scratch 5 ""))]
15261   "reload_completed"
15262   [(parallel [(set (match_dup 0)
15263                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15264               (use (match_dup 2))
15265               (use (match_dup 3))
15266               (clobber (match_dup 5))])])
15267
15268 (define_insn "fist<mode>2_ceil"
15269   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15270         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15271                       UNSPEC_FIST_CEIL))
15272    (use (match_operand:HI 2 "memory_operand" "m"))
15273    (use (match_operand:HI 3 "memory_operand" "m"))]
15274   "TARGET_USE_FANCY_MATH_387
15275    && flag_unsafe_math_optimizations"
15276   "* return output_fix_trunc (insn, operands, false);"
15277   [(set_attr "type" "fistp")
15278    (set_attr "i387_cw" "ceil")
15279    (set_attr "mode" "<MODE>")])
15280
15281 (define_insn "fist<mode>2_ceil_with_temp"
15282   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15283         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15284                       UNSPEC_FIST_CEIL))
15285    (use (match_operand:HI 2 "memory_operand" "m,m"))
15286    (use (match_operand:HI 3 "memory_operand" "m,m"))
15287    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15288   "TARGET_USE_FANCY_MATH_387
15289    && flag_unsafe_math_optimizations"
15290   "#"
15291   [(set_attr "type" "fistp")
15292    (set_attr "i387_cw" "ceil")
15293    (set_attr "mode" "<MODE>")])
15294
15295 (define_split
15296   [(set (match_operand:SWI24 0 "register_operand" "")
15297         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15298                       UNSPEC_FIST_CEIL))
15299    (use (match_operand:HI 2 "memory_operand" ""))
15300    (use (match_operand:HI 3 "memory_operand" ""))
15301    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15302   "reload_completed"
15303   [(parallel [(set (match_dup 4)
15304                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15305               (use (match_dup 2))
15306               (use (match_dup 3))])
15307    (set (match_dup 0) (match_dup 4))])
15308
15309 (define_split
15310   [(set (match_operand:SWI24 0 "memory_operand" "")
15311         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15312                       UNSPEC_FIST_CEIL))
15313    (use (match_operand:HI 2 "memory_operand" ""))
15314    (use (match_operand:HI 3 "memory_operand" ""))
15315    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15316   "reload_completed"
15317   [(parallel [(set (match_dup 0)
15318                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15319               (use (match_dup 2))
15320               (use (match_dup 3))])])
15321
15322 (define_expand "lceilxf<mode>2"
15323   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15324                    (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15325                                    UNSPEC_FIST_CEIL))
15326               (clobber (reg:CC FLAGS_REG))])]
15327   "TARGET_USE_FANCY_MATH_387
15328    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15329    && flag_unsafe_math_optimizations")
15330
15331 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15332   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15333    (match_operand:MODEF 1 "register_operand" "")]
15334   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15335    && !flag_trapping_math"
15336 {
15337   ix86_expand_lfloorceil (operand0, operand1, false);
15338   DONE;
15339 })
15340
15341 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15342 (define_insn_and_split "frndintxf2_trunc"
15343   [(set (match_operand:XF 0 "register_operand" "")
15344         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15345          UNSPEC_FRNDINT_TRUNC))
15346    (clobber (reg:CC FLAGS_REG))]
15347   "TARGET_USE_FANCY_MATH_387
15348    && flag_unsafe_math_optimizations
15349    && can_create_pseudo_p ()"
15350   "#"
15351   "&& 1"
15352   [(const_int 0)]
15353 {
15354   ix86_optimize_mode_switching[I387_TRUNC] = 1;
15355
15356   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15357   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15358
15359   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15360                                         operands[2], operands[3]));
15361   DONE;
15362 }
15363   [(set_attr "type" "frndint")
15364    (set_attr "i387_cw" "trunc")
15365    (set_attr "mode" "XF")])
15366
15367 (define_insn "frndintxf2_trunc_i387"
15368   [(set (match_operand:XF 0 "register_operand" "=f")
15369         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15370          UNSPEC_FRNDINT_TRUNC))
15371    (use (match_operand:HI 2 "memory_operand" "m"))
15372    (use (match_operand:HI 3 "memory_operand" "m"))]
15373   "TARGET_USE_FANCY_MATH_387
15374    && flag_unsafe_math_optimizations"
15375   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15376   [(set_attr "type" "frndint")
15377    (set_attr "i387_cw" "trunc")
15378    (set_attr "mode" "XF")])
15379
15380 (define_expand "btruncxf2"
15381   [(use (match_operand:XF 0 "register_operand" ""))
15382    (use (match_operand:XF 1 "register_operand" ""))]
15383   "TARGET_USE_FANCY_MATH_387
15384    && flag_unsafe_math_optimizations"
15385 {
15386   if (optimize_insn_for_size_p ())
15387     FAIL;
15388   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15389   DONE;
15390 })
15391
15392 (define_expand "btrunc<mode>2"
15393   [(use (match_operand:MODEF 0 "register_operand" ""))
15394    (use (match_operand:MODEF 1 "register_operand" ""))]
15395   "(TARGET_USE_FANCY_MATH_387
15396     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15397         || TARGET_MIX_SSE_I387)
15398     && flag_unsafe_math_optimizations)
15399    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15400        && !flag_trapping_math)"
15401 {
15402   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15403       && !flag_trapping_math)
15404     {
15405       if (TARGET_ROUND)
15406         emit_insn (gen_sse4_1_round<mode>2
15407                    (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15408       else if (optimize_insn_for_size_p ())
15409         FAIL;
15410       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15411         ix86_expand_trunc (operand0, operand1);
15412       else
15413         ix86_expand_truncdf_32 (operand0, operand1);
15414     }
15415   else
15416     {
15417       rtx op0, op1;
15418
15419       if (optimize_insn_for_size_p ())
15420         FAIL;
15421
15422       op0 = gen_reg_rtx (XFmode);
15423       op1 = gen_reg_rtx (XFmode);
15424       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15425       emit_insn (gen_frndintxf2_trunc (op0, op1));
15426
15427       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15428     }
15429   DONE;
15430 })
15431
15432 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15433 (define_insn_and_split "frndintxf2_mask_pm"
15434   [(set (match_operand:XF 0 "register_operand" "")
15435         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15436          UNSPEC_FRNDINT_MASK_PM))
15437    (clobber (reg:CC FLAGS_REG))]
15438   "TARGET_USE_FANCY_MATH_387
15439    && flag_unsafe_math_optimizations
15440    && can_create_pseudo_p ()"
15441   "#"
15442   "&& 1"
15443   [(const_int 0)]
15444 {
15445   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15446
15447   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15448   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15449
15450   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15451                                           operands[2], operands[3]));
15452   DONE;
15453 }
15454   [(set_attr "type" "frndint")
15455    (set_attr "i387_cw" "mask_pm")
15456    (set_attr "mode" "XF")])
15457
15458 (define_insn "frndintxf2_mask_pm_i387"
15459   [(set (match_operand:XF 0 "register_operand" "=f")
15460         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15461          UNSPEC_FRNDINT_MASK_PM))
15462    (use (match_operand:HI 2 "memory_operand" "m"))
15463    (use (match_operand:HI 3 "memory_operand" "m"))]
15464   "TARGET_USE_FANCY_MATH_387
15465    && flag_unsafe_math_optimizations"
15466   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15467   [(set_attr "type" "frndint")
15468    (set_attr "i387_cw" "mask_pm")
15469    (set_attr "mode" "XF")])
15470
15471 (define_expand "nearbyintxf2"
15472   [(use (match_operand:XF 0 "register_operand" ""))
15473    (use (match_operand:XF 1 "register_operand" ""))]
15474   "TARGET_USE_FANCY_MATH_387
15475    && flag_unsafe_math_optimizations"
15476 {
15477   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15478   DONE;
15479 })
15480
15481 (define_expand "nearbyint<mode>2"
15482   [(use (match_operand:MODEF 0 "register_operand" ""))
15483    (use (match_operand:MODEF 1 "register_operand" ""))]
15484   "TARGET_USE_FANCY_MATH_387
15485    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15486        || TARGET_MIX_SSE_I387)
15487    && flag_unsafe_math_optimizations"
15488 {
15489   rtx op0 = gen_reg_rtx (XFmode);
15490   rtx op1 = gen_reg_rtx (XFmode);
15491
15492   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15493   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15494
15495   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15496   DONE;
15497 })
15498
15499 (define_insn "fxam<mode>2_i387"
15500   [(set (match_operand:HI 0 "register_operand" "=a")
15501         (unspec:HI
15502           [(match_operand:X87MODEF 1 "register_operand" "f")]
15503           UNSPEC_FXAM))]
15504   "TARGET_USE_FANCY_MATH_387"
15505   "fxam\n\tfnstsw\t%0"
15506   [(set_attr "type" "multi")
15507    (set_attr "length" "4")
15508    (set_attr "unit" "i387")
15509    (set_attr "mode" "<MODE>")])
15510
15511 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15512   [(set (match_operand:HI 0 "register_operand" "")
15513         (unspec:HI
15514           [(match_operand:MODEF 1 "memory_operand" "")]
15515           UNSPEC_FXAM_MEM))]
15516   "TARGET_USE_FANCY_MATH_387
15517    && can_create_pseudo_p ()"
15518   "#"
15519   "&& 1"
15520   [(set (match_dup 2)(match_dup 1))
15521    (set (match_dup 0)
15522         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15523 {
15524   operands[2] = gen_reg_rtx (<MODE>mode);
15525
15526   MEM_VOLATILE_P (operands[1]) = 1;
15527 }
15528   [(set_attr "type" "multi")
15529    (set_attr "unit" "i387")
15530    (set_attr "mode" "<MODE>")])
15531
15532 (define_expand "isinfxf2"
15533   [(use (match_operand:SI 0 "register_operand" ""))
15534    (use (match_operand:XF 1 "register_operand" ""))]
15535   "TARGET_USE_FANCY_MATH_387
15536    && TARGET_C99_FUNCTIONS"
15537 {
15538   rtx mask = GEN_INT (0x45);
15539   rtx val = GEN_INT (0x05);
15540
15541   rtx cond;
15542
15543   rtx scratch = gen_reg_rtx (HImode);
15544   rtx res = gen_reg_rtx (QImode);
15545
15546   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15547
15548   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15549   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15550   cond = gen_rtx_fmt_ee (EQ, QImode,
15551                          gen_rtx_REG (CCmode, FLAGS_REG),
15552                          const0_rtx);
15553   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15554   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15555   DONE;
15556 })
15557
15558 (define_expand "isinf<mode>2"
15559   [(use (match_operand:SI 0 "register_operand" ""))
15560    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15561   "TARGET_USE_FANCY_MATH_387
15562    && TARGET_C99_FUNCTIONS
15563    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15564 {
15565   rtx mask = GEN_INT (0x45);
15566   rtx val = GEN_INT (0x05);
15567
15568   rtx cond;
15569
15570   rtx scratch = gen_reg_rtx (HImode);
15571   rtx res = gen_reg_rtx (QImode);
15572
15573   /* Remove excess precision by forcing value through memory. */
15574   if (memory_operand (operands[1], VOIDmode))
15575     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15576   else
15577     {
15578       enum ix86_stack_slot slot = (virtuals_instantiated
15579                                    ? SLOT_TEMP
15580                                    : SLOT_VIRTUAL);
15581       rtx temp = assign_386_stack_local (<MODE>mode, slot);
15582
15583       emit_move_insn (temp, operands[1]);
15584       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15585     }
15586
15587   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15588   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15589   cond = gen_rtx_fmt_ee (EQ, QImode,
15590                          gen_rtx_REG (CCmode, FLAGS_REG),
15591                          const0_rtx);
15592   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15593   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15594   DONE;
15595 })
15596
15597 (define_expand "signbitxf2"
15598   [(use (match_operand:SI 0 "register_operand" ""))
15599    (use (match_operand:XF 1 "register_operand" ""))]
15600   "TARGET_USE_FANCY_MATH_387"
15601 {
15602   rtx scratch = gen_reg_rtx (HImode);
15603
15604   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15605   emit_insn (gen_andsi3 (operands[0],
15606              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15607   DONE;
15608 })
15609
15610 (define_insn "movmsk_df"
15611   [(set (match_operand:SI 0 "register_operand" "=r")
15612         (unspec:SI
15613           [(match_operand:DF 1 "register_operand" "x")]
15614           UNSPEC_MOVMSK))]
15615   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15616   "%vmovmskpd\t{%1, %0|%0, %1}"
15617   [(set_attr "type" "ssemov")
15618    (set_attr "prefix" "maybe_vex")
15619    (set_attr "mode" "DF")])
15620
15621 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15622 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15623 (define_expand "signbitdf2"
15624   [(use (match_operand:SI 0 "register_operand" ""))
15625    (use (match_operand:DF 1 "register_operand" ""))]
15626   "TARGET_USE_FANCY_MATH_387
15627    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15628 {
15629   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15630     {
15631       emit_insn (gen_movmsk_df (operands[0], operands[1]));
15632       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15633     }
15634   else
15635     {
15636       rtx scratch = gen_reg_rtx (HImode);
15637
15638       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15639       emit_insn (gen_andsi3 (operands[0],
15640                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15641     }
15642   DONE;
15643 })
15644
15645 (define_expand "signbitsf2"
15646   [(use (match_operand:SI 0 "register_operand" ""))
15647    (use (match_operand:SF 1 "register_operand" ""))]
15648   "TARGET_USE_FANCY_MATH_387
15649    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15650 {
15651   rtx scratch = gen_reg_rtx (HImode);
15652
15653   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15654   emit_insn (gen_andsi3 (operands[0],
15655              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15656   DONE;
15657 })
15658 \f
15659 ;; Block operation instructions
15660
15661 (define_insn "cld"
15662   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15663   ""
15664   "cld"
15665   [(set_attr "length" "1")
15666    (set_attr "length_immediate" "0")
15667    (set_attr "modrm" "0")])
15668
15669 (define_expand "movmem<mode>"
15670   [(use (match_operand:BLK 0 "memory_operand" ""))
15671    (use (match_operand:BLK 1 "memory_operand" ""))
15672    (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15673    (use (match_operand:SWI48 3 "const_int_operand" ""))
15674    (use (match_operand:SI 4 "const_int_operand" ""))
15675    (use (match_operand:SI 5 "const_int_operand" ""))]
15676   ""
15677 {
15678  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15679                          operands[4], operands[5]))
15680    DONE;
15681  else
15682    FAIL;
15683 })
15684
15685 ;; Most CPUs don't like single string operations
15686 ;; Handle this case here to simplify previous expander.
15687
15688 (define_expand "strmov"
15689   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15690    (set (match_operand 1 "memory_operand" "") (match_dup 4))
15691    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15692               (clobber (reg:CC FLAGS_REG))])
15693    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15694               (clobber (reg:CC FLAGS_REG))])]
15695   ""
15696 {
15697   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15698
15699   /* If .md ever supports :P for Pmode, these can be directly
15700      in the pattern above.  */
15701   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15702   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15703
15704   /* Can't use this if the user has appropriated esi or edi.  */
15705   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15706       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15707     {
15708       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15709                                       operands[2], operands[3],
15710                                       operands[5], operands[6]));
15711       DONE;
15712     }
15713
15714   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15715 })
15716
15717 (define_expand "strmov_singleop"
15718   [(parallel [(set (match_operand 1 "memory_operand" "")
15719                    (match_operand 3 "memory_operand" ""))
15720               (set (match_operand 0 "register_operand" "")
15721                    (match_operand 4 "" ""))
15722               (set (match_operand 2 "register_operand" "")
15723                    (match_operand 5 "" ""))])]
15724   ""
15725   "ix86_current_function_needs_cld = 1;")
15726
15727 (define_insn "*strmovdi_rex_1"
15728   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15729         (mem:DI (match_operand:DI 3 "register_operand" "1")))
15730    (set (match_operand:DI 0 "register_operand" "=D")
15731         (plus:DI (match_dup 2)
15732                  (const_int 8)))
15733    (set (match_operand:DI 1 "register_operand" "=S")
15734         (plus:DI (match_dup 3)
15735                  (const_int 8)))]
15736   "TARGET_64BIT
15737    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15738   "movsq"
15739   [(set_attr "type" "str")
15740    (set_attr "memory" "both")
15741    (set_attr "mode" "DI")])
15742
15743 (define_insn "*strmovsi_1"
15744   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15745         (mem:SI (match_operand:P 3 "register_operand" "1")))
15746    (set (match_operand:P 0 "register_operand" "=D")
15747         (plus:P (match_dup 2)
15748                 (const_int 4)))
15749    (set (match_operand:P 1 "register_operand" "=S")
15750         (plus:P (match_dup 3)
15751                 (const_int 4)))]
15752   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15753   "movs{l|d}"
15754   [(set_attr "type" "str")
15755    (set_attr "memory" "both")
15756    (set_attr "mode" "SI")])
15757
15758 (define_insn "*strmovhi_1"
15759   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15760         (mem:HI (match_operand:P 3 "register_operand" "1")))
15761    (set (match_operand:P 0 "register_operand" "=D")
15762         (plus:P (match_dup 2)
15763                 (const_int 2)))
15764    (set (match_operand:P 1 "register_operand" "=S")
15765         (plus:P (match_dup 3)
15766                 (const_int 2)))]
15767   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15768   "movsw"
15769   [(set_attr "type" "str")
15770    (set_attr "memory" "both")
15771    (set_attr "mode" "HI")])
15772
15773 (define_insn "*strmovqi_1"
15774   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15775         (mem:QI (match_operand:P 3 "register_operand" "1")))
15776    (set (match_operand:P 0 "register_operand" "=D")
15777         (plus:P (match_dup 2)
15778                 (const_int 1)))
15779    (set (match_operand:P 1 "register_operand" "=S")
15780         (plus:P (match_dup 3)
15781                 (const_int 1)))]
15782   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15783   "movsb"
15784   [(set_attr "type" "str")
15785    (set_attr "memory" "both")
15786    (set (attr "prefix_rex")
15787         (if_then_else
15788           (match_test "<P:MODE>mode == DImode")
15789           (const_string "0")
15790           (const_string "*")))
15791    (set_attr "mode" "QI")])
15792
15793 (define_expand "rep_mov"
15794   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15795               (set (match_operand 0 "register_operand" "")
15796                    (match_operand 5 "" ""))
15797               (set (match_operand 2 "register_operand" "")
15798                    (match_operand 6 "" ""))
15799               (set (match_operand 1 "memory_operand" "")
15800                    (match_operand 3 "memory_operand" ""))
15801               (use (match_dup 4))])]
15802   ""
15803   "ix86_current_function_needs_cld = 1;")
15804
15805 (define_insn "*rep_movdi_rex64"
15806   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15807    (set (match_operand:DI 0 "register_operand" "=D")
15808         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15809                             (const_int 3))
15810                  (match_operand:DI 3 "register_operand" "0")))
15811    (set (match_operand:DI 1 "register_operand" "=S")
15812         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15813                  (match_operand:DI 4 "register_operand" "1")))
15814    (set (mem:BLK (match_dup 3))
15815         (mem:BLK (match_dup 4)))
15816    (use (match_dup 5))]
15817   "TARGET_64BIT
15818    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15819   "rep{%;} movsq"
15820   [(set_attr "type" "str")
15821    (set_attr "prefix_rep" "1")
15822    (set_attr "memory" "both")
15823    (set_attr "mode" "DI")])
15824
15825 (define_insn "*rep_movsi"
15826   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15827    (set (match_operand:P 0 "register_operand" "=D")
15828         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15829                           (const_int 2))
15830                  (match_operand:P 3 "register_operand" "0")))
15831    (set (match_operand:P 1 "register_operand" "=S")
15832         (plus:P (ashift:P (match_dup 5) (const_int 2))
15833                 (match_operand:P 4 "register_operand" "1")))
15834    (set (mem:BLK (match_dup 3))
15835         (mem:BLK (match_dup 4)))
15836    (use (match_dup 5))]
15837   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15838   "rep{%;} movs{l|d}"
15839   [(set_attr "type" "str")
15840    (set_attr "prefix_rep" "1")
15841    (set_attr "memory" "both")
15842    (set_attr "mode" "SI")])
15843
15844 (define_insn "*rep_movqi"
15845   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15846    (set (match_operand:P 0 "register_operand" "=D")
15847         (plus:P (match_operand:P 3 "register_operand" "0")
15848                 (match_operand:P 5 "register_operand" "2")))
15849    (set (match_operand:P 1 "register_operand" "=S")
15850         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15851    (set (mem:BLK (match_dup 3))
15852         (mem:BLK (match_dup 4)))
15853    (use (match_dup 5))]
15854   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15855   "rep{%;} movsb"
15856   [(set_attr "type" "str")
15857    (set_attr "prefix_rep" "1")
15858    (set_attr "memory" "both")
15859    (set_attr "mode" "QI")])
15860
15861 (define_expand "setmem<mode>"
15862    [(use (match_operand:BLK 0 "memory_operand" ""))
15863     (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15864     (use (match_operand:QI 2 "nonmemory_operand" ""))
15865     (use (match_operand 3 "const_int_operand" ""))
15866     (use (match_operand:SI 4 "const_int_operand" ""))
15867     (use (match_operand:SI 5 "const_int_operand" ""))]
15868   ""
15869 {
15870  if (ix86_expand_setmem (operands[0], operands[1],
15871                          operands[2], operands[3],
15872                          operands[4], operands[5]))
15873    DONE;
15874  else
15875    FAIL;
15876 })
15877
15878 ;; Most CPUs don't like single string operations
15879 ;; Handle this case here to simplify previous expander.
15880
15881 (define_expand "strset"
15882   [(set (match_operand 1 "memory_operand" "")
15883         (match_operand 2 "register_operand" ""))
15884    (parallel [(set (match_operand 0 "register_operand" "")
15885                    (match_dup 3))
15886               (clobber (reg:CC FLAGS_REG))])]
15887   ""
15888 {
15889   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15890     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15891
15892   /* If .md ever supports :P for Pmode, this can be directly
15893      in the pattern above.  */
15894   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15895                               GEN_INT (GET_MODE_SIZE (GET_MODE
15896                                                       (operands[2]))));
15897   /* Can't use this if the user has appropriated eax or edi.  */
15898   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15899       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15900     {
15901       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15902                                       operands[3]));
15903       DONE;
15904     }
15905 })
15906
15907 (define_expand "strset_singleop"
15908   [(parallel [(set (match_operand 1 "memory_operand" "")
15909                    (match_operand 2 "register_operand" ""))
15910               (set (match_operand 0 "register_operand" "")
15911                    (match_operand 3 "" ""))])]
15912   ""
15913   "ix86_current_function_needs_cld = 1;")
15914
15915 (define_insn "*strsetdi_rex_1"
15916   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15917         (match_operand:DI 2 "register_operand" "a"))
15918    (set (match_operand:DI 0 "register_operand" "=D")
15919         (plus:DI (match_dup 1)
15920                  (const_int 8)))]
15921   "TARGET_64BIT
15922    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15923   "stosq"
15924   [(set_attr "type" "str")
15925    (set_attr "memory" "store")
15926    (set_attr "mode" "DI")])
15927
15928 (define_insn "*strsetsi_1"
15929   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15930         (match_operand:SI 2 "register_operand" "a"))
15931    (set (match_operand:P 0 "register_operand" "=D")
15932         (plus:P (match_dup 1)
15933                 (const_int 4)))]
15934   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15935   "stos{l|d}"
15936   [(set_attr "type" "str")
15937    (set_attr "memory" "store")
15938    (set_attr "mode" "SI")])
15939
15940 (define_insn "*strsethi_1"
15941   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15942         (match_operand:HI 2 "register_operand" "a"))
15943    (set (match_operand:P 0 "register_operand" "=D")
15944         (plus:P (match_dup 1)
15945                 (const_int 2)))]
15946   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15947   "stosw"
15948   [(set_attr "type" "str")
15949    (set_attr "memory" "store")
15950    (set_attr "mode" "HI")])
15951
15952 (define_insn "*strsetqi_1"
15953   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15954         (match_operand:QI 2 "register_operand" "a"))
15955    (set (match_operand:P 0 "register_operand" "=D")
15956         (plus:P (match_dup 1)
15957                 (const_int 1)))]
15958   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15959   "stosb"
15960   [(set_attr "type" "str")
15961    (set_attr "memory" "store")
15962    (set (attr "prefix_rex")
15963         (if_then_else
15964           (match_test "<P:MODE>mode == DImode")
15965           (const_string "0")
15966           (const_string "*")))
15967    (set_attr "mode" "QI")])
15968
15969 (define_expand "rep_stos"
15970   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15971               (set (match_operand 0 "register_operand" "")
15972                    (match_operand 4 "" ""))
15973               (set (match_operand 2 "memory_operand" "") (const_int 0))
15974               (use (match_operand 3 "register_operand" ""))
15975               (use (match_dup 1))])]
15976   ""
15977   "ix86_current_function_needs_cld = 1;")
15978
15979 (define_insn "*rep_stosdi_rex64"
15980   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15981    (set (match_operand:DI 0 "register_operand" "=D")
15982         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15983                             (const_int 3))
15984                  (match_operand:DI 3 "register_operand" "0")))
15985    (set (mem:BLK (match_dup 3))
15986         (const_int 0))
15987    (use (match_operand:DI 2 "register_operand" "a"))
15988    (use (match_dup 4))]
15989   "TARGET_64BIT
15990    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15991   "rep{%;} stosq"
15992   [(set_attr "type" "str")
15993    (set_attr "prefix_rep" "1")
15994    (set_attr "memory" "store")
15995    (set_attr "mode" "DI")])
15996
15997 (define_insn "*rep_stossi"
15998   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15999    (set (match_operand:P 0 "register_operand" "=D")
16000         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16001                           (const_int 2))
16002                  (match_operand:P 3 "register_operand" "0")))
16003    (set (mem:BLK (match_dup 3))
16004         (const_int 0))
16005    (use (match_operand:SI 2 "register_operand" "a"))
16006    (use (match_dup 4))]
16007   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16008   "rep{%;} stos{l|d}"
16009   [(set_attr "type" "str")
16010    (set_attr "prefix_rep" "1")
16011    (set_attr "memory" "store")
16012    (set_attr "mode" "SI")])
16013
16014 (define_insn "*rep_stosqi"
16015   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16016    (set (match_operand:P 0 "register_operand" "=D")
16017         (plus:P (match_operand:P 3 "register_operand" "0")
16018                 (match_operand:P 4 "register_operand" "1")))
16019    (set (mem:BLK (match_dup 3))
16020         (const_int 0))
16021    (use (match_operand:QI 2 "register_operand" "a"))
16022    (use (match_dup 4))]
16023   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16024   "rep{%;} stosb"
16025   [(set_attr "type" "str")
16026    (set_attr "prefix_rep" "1")
16027    (set_attr "memory" "store")
16028    (set (attr "prefix_rex")
16029         (if_then_else
16030           (match_test "<P:MODE>mode == DImode")
16031           (const_string "0")
16032           (const_string "*")))
16033    (set_attr "mode" "QI")])
16034
16035 (define_expand "cmpstrnsi"
16036   [(set (match_operand:SI 0 "register_operand" "")
16037         (compare:SI (match_operand:BLK 1 "general_operand" "")
16038                     (match_operand:BLK 2 "general_operand" "")))
16039    (use (match_operand 3 "general_operand" ""))
16040    (use (match_operand 4 "immediate_operand" ""))]
16041   ""
16042 {
16043   rtx addr1, addr2, out, outlow, count, countreg, align;
16044
16045   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16046     FAIL;
16047
16048   /* Can't use this if the user has appropriated ecx, esi or edi.  */
16049   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16050     FAIL;
16051
16052   out = operands[0];
16053   if (!REG_P (out))
16054     out = gen_reg_rtx (SImode);
16055
16056   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16057   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16058   if (addr1 != XEXP (operands[1], 0))
16059     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16060   if (addr2 != XEXP (operands[2], 0))
16061     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16062
16063   count = operands[3];
16064   countreg = ix86_zero_extend_to_Pmode (count);
16065
16066   /* %%% Iff we are testing strict equality, we can use known alignment
16067      to good advantage.  This may be possible with combine, particularly
16068      once cc0 is dead.  */
16069   align = operands[4];
16070
16071   if (CONST_INT_P (count))
16072     {
16073       if (INTVAL (count) == 0)
16074         {
16075           emit_move_insn (operands[0], const0_rtx);
16076           DONE;
16077         }
16078       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16079                                      operands[1], operands[2]));
16080     }
16081   else
16082     {
16083       rtx (*gen_cmp) (rtx, rtx);
16084
16085       gen_cmp = (TARGET_64BIT
16086                  ? gen_cmpdi_1 : gen_cmpsi_1);
16087
16088       emit_insn (gen_cmp (countreg, countreg));
16089       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16090                                   operands[1], operands[2]));
16091     }
16092
16093   outlow = gen_lowpart (QImode, out);
16094   emit_insn (gen_cmpintqi (outlow));
16095   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16096
16097   if (operands[0] != out)
16098     emit_move_insn (operands[0], out);
16099
16100   DONE;
16101 })
16102
16103 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16104
16105 (define_expand "cmpintqi"
16106   [(set (match_dup 1)
16107         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16108    (set (match_dup 2)
16109         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16110    (parallel [(set (match_operand:QI 0 "register_operand" "")
16111                    (minus:QI (match_dup 1)
16112                              (match_dup 2)))
16113               (clobber (reg:CC FLAGS_REG))])]
16114   ""
16115 {
16116   operands[1] = gen_reg_rtx (QImode);
16117   operands[2] = gen_reg_rtx (QImode);
16118 })
16119
16120 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16121 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16122
16123 (define_expand "cmpstrnqi_nz_1"
16124   [(parallel [(set (reg:CC FLAGS_REG)
16125                    (compare:CC (match_operand 4 "memory_operand" "")
16126                                (match_operand 5 "memory_operand" "")))
16127               (use (match_operand 2 "register_operand" ""))
16128               (use (match_operand:SI 3 "immediate_operand" ""))
16129               (clobber (match_operand 0 "register_operand" ""))
16130               (clobber (match_operand 1 "register_operand" ""))
16131               (clobber (match_dup 2))])]
16132   ""
16133   "ix86_current_function_needs_cld = 1;")
16134
16135 (define_insn "*cmpstrnqi_nz_1"
16136   [(set (reg:CC FLAGS_REG)
16137         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16138                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16139    (use (match_operand:P 6 "register_operand" "2"))
16140    (use (match_operand:SI 3 "immediate_operand" "i"))
16141    (clobber (match_operand:P 0 "register_operand" "=S"))
16142    (clobber (match_operand:P 1 "register_operand" "=D"))
16143    (clobber (match_operand:P 2 "register_operand" "=c"))]
16144   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16145   "repz{%;} cmpsb"
16146   [(set_attr "type" "str")
16147    (set_attr "mode" "QI")
16148    (set (attr "prefix_rex")
16149         (if_then_else
16150           (match_test "<P:MODE>mode == DImode")
16151           (const_string "0")
16152           (const_string "*")))
16153    (set_attr "prefix_rep" "1")])
16154
16155 ;; The same, but the count is not known to not be zero.
16156
16157 (define_expand "cmpstrnqi_1"
16158   [(parallel [(set (reg:CC FLAGS_REG)
16159                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16160                                      (const_int 0))
16161                   (compare:CC (match_operand 4 "memory_operand" "")
16162                               (match_operand 5 "memory_operand" ""))
16163                   (const_int 0)))
16164               (use (match_operand:SI 3 "immediate_operand" ""))
16165               (use (reg:CC FLAGS_REG))
16166               (clobber (match_operand 0 "register_operand" ""))
16167               (clobber (match_operand 1 "register_operand" ""))
16168               (clobber (match_dup 2))])]
16169   ""
16170   "ix86_current_function_needs_cld = 1;")
16171
16172 (define_insn "*cmpstrnqi_1"
16173   [(set (reg:CC FLAGS_REG)
16174         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16175                              (const_int 0))
16176           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16177                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
16178           (const_int 0)))
16179    (use (match_operand:SI 3 "immediate_operand" "i"))
16180    (use (reg:CC FLAGS_REG))
16181    (clobber (match_operand:P 0 "register_operand" "=S"))
16182    (clobber (match_operand:P 1 "register_operand" "=D"))
16183    (clobber (match_operand:P 2 "register_operand" "=c"))]
16184   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16185   "repz{%;} cmpsb"
16186   [(set_attr "type" "str")
16187    (set_attr "mode" "QI")
16188    (set (attr "prefix_rex")
16189         (if_then_else
16190           (match_test "<P:MODE>mode == DImode")
16191           (const_string "0")
16192           (const_string "*")))
16193    (set_attr "prefix_rep" "1")])
16194
16195 (define_expand "strlen<mode>"
16196   [(set (match_operand:P 0 "register_operand" "")
16197         (unspec:P [(match_operand:BLK 1 "general_operand" "")
16198                    (match_operand:QI 2 "immediate_operand" "")
16199                    (match_operand 3 "immediate_operand" "")]
16200                   UNSPEC_SCAS))]
16201   ""
16202 {
16203  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16204    DONE;
16205  else
16206    FAIL;
16207 })
16208
16209 (define_expand "strlenqi_1"
16210   [(parallel [(set (match_operand 0 "register_operand" "")
16211                    (match_operand 2 "" ""))
16212               (clobber (match_operand 1 "register_operand" ""))
16213               (clobber (reg:CC FLAGS_REG))])]
16214   ""
16215   "ix86_current_function_needs_cld = 1;")
16216
16217 (define_insn "*strlenqi_1"
16218   [(set (match_operand:P 0 "register_operand" "=&c")
16219         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16220                    (match_operand:QI 2 "register_operand" "a")
16221                    (match_operand:P 3 "immediate_operand" "i")
16222                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16223    (clobber (match_operand:P 1 "register_operand" "=D"))
16224    (clobber (reg:CC FLAGS_REG))]
16225   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16226   "repnz{%;} scasb"
16227   [(set_attr "type" "str")
16228    (set_attr "mode" "QI")
16229    (set (attr "prefix_rex")
16230         (if_then_else
16231           (match_test "<P:MODE>mode == DImode")
16232           (const_string "0")
16233           (const_string "*")))
16234    (set_attr "prefix_rep" "1")])
16235
16236 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
16237 ;; handled in combine, but it is not currently up to the task.
16238 ;; When used for their truth value, the cmpstrn* expanders generate
16239 ;; code like this:
16240 ;;
16241 ;;   repz cmpsb
16242 ;;   seta       %al
16243 ;;   setb       %dl
16244 ;;   cmpb       %al, %dl
16245 ;;   jcc        label
16246 ;;
16247 ;; The intermediate three instructions are unnecessary.
16248
16249 ;; This one handles cmpstrn*_nz_1...
16250 (define_peephole2
16251   [(parallel[
16252      (set (reg:CC FLAGS_REG)
16253           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16254                       (mem:BLK (match_operand 5 "register_operand" ""))))
16255      (use (match_operand 6 "register_operand" ""))
16256      (use (match_operand:SI 3 "immediate_operand" ""))
16257      (clobber (match_operand 0 "register_operand" ""))
16258      (clobber (match_operand 1 "register_operand" ""))
16259      (clobber (match_operand 2 "register_operand" ""))])
16260    (set (match_operand:QI 7 "register_operand" "")
16261         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16262    (set (match_operand:QI 8 "register_operand" "")
16263         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16264    (set (reg FLAGS_REG)
16265         (compare (match_dup 7) (match_dup 8)))
16266   ]
16267   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16268   [(parallel[
16269      (set (reg:CC FLAGS_REG)
16270           (compare:CC (mem:BLK (match_dup 4))
16271                       (mem:BLK (match_dup 5))))
16272      (use (match_dup 6))
16273      (use (match_dup 3))
16274      (clobber (match_dup 0))
16275      (clobber (match_dup 1))
16276      (clobber (match_dup 2))])])
16277
16278 ;; ...and this one handles cmpstrn*_1.
16279 (define_peephole2
16280   [(parallel[
16281      (set (reg:CC FLAGS_REG)
16282           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16283                                (const_int 0))
16284             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16285                         (mem:BLK (match_operand 5 "register_operand" "")))
16286             (const_int 0)))
16287      (use (match_operand:SI 3 "immediate_operand" ""))
16288      (use (reg:CC FLAGS_REG))
16289      (clobber (match_operand 0 "register_operand" ""))
16290      (clobber (match_operand 1 "register_operand" ""))
16291      (clobber (match_operand 2 "register_operand" ""))])
16292    (set (match_operand:QI 7 "register_operand" "")
16293         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16294    (set (match_operand:QI 8 "register_operand" "")
16295         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16296    (set (reg FLAGS_REG)
16297         (compare (match_dup 7) (match_dup 8)))
16298   ]
16299   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16300   [(parallel[
16301      (set (reg:CC FLAGS_REG)
16302           (if_then_else:CC (ne (match_dup 6)
16303                                (const_int 0))
16304             (compare:CC (mem:BLK (match_dup 4))
16305                         (mem:BLK (match_dup 5)))
16306             (const_int 0)))
16307      (use (match_dup 3))
16308      (use (reg:CC FLAGS_REG))
16309      (clobber (match_dup 0))
16310      (clobber (match_dup 1))
16311      (clobber (match_dup 2))])])
16312 \f
16313 ;; Conditional move instructions.
16314
16315 (define_expand "mov<mode>cc"
16316   [(set (match_operand:SWIM 0 "register_operand" "")
16317         (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16318                            (match_operand:SWIM 2 "<general_operand>" "")
16319                            (match_operand:SWIM 3 "<general_operand>" "")))]
16320   ""
16321   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16322
16323 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16324 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16325 ;; So just document what we're doing explicitly.
16326
16327 (define_expand "x86_mov<mode>cc_0_m1"
16328   [(parallel
16329     [(set (match_operand:SWI48 0 "register_operand" "")
16330           (if_then_else:SWI48
16331             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16332              [(match_operand 1 "flags_reg_operand" "")
16333               (const_int 0)])
16334             (const_int -1)
16335             (const_int 0)))
16336      (clobber (reg:CC FLAGS_REG))])])
16337
16338 (define_insn "*x86_mov<mode>cc_0_m1"
16339   [(set (match_operand:SWI48 0 "register_operand" "=r")
16340         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16341                              [(reg FLAGS_REG) (const_int 0)])
16342           (const_int -1)
16343           (const_int 0)))
16344    (clobber (reg:CC FLAGS_REG))]
16345   ""
16346   "sbb{<imodesuffix>}\t%0, %0"
16347   ; Since we don't have the proper number of operands for an alu insn,
16348   ; fill in all the blanks.
16349   [(set_attr "type" "alu")
16350    (set_attr "use_carry" "1")
16351    (set_attr "pent_pair" "pu")
16352    (set_attr "memory" "none")
16353    (set_attr "imm_disp" "false")
16354    (set_attr "mode" "<MODE>")
16355    (set_attr "length_immediate" "0")])
16356
16357 (define_insn "*x86_mov<mode>cc_0_m1_se"
16358   [(set (match_operand:SWI48 0 "register_operand" "=r")
16359         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16360                              [(reg FLAGS_REG) (const_int 0)])
16361                             (const_int 1)
16362                             (const_int 0)))
16363    (clobber (reg:CC FLAGS_REG))]
16364   ""
16365   "sbb{<imodesuffix>}\t%0, %0"
16366   [(set_attr "type" "alu")
16367    (set_attr "use_carry" "1")
16368    (set_attr "pent_pair" "pu")
16369    (set_attr "memory" "none")
16370    (set_attr "imm_disp" "false")
16371    (set_attr "mode" "<MODE>")
16372    (set_attr "length_immediate" "0")])
16373
16374 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16375   [(set (match_operand:SWI48 0 "register_operand" "=r")
16376         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16377                     [(reg FLAGS_REG) (const_int 0)])))]
16378   ""
16379   "sbb{<imodesuffix>}\t%0, %0"
16380   [(set_attr "type" "alu")
16381    (set_attr "use_carry" "1")
16382    (set_attr "pent_pair" "pu")
16383    (set_attr "memory" "none")
16384    (set_attr "imm_disp" "false")
16385    (set_attr "mode" "<MODE>")
16386    (set_attr "length_immediate" "0")])
16387
16388 (define_insn "*mov<mode>cc_noc"
16389   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16390         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16391                                [(reg FLAGS_REG) (const_int 0)])
16392           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16393           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16394   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16395   "@
16396    cmov%O2%C1\t{%2, %0|%0, %2}
16397    cmov%O2%c1\t{%3, %0|%0, %3}"
16398   [(set_attr "type" "icmov")
16399    (set_attr "mode" "<MODE>")])
16400
16401 (define_insn_and_split "*movqicc_noc"
16402   [(set (match_operand:QI 0 "register_operand" "=r,r")
16403         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16404                            [(match_operand 4 "flags_reg_operand" "")
16405                             (const_int 0)])
16406                       (match_operand:QI 2 "register_operand" "r,0")
16407                       (match_operand:QI 3 "register_operand" "0,r")))]
16408   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16409   "#"
16410   "&& reload_completed"
16411   [(set (match_dup 0)
16412         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16413                       (match_dup 2)
16414                       (match_dup 3)))]
16415   "operands[0] = gen_lowpart (SImode, operands[0]);
16416    operands[2] = gen_lowpart (SImode, operands[2]);
16417    operands[3] = gen_lowpart (SImode, operands[3]);"
16418   [(set_attr "type" "icmov")
16419    (set_attr "mode" "SI")])
16420
16421 (define_expand "mov<mode>cc"
16422   [(set (match_operand:X87MODEF 0 "register_operand" "")
16423         (if_then_else:X87MODEF
16424           (match_operand 1 "ix86_fp_comparison_operator" "")
16425           (match_operand:X87MODEF 2 "register_operand" "")
16426           (match_operand:X87MODEF 3 "register_operand" "")))]
16427   "(TARGET_80387 && TARGET_CMOVE)
16428    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16429   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16430
16431 (define_insn "*movxfcc_1"
16432   [(set (match_operand:XF 0 "register_operand" "=f,f")
16433         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16434                                 [(reg FLAGS_REG) (const_int 0)])
16435                       (match_operand:XF 2 "register_operand" "f,0")
16436                       (match_operand:XF 3 "register_operand" "0,f")))]
16437   "TARGET_80387 && TARGET_CMOVE"
16438   "@
16439    fcmov%F1\t{%2, %0|%0, %2}
16440    fcmov%f1\t{%3, %0|%0, %3}"
16441   [(set_attr "type" "fcmov")
16442    (set_attr "mode" "XF")])
16443
16444 (define_insn "*movdfcc_1_rex64"
16445   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16446         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16447                                 [(reg FLAGS_REG) (const_int 0)])
16448                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16449                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16450   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16451    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16452   "@
16453    fcmov%F1\t{%2, %0|%0, %2}
16454    fcmov%f1\t{%3, %0|%0, %3}
16455    cmov%O2%C1\t{%2, %0|%0, %2}
16456    cmov%O2%c1\t{%3, %0|%0, %3}"
16457   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16458    (set_attr "mode" "DF,DF,DI,DI")])
16459
16460 (define_insn "*movdfcc_1"
16461   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16462         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16463                                 [(reg FLAGS_REG) (const_int 0)])
16464                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16465                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16466   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16467    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16468   "@
16469    fcmov%F1\t{%2, %0|%0, %2}
16470    fcmov%f1\t{%3, %0|%0, %3}
16471    #
16472    #"
16473   [(set_attr "type" "fcmov,fcmov,multi,multi")
16474    (set_attr "mode" "DF,DF,DI,DI")])
16475
16476 (define_split
16477   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16478         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16479                                 [(match_operand 4 "flags_reg_operand" "")
16480                                  (const_int 0)])
16481                       (match_operand:DF 2 "nonimmediate_operand" "")
16482                       (match_operand:DF 3 "nonimmediate_operand" "")))]
16483   "!TARGET_64BIT && reload_completed"
16484   [(set (match_dup 2)
16485         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16486                       (match_dup 5)
16487                       (match_dup 6)))
16488    (set (match_dup 3)
16489         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16490                       (match_dup 7)
16491                       (match_dup 8)))]
16492 {
16493   split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16494   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16495 })
16496
16497 (define_insn "*movsfcc_1_387"
16498   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16499         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16500                                 [(reg FLAGS_REG) (const_int 0)])
16501                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16502                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16503   "TARGET_80387 && TARGET_CMOVE
16504    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16505   "@
16506    fcmov%F1\t{%2, %0|%0, %2}
16507    fcmov%f1\t{%3, %0|%0, %3}
16508    cmov%O2%C1\t{%2, %0|%0, %2}
16509    cmov%O2%c1\t{%3, %0|%0, %3}"
16510   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16511    (set_attr "mode" "SF,SF,SI,SI")])
16512
16513 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16514 ;; the scalar versions to have only XMM registers as operands.
16515
16516 ;; XOP conditional move
16517 (define_insn "*xop_pcmov_<mode>"
16518   [(set (match_operand:MODEF 0 "register_operand" "=x")
16519         (if_then_else:MODEF
16520           (match_operand:MODEF 1 "register_operand" "x")
16521           (match_operand:MODEF 2 "register_operand" "x")
16522           (match_operand:MODEF 3 "register_operand" "x")))]
16523   "TARGET_XOP"
16524   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16525   [(set_attr "type" "sse4arg")])
16526
16527 ;; These versions of the min/max patterns are intentionally ignorant of
16528 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16529 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16530 ;; are undefined in this condition, we're certain this is correct.
16531
16532 (define_insn "<code><mode>3"
16533   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16534         (smaxmin:MODEF
16535           (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16536           (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16537   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16538   "@
16539    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16540    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16541   [(set_attr "isa" "noavx,avx")
16542    (set_attr "prefix" "orig,vex")
16543    (set_attr "type" "sseadd")
16544    (set_attr "mode" "<MODE>")])
16545
16546 ;; These versions of the min/max patterns implement exactly the operations
16547 ;;   min = (op1 < op2 ? op1 : op2)
16548 ;;   max = (!(op1 < op2) ? op1 : op2)
16549 ;; Their operands are not commutative, and thus they may be used in the
16550 ;; presence of -0.0 and NaN.
16551
16552 (define_insn "*ieee_smin<mode>3"
16553   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16554         (unspec:MODEF
16555           [(match_operand:MODEF 1 "register_operand" "0,x")
16556            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16557          UNSPEC_IEEE_MIN))]
16558   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16559   "@
16560    min<ssemodesuffix>\t{%2, %0|%0, %2}
16561    vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16562   [(set_attr "isa" "noavx,avx")
16563    (set_attr "prefix" "orig,vex")
16564    (set_attr "type" "sseadd")
16565    (set_attr "mode" "<MODE>")])
16566
16567 (define_insn "*ieee_smax<mode>3"
16568   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16569         (unspec:MODEF
16570           [(match_operand:MODEF 1 "register_operand" "0,x")
16571            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16572          UNSPEC_IEEE_MAX))]
16573   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16574   "@
16575    max<ssemodesuffix>\t{%2, %0|%0, %2}
16576    vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16577   [(set_attr "isa" "noavx,avx")
16578    (set_attr "prefix" "orig,vex")
16579    (set_attr "type" "sseadd")
16580    (set_attr "mode" "<MODE>")])
16581
16582 ;; Make two stack loads independent:
16583 ;;   fld aa              fld aa
16584 ;;   fld %st(0)     ->   fld bb
16585 ;;   fmul bb             fmul %st(1), %st
16586 ;;
16587 ;; Actually we only match the last two instructions for simplicity.
16588 (define_peephole2
16589   [(set (match_operand 0 "fp_register_operand" "")
16590         (match_operand 1 "fp_register_operand" ""))
16591    (set (match_dup 0)
16592         (match_operator 2 "binary_fp_operator"
16593            [(match_dup 0)
16594             (match_operand 3 "memory_operand" "")]))]
16595   "REGNO (operands[0]) != REGNO (operands[1])"
16596   [(set (match_dup 0) (match_dup 3))
16597    (set (match_dup 0) (match_dup 4))]
16598
16599   ;; The % modifier is not operational anymore in peephole2's, so we have to
16600   ;; swap the operands manually in the case of addition and multiplication.
16601   "if (COMMUTATIVE_ARITH_P (operands[2]))
16602      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16603                                    GET_MODE (operands[2]),
16604                                    operands[0], operands[1]);
16605    else
16606      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16607                                    GET_MODE (operands[2]),
16608                                    operands[1], operands[0]);")
16609
16610 ;; Conditional addition patterns
16611 (define_expand "add<mode>cc"
16612   [(match_operand:SWI 0 "register_operand" "")
16613    (match_operand 1 "ordered_comparison_operator" "")
16614    (match_operand:SWI 2 "register_operand" "")
16615    (match_operand:SWI 3 "const_int_operand" "")]
16616   ""
16617   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16618 \f
16619 ;; Misc patterns (?)
16620
16621 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16622 ;; Otherwise there will be nothing to keep
16623 ;;
16624 ;; [(set (reg ebp) (reg esp))]
16625 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16626 ;;  (clobber (eflags)]
16627 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16628 ;;
16629 ;; in proper program order.
16630
16631 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16632   [(set (match_operand:P 0 "register_operand" "=r,r")
16633         (plus:P (match_operand:P 1 "register_operand" "0,r")
16634                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16635    (clobber (reg:CC FLAGS_REG))
16636    (clobber (mem:BLK (scratch)))]
16637   ""
16638 {
16639   switch (get_attr_type (insn))
16640     {
16641     case TYPE_IMOV:
16642       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16643
16644     case TYPE_ALU:
16645       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16646       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16647         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16648
16649       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16650
16651     default:
16652       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16653       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16654     }
16655 }
16656   [(set (attr "type")
16657         (cond [(and (eq_attr "alternative" "0")
16658                     (not (match_test "TARGET_OPT_AGU")))
16659                  (const_string "alu")
16660                (match_operand:<MODE> 2 "const0_operand" "")
16661                  (const_string "imov")
16662               ]
16663               (const_string "lea")))
16664    (set (attr "length_immediate")
16665         (cond [(eq_attr "type" "imov")
16666                  (const_string "0")
16667                (and (eq_attr "type" "alu")
16668                     (match_operand 2 "const128_operand" ""))
16669                  (const_string "1")
16670               ]
16671               (const_string "*")))
16672    (set_attr "mode" "<MODE>")])
16673
16674 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16675   [(set (match_operand:P 0 "register_operand" "=r")
16676         (minus:P (match_operand:P 1 "register_operand" "0")
16677                  (match_operand:P 2 "register_operand" "r")))
16678    (clobber (reg:CC FLAGS_REG))
16679    (clobber (mem:BLK (scratch)))]
16680   ""
16681   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16682   [(set_attr "type" "alu")
16683    (set_attr "mode" "<MODE>")])
16684
16685 (define_insn "allocate_stack_worker_probe_<mode>"
16686   [(set (match_operand:P 0 "register_operand" "=a")
16687         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16688                             UNSPECV_STACK_PROBE))
16689    (clobber (reg:CC FLAGS_REG))]
16690   "ix86_target_stack_probe ()"
16691   "call\t___chkstk_ms"
16692   [(set_attr "type" "multi")
16693    (set_attr "length" "5")])
16694
16695 (define_expand "allocate_stack"
16696   [(match_operand 0 "register_operand" "")
16697    (match_operand 1 "general_operand" "")]
16698   "ix86_target_stack_probe ()"
16699 {
16700   rtx x;
16701
16702 #ifndef CHECK_STACK_LIMIT
16703 #define CHECK_STACK_LIMIT 0
16704 #endif
16705
16706   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16707       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16708     {
16709       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16710                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16711       if (x != stack_pointer_rtx)
16712         emit_move_insn (stack_pointer_rtx, x);
16713     }
16714   else
16715     {
16716       x = copy_to_mode_reg (Pmode, operands[1]);
16717       if (TARGET_64BIT)
16718         emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16719       else
16720         emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16721       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16722                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16723       if (x != stack_pointer_rtx)
16724         emit_move_insn (stack_pointer_rtx, x);
16725     }
16726
16727   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16728   DONE;
16729 })
16730
16731 ;; Use IOR for stack probes, this is shorter.
16732 (define_expand "probe_stack"
16733   [(match_operand 0 "memory_operand" "")]
16734   ""
16735 {
16736   rtx (*gen_ior3) (rtx, rtx, rtx);
16737
16738   gen_ior3 = (GET_MODE (operands[0]) == DImode
16739               ? gen_iordi3 : gen_iorsi3);
16740
16741   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16742   DONE;
16743 })
16744
16745 (define_insn "adjust_stack_and_probe<mode>"
16746   [(set (match_operand:P 0 "register_operand" "=r")
16747         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16748                             UNSPECV_PROBE_STACK_RANGE))
16749    (set (reg:P SP_REG)
16750         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16751    (clobber (reg:CC FLAGS_REG))
16752    (clobber (mem:BLK (scratch)))]
16753   ""
16754   "* return output_adjust_stack_and_probe (operands[0]);"
16755   [(set_attr "type" "multi")])
16756
16757 (define_insn "probe_stack_range<mode>"
16758   [(set (match_operand:P 0 "register_operand" "=r")
16759         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16760                             (match_operand:P 2 "const_int_operand" "n")]
16761                             UNSPECV_PROBE_STACK_RANGE))
16762    (clobber (reg:CC FLAGS_REG))]
16763   ""
16764   "* return output_probe_stack_range (operands[0], operands[2]);"
16765   [(set_attr "type" "multi")])
16766
16767 (define_expand "builtin_setjmp_receiver"
16768   [(label_ref (match_operand 0 "" ""))]
16769   "!TARGET_64BIT && flag_pic"
16770 {
16771 #if TARGET_MACHO
16772   if (TARGET_MACHO)
16773     {
16774       rtx xops[3];
16775       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16776       rtx label_rtx = gen_label_rtx ();
16777       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16778       xops[0] = xops[1] = picreg;
16779       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16780       ix86_expand_binary_operator (MINUS, SImode, xops);
16781     }
16782   else
16783 #endif
16784     emit_insn (gen_set_got (pic_offset_table_rtx));
16785   DONE;
16786 })
16787 \f
16788 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16789
16790 (define_split
16791   [(set (match_operand 0 "register_operand" "")
16792         (match_operator 3 "promotable_binary_operator"
16793            [(match_operand 1 "register_operand" "")
16794             (match_operand 2 "aligned_operand" "")]))
16795    (clobber (reg:CC FLAGS_REG))]
16796   "! TARGET_PARTIAL_REG_STALL && reload_completed
16797    && ((GET_MODE (operands[0]) == HImode
16798         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16799             /* ??? next two lines just !satisfies_constraint_K (...) */
16800             || !CONST_INT_P (operands[2])
16801             || satisfies_constraint_K (operands[2])))
16802        || (GET_MODE (operands[0]) == QImode
16803            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16804   [(parallel [(set (match_dup 0)
16805                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16806               (clobber (reg:CC FLAGS_REG))])]
16807   "operands[0] = gen_lowpart (SImode, operands[0]);
16808    operands[1] = gen_lowpart (SImode, operands[1]);
16809    if (GET_CODE (operands[3]) != ASHIFT)
16810      operands[2] = gen_lowpart (SImode, operands[2]);
16811    PUT_MODE (operands[3], SImode);")
16812
16813 ; Promote the QImode tests, as i386 has encoding of the AND
16814 ; instruction with 32-bit sign-extended immediate and thus the
16815 ; instruction size is unchanged, except in the %eax case for
16816 ; which it is increased by one byte, hence the ! optimize_size.
16817 (define_split
16818   [(set (match_operand 0 "flags_reg_operand" "")
16819         (match_operator 2 "compare_operator"
16820           [(and (match_operand 3 "aligned_operand" "")
16821                 (match_operand 4 "const_int_operand" ""))
16822            (const_int 0)]))
16823    (set (match_operand 1 "register_operand" "")
16824         (and (match_dup 3) (match_dup 4)))]
16825   "! TARGET_PARTIAL_REG_STALL && reload_completed
16826    && optimize_insn_for_speed_p ()
16827    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16828        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16829    /* Ensure that the operand will remain sign-extended immediate.  */
16830    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16831   [(parallel [(set (match_dup 0)
16832                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16833                                     (const_int 0)]))
16834               (set (match_dup 1)
16835                    (and:SI (match_dup 3) (match_dup 4)))])]
16836 {
16837   operands[4]
16838     = gen_int_mode (INTVAL (operands[4])
16839                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16840   operands[1] = gen_lowpart (SImode, operands[1]);
16841   operands[3] = gen_lowpart (SImode, operands[3]);
16842 })
16843
16844 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16845 ; the TEST instruction with 32-bit sign-extended immediate and thus
16846 ; the instruction size would at least double, which is not what we
16847 ; want even with ! optimize_size.
16848 (define_split
16849   [(set (match_operand 0 "flags_reg_operand" "")
16850         (match_operator 1 "compare_operator"
16851           [(and (match_operand:HI 2 "aligned_operand" "")
16852                 (match_operand:HI 3 "const_int_operand" ""))
16853            (const_int 0)]))]
16854   "! TARGET_PARTIAL_REG_STALL && reload_completed
16855    && ! TARGET_FAST_PREFIX
16856    && optimize_insn_for_speed_p ()
16857    /* Ensure that the operand will remain sign-extended immediate.  */
16858    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16859   [(set (match_dup 0)
16860         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16861                          (const_int 0)]))]
16862 {
16863   operands[3]
16864     = gen_int_mode (INTVAL (operands[3])
16865                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16866   operands[2] = gen_lowpart (SImode, operands[2]);
16867 })
16868
16869 (define_split
16870   [(set (match_operand 0 "register_operand" "")
16871         (neg (match_operand 1 "register_operand" "")))
16872    (clobber (reg:CC FLAGS_REG))]
16873   "! TARGET_PARTIAL_REG_STALL && reload_completed
16874    && (GET_MODE (operands[0]) == HImode
16875        || (GET_MODE (operands[0]) == QImode
16876            && (TARGET_PROMOTE_QImode
16877                || optimize_insn_for_size_p ())))"
16878   [(parallel [(set (match_dup 0)
16879                    (neg:SI (match_dup 1)))
16880               (clobber (reg:CC FLAGS_REG))])]
16881   "operands[0] = gen_lowpart (SImode, operands[0]);
16882    operands[1] = gen_lowpart (SImode, operands[1]);")
16883
16884 (define_split
16885   [(set (match_operand 0 "register_operand" "")
16886         (not (match_operand 1 "register_operand" "")))]
16887   "! TARGET_PARTIAL_REG_STALL && reload_completed
16888    && (GET_MODE (operands[0]) == HImode
16889        || (GET_MODE (operands[0]) == QImode
16890            && (TARGET_PROMOTE_QImode
16891                || optimize_insn_for_size_p ())))"
16892   [(set (match_dup 0)
16893         (not:SI (match_dup 1)))]
16894   "operands[0] = gen_lowpart (SImode, operands[0]);
16895    operands[1] = gen_lowpart (SImode, operands[1]);")
16896
16897 (define_split
16898   [(set (match_operand 0 "register_operand" "")
16899         (if_then_else (match_operator 1 "ordered_comparison_operator"
16900                                 [(reg FLAGS_REG) (const_int 0)])
16901                       (match_operand 2 "register_operand" "")
16902                       (match_operand 3 "register_operand" "")))]
16903   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16904    && (GET_MODE (operands[0]) == HImode
16905        || (GET_MODE (operands[0]) == QImode
16906            && (TARGET_PROMOTE_QImode
16907                || optimize_insn_for_size_p ())))"
16908   [(set (match_dup 0)
16909         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16910   "operands[0] = gen_lowpart (SImode, operands[0]);
16911    operands[2] = gen_lowpart (SImode, operands[2]);
16912    operands[3] = gen_lowpart (SImode, operands[3]);")
16913 \f
16914 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
16915 ;; transform a complex memory operation into two memory to register operations.
16916
16917 ;; Don't push memory operands
16918 (define_peephole2
16919   [(set (match_operand:SWI 0 "push_operand" "")
16920         (match_operand:SWI 1 "memory_operand" ""))
16921    (match_scratch:SWI 2 "<r>")]
16922   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16923    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16924   [(set (match_dup 2) (match_dup 1))
16925    (set (match_dup 0) (match_dup 2))])
16926
16927 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16928 ;; SImode pushes.
16929 (define_peephole2
16930   [(set (match_operand:SF 0 "push_operand" "")
16931         (match_operand:SF 1 "memory_operand" ""))
16932    (match_scratch:SF 2 "r")]
16933   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16934    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16935   [(set (match_dup 2) (match_dup 1))
16936    (set (match_dup 0) (match_dup 2))])
16937
16938 ;; Don't move an immediate directly to memory when the instruction
16939 ;; gets too big.
16940 (define_peephole2
16941   [(match_scratch:SWI124 1 "<r>")
16942    (set (match_operand:SWI124 0 "memory_operand" "")
16943         (const_int 0))]
16944   "optimize_insn_for_speed_p ()
16945    && !TARGET_USE_MOV0
16946    && TARGET_SPLIT_LONG_MOVES
16947    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16948    && peep2_regno_dead_p (0, FLAGS_REG)"
16949   [(parallel [(set (match_dup 2) (const_int 0))
16950               (clobber (reg:CC FLAGS_REG))])
16951    (set (match_dup 0) (match_dup 1))]
16952   "operands[2] = gen_lowpart (SImode, operands[1]);")
16953
16954 (define_peephole2
16955   [(match_scratch:SWI124 2 "<r>")
16956    (set (match_operand:SWI124 0 "memory_operand" "")
16957         (match_operand:SWI124 1 "immediate_operand" ""))]
16958   "optimize_insn_for_speed_p ()
16959    && TARGET_SPLIT_LONG_MOVES
16960    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16961   [(set (match_dup 2) (match_dup 1))
16962    (set (match_dup 0) (match_dup 2))])
16963
16964 ;; Don't compare memory with zero, load and use a test instead.
16965 (define_peephole2
16966   [(set (match_operand 0 "flags_reg_operand" "")
16967         (match_operator 1 "compare_operator"
16968           [(match_operand:SI 2 "memory_operand" "")
16969            (const_int 0)]))
16970    (match_scratch:SI 3 "r")]
16971   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16972   [(set (match_dup 3) (match_dup 2))
16973    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16974
16975 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16976 ;; Don't split NOTs with a displacement operand, because resulting XOR
16977 ;; will not be pairable anyway.
16978 ;;
16979 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16980 ;; represented using a modRM byte.  The XOR replacement is long decoded,
16981 ;; so this split helps here as well.
16982 ;;
16983 ;; Note: Can't do this as a regular split because we can't get proper
16984 ;; lifetime information then.
16985
16986 (define_peephole2
16987   [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16988         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16989   "optimize_insn_for_speed_p ()
16990    && ((TARGET_NOT_UNPAIRABLE
16991         && (!MEM_P (operands[0])
16992             || !memory_displacement_operand (operands[0], <MODE>mode)))
16993        || (TARGET_NOT_VECTORMODE
16994            && long_memory_operand (operands[0], <MODE>mode)))
16995    && peep2_regno_dead_p (0, FLAGS_REG)"
16996   [(parallel [(set (match_dup 0)
16997                    (xor:SWI124 (match_dup 1) (const_int -1)))
16998               (clobber (reg:CC FLAGS_REG))])])
16999
17000 ;; Non pairable "test imm, reg" instructions can be translated to
17001 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17002 ;; byte opcode instead of two, have a short form for byte operands),
17003 ;; so do it for other CPUs as well.  Given that the value was dead,
17004 ;; this should not create any new dependencies.  Pass on the sub-word
17005 ;; versions if we're concerned about partial register stalls.
17006
17007 (define_peephole2
17008   [(set (match_operand 0 "flags_reg_operand" "")
17009         (match_operator 1 "compare_operator"
17010           [(and:SI (match_operand:SI 2 "register_operand" "")
17011                    (match_operand:SI 3 "immediate_operand" ""))
17012            (const_int 0)]))]
17013   "ix86_match_ccmode (insn, CCNOmode)
17014    && (true_regnum (operands[2]) != AX_REG
17015        || satisfies_constraint_K (operands[3]))
17016    && peep2_reg_dead_p (1, operands[2])"
17017   [(parallel
17018      [(set (match_dup 0)
17019            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17020                             (const_int 0)]))
17021       (set (match_dup 2)
17022            (and:SI (match_dup 2) (match_dup 3)))])])
17023
17024 ;; We don't need to handle HImode case, because it will be promoted to SImode
17025 ;; on ! TARGET_PARTIAL_REG_STALL
17026
17027 (define_peephole2
17028   [(set (match_operand 0 "flags_reg_operand" "")
17029         (match_operator 1 "compare_operator"
17030           [(and:QI (match_operand:QI 2 "register_operand" "")
17031                    (match_operand:QI 3 "immediate_operand" ""))
17032            (const_int 0)]))]
17033   "! TARGET_PARTIAL_REG_STALL
17034    && ix86_match_ccmode (insn, CCNOmode)
17035    && true_regnum (operands[2]) != AX_REG
17036    && peep2_reg_dead_p (1, operands[2])"
17037   [(parallel
17038      [(set (match_dup 0)
17039            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17040                             (const_int 0)]))
17041       (set (match_dup 2)
17042            (and:QI (match_dup 2) (match_dup 3)))])])
17043
17044 (define_peephole2
17045   [(set (match_operand 0 "flags_reg_operand" "")
17046         (match_operator 1 "compare_operator"
17047           [(and:SI
17048              (zero_extract:SI
17049                (match_operand 2 "ext_register_operand" "")
17050                (const_int 8)
17051                (const_int 8))
17052              (match_operand 3 "const_int_operand" ""))
17053            (const_int 0)]))]
17054   "! TARGET_PARTIAL_REG_STALL
17055    && ix86_match_ccmode (insn, CCNOmode)
17056    && true_regnum (operands[2]) != AX_REG
17057    && peep2_reg_dead_p (1, operands[2])"
17058   [(parallel [(set (match_dup 0)
17059                    (match_op_dup 1
17060                      [(and:SI
17061                         (zero_extract:SI
17062                           (match_dup 2)
17063                           (const_int 8)
17064                           (const_int 8))
17065                         (match_dup 3))
17066                       (const_int 0)]))
17067               (set (zero_extract:SI (match_dup 2)
17068                                     (const_int 8)
17069                                     (const_int 8))
17070                    (and:SI
17071                      (zero_extract:SI
17072                        (match_dup 2)
17073                        (const_int 8)
17074                        (const_int 8))
17075                      (match_dup 3)))])])
17076
17077 ;; Don't do logical operations with memory inputs.
17078 (define_peephole2
17079   [(match_scratch:SI 2 "r")
17080    (parallel [(set (match_operand:SI 0 "register_operand" "")
17081                    (match_operator:SI 3 "arith_or_logical_operator"
17082                      [(match_dup 0)
17083                       (match_operand:SI 1 "memory_operand" "")]))
17084               (clobber (reg:CC FLAGS_REG))])]
17085   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17086   [(set (match_dup 2) (match_dup 1))
17087    (parallel [(set (match_dup 0)
17088                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17089               (clobber (reg:CC FLAGS_REG))])])
17090
17091 (define_peephole2
17092   [(match_scratch:SI 2 "r")
17093    (parallel [(set (match_operand:SI 0 "register_operand" "")
17094                    (match_operator:SI 3 "arith_or_logical_operator"
17095                      [(match_operand:SI 1 "memory_operand" "")
17096                       (match_dup 0)]))
17097               (clobber (reg:CC FLAGS_REG))])]
17098   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17099   [(set (match_dup 2) (match_dup 1))
17100    (parallel [(set (match_dup 0)
17101                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17102               (clobber (reg:CC FLAGS_REG))])])
17103
17104 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17105 ;; refers to the destination of the load!
17106
17107 (define_peephole2
17108   [(set (match_operand:SI 0 "register_operand" "")
17109         (match_operand:SI 1 "register_operand" ""))
17110    (parallel [(set (match_dup 0)
17111                    (match_operator:SI 3 "commutative_operator"
17112                      [(match_dup 0)
17113                       (match_operand:SI 2 "memory_operand" "")]))
17114               (clobber (reg:CC FLAGS_REG))])]
17115   "REGNO (operands[0]) != REGNO (operands[1])
17116    && GENERAL_REGNO_P (REGNO (operands[0]))
17117    && GENERAL_REGNO_P (REGNO (operands[1]))"
17118   [(set (match_dup 0) (match_dup 4))
17119    (parallel [(set (match_dup 0)
17120                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17121               (clobber (reg:CC FLAGS_REG))])]
17122   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17123
17124 (define_peephole2
17125   [(set (match_operand 0 "register_operand" "")
17126         (match_operand 1 "register_operand" ""))
17127    (set (match_dup 0)
17128                    (match_operator 3 "commutative_operator"
17129                      [(match_dup 0)
17130                       (match_operand 2 "memory_operand" "")]))]
17131   "REGNO (operands[0]) != REGNO (operands[1])
17132    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
17133        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17134   [(set (match_dup 0) (match_dup 2))
17135    (set (match_dup 0)
17136         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17137
17138 ; Don't do logical operations with memory outputs
17139 ;
17140 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17141 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17142 ; the same decoder scheduling characteristics as the original.
17143
17144 (define_peephole2
17145   [(match_scratch:SI 2 "r")
17146    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17147                    (match_operator:SI 3 "arith_or_logical_operator"
17148                      [(match_dup 0)
17149                       (match_operand:SI 1 "nonmemory_operand" "")]))
17150               (clobber (reg:CC FLAGS_REG))])]
17151   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17152    /* Do not split stack checking probes.  */
17153    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17154   [(set (match_dup 2) (match_dup 0))
17155    (parallel [(set (match_dup 2)
17156                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17157               (clobber (reg:CC FLAGS_REG))])
17158    (set (match_dup 0) (match_dup 2))])
17159
17160 (define_peephole2
17161   [(match_scratch:SI 2 "r")
17162    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17163                    (match_operator:SI 3 "arith_or_logical_operator"
17164                      [(match_operand:SI 1 "nonmemory_operand" "")
17165                       (match_dup 0)]))
17166               (clobber (reg:CC FLAGS_REG))])]
17167   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17168    /* Do not split stack checking probes.  */
17169    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17170   [(set (match_dup 2) (match_dup 0))
17171    (parallel [(set (match_dup 2)
17172                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17173               (clobber (reg:CC FLAGS_REG))])
17174    (set (match_dup 0) (match_dup 2))])
17175
17176 ;; Attempt to use arith or logical operations with memory outputs with
17177 ;; setting of flags.
17178 (define_peephole2
17179   [(set (match_operand:SWI 0 "register_operand" "")
17180         (match_operand:SWI 1 "memory_operand" ""))
17181    (parallel [(set (match_dup 0)
17182                    (match_operator:SWI 3 "plusminuslogic_operator"
17183                      [(match_dup 0)
17184                       (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17185               (clobber (reg:CC FLAGS_REG))])
17186    (set (match_dup 1) (match_dup 0))
17187    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17188   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17189    && peep2_reg_dead_p (4, operands[0])
17190    && !reg_overlap_mentioned_p (operands[0], operands[1])
17191    && ix86_match_ccmode (peep2_next_insn (3),
17192                          (GET_CODE (operands[3]) == PLUS
17193                           || GET_CODE (operands[3]) == MINUS)
17194                          ? CCGOCmode : CCNOmode)"
17195   [(parallel [(set (match_dup 4) (match_dup 5))
17196               (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17197                                                   (match_dup 2)]))])]
17198   "operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17199    operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17200                                  copy_rtx (operands[1]),
17201                                  copy_rtx (operands[2]));
17202    operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17203                                   operands[5], const0_rtx);")
17204
17205 (define_peephole2
17206   [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17207                    (match_operator:SWI 2 "plusminuslogic_operator"
17208                      [(match_dup 0)
17209                       (match_operand:SWI 1 "memory_operand" "")]))
17210               (clobber (reg:CC FLAGS_REG))])
17211    (set (match_dup 1) (match_dup 0))
17212    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17213   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17214    && GET_CODE (operands[2]) != MINUS
17215    && peep2_reg_dead_p (3, operands[0])
17216    && !reg_overlap_mentioned_p (operands[0], operands[1])
17217    && ix86_match_ccmode (peep2_next_insn (2),
17218                          GET_CODE (operands[2]) == PLUS
17219                          ? CCGOCmode : CCNOmode)"
17220   [(parallel [(set (match_dup 3) (match_dup 4))
17221               (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17222                                                   (match_dup 0)]))])]
17223   "operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17224    operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17225                                  copy_rtx (operands[1]),
17226                                  copy_rtx (operands[0]));
17227    operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17228                                   operands[4], const0_rtx);")
17229
17230 (define_peephole2
17231   [(set (match_operand:SWI12 0 "register_operand" "")
17232         (match_operand:SWI12 1 "memory_operand" ""))
17233    (parallel [(set (match_operand:SI 4 "register_operand" "")
17234                    (match_operator:SI 3 "plusminuslogic_operator"
17235                      [(match_dup 4)
17236                       (match_operand:SI 2 "nonmemory_operand" "")]))
17237               (clobber (reg:CC FLAGS_REG))])
17238    (set (match_dup 1) (match_dup 0))
17239    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17240   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17241    && REG_P (operands[0]) && REG_P (operands[4])
17242    && REGNO (operands[0]) == REGNO (operands[4])
17243    && peep2_reg_dead_p (4, operands[0])
17244    && !reg_overlap_mentioned_p (operands[0], operands[1])
17245    && ix86_match_ccmode (peep2_next_insn (3),
17246                          (GET_CODE (operands[3]) == PLUS
17247                           || GET_CODE (operands[3]) == MINUS)
17248                          ? CCGOCmode : CCNOmode)"
17249   [(parallel [(set (match_dup 4) (match_dup 5))
17250               (set (match_dup 1) (match_dup 6))])]
17251   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17252    operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17253    operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17254                                  copy_rtx (operands[1]), operands[2]);
17255    operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17256                                   operands[5], const0_rtx);
17257    operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17258                                  copy_rtx (operands[1]),
17259                                  copy_rtx (operands[2]));")
17260
17261 ;; Attempt to always use XOR for zeroing registers.
17262 (define_peephole2
17263   [(set (match_operand 0 "register_operand" "")
17264         (match_operand 1 "const0_operand" ""))]
17265   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17266    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17267    && GENERAL_REG_P (operands[0])
17268    && peep2_regno_dead_p (0, FLAGS_REG)"
17269   [(parallel [(set (match_dup 0) (const_int 0))
17270               (clobber (reg:CC FLAGS_REG))])]
17271   "operands[0] = gen_lowpart (word_mode, operands[0]);")
17272
17273 (define_peephole2
17274   [(set (strict_low_part (match_operand 0 "register_operand" ""))
17275         (const_int 0))]
17276   "(GET_MODE (operands[0]) == QImode
17277     || GET_MODE (operands[0]) == HImode)
17278    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17279    && peep2_regno_dead_p (0, FLAGS_REG)"
17280   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17281               (clobber (reg:CC FLAGS_REG))])])
17282
17283 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17284 (define_peephole2
17285   [(set (match_operand:SWI248 0 "register_operand" "")
17286         (const_int -1))]
17287   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17288    && peep2_regno_dead_p (0, FLAGS_REG)"
17289   [(parallel [(set (match_dup 0) (const_int -1))
17290               (clobber (reg:CC FLAGS_REG))])]
17291 {
17292   if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17293     operands[0] = gen_lowpart (SImode, operands[0]);
17294 })
17295
17296 ;; Attempt to convert simple lea to add/shift.
17297 ;; These can be created by move expanders.
17298
17299 (define_peephole2
17300   [(set (match_operand:SWI48 0 "register_operand" "")
17301         (plus:SWI48 (match_dup 0)
17302                     (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17303   "peep2_regno_dead_p (0, FLAGS_REG)"
17304   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17305               (clobber (reg:CC FLAGS_REG))])])
17306
17307 (define_peephole2
17308   [(set (match_operand:SI 0 "register_operand" "")
17309         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17310                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17311   "TARGET_64BIT
17312    && peep2_regno_dead_p (0, FLAGS_REG)
17313    && REGNO (operands[0]) == REGNO (operands[1])"
17314   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17315               (clobber (reg:CC FLAGS_REG))])]
17316   "operands[2] = gen_lowpart (SImode, operands[2]);")
17317
17318 (define_peephole2
17319   [(set (match_operand:SWI48 0 "register_operand" "")
17320         (mult:SWI48 (match_dup 0)
17321                     (match_operand:SWI48 1 "const_int_operand" "")))]
17322   "exact_log2 (INTVAL (operands[1])) >= 0
17323    && peep2_regno_dead_p (0, FLAGS_REG)"
17324   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17325               (clobber (reg:CC FLAGS_REG))])]
17326   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17327
17328 (define_peephole2
17329   [(set (match_operand:SI 0 "register_operand" "")
17330         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17331                    (match_operand:DI 2 "const_int_operand" "")) 0))]
17332   "TARGET_64BIT
17333    && exact_log2 (INTVAL (operands[2])) >= 0
17334    && REGNO (operands[0]) == REGNO (operands[1])
17335    && peep2_regno_dead_p (0, FLAGS_REG)"
17336   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17337               (clobber (reg:CC FLAGS_REG))])]
17338   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17339
17340 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17341 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17342 ;; On many CPUs it is also faster, since special hardware to avoid esp
17343 ;; dependencies is present.
17344
17345 ;; While some of these conversions may be done using splitters, we use
17346 ;; peepholes in order to allow combine_stack_adjustments pass to see
17347 ;; nonobfuscated RTL.
17348
17349 ;; Convert prologue esp subtractions to push.
17350 ;; We need register to push.  In order to keep verify_flow_info happy we have
17351 ;; two choices
17352 ;; - use scratch and clobber it in order to avoid dependencies
17353 ;; - use already live register
17354 ;; We can't use the second way right now, since there is no reliable way how to
17355 ;; verify that given register is live.  First choice will also most likely in
17356 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17357 ;; call clobbered registers are dead.  We may want to use base pointer as an
17358 ;; alternative when no register is available later.
17359
17360 (define_peephole2
17361   [(match_scratch:P 1 "r")
17362    (parallel [(set (reg:P SP_REG)
17363                    (plus:P (reg:P SP_REG)
17364                            (match_operand:P 0 "const_int_operand" "")))
17365               (clobber (reg:CC FLAGS_REG))
17366               (clobber (mem:BLK (scratch)))])]
17367   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17368    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17369   [(clobber (match_dup 1))
17370    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17371               (clobber (mem:BLK (scratch)))])])
17372
17373 (define_peephole2
17374   [(match_scratch:P 1 "r")
17375    (parallel [(set (reg:P SP_REG)
17376                    (plus:P (reg:P SP_REG)
17377                            (match_operand:P 0 "const_int_operand" "")))
17378               (clobber (reg:CC FLAGS_REG))
17379               (clobber (mem:BLK (scratch)))])]
17380   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17381    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17382   [(clobber (match_dup 1))
17383    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17384    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17385               (clobber (mem:BLK (scratch)))])])
17386
17387 ;; Convert esp subtractions to push.
17388 (define_peephole2
17389   [(match_scratch:P 1 "r")
17390    (parallel [(set (reg:P SP_REG)
17391                    (plus:P (reg:P SP_REG)
17392                            (match_operand:P 0 "const_int_operand" "")))
17393               (clobber (reg:CC FLAGS_REG))])]
17394   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17395    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17396   [(clobber (match_dup 1))
17397    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17398
17399 (define_peephole2
17400   [(match_scratch:P 1 "r")
17401    (parallel [(set (reg:P SP_REG)
17402                    (plus:P (reg:P SP_REG)
17403                            (match_operand:P 0 "const_int_operand" "")))
17404               (clobber (reg:CC FLAGS_REG))])]
17405   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17406    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17407   [(clobber (match_dup 1))
17408    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17409    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17410
17411 ;; Convert epilogue deallocator to pop.
17412 (define_peephole2
17413   [(match_scratch:P 1 "r")
17414    (parallel [(set (reg:P SP_REG)
17415                    (plus:P (reg:P SP_REG)
17416                            (match_operand:P 0 "const_int_operand" "")))
17417               (clobber (reg:CC FLAGS_REG))
17418               (clobber (mem:BLK (scratch)))])]
17419   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17420    && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17421   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17422               (clobber (mem:BLK (scratch)))])])
17423
17424 ;; Two pops case is tricky, since pop causes dependency
17425 ;; on destination register.  We use two registers if available.
17426 (define_peephole2
17427   [(match_scratch:P 1 "r")
17428    (match_scratch:P 2 "r")
17429    (parallel [(set (reg:P SP_REG)
17430                    (plus:P (reg:P SP_REG)
17431                            (match_operand:P 0 "const_int_operand" "")))
17432               (clobber (reg:CC FLAGS_REG))
17433               (clobber (mem:BLK (scratch)))])]
17434   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17435    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17436   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17437               (clobber (mem:BLK (scratch)))])
17438    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17439
17440 (define_peephole2
17441   [(match_scratch:P 1 "r")
17442    (parallel [(set (reg:P SP_REG)
17443                    (plus:P (reg:P SP_REG)
17444                            (match_operand:P 0 "const_int_operand" "")))
17445               (clobber (reg:CC FLAGS_REG))
17446               (clobber (mem:BLK (scratch)))])]
17447   "optimize_insn_for_size_p ()
17448    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17449   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17450               (clobber (mem:BLK (scratch)))])
17451    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17452
17453 ;; Convert esp additions to pop.
17454 (define_peephole2
17455   [(match_scratch:P 1 "r")
17456    (parallel [(set (reg:P SP_REG)
17457                    (plus:P (reg:P SP_REG)
17458                            (match_operand:P 0 "const_int_operand" "")))
17459               (clobber (reg:CC FLAGS_REG))])]
17460   "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17461   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17462
17463 ;; Two pops case is tricky, since pop causes dependency
17464 ;; on destination register.  We use two registers if available.
17465 (define_peephole2
17466   [(match_scratch:P 1 "r")
17467    (match_scratch:P 2 "r")
17468    (parallel [(set (reg:P SP_REG)
17469                    (plus:P (reg:P SP_REG)
17470                            (match_operand:P 0 "const_int_operand" "")))
17471               (clobber (reg:CC FLAGS_REG))])]
17472   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17473   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17474    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17475
17476 (define_peephole2
17477   [(match_scratch:P 1 "r")
17478    (parallel [(set (reg:P SP_REG)
17479                    (plus:P (reg:P SP_REG)
17480                            (match_operand:P 0 "const_int_operand" "")))
17481               (clobber (reg:CC FLAGS_REG))])]
17482   "optimize_insn_for_size_p ()
17483    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17484   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17485    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17486 \f
17487 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17488 ;; required and register dies.  Similarly for 128 to -128.
17489 (define_peephole2
17490   [(set (match_operand 0 "flags_reg_operand" "")
17491         (match_operator 1 "compare_operator"
17492           [(match_operand 2 "register_operand" "")
17493            (match_operand 3 "const_int_operand" "")]))]
17494   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17495      && incdec_operand (operands[3], GET_MODE (operands[3])))
17496     || (!TARGET_FUSE_CMP_AND_BRANCH
17497         && INTVAL (operands[3]) == 128))
17498    && ix86_match_ccmode (insn, CCGCmode)
17499    && peep2_reg_dead_p (1, operands[2])"
17500   [(parallel [(set (match_dup 0)
17501                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17502               (clobber (match_dup 2))])])
17503 \f
17504 ;; Convert imul by three, five and nine into lea
17505 (define_peephole2
17506   [(parallel
17507     [(set (match_operand:SWI48 0 "register_operand" "")
17508           (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17509                       (match_operand:SWI48 2 "const359_operand" "")))
17510      (clobber (reg:CC FLAGS_REG))])]
17511   "!TARGET_PARTIAL_REG_STALL
17512    || <MODE>mode == SImode
17513    || optimize_function_for_size_p (cfun)"
17514   [(set (match_dup 0)
17515         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17516                     (match_dup 1)))]
17517   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17518
17519 (define_peephole2
17520   [(parallel
17521     [(set (match_operand:SWI48 0 "register_operand" "")
17522           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17523                       (match_operand:SWI48 2 "const359_operand" "")))
17524      (clobber (reg:CC FLAGS_REG))])]
17525   "optimize_insn_for_speed_p ()
17526    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17527   [(set (match_dup 0) (match_dup 1))
17528    (set (match_dup 0)
17529         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17530                     (match_dup 0)))]
17531   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17532
17533 ;; imul $32bit_imm, mem, reg is vector decoded, while
17534 ;; imul $32bit_imm, reg, reg is direct decoded.
17535 (define_peephole2
17536   [(match_scratch:SWI48 3 "r")
17537    (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17538                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17539                                (match_operand:SWI48 2 "immediate_operand" "")))
17540               (clobber (reg:CC FLAGS_REG))])]
17541   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17542    && !satisfies_constraint_K (operands[2])"
17543   [(set (match_dup 3) (match_dup 1))
17544    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17545               (clobber (reg:CC FLAGS_REG))])])
17546
17547 (define_peephole2
17548   [(match_scratch:SI 3 "r")
17549    (parallel [(set (match_operand:DI 0 "register_operand" "")
17550                    (zero_extend:DI
17551                      (mult:SI (match_operand:SI 1 "memory_operand" "")
17552                               (match_operand:SI 2 "immediate_operand" ""))))
17553               (clobber (reg:CC FLAGS_REG))])]
17554   "TARGET_64BIT
17555    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17556    && !satisfies_constraint_K (operands[2])"
17557   [(set (match_dup 3) (match_dup 1))
17558    (parallel [(set (match_dup 0)
17559                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17560               (clobber (reg:CC FLAGS_REG))])])
17561
17562 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17563 ;; Convert it into imul reg, reg
17564 ;; It would be better to force assembler to encode instruction using long
17565 ;; immediate, but there is apparently no way to do so.
17566 (define_peephole2
17567   [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17568                    (mult:SWI248
17569                     (match_operand:SWI248 1 "nonimmediate_operand" "")
17570                     (match_operand:SWI248 2 "const_int_operand" "")))
17571               (clobber (reg:CC FLAGS_REG))])
17572    (match_scratch:SWI248 3 "r")]
17573   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17574    && satisfies_constraint_K (operands[2])"
17575   [(set (match_dup 3) (match_dup 2))
17576    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17577               (clobber (reg:CC FLAGS_REG))])]
17578 {
17579   if (!rtx_equal_p (operands[0], operands[1]))
17580     emit_move_insn (operands[0], operands[1]);
17581 })
17582
17583 ;; After splitting up read-modify operations, array accesses with memory
17584 ;; operands might end up in form:
17585 ;;  sall    $2, %eax
17586 ;;  movl    4(%esp), %edx
17587 ;;  addl    %edx, %eax
17588 ;; instead of pre-splitting:
17589 ;;  sall    $2, %eax
17590 ;;  addl    4(%esp), %eax
17591 ;; Turn it into:
17592 ;;  movl    4(%esp), %edx
17593 ;;  leal    (%edx,%eax,4), %eax
17594
17595 (define_peephole2
17596   [(match_scratch:P 5 "r")
17597    (parallel [(set (match_operand 0 "register_operand" "")
17598                    (ashift (match_operand 1 "register_operand" "")
17599                            (match_operand 2 "const_int_operand" "")))
17600                (clobber (reg:CC FLAGS_REG))])
17601    (parallel [(set (match_operand 3 "register_operand" "")
17602                    (plus (match_dup 0)
17603                          (match_operand 4 "x86_64_general_operand" "")))
17604                    (clobber (reg:CC FLAGS_REG))])]
17605   "IN_RANGE (INTVAL (operands[2]), 1, 3)
17606    /* Validate MODE for lea.  */
17607    && ((!TARGET_PARTIAL_REG_STALL
17608         && (GET_MODE (operands[0]) == QImode
17609             || GET_MODE (operands[0]) == HImode))
17610        || GET_MODE (operands[0]) == SImode
17611        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17612    && (rtx_equal_p (operands[0], operands[3])
17613        || peep2_reg_dead_p (2, operands[0]))
17614    /* We reorder load and the shift.  */
17615    && !reg_overlap_mentioned_p (operands[0], operands[4])"
17616   [(set (match_dup 5) (match_dup 4))
17617    (set (match_dup 0) (match_dup 1))]
17618 {
17619   enum machine_mode op1mode = GET_MODE (operands[1]);
17620   enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17621   int scale = 1 << INTVAL (operands[2]);
17622   rtx index = gen_lowpart (Pmode, operands[1]);
17623   rtx base = gen_lowpart (Pmode, operands[5]);
17624   rtx dest = gen_lowpart (mode, operands[3]);
17625
17626   operands[1] = gen_rtx_PLUS (Pmode, base,
17627                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17628   operands[5] = base;
17629   if (mode != Pmode)
17630     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17631   if (op1mode != Pmode)
17632     operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17633   operands[0] = dest;
17634 })
17635 \f
17636 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17637 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17638 ;; caught for use by garbage collectors and the like.  Using an insn that
17639 ;; maps to SIGILL makes it more likely the program will rightfully die.
17640 ;; Keeping with tradition, "6" is in honor of #UD.
17641 (define_insn "trap"
17642   [(trap_if (const_int 1) (const_int 6))]
17643   ""
17644   { return ASM_SHORT "0x0b0f"; }
17645   [(set_attr "length" "2")])
17646
17647 (define_expand "prefetch"
17648   [(prefetch (match_operand 0 "address_operand" "")
17649              (match_operand:SI 1 "const_int_operand" "")
17650              (match_operand:SI 2 "const_int_operand" ""))]
17651   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17652 {
17653   int rw = INTVAL (operands[1]);
17654   int locality = INTVAL (operands[2]);
17655
17656   gcc_assert (rw == 0 || rw == 1);
17657   gcc_assert (locality >= 0 && locality <= 3);
17658   gcc_assert (GET_MODE (operands[0]) == Pmode
17659               || GET_MODE (operands[0]) == VOIDmode);
17660
17661   /* Use 3dNOW prefetch in case we are asking for write prefetch not
17662      supported by SSE counterpart or the SSE prefetch is not available
17663      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17664      of locality.  */
17665   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17666     operands[2] = GEN_INT (3);
17667   else
17668     operands[1] = const0_rtx;
17669 })
17670
17671 (define_insn "*prefetch_sse_<mode>"
17672   [(prefetch (match_operand:P 0 "address_operand" "p")
17673              (const_int 0)
17674              (match_operand:SI 1 "const_int_operand" ""))]
17675   "TARGET_PREFETCH_SSE"
17676 {
17677   static const char * const patterns[4] = {
17678    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17679   };
17680
17681   int locality = INTVAL (operands[1]);
17682   gcc_assert (locality >= 0 && locality <= 3);
17683
17684   return patterns[locality];
17685 }
17686   [(set_attr "type" "sse")
17687    (set_attr "atom_sse_attr" "prefetch")
17688    (set (attr "length_address")
17689         (symbol_ref "memory_address_length (operands[0])"))
17690    (set_attr "memory" "none")])
17691
17692 (define_insn "*prefetch_3dnow_<mode>"
17693   [(prefetch (match_operand:P 0 "address_operand" "p")
17694              (match_operand:SI 1 "const_int_operand" "n")
17695              (const_int 3))]
17696   "TARGET_3DNOW"
17697 {
17698   if (INTVAL (operands[1]) == 0)
17699     return "prefetch\t%a0";
17700   else
17701     return "prefetchw\t%a0";
17702 }
17703   [(set_attr "type" "mmx")
17704    (set (attr "length_address")
17705         (symbol_ref "memory_address_length (operands[0])"))
17706    (set_attr "memory" "none")])
17707
17708 (define_expand "stack_protect_set"
17709   [(match_operand 0 "memory_operand" "")
17710    (match_operand 1 "memory_operand" "")]
17711   ""
17712 {
17713   rtx (*insn)(rtx, rtx);
17714
17715 #ifdef TARGET_THREAD_SSP_OFFSET
17716   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17717   insn = (TARGET_LP64
17718           ? gen_stack_tls_protect_set_di
17719           : gen_stack_tls_protect_set_si);
17720 #else
17721   insn = (TARGET_LP64
17722           ? gen_stack_protect_set_di
17723           : gen_stack_protect_set_si);
17724 #endif
17725
17726   emit_insn (insn (operands[0], operands[1]));
17727   DONE;
17728 })
17729
17730 (define_insn "stack_protect_set_<mode>"
17731   [(set (match_operand:PTR 0 "memory_operand" "=m")
17732         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17733                     UNSPEC_SP_SET))
17734    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17735    (clobber (reg:CC FLAGS_REG))]
17736   ""
17737   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17738   [(set_attr "type" "multi")])
17739
17740 (define_insn "stack_tls_protect_set_<mode>"
17741   [(set (match_operand:PTR 0 "memory_operand" "=m")
17742         (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17743                     UNSPEC_SP_TLS_SET))
17744    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17745    (clobber (reg:CC FLAGS_REG))]
17746   ""
17747   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17748   [(set_attr "type" "multi")])
17749
17750 (define_expand "stack_protect_test"
17751   [(match_operand 0 "memory_operand" "")
17752    (match_operand 1 "memory_operand" "")
17753    (match_operand 2 "" "")]
17754   ""
17755 {
17756   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17757
17758   rtx (*insn)(rtx, rtx, rtx);
17759
17760 #ifdef TARGET_THREAD_SSP_OFFSET
17761   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17762   insn = (TARGET_LP64
17763           ? gen_stack_tls_protect_test_di
17764           : gen_stack_tls_protect_test_si);
17765 #else
17766   insn = (TARGET_LP64
17767           ? gen_stack_protect_test_di
17768           : gen_stack_protect_test_si);
17769 #endif
17770
17771   emit_insn (insn (flags, operands[0], operands[1]));
17772
17773   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17774                                   flags, const0_rtx, operands[2]));
17775   DONE;
17776 })
17777
17778 (define_insn "stack_protect_test_<mode>"
17779   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17780         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17781                      (match_operand:PTR 2 "memory_operand" "m")]
17782                     UNSPEC_SP_TEST))
17783    (clobber (match_scratch:PTR 3 "=&r"))]
17784   ""
17785   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17786   [(set_attr "type" "multi")])
17787
17788 (define_insn "stack_tls_protect_test_<mode>"
17789   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17790         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17791                      (match_operand:PTR 2 "const_int_operand" "i")]
17792                     UNSPEC_SP_TLS_TEST))
17793    (clobber (match_scratch:PTR 3 "=r"))]
17794   ""
17795   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17796   [(set_attr "type" "multi")])
17797
17798 (define_insn "sse4_2_crc32<mode>"
17799   [(set (match_operand:SI 0 "register_operand" "=r")
17800         (unspec:SI
17801           [(match_operand:SI 1 "register_operand" "0")
17802            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17803           UNSPEC_CRC32))]
17804   "TARGET_SSE4_2 || TARGET_CRC32"
17805   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17806   [(set_attr "type" "sselog1")
17807    (set_attr "prefix_rep" "1")
17808    (set_attr "prefix_extra" "1")
17809    (set (attr "prefix_data16")
17810      (if_then_else (match_operand:HI 2 "" "")
17811        (const_string "1")
17812        (const_string "*")))
17813    (set (attr "prefix_rex")
17814      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17815        (const_string "1")
17816        (const_string "*")))
17817    (set_attr "mode" "SI")])
17818
17819 (define_insn "sse4_2_crc32di"
17820   [(set (match_operand:DI 0 "register_operand" "=r")
17821         (unspec:DI
17822           [(match_operand:DI 1 "register_operand" "0")
17823            (match_operand:DI 2 "nonimmediate_operand" "rm")]
17824           UNSPEC_CRC32))]
17825   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17826   "crc32{q}\t{%2, %0|%0, %2}"
17827   [(set_attr "type" "sselog1")
17828    (set_attr "prefix_rep" "1")
17829    (set_attr "prefix_extra" "1")
17830    (set_attr "mode" "DI")])
17831
17832 (define_expand "rdpmc"
17833   [(match_operand:DI 0 "register_operand" "")
17834    (match_operand:SI 1 "register_operand" "")]
17835   ""
17836 {
17837   rtx reg = gen_reg_rtx (DImode);
17838   rtx si;
17839
17840   /* Force operand 1 into ECX.  */
17841   rtx ecx = gen_rtx_REG (SImode, CX_REG);
17842   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17843   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17844                                 UNSPECV_RDPMC);
17845
17846   if (TARGET_64BIT)
17847     {
17848       rtvec vec = rtvec_alloc (2);
17849       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17850       rtx upper = gen_reg_rtx (DImode);
17851       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17852                                         gen_rtvec (1, const0_rtx),
17853                                         UNSPECV_RDPMC);
17854       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17855       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17856       emit_insn (load);
17857       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17858                                    NULL, 1, OPTAB_DIRECT);
17859       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17860                                  OPTAB_DIRECT);
17861     }
17862   else
17863     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17864   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17865   DONE;
17866 })
17867
17868 (define_insn "*rdpmc"
17869   [(set (match_operand:DI 0 "register_operand" "=A")
17870         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17871                             UNSPECV_RDPMC))]
17872   "!TARGET_64BIT"
17873   "rdpmc"
17874   [(set_attr "type" "other")
17875    (set_attr "length" "2")])
17876
17877 (define_insn "*rdpmc_rex64"
17878   [(set (match_operand:DI 0 "register_operand" "=a")
17879         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17880                             UNSPECV_RDPMC))
17881   (set (match_operand:DI 1 "register_operand" "=d")
17882        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17883   "TARGET_64BIT"
17884   "rdpmc"
17885   [(set_attr "type" "other")
17886    (set_attr "length" "2")])
17887
17888 (define_expand "rdtsc"
17889   [(set (match_operand:DI 0 "register_operand" "")
17890         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17891   ""
17892 {
17893   if (TARGET_64BIT)
17894     {
17895       rtvec vec = rtvec_alloc (2);
17896       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17897       rtx upper = gen_reg_rtx (DImode);
17898       rtx lower = gen_reg_rtx (DImode);
17899       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17900                                          gen_rtvec (1, const0_rtx),
17901                                          UNSPECV_RDTSC);
17902       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17903       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17904       emit_insn (load);
17905       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17906                                    NULL, 1, OPTAB_DIRECT);
17907       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17908                                    OPTAB_DIRECT);
17909       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17910       DONE;
17911     }
17912 })
17913
17914 (define_insn "*rdtsc"
17915   [(set (match_operand:DI 0 "register_operand" "=A")
17916         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17917   "!TARGET_64BIT"
17918   "rdtsc"
17919   [(set_attr "type" "other")
17920    (set_attr "length" "2")])
17921
17922 (define_insn "*rdtsc_rex64"
17923   [(set (match_operand:DI 0 "register_operand" "=a")
17924         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17925    (set (match_operand:DI 1 "register_operand" "=d")
17926         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17927   "TARGET_64BIT"
17928   "rdtsc"
17929   [(set_attr "type" "other")
17930    (set_attr "length" "2")])
17931
17932 (define_expand "rdtscp"
17933   [(match_operand:DI 0 "register_operand" "")
17934    (match_operand:SI 1 "memory_operand" "")]
17935   ""
17936 {
17937   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17938                                     gen_rtvec (1, const0_rtx),
17939                                     UNSPECV_RDTSCP);
17940   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17941                                     gen_rtvec (1, const0_rtx),
17942                                     UNSPECV_RDTSCP);
17943   rtx reg = gen_reg_rtx (DImode);
17944   rtx tmp = gen_reg_rtx (SImode);
17945
17946   if (TARGET_64BIT)
17947     {
17948       rtvec vec = rtvec_alloc (3);
17949       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17950       rtx upper = gen_reg_rtx (DImode);
17951       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17952       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17953       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17954       emit_insn (load);
17955       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17956                                    NULL, 1, OPTAB_DIRECT);
17957       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17958                                  OPTAB_DIRECT);
17959     }
17960   else
17961     {
17962       rtvec vec = rtvec_alloc (2);
17963       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17964       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17965       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17966       emit_insn (load);
17967     }
17968   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17969   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17970   DONE;
17971 })
17972
17973 (define_insn "*rdtscp"
17974   [(set (match_operand:DI 0 "register_operand" "=A")
17975         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17976    (set (match_operand:SI 1 "register_operand" "=c")
17977         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17978   "!TARGET_64BIT"
17979   "rdtscp"
17980   [(set_attr "type" "other")
17981    (set_attr "length" "3")])
17982
17983 (define_insn "*rdtscp_rex64"
17984   [(set (match_operand:DI 0 "register_operand" "=a")
17985         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17986    (set (match_operand:DI 1 "register_operand" "=d")
17987         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17988    (set (match_operand:SI 2 "register_operand" "=c")
17989         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17990   "TARGET_64BIT"
17991   "rdtscp"
17992   [(set_attr "type" "other")
17993    (set_attr "length" "3")])
17994
17995 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17996 ;;
17997 ;; LWP instructions
17998 ;;
17999 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18000
18001 (define_expand "lwp_llwpcb"
18002   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18003                     UNSPECV_LLWP_INTRINSIC)]
18004   "TARGET_LWP")
18005
18006 (define_insn "*lwp_llwpcb<mode>1"
18007   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18008                     UNSPECV_LLWP_INTRINSIC)]
18009   "TARGET_LWP"
18010   "llwpcb\t%0"
18011   [(set_attr "type" "lwp")
18012    (set_attr "mode" "<MODE>")
18013    (set_attr "length" "5")])
18014
18015 (define_expand "lwp_slwpcb"
18016   [(set (match_operand 0 "register_operand" "=r")
18017         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18018   "TARGET_LWP"
18019 {
18020   rtx (*insn)(rtx);
18021
18022   insn = (TARGET_64BIT
18023           ? gen_lwp_slwpcbdi
18024           : gen_lwp_slwpcbsi);
18025
18026   emit_insn (insn (operands[0]));
18027   DONE;
18028 })
18029
18030 (define_insn "lwp_slwpcb<mode>"
18031   [(set (match_operand:P 0 "register_operand" "=r")
18032         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18033   "TARGET_LWP"
18034   "slwpcb\t%0"
18035   [(set_attr "type" "lwp")
18036    (set_attr "mode" "<MODE>")
18037    (set_attr "length" "5")])
18038
18039 (define_expand "lwp_lwpval<mode>3"
18040   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18041                      (match_operand:SI 2 "nonimmediate_operand" "rm")
18042                      (match_operand:SI 3 "const_int_operand" "i")]
18043                     UNSPECV_LWPVAL_INTRINSIC)]
18044   "TARGET_LWP"
18045   "/* Avoid unused variable warning.  */
18046    (void) operand0;")
18047
18048 (define_insn "*lwp_lwpval<mode>3_1"
18049   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18050                      (match_operand:SI 1 "nonimmediate_operand" "rm")
18051                      (match_operand:SI 2 "const_int_operand" "i")]
18052                     UNSPECV_LWPVAL_INTRINSIC)]
18053   "TARGET_LWP"
18054   "lwpval\t{%2, %1, %0|%0, %1, %2}"
18055   [(set_attr "type" "lwp")
18056    (set_attr "mode" "<MODE>")
18057    (set (attr "length")
18058         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18059
18060 (define_expand "lwp_lwpins<mode>3"
18061   [(set (reg:CCC FLAGS_REG)
18062         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18063                               (match_operand:SI 2 "nonimmediate_operand" "rm")
18064                               (match_operand:SI 3 "const_int_operand" "i")]
18065                              UNSPECV_LWPINS_INTRINSIC))
18066    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18067         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18068   "TARGET_LWP")
18069
18070 (define_insn "*lwp_lwpins<mode>3_1"
18071   [(set (reg:CCC FLAGS_REG)
18072         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18073                               (match_operand:SI 1 "nonimmediate_operand" "rm")
18074                               (match_operand:SI 2 "const_int_operand" "i")]
18075                              UNSPECV_LWPINS_INTRINSIC))]
18076   "TARGET_LWP"
18077   "lwpins\t{%2, %1, %0|%0, %1, %2}"
18078   [(set_attr "type" "lwp")
18079    (set_attr "mode" "<MODE>")
18080    (set (attr "length")
18081         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18082
18083 (define_insn "rdfsbase<mode>"
18084   [(set (match_operand:SWI48 0 "register_operand" "=r")
18085         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18086   "TARGET_64BIT && TARGET_FSGSBASE"
18087   "rdfsbase %0"
18088   [(set_attr "type" "other")
18089    (set_attr "prefix_extra" "2")])
18090
18091 (define_insn "rdgsbase<mode>"
18092   [(set (match_operand:SWI48 0 "register_operand" "=r")
18093         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18094   "TARGET_64BIT && TARGET_FSGSBASE"
18095   "rdgsbase %0"
18096   [(set_attr "type" "other")
18097    (set_attr "prefix_extra" "2")])
18098
18099 (define_insn "wrfsbase<mode>"
18100   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18101                     UNSPECV_WRFSBASE)]
18102   "TARGET_64BIT && TARGET_FSGSBASE"
18103   "wrfsbase %0"
18104   [(set_attr "type" "other")
18105    (set_attr "prefix_extra" "2")])
18106
18107 (define_insn "wrgsbase<mode>"
18108   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18109                     UNSPECV_WRGSBASE)]
18110   "TARGET_64BIT && TARGET_FSGSBASE"
18111   "wrgsbase %0"
18112   [(set_attr "type" "other")
18113    (set_attr "prefix_extra" "2")])
18114
18115 (define_insn "rdrand<mode>_1"
18116   [(set (match_operand:SWI248 0 "register_operand" "=r")
18117         (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18118    (set (reg:CCC FLAGS_REG)
18119         (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18120   "TARGET_RDRND"
18121   "rdrand\t%0"
18122   [(set_attr "type" "other")
18123    (set_attr "prefix_extra" "1")])
18124
18125 (define_expand "pause"
18126   [(set (match_dup 0)
18127         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18128   ""
18129 {
18130   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18131   MEM_VOLATILE_P (operands[0]) = 1;
18132 })
18133
18134 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18135 ;; They have the same encoding.
18136 (define_insn "*pause"
18137   [(set (match_operand:BLK 0 "" "")
18138         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18139   ""
18140   "rep; nop"
18141   [(set_attr "length" "2")
18142    (set_attr "memory" "unknown")])
18143
18144 (include "mmx.md")
18145 (include "sse.md")
18146 (include "sync.md")