eace56d9f78ae848881a44113325229b91389b4a
[dragonfly.git] / contrib / gcc-4.7 / 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, 2012
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 ;; E -- print address with DImode register names if TARGET_64BIT.
42 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
43 ;; s -- print a shift double count, followed by the assemblers argument
44 ;;      delimiter.
45 ;; b -- print the QImode name of the register for the indicated operand.
46 ;;      %b0 would print %al if operands[0] is reg 0.
47 ;; w --  likewise, print the HImode name of the register.
48 ;; k --  likewise, print the SImode name of the register.
49 ;; q --  likewise, print the DImode name of the register.
50 ;; x --  likewise, print the V4SFmode name of the register.
51 ;; t --  likewise, print the V8SFmode name of the register.
52 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
53 ;; y -- print "st(0)" instead of "st" as a register.
54 ;; d -- print duplicated register operand for AVX instruction.
55 ;; D -- print condition for SSE cmp instruction.
56 ;; P -- if PIC, print an @PLT suffix.
57 ;; p -- print raw symbol name.
58 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
59 ;; & -- print some in-use local-dynamic symbol name.
60 ;; H -- print a memory address offset by 8; used for sse high-parts
61 ;; Y -- print condition for XOP pcom* instruction.
62 ;; + -- print a branch hint as 'cs' or 'ds' prefix
63 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
64 ;; @ -- print a segment register of thread base pointer load
65
66 (define_c_enum "unspec" [
67   ;; Relocation specifiers
68   UNSPEC_GOT
69   UNSPEC_GOTOFF
70   UNSPEC_GOTPCREL
71   UNSPEC_GOTTPOFF
72   UNSPEC_TPOFF
73   UNSPEC_NTPOFF
74   UNSPEC_DTPOFF
75   UNSPEC_GOTNTPOFF
76   UNSPEC_INDNTPOFF
77   UNSPEC_PLTOFF
78   UNSPEC_MACHOPIC_OFFSET
79   UNSPEC_PCREL
80
81   ;; Prologue support
82   UNSPEC_STACK_ALLOC
83   UNSPEC_SET_GOT
84   UNSPEC_SET_RIP
85   UNSPEC_SET_GOT_OFFSET
86   UNSPEC_MEMORY_BLOCKAGE
87   UNSPEC_STACK_CHECK
88
89   ;; TLS support
90   UNSPEC_TP
91   UNSPEC_TLS_GD
92   UNSPEC_TLS_LD_BASE
93   UNSPEC_TLSDESC
94   UNSPEC_TLS_IE_SUN
95
96   ;; Other random patterns
97   UNSPEC_SCAS
98   UNSPEC_FNSTSW
99   UNSPEC_SAHF
100   UNSPEC_PARITY
101   UNSPEC_FSTCW
102   UNSPEC_ADD_CARRY
103   UNSPEC_FLDCW
104   UNSPEC_REP
105   UNSPEC_LD_MPIC        ; load_macho_picbase
106   UNSPEC_TRUNC_NOOP
107   UNSPEC_DIV_ALREADY_SPLIT
108   UNSPEC_MS_TO_SYSV_CALL
109   UNSPEC_CALL_NEEDS_VZEROUPPER
110   UNSPEC_PAUSE
111   UNSPEC_LEA_ADDR
112
113   ;; For SSE/MMX support:
114   UNSPEC_FIX_NOTRUNC
115   UNSPEC_MASKMOV
116   UNSPEC_MOVMSK
117   UNSPEC_RCP
118   UNSPEC_RSQRT
119   UNSPEC_PSADBW
120
121   ;; Generic math support
122   UNSPEC_COPYSIGN
123   UNSPEC_IEEE_MIN       ; not commutative
124   UNSPEC_IEEE_MAX       ; not commutative
125
126   ;; x87 Floating point
127   UNSPEC_SIN
128   UNSPEC_COS
129   UNSPEC_FPATAN
130   UNSPEC_FYL2X
131   UNSPEC_FYL2XP1
132   UNSPEC_FRNDINT
133   UNSPEC_FIST
134   UNSPEC_F2XM1
135   UNSPEC_TAN
136   UNSPEC_FXAM
137
138   ;; x87 Rounding
139   UNSPEC_FRNDINT_FLOOR
140   UNSPEC_FRNDINT_CEIL
141   UNSPEC_FRNDINT_TRUNC
142   UNSPEC_FRNDINT_MASK_PM
143   UNSPEC_FIST_FLOOR
144   UNSPEC_FIST_CEIL
145
146   ;; x87 Double output FP
147   UNSPEC_SINCOS_COS
148   UNSPEC_SINCOS_SIN
149   UNSPEC_XTRACT_FRACT
150   UNSPEC_XTRACT_EXP
151   UNSPEC_FSCALE_FRACT
152   UNSPEC_FSCALE_EXP
153   UNSPEC_FPREM_F
154   UNSPEC_FPREM_U
155   UNSPEC_FPREM1_F
156   UNSPEC_FPREM1_U
157
158   UNSPEC_C2_FLAG
159   UNSPEC_FXAM_MEM
160
161   ;; SSP patterns
162   UNSPEC_SP_SET
163   UNSPEC_SP_TEST
164   UNSPEC_SP_TLS_SET
165   UNSPEC_SP_TLS_TEST
166
167   ;; For ROUND support
168   UNSPEC_ROUND
169
170   ;; For CRC32 support
171   UNSPEC_CRC32
172
173   ;; For BMI support
174   UNSPEC_BEXTR
175
176   ;; For BMI2 support
177   UNSPEC_PDEP
178   UNSPEC_PEXT
179 ])
180
181 (define_c_enum "unspecv" [
182   UNSPECV_BLOCKAGE
183   UNSPECV_STACK_PROBE
184   UNSPECV_PROBE_STACK_RANGE
185   UNSPECV_ALIGN
186   UNSPECV_PROLOGUE_USE
187   UNSPECV_SPLIT_STACK_RETURN
188   UNSPECV_CLD
189   UNSPECV_NOPS
190   UNSPECV_RDTSC
191   UNSPECV_RDTSCP
192   UNSPECV_RDPMC
193   UNSPECV_LLWP_INTRINSIC
194   UNSPECV_SLWP_INTRINSIC
195   UNSPECV_LWPVAL_INTRINSIC
196   UNSPECV_LWPINS_INTRINSIC
197   UNSPECV_RDFSBASE
198   UNSPECV_RDGSBASE
199   UNSPECV_WRFSBASE
200   UNSPECV_WRGSBASE
201
202   ;; For RDRAND support
203   UNSPECV_RDRAND
204 ])
205
206 ;; Constants to represent rounding modes in the ROUND instruction
207 (define_constants
208   [(ROUND_FLOOR                 0x1)
209    (ROUND_CEIL                  0x2)
210    (ROUND_TRUNC                 0x3)
211    (ROUND_MXCSR                 0x4)
212    (ROUND_NO_EXC                0x8)
213   ])
214
215 ;; Constants to represent pcomtrue/pcomfalse variants
216 (define_constants
217   [(PCOM_FALSE                  0)
218    (PCOM_TRUE                   1)
219    (COM_FALSE_S                 2)
220    (COM_FALSE_P                 3)
221    (COM_TRUE_S                  4)
222    (COM_TRUE_P                  5)
223   ])
224
225 ;; Constants used in the XOP pperm instruction
226 (define_constants
227   [(PPERM_SRC                   0x00)   /* copy source */
228    (PPERM_INVERT                0x20)   /* invert source */
229    (PPERM_REVERSE               0x40)   /* bit reverse source */
230    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
231    (PPERM_ZERO                  0x80)   /* all 0's */
232    (PPERM_ONES                  0xa0)   /* all 1's */
233    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
234    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
235    (PPERM_SRC1                  0x00)   /* use first source byte */
236    (PPERM_SRC2                  0x10)   /* use second source byte */
237    ])
238
239 ;; Registers by name.
240 (define_constants
241   [(AX_REG                       0)
242    (DX_REG                       1)
243    (CX_REG                       2)
244    (BX_REG                       3)
245    (SI_REG                       4)
246    (DI_REG                       5)
247    (BP_REG                       6)
248    (SP_REG                       7)
249    (ST0_REG                      8)
250    (ST1_REG                      9)
251    (ST2_REG                     10)
252    (ST3_REG                     11)
253    (ST4_REG                     12)
254    (ST5_REG                     13)
255    (ST6_REG                     14)
256    (ST7_REG                     15)
257    (FLAGS_REG                   17)
258    (FPSR_REG                    18)
259    (FPCR_REG                    19)
260    (XMM0_REG                    21)
261    (XMM1_REG                    22)
262    (XMM2_REG                    23)
263    (XMM3_REG                    24)
264    (XMM4_REG                    25)
265    (XMM5_REG                    26)
266    (XMM6_REG                    27)
267    (XMM7_REG                    28)
268    (MM0_REG                     29)
269    (MM1_REG                     30)
270    (MM2_REG                     31)
271    (MM3_REG                     32)
272    (MM4_REG                     33)
273    (MM5_REG                     34)
274    (MM6_REG                     35)
275    (MM7_REG                     36)
276    (R8_REG                      37)
277    (R9_REG                      38)
278    (R10_REG                     39)
279    (R11_REG                     40)
280    (R12_REG                     41)
281    (R13_REG                     42)
282    (XMM8_REG                    45)
283    (XMM9_REG                    46)
284    (XMM10_REG                   47)
285    (XMM11_REG                   48)
286    (XMM12_REG                   49)
287    (XMM13_REG                   50)
288    (XMM14_REG                   51)
289    (XMM15_REG                   52)
290   ])
291
292 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
293 ;; from i386.c.
294
295 ;; In C guard expressions, put expressions which may be compile-time
296 ;; constants first.  This allows for better optimization.  For
297 ;; example, write "TARGET_64BIT && reload_completed", not
298 ;; "reload_completed && TARGET_64BIT".
299
300 \f
301 ;; Processor type.
302 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
303                     atom,generic64,amdfam10,bdver1,bdver2,btver1"
304   (const (symbol_ref "ix86_schedule")))
305
306 ;; A basic instruction type.  Refinements due to arguments to be
307 ;; provided in other attributes.
308 (define_attr "type"
309   "other,multi,
310    alu,alu1,negnot,imov,imovx,lea,
311    incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
312    icmp,test,ibr,setcc,icmov,
313    push,pop,call,callv,leave,
314    str,bitmanip,
315    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
316    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
317    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
318    ssemuladd,sse4arg,lwp,
319    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
320   (const_string "other"))
321
322 ;; Main data type used by the insn
323 (define_attr "mode"
324   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
325   (const_string "unknown"))
326
327 ;; The CPU unit operations uses.
328 (define_attr "unit" "integer,i387,sse,mmx,unknown"
329   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
330            (const_string "i387")
331          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
332                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
333                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
334            (const_string "sse")
335          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
336            (const_string "mmx")
337          (eq_attr "type" "other")
338            (const_string "unknown")]
339          (const_string "integer")))
340
341 ;; The (bounding maximum) length of an instruction immediate.
342 (define_attr "length_immediate" ""
343   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
344                           bitmanip,imulx")
345            (const_int 0)
346          (eq_attr "unit" "i387,sse,mmx")
347            (const_int 0)
348          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
349                           rotate,rotatex,rotate1,imul,icmp,push,pop")
350            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
351          (eq_attr "type" "imov,test")
352            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
353          (eq_attr "type" "call")
354            (if_then_else (match_operand 0 "constant_call_address_operand" "")
355              (const_int 4)
356              (const_int 0))
357          (eq_attr "type" "callv")
358            (if_then_else (match_operand 1 "constant_call_address_operand" "")
359              (const_int 4)
360              (const_int 0))
361          ;; We don't know the size before shorten_branches.  Expect
362          ;; the instruction to fit for better scheduling.
363          (eq_attr "type" "ibr")
364            (const_int 1)
365          ]
366          (symbol_ref "/* Update immediate_length and other attributes! */
367                       gcc_unreachable (),1")))
368
369 ;; The (bounding maximum) length of an instruction address.
370 (define_attr "length_address" ""
371   (cond [(eq_attr "type" "str,other,multi,fxch")
372            (const_int 0)
373          (and (eq_attr "type" "call")
374               (match_operand 0 "constant_call_address_operand" ""))
375              (const_int 0)
376          (and (eq_attr "type" "callv")
377               (match_operand 1 "constant_call_address_operand" ""))
378              (const_int 0)
379          ]
380          (symbol_ref "ix86_attr_length_address_default (insn)")))
381
382 ;; Set when length prefix is used.
383 (define_attr "prefix_data16" ""
384   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
385            (const_int 0)
386          (eq_attr "mode" "HI")
387            (const_int 1)
388          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
389            (const_int 1)
390         ]
391         (const_int 0)))
392
393 ;; Set when string REP prefix is used.
394 (define_attr "prefix_rep" ""
395   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
396            (const_int 0)
397          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
398            (const_int 1)
399         ]
400         (const_int 0)))
401
402 ;; Set when 0f opcode prefix is used.
403 (define_attr "prefix_0f" ""
404   (if_then_else
405     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
406          (eq_attr "unit" "sse,mmx"))
407     (const_int 1)
408     (const_int 0)))
409
410 ;; Set when REX opcode prefix is used.
411 (define_attr "prefix_rex" ""
412   (cond [(not (match_test "TARGET_64BIT"))
413            (const_int 0)
414          (and (eq_attr "mode" "DI")
415               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
416                    (eq_attr "unit" "!mmx")))
417            (const_int 1)
418          (and (eq_attr "mode" "QI")
419               (match_test "x86_extended_QIreg_mentioned_p (insn)"))
420            (const_int 1)
421          (match_test "x86_extended_reg_mentioned_p (insn)")
422            (const_int 1)
423          (and (eq_attr "type" "imovx")
424               (match_operand:QI 1 "ext_QIreg_operand" ""))
425            (const_int 1)
426         ]
427         (const_int 0)))
428
429 ;; There are also additional prefixes in 3DNOW, SSSE3.
430 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
431 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
432 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
433 (define_attr "prefix_extra" ""
434   (cond [(eq_attr "type" "ssemuladd,sse4arg")
435            (const_int 2)
436          (eq_attr "type" "sseiadd1,ssecvt1")
437            (const_int 1)
438         ]
439         (const_int 0)))
440
441 ;; Prefix used: original, VEX or maybe VEX.
442 (define_attr "prefix" "orig,vex,maybe_vex"
443   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
444     (const_string "vex")
445     (const_string "orig")))
446
447 ;; VEX W bit is used.
448 (define_attr "prefix_vex_w" "" (const_int 0))
449
450 ;; The length of VEX prefix
451 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
452 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
453 ;; still prefix_0f 1, with prefix_extra 1.
454 (define_attr "length_vex" ""
455   (if_then_else (and (eq_attr "prefix_0f" "1")
456                      (eq_attr "prefix_extra" "0"))
457     (if_then_else (eq_attr "prefix_vex_w" "1")
458       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
459       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
460     (if_then_else (eq_attr "prefix_vex_w" "1")
461       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
462       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
463
464 ;; Set when modrm byte is used.
465 (define_attr "modrm" ""
466   (cond [(eq_attr "type" "str,leave")
467            (const_int 0)
468          (eq_attr "unit" "i387")
469            (const_int 0)
470          (and (eq_attr "type" "incdec")
471               (and (not (match_test "TARGET_64BIT"))
472                    (ior (match_operand:SI 1 "register_operand" "")
473                         (match_operand:HI 1 "register_operand" ""))))
474            (const_int 0)
475          (and (eq_attr "type" "push")
476               (not (match_operand 1 "memory_operand" "")))
477            (const_int 0)
478          (and (eq_attr "type" "pop")
479               (not (match_operand 0 "memory_operand" "")))
480            (const_int 0)
481          (and (eq_attr "type" "imov")
482               (and (not (eq_attr "mode" "DI"))
483                    (ior (and (match_operand 0 "register_operand" "")
484                              (match_operand 1 "immediate_operand" ""))
485                         (ior (and (match_operand 0 "ax_reg_operand" "")
486                                   (match_operand 1 "memory_displacement_only_operand" ""))
487                              (and (match_operand 0 "memory_displacement_only_operand" "")
488                                   (match_operand 1 "ax_reg_operand" ""))))))
489            (const_int 0)
490          (and (eq_attr "type" "call")
491               (match_operand 0 "constant_call_address_operand" ""))
492              (const_int 0)
493          (and (eq_attr "type" "callv")
494               (match_operand 1 "constant_call_address_operand" ""))
495              (const_int 0)
496          (and (eq_attr "type" "alu,alu1,icmp,test")
497               (match_operand 0 "ax_reg_operand" ""))
498              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
499          ]
500          (const_int 1)))
501
502 ;; The (bounding maximum) length of an instruction in bytes.
503 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
504 ;; Later we may want to split them and compute proper length as for
505 ;; other insns.
506 (define_attr "length" ""
507   (cond [(eq_attr "type" "other,multi,fistp,frndint")
508            (const_int 16)
509          (eq_attr "type" "fcmp")
510            (const_int 4)
511          (eq_attr "unit" "i387")
512            (plus (const_int 2)
513                  (plus (attr "prefix_data16")
514                        (attr "length_address")))
515          (ior (eq_attr "prefix" "vex")
516               (and (eq_attr "prefix" "maybe_vex")
517                    (match_test "TARGET_AVX")))
518            (plus (attr "length_vex")
519                  (plus (attr "length_immediate")
520                        (plus (attr "modrm")
521                              (attr "length_address"))))]
522          (plus (plus (attr "modrm")
523                      (plus (attr "prefix_0f")
524                            (plus (attr "prefix_rex")
525                                  (plus (attr "prefix_extra")
526                                        (const_int 1)))))
527                (plus (attr "prefix_rep")
528                      (plus (attr "prefix_data16")
529                            (plus (attr "length_immediate")
530                                  (attr "length_address")))))))
531
532 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
533 ;; `store' if there is a simple memory reference therein, or `unknown'
534 ;; if the instruction is complex.
535
536 (define_attr "memory" "none,load,store,both,unknown"
537   (cond [(eq_attr "type" "other,multi,str,lwp")
538            (const_string "unknown")
539          (eq_attr "type" "lea,fcmov,fpspc")
540            (const_string "none")
541          (eq_attr "type" "fistp,leave")
542            (const_string "both")
543          (eq_attr "type" "frndint")
544            (const_string "load")
545          (eq_attr "type" "push")
546            (if_then_else (match_operand 1 "memory_operand" "")
547              (const_string "both")
548              (const_string "store"))
549          (eq_attr "type" "pop")
550            (if_then_else (match_operand 0 "memory_operand" "")
551              (const_string "both")
552              (const_string "load"))
553          (eq_attr "type" "setcc")
554            (if_then_else (match_operand 0 "memory_operand" "")
555              (const_string "store")
556              (const_string "none"))
557          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
558            (if_then_else (ior (match_operand 0 "memory_operand" "")
559                               (match_operand 1 "memory_operand" ""))
560              (const_string "load")
561              (const_string "none"))
562          (eq_attr "type" "ibr")
563            (if_then_else (match_operand 0 "memory_operand" "")
564              (const_string "load")
565              (const_string "none"))
566          (eq_attr "type" "call")
567            (if_then_else (match_operand 0 "constant_call_address_operand" "")
568              (const_string "none")
569              (const_string "load"))
570          (eq_attr "type" "callv")
571            (if_then_else (match_operand 1 "constant_call_address_operand" "")
572              (const_string "none")
573              (const_string "load"))
574          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
575               (match_operand 1 "memory_operand" ""))
576            (const_string "both")
577          (and (match_operand 0 "memory_operand" "")
578               (match_operand 1 "memory_operand" ""))
579            (const_string "both")
580          (match_operand 0 "memory_operand" "")
581            (const_string "store")
582          (match_operand 1 "memory_operand" "")
583            (const_string "load")
584          (and (eq_attr "type"
585                  "!alu1,negnot,ishift1,
586                    imov,imovx,icmp,test,bitmanip,
587                    fmov,fcmp,fsgn,
588                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
589                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
590               (match_operand 2 "memory_operand" ""))
591            (const_string "load")
592          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
593               (match_operand 3 "memory_operand" ""))
594            (const_string "load")
595         ]
596         (const_string "none")))
597
598 ;; Indicates if an instruction has both an immediate and a displacement.
599
600 (define_attr "imm_disp" "false,true,unknown"
601   (cond [(eq_attr "type" "other,multi")
602            (const_string "unknown")
603          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
604               (and (match_operand 0 "memory_displacement_operand" "")
605                    (match_operand 1 "immediate_operand" "")))
606            (const_string "true")
607          (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
608               (and (match_operand 0 "memory_displacement_operand" "")
609                    (match_operand 2 "immediate_operand" "")))
610            (const_string "true")
611         ]
612         (const_string "false")))
613
614 ;; Indicates if an FP operation has an integer source.
615
616 (define_attr "fp_int_src" "false,true"
617   (const_string "false"))
618
619 ;; Defines rounding mode of an FP operation.
620
621 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
622   (const_string "any"))
623
624 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
625 (define_attr "use_carry" "0,1" (const_string "0"))
626
627 ;; Define attribute to indicate unaligned ssemov insns
628 (define_attr "movu" "0,1" (const_string "0"))
629
630 ;; Used to control the "enabled" attribute on a per-instruction basis.
631 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,
632                     bmi2,fma,fma4"
633   (const_string "base"))
634
635 (define_attr "enabled" ""
636   (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
637          (eq_attr "isa" "sse2_noavx")
638            (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
639          (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
640          (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
641          (eq_attr "isa" "sse4_noavx")
642            (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
643          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
644          (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
645          (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
646          (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
647          ;; Fma instruction selection has to be done based on
648          ;; register pressure. For generating fma4, a cost model
649          ;; based on register pressure is required. Till then,
650          ;; fma4 instruction is disabled for targets that implement
651          ;; both fma and fma4 instruction sets.
652          (eq_attr "isa" "fma4")
653            (symbol_ref "TARGET_FMA4 && !TARGET_FMA")
654         ]
655         (const_int 1)))
656
657 ;; Describe a user's asm statement.
658 (define_asm_attributes
659   [(set_attr "length" "128")
660    (set_attr "type" "multi")])
661
662 (define_code_iterator plusminus [plus minus])
663
664 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
665
666 ;; Base name for define_insn
667 (define_code_attr plusminus_insn
668   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
669    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
670
671 ;; Base name for insn mnemonic.
672 (define_code_attr plusminus_mnemonic
673   [(plus "add") (ss_plus "adds") (us_plus "addus")
674    (minus "sub") (ss_minus "subs") (us_minus "subus")])
675 (define_code_attr plusminus_carry_mnemonic
676   [(plus "adc") (minus "sbb")])
677
678 ;; Mark commutative operators as such in constraints.
679 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
680                         (minus "") (ss_minus "") (us_minus "")])
681
682 ;; Mapping of max and min
683 (define_code_iterator maxmin [smax smin umax umin])
684
685 ;; Mapping of signed max and min
686 (define_code_iterator smaxmin [smax smin])
687
688 ;; Mapping of unsigned max and min
689 (define_code_iterator umaxmin [umax umin])
690
691 ;; Base name for integer and FP insn mnemonic
692 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
693                               (umax "maxu") (umin "minu")])
694 (define_code_attr maxmin_float [(smax "max") (smin "min")])
695
696 ;; Mapping of logic operators
697 (define_code_iterator any_logic [and ior xor])
698 (define_code_iterator any_or [ior xor])
699
700 ;; Base name for insn mnemonic.
701 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
702
703 ;; Mapping of logic-shift operators
704 (define_code_iterator any_lshift [ashift lshiftrt])
705
706 ;; Mapping of shift-right operators
707 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
708
709 ;; Base name for define_insn
710 (define_code_attr shift_insn
711   [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
712
713 ;; Base name for insn mnemonic.
714 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
715 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
716
717 ;; Mapping of rotate operators
718 (define_code_iterator any_rotate [rotate rotatert])
719
720 ;; Base name for define_insn
721 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
722
723 ;; Base name for insn mnemonic.
724 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
725
726 ;; Mapping of abs neg operators
727 (define_code_iterator absneg [abs neg])
728
729 ;; Base name for x87 insn mnemonic.
730 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
731
732 ;; Used in signed and unsigned widening multiplications.
733 (define_code_iterator any_extend [sign_extend zero_extend])
734
735 ;; Prefix for insn menmonic.
736 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
737
738 ;; Prefix for define_insn
739 (define_code_attr u [(sign_extend "") (zero_extend "u")])
740 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
741
742 ;; All integer modes.
743 (define_mode_iterator SWI1248x [QI HI SI DI])
744
745 ;; All integer modes without QImode.
746 (define_mode_iterator SWI248x [HI SI DI])
747
748 ;; All integer modes without QImode and HImode.
749 (define_mode_iterator SWI48x [SI DI])
750
751 ;; All integer modes without SImode and DImode.
752 (define_mode_iterator SWI12 [QI HI])
753
754 ;; All integer modes without DImode.
755 (define_mode_iterator SWI124 [QI HI SI])
756
757 ;; All integer modes without QImode and DImode.
758 (define_mode_iterator SWI24 [HI SI])
759
760 ;; Single word integer modes.
761 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
762
763 ;; Single word integer modes without QImode.
764 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
765
766 ;; Single word integer modes without QImode and HImode.
767 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
768
769 ;; All math-dependant single and double word integer modes.
770 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
771                              (HI "TARGET_HIMODE_MATH")
772                              SI DI (TI "TARGET_64BIT")])
773
774 ;; Math-dependant single word integer modes.
775 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
776                             (HI "TARGET_HIMODE_MATH")
777                             SI (DI "TARGET_64BIT")])
778
779 ;; Math-dependant integer modes without DImode.
780 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
781                                (HI "TARGET_HIMODE_MATH")
782                                SI])
783
784 ;; Math-dependant single word integer modes without QImode.
785 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
786                                SI (DI "TARGET_64BIT")])
787
788 ;; Double word integer modes.
789 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
790                            (TI "TARGET_64BIT")])
791
792 ;; Double word integer modes as mode attribute.
793 (define_mode_attr DWI [(SI "DI") (DI "TI")])
794 (define_mode_attr dwi [(SI "di") (DI "ti")])
795
796 ;; Half mode for double word integer modes.
797 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
798                             (DI "TARGET_64BIT")])
799
800 ;; Instruction suffix for integer modes.
801 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
802
803 ;; Pointer size prefix for integer modes (Intel asm dialect)
804 (define_mode_attr iptrsize [(QI "BYTE")
805                             (HI "WORD")
806                             (SI "DWORD")
807                             (DI "QWORD")])
808
809 ;; Register class for integer modes.
810 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
811
812 ;; Immediate operand constraint for integer modes.
813 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
814
815 ;; General operand constraint for word modes.
816 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
817
818 ;; Immediate operand constraint for double integer modes.
819 (define_mode_attr di [(SI "nF") (DI "e")])
820
821 ;; Immediate operand constraint for shifts.
822 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
823
824 ;; General operand predicate for integer modes.
825 (define_mode_attr general_operand
826         [(QI "general_operand")
827          (HI "general_operand")
828          (SI "x86_64_general_operand")
829          (DI "x86_64_general_operand")
830          (TI "x86_64_general_operand")])
831
832 ;; General sign/zero extend operand predicate for integer modes.
833 (define_mode_attr general_szext_operand
834         [(QI "general_operand")
835          (HI "general_operand")
836          (SI "x86_64_szext_general_operand")
837          (DI "x86_64_szext_general_operand")])
838
839 ;; Immediate operand predicate for integer modes.
840 (define_mode_attr immediate_operand
841         [(QI "immediate_operand")
842          (HI "immediate_operand")
843          (SI "x86_64_immediate_operand")
844          (DI "x86_64_immediate_operand")])
845
846 ;; Nonmemory operand predicate for integer modes.
847 (define_mode_attr nonmemory_operand
848         [(QI "nonmemory_operand")
849          (HI "nonmemory_operand")
850          (SI "x86_64_nonmemory_operand")
851          (DI "x86_64_nonmemory_operand")])
852
853 ;; Operand predicate for shifts.
854 (define_mode_attr shift_operand
855         [(QI "nonimmediate_operand")
856          (HI "nonimmediate_operand")
857          (SI "nonimmediate_operand")
858          (DI "shiftdi_operand")
859          (TI "register_operand")])
860
861 ;; Operand predicate for shift argument.
862 (define_mode_attr shift_immediate_operand
863         [(QI "const_1_to_31_operand")
864          (HI "const_1_to_31_operand")
865          (SI "const_1_to_31_operand")
866          (DI "const_1_to_63_operand")])
867
868 ;; Input operand predicate for arithmetic left shifts.
869 (define_mode_attr ashl_input_operand
870         [(QI "nonimmediate_operand")
871          (HI "nonimmediate_operand")
872          (SI "nonimmediate_operand")
873          (DI "ashldi_input_operand")
874          (TI "reg_or_pm1_operand")])
875
876 ;; SSE and x87 SFmode and DFmode floating point modes
877 (define_mode_iterator MODEF [SF DF])
878
879 ;; All x87 floating point modes
880 (define_mode_iterator X87MODEF [SF DF XF])
881
882 ;; SSE instruction suffix for various modes
883 (define_mode_attr ssemodesuffix
884   [(SF "ss") (DF "sd")
885    (V8SF "ps") (V4DF "pd")
886    (V4SF "ps") (V2DF "pd")
887    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
888    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
889
890 ;; SSE vector suffix for floating point modes
891 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
892
893 ;; SSE vector mode corresponding to a scalar mode
894 (define_mode_attr ssevecmode
895   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
896
897 ;; Instruction suffix for REX 64bit operators.
898 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
899
900 ;; This mode iterator allows :P to be used for patterns that operate on
901 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
902 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
903
904 ;; This mode iterator allows :PTR to be used for patterns that operate on
905 ;; ptr_mode sized quantities.
906 (define_mode_iterator PTR
907   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
908 \f
909 ;; Scheduling descriptions
910
911 (include "pentium.md")
912 (include "ppro.md")
913 (include "k6.md")
914 (include "athlon.md")
915 (include "bdver1.md")
916 (include "geode.md")
917 (include "atom.md")
918 (include "core2.md")
919
920 \f
921 ;; Operand and operator predicates and constraints
922
923 (include "predicates.md")
924 (include "constraints.md")
925
926 \f
927 ;; Compare and branch/compare and store instructions.
928
929 (define_expand "cbranch<mode>4"
930   [(set (reg:CC FLAGS_REG)
931         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
932                     (match_operand:SDWIM 2 "<general_operand>" "")))
933    (set (pc) (if_then_else
934                (match_operator 0 "ordered_comparison_operator"
935                 [(reg:CC FLAGS_REG) (const_int 0)])
936                (label_ref (match_operand 3 "" ""))
937                (pc)))]
938   ""
939 {
940   if (MEM_P (operands[1]) && MEM_P (operands[2]))
941     operands[1] = force_reg (<MODE>mode, operands[1]);
942   ix86_expand_branch (GET_CODE (operands[0]),
943                       operands[1], operands[2], operands[3]);
944   DONE;
945 })
946
947 (define_expand "cstore<mode>4"
948   [(set (reg:CC FLAGS_REG)
949         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
950                     (match_operand:SWIM 3 "<general_operand>" "")))
951    (set (match_operand:QI 0 "register_operand" "")
952         (match_operator 1 "ordered_comparison_operator"
953           [(reg:CC FLAGS_REG) (const_int 0)]))]
954   ""
955 {
956   if (MEM_P (operands[2]) && MEM_P (operands[3]))
957     operands[2] = force_reg (<MODE>mode, operands[2]);
958   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
959                      operands[2], operands[3]);
960   DONE;
961 })
962
963 (define_expand "cmp<mode>_1"
964   [(set (reg:CC FLAGS_REG)
965         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
966                     (match_operand:SWI48 1 "<general_operand>" "")))])
967
968 (define_insn "*cmp<mode>_ccno_1"
969   [(set (reg FLAGS_REG)
970         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
971                  (match_operand:SWI 1 "const0_operand" "")))]
972   "ix86_match_ccmode (insn, CCNOmode)"
973   "@
974    test{<imodesuffix>}\t%0, %0
975    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
976   [(set_attr "type" "test,icmp")
977    (set_attr "length_immediate" "0,1")
978    (set_attr "mode" "<MODE>")])
979
980 (define_insn "*cmp<mode>_1"
981   [(set (reg FLAGS_REG)
982         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
983                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
984   "ix86_match_ccmode (insn, CCmode)"
985   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
986   [(set_attr "type" "icmp")
987    (set_attr "mode" "<MODE>")])
988
989 (define_insn "*cmp<mode>_minus_1"
990   [(set (reg FLAGS_REG)
991         (compare
992           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
993                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
994           (const_int 0)))]
995   "ix86_match_ccmode (insn, CCGOCmode)"
996   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
997   [(set_attr "type" "icmp")
998    (set_attr "mode" "<MODE>")])
999
1000 (define_insn "*cmpqi_ext_1"
1001   [(set (reg FLAGS_REG)
1002         (compare
1003           (match_operand:QI 0 "general_operand" "Qm")
1004           (subreg:QI
1005             (zero_extract:SI
1006               (match_operand 1 "ext_register_operand" "Q")
1007               (const_int 8)
1008               (const_int 8)) 0)))]
1009   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1010   "cmp{b}\t{%h1, %0|%0, %h1}"
1011   [(set_attr "type" "icmp")
1012    (set_attr "mode" "QI")])
1013
1014 (define_insn "*cmpqi_ext_1_rex64"
1015   [(set (reg FLAGS_REG)
1016         (compare
1017           (match_operand:QI 0 "register_operand" "Q")
1018           (subreg:QI
1019             (zero_extract:SI
1020               (match_operand 1 "ext_register_operand" "Q")
1021               (const_int 8)
1022               (const_int 8)) 0)))]
1023   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1024   "cmp{b}\t{%h1, %0|%0, %h1}"
1025   [(set_attr "type" "icmp")
1026    (set_attr "mode" "QI")])
1027
1028 (define_insn "*cmpqi_ext_2"
1029   [(set (reg FLAGS_REG)
1030         (compare
1031           (subreg:QI
1032             (zero_extract:SI
1033               (match_operand 0 "ext_register_operand" "Q")
1034               (const_int 8)
1035               (const_int 8)) 0)
1036           (match_operand:QI 1 "const0_operand" "")))]
1037   "ix86_match_ccmode (insn, CCNOmode)"
1038   "test{b}\t%h0, %h0"
1039   [(set_attr "type" "test")
1040    (set_attr "length_immediate" "0")
1041    (set_attr "mode" "QI")])
1042
1043 (define_expand "cmpqi_ext_3"
1044   [(set (reg:CC FLAGS_REG)
1045         (compare:CC
1046           (subreg:QI
1047             (zero_extract:SI
1048               (match_operand 0 "ext_register_operand" "")
1049               (const_int 8)
1050               (const_int 8)) 0)
1051           (match_operand:QI 1 "immediate_operand" "")))])
1052
1053 (define_insn "*cmpqi_ext_3_insn"
1054   [(set (reg FLAGS_REG)
1055         (compare
1056           (subreg:QI
1057             (zero_extract:SI
1058               (match_operand 0 "ext_register_operand" "Q")
1059               (const_int 8)
1060               (const_int 8)) 0)
1061           (match_operand:QI 1 "general_operand" "Qmn")))]
1062   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1063   "cmp{b}\t{%1, %h0|%h0, %1}"
1064   [(set_attr "type" "icmp")
1065    (set_attr "modrm" "1")
1066    (set_attr "mode" "QI")])
1067
1068 (define_insn "*cmpqi_ext_3_insn_rex64"
1069   [(set (reg FLAGS_REG)
1070         (compare
1071           (subreg:QI
1072             (zero_extract:SI
1073               (match_operand 0 "ext_register_operand" "Q")
1074               (const_int 8)
1075               (const_int 8)) 0)
1076           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1077   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1078   "cmp{b}\t{%1, %h0|%h0, %1}"
1079   [(set_attr "type" "icmp")
1080    (set_attr "modrm" "1")
1081    (set_attr "mode" "QI")])
1082
1083 (define_insn "*cmpqi_ext_4"
1084   [(set (reg FLAGS_REG)
1085         (compare
1086           (subreg:QI
1087             (zero_extract:SI
1088               (match_operand 0 "ext_register_operand" "Q")
1089               (const_int 8)
1090               (const_int 8)) 0)
1091           (subreg:QI
1092             (zero_extract:SI
1093               (match_operand 1 "ext_register_operand" "Q")
1094               (const_int 8)
1095               (const_int 8)) 0)))]
1096   "ix86_match_ccmode (insn, CCmode)"
1097   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1098   [(set_attr "type" "icmp")
1099    (set_attr "mode" "QI")])
1100
1101 ;; These implement float point compares.
1102 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1103 ;; which would allow mix and match FP modes on the compares.  Which is what
1104 ;; the old patterns did, but with many more of them.
1105
1106 (define_expand "cbranchxf4"
1107   [(set (reg:CC FLAGS_REG)
1108         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1109                     (match_operand:XF 2 "nonmemory_operand" "")))
1110    (set (pc) (if_then_else
1111               (match_operator 0 "ix86_fp_comparison_operator"
1112                [(reg:CC FLAGS_REG)
1113                 (const_int 0)])
1114               (label_ref (match_operand 3 "" ""))
1115               (pc)))]
1116   "TARGET_80387"
1117 {
1118   ix86_expand_branch (GET_CODE (operands[0]),
1119                       operands[1], operands[2], operands[3]);
1120   DONE;
1121 })
1122
1123 (define_expand "cstorexf4"
1124   [(set (reg:CC FLAGS_REG)
1125         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1126                     (match_operand:XF 3 "nonmemory_operand" "")))
1127    (set (match_operand:QI 0 "register_operand" "")
1128               (match_operator 1 "ix86_fp_comparison_operator"
1129                [(reg:CC FLAGS_REG)
1130                 (const_int 0)]))]
1131   "TARGET_80387"
1132 {
1133   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1134                      operands[2], operands[3]);
1135   DONE;
1136 })
1137
1138 (define_expand "cbranch<mode>4"
1139   [(set (reg:CC FLAGS_REG)
1140         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1141                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1142    (set (pc) (if_then_else
1143               (match_operator 0 "ix86_fp_comparison_operator"
1144                [(reg:CC FLAGS_REG)
1145                 (const_int 0)])
1146               (label_ref (match_operand 3 "" ""))
1147               (pc)))]
1148   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1149 {
1150   ix86_expand_branch (GET_CODE (operands[0]),
1151                       operands[1], operands[2], operands[3]);
1152   DONE;
1153 })
1154
1155 (define_expand "cstore<mode>4"
1156   [(set (reg:CC FLAGS_REG)
1157         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1158                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1159    (set (match_operand:QI 0 "register_operand" "")
1160               (match_operator 1 "ix86_fp_comparison_operator"
1161                [(reg:CC FLAGS_REG)
1162                 (const_int 0)]))]
1163   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1164 {
1165   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1166                      operands[2], operands[3]);
1167   DONE;
1168 })
1169
1170 (define_expand "cbranchcc4"
1171   [(set (pc) (if_then_else
1172               (match_operator 0 "comparison_operator"
1173                [(match_operand 1 "flags_reg_operand" "")
1174                 (match_operand 2 "const0_operand" "")])
1175               (label_ref (match_operand 3 "" ""))
1176               (pc)))]
1177   ""
1178 {
1179   ix86_expand_branch (GET_CODE (operands[0]),
1180                       operands[1], operands[2], operands[3]);
1181   DONE;
1182 })
1183
1184 (define_expand "cstorecc4"
1185   [(set (match_operand:QI 0 "register_operand" "")
1186               (match_operator 1 "comparison_operator"
1187                [(match_operand 2 "flags_reg_operand" "")
1188                 (match_operand 3 "const0_operand" "")]))]
1189   ""
1190 {
1191   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1192                      operands[2], operands[3]);
1193   DONE;
1194 })
1195
1196
1197 ;; FP compares, step 1:
1198 ;; Set the FP condition codes.
1199 ;;
1200 ;; CCFPmode     compare with exceptions
1201 ;; CCFPUmode    compare with no exceptions
1202
1203 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1204 ;; used to manage the reg stack popping would not be preserved.
1205
1206 (define_insn "*cmpfp_0"
1207   [(set (match_operand:HI 0 "register_operand" "=a")
1208         (unspec:HI
1209           [(compare:CCFP
1210              (match_operand 1 "register_operand" "f")
1211              (match_operand 2 "const0_operand" ""))]
1212         UNSPEC_FNSTSW))]
1213   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1214    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1215   "* return output_fp_compare (insn, operands, false, false);"
1216   [(set_attr "type" "multi")
1217    (set_attr "unit" "i387")
1218    (set (attr "mode")
1219      (cond [(match_operand:SF 1 "" "")
1220               (const_string "SF")
1221             (match_operand:DF 1 "" "")
1222               (const_string "DF")
1223            ]
1224            (const_string "XF")))])
1225
1226 (define_insn_and_split "*cmpfp_0_cc"
1227   [(set (reg:CCFP FLAGS_REG)
1228         (compare:CCFP
1229           (match_operand 1 "register_operand" "f")
1230           (match_operand 2 "const0_operand" "")))
1231    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1232   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1233    && TARGET_SAHF && !TARGET_CMOVE
1234    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1235   "#"
1236   "&& reload_completed"
1237   [(set (match_dup 0)
1238         (unspec:HI
1239           [(compare:CCFP (match_dup 1)(match_dup 2))]
1240         UNSPEC_FNSTSW))
1241    (set (reg:CC FLAGS_REG)
1242         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1243   ""
1244   [(set_attr "type" "multi")
1245    (set_attr "unit" "i387")
1246    (set (attr "mode")
1247      (cond [(match_operand:SF 1 "" "")
1248               (const_string "SF")
1249             (match_operand:DF 1 "" "")
1250               (const_string "DF")
1251            ]
1252            (const_string "XF")))])
1253
1254 (define_insn "*cmpfp_xf"
1255   [(set (match_operand:HI 0 "register_operand" "=a")
1256         (unspec:HI
1257           [(compare:CCFP
1258              (match_operand:XF 1 "register_operand" "f")
1259              (match_operand:XF 2 "register_operand" "f"))]
1260           UNSPEC_FNSTSW))]
1261   "TARGET_80387"
1262   "* return output_fp_compare (insn, operands, false, false);"
1263   [(set_attr "type" "multi")
1264    (set_attr "unit" "i387")
1265    (set_attr "mode" "XF")])
1266
1267 (define_insn_and_split "*cmpfp_xf_cc"
1268   [(set (reg:CCFP FLAGS_REG)
1269         (compare:CCFP
1270           (match_operand:XF 1 "register_operand" "f")
1271           (match_operand:XF 2 "register_operand" "f")))
1272    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1273   "TARGET_80387
1274    && TARGET_SAHF && !TARGET_CMOVE"
1275   "#"
1276   "&& reload_completed"
1277   [(set (match_dup 0)
1278         (unspec:HI
1279           [(compare:CCFP (match_dup 1)(match_dup 2))]
1280         UNSPEC_FNSTSW))
1281    (set (reg:CC FLAGS_REG)
1282         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1283   ""
1284   [(set_attr "type" "multi")
1285    (set_attr "unit" "i387")
1286    (set_attr "mode" "XF")])
1287
1288 (define_insn "*cmpfp_<mode>"
1289   [(set (match_operand:HI 0 "register_operand" "=a")
1290         (unspec:HI
1291           [(compare:CCFP
1292              (match_operand:MODEF 1 "register_operand" "f")
1293              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1294           UNSPEC_FNSTSW))]
1295   "TARGET_80387"
1296   "* return output_fp_compare (insn, operands, false, false);"
1297   [(set_attr "type" "multi")
1298    (set_attr "unit" "i387")
1299    (set_attr "mode" "<MODE>")])
1300
1301 (define_insn_and_split "*cmpfp_<mode>_cc"
1302   [(set (reg:CCFP FLAGS_REG)
1303         (compare:CCFP
1304           (match_operand:MODEF 1 "register_operand" "f")
1305           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1306    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1307   "TARGET_80387
1308    && TARGET_SAHF && !TARGET_CMOVE"
1309   "#"
1310   "&& reload_completed"
1311   [(set (match_dup 0)
1312         (unspec:HI
1313           [(compare:CCFP (match_dup 1)(match_dup 2))]
1314         UNSPEC_FNSTSW))
1315    (set (reg:CC FLAGS_REG)
1316         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1317   ""
1318   [(set_attr "type" "multi")
1319    (set_attr "unit" "i387")
1320    (set_attr "mode" "<MODE>")])
1321
1322 (define_insn "*cmpfp_u"
1323   [(set (match_operand:HI 0 "register_operand" "=a")
1324         (unspec:HI
1325           [(compare:CCFPU
1326              (match_operand 1 "register_operand" "f")
1327              (match_operand 2 "register_operand" "f"))]
1328           UNSPEC_FNSTSW))]
1329   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1330    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1331   "* return output_fp_compare (insn, operands, false, true);"
1332   [(set_attr "type" "multi")
1333    (set_attr "unit" "i387")
1334    (set (attr "mode")
1335      (cond [(match_operand:SF 1 "" "")
1336               (const_string "SF")
1337             (match_operand:DF 1 "" "")
1338               (const_string "DF")
1339            ]
1340            (const_string "XF")))])
1341
1342 (define_insn_and_split "*cmpfp_u_cc"
1343   [(set (reg:CCFPU FLAGS_REG)
1344         (compare:CCFPU
1345           (match_operand 1 "register_operand" "f")
1346           (match_operand 2 "register_operand" "f")))
1347    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1348   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1349    && TARGET_SAHF && !TARGET_CMOVE
1350    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1351   "#"
1352   "&& reload_completed"
1353   [(set (match_dup 0)
1354         (unspec:HI
1355           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1356         UNSPEC_FNSTSW))
1357    (set (reg:CC FLAGS_REG)
1358         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1359   ""
1360   [(set_attr "type" "multi")
1361    (set_attr "unit" "i387")
1362    (set (attr "mode")
1363      (cond [(match_operand:SF 1 "" "")
1364               (const_string "SF")
1365             (match_operand:DF 1 "" "")
1366               (const_string "DF")
1367            ]
1368            (const_string "XF")))])
1369
1370 (define_insn "*cmpfp_<mode>"
1371   [(set (match_operand:HI 0 "register_operand" "=a")
1372         (unspec:HI
1373           [(compare:CCFP
1374              (match_operand 1 "register_operand" "f")
1375              (match_operator 3 "float_operator"
1376                [(match_operand:SWI24 2 "memory_operand" "m")]))]
1377           UNSPEC_FNSTSW))]
1378   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1379    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1380    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1381   "* return output_fp_compare (insn, operands, false, false);"
1382   [(set_attr "type" "multi")
1383    (set_attr "unit" "i387")
1384    (set_attr "fp_int_src" "true")
1385    (set_attr "mode" "<MODE>")])
1386
1387 (define_insn_and_split "*cmpfp_<mode>_cc"
1388   [(set (reg:CCFP FLAGS_REG)
1389         (compare:CCFP
1390           (match_operand 1 "register_operand" "f")
1391           (match_operator 3 "float_operator"
1392             [(match_operand:SWI24 2 "memory_operand" "m")])))
1393    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1394   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1395    && TARGET_SAHF && !TARGET_CMOVE
1396    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1397    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1398   "#"
1399   "&& reload_completed"
1400   [(set (match_dup 0)
1401         (unspec:HI
1402           [(compare:CCFP
1403              (match_dup 1)
1404              (match_op_dup 3 [(match_dup 2)]))]
1405         UNSPEC_FNSTSW))
1406    (set (reg:CC FLAGS_REG)
1407         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1408   ""
1409   [(set_attr "type" "multi")
1410    (set_attr "unit" "i387")
1411    (set_attr "fp_int_src" "true")
1412    (set_attr "mode" "<MODE>")])
1413
1414 ;; FP compares, step 2
1415 ;; Move the fpsw to ax.
1416
1417 (define_insn "x86_fnstsw_1"
1418   [(set (match_operand:HI 0 "register_operand" "=a")
1419         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1420   "TARGET_80387"
1421   "fnstsw\t%0"
1422   [(set (attr "length")
1423         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1424    (set_attr "mode" "SI")
1425    (set_attr "unit" "i387")])
1426
1427 ;; FP compares, step 3
1428 ;; Get ax into flags, general case.
1429
1430 (define_insn "x86_sahf_1"
1431   [(set (reg:CC FLAGS_REG)
1432         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1433                    UNSPEC_SAHF))]
1434   "TARGET_SAHF"
1435 {
1436 #ifndef HAVE_AS_IX86_SAHF
1437   if (TARGET_64BIT)
1438     return ASM_BYTE "0x9e";
1439   else
1440 #endif
1441   return "sahf";
1442 }
1443   [(set_attr "length" "1")
1444    (set_attr "athlon_decode" "vector")
1445    (set_attr "amdfam10_decode" "direct")
1446    (set_attr "bdver1_decode" "direct")
1447    (set_attr "mode" "SI")])
1448
1449 ;; Pentium Pro can do steps 1 through 3 in one go.
1450 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1451 ;; (these i387 instructions set flags directly)
1452 (define_insn "*cmpfp_i_mixed"
1453   [(set (reg:CCFP FLAGS_REG)
1454         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1455                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1456   "TARGET_MIX_SSE_I387
1457    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1458    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1459   "* return output_fp_compare (insn, operands, true, false);"
1460   [(set_attr "type" "fcmp,ssecomi")
1461    (set_attr "prefix" "orig,maybe_vex")
1462    (set (attr "mode")
1463      (if_then_else (match_operand:SF 1 "" "")
1464         (const_string "SF")
1465         (const_string "DF")))
1466    (set (attr "prefix_rep")
1467         (if_then_else (eq_attr "type" "ssecomi")
1468                       (const_string "0")
1469                       (const_string "*")))
1470    (set (attr "prefix_data16")
1471         (cond [(eq_attr "type" "fcmp")
1472                  (const_string "*")
1473                (eq_attr "mode" "DF")
1474                  (const_string "1")
1475               ]
1476               (const_string "0")))
1477    (set_attr "athlon_decode" "vector")
1478    (set_attr "amdfam10_decode" "direct")
1479    (set_attr "bdver1_decode" "double")])
1480
1481 (define_insn "*cmpfp_i_sse"
1482   [(set (reg:CCFP FLAGS_REG)
1483         (compare:CCFP (match_operand 0 "register_operand" "x")
1484                       (match_operand 1 "nonimmediate_operand" "xm")))]
1485   "TARGET_SSE_MATH
1486    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1487    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1488   "* return output_fp_compare (insn, operands, true, false);"
1489   [(set_attr "type" "ssecomi")
1490    (set_attr "prefix" "maybe_vex")
1491    (set (attr "mode")
1492      (if_then_else (match_operand:SF 1 "" "")
1493         (const_string "SF")
1494         (const_string "DF")))
1495    (set_attr "prefix_rep" "0")
1496    (set (attr "prefix_data16")
1497         (if_then_else (eq_attr "mode" "DF")
1498                       (const_string "1")
1499                       (const_string "0")))
1500    (set_attr "athlon_decode" "vector")
1501    (set_attr "amdfam10_decode" "direct")
1502    (set_attr "bdver1_decode" "double")])
1503
1504 (define_insn "*cmpfp_i_i387"
1505   [(set (reg:CCFP FLAGS_REG)
1506         (compare:CCFP (match_operand 0 "register_operand" "f")
1507                       (match_operand 1 "register_operand" "f")))]
1508   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1509    && TARGET_CMOVE
1510    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1511    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1512   "* return output_fp_compare (insn, operands, true, false);"
1513   [(set_attr "type" "fcmp")
1514    (set (attr "mode")
1515      (cond [(match_operand:SF 1 "" "")
1516               (const_string "SF")
1517             (match_operand:DF 1 "" "")
1518               (const_string "DF")
1519            ]
1520            (const_string "XF")))
1521    (set_attr "athlon_decode" "vector")
1522    (set_attr "amdfam10_decode" "direct")
1523    (set_attr "bdver1_decode" "double")])
1524
1525 (define_insn "*cmpfp_iu_mixed"
1526   [(set (reg:CCFPU FLAGS_REG)
1527         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1528                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1529   "TARGET_MIX_SSE_I387
1530    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1531    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1532   "* return output_fp_compare (insn, operands, true, true);"
1533   [(set_attr "type" "fcmp,ssecomi")
1534    (set_attr "prefix" "orig,maybe_vex")
1535    (set (attr "mode")
1536      (if_then_else (match_operand:SF 1 "" "")
1537         (const_string "SF")
1538         (const_string "DF")))
1539    (set (attr "prefix_rep")
1540         (if_then_else (eq_attr "type" "ssecomi")
1541                       (const_string "0")
1542                       (const_string "*")))
1543    (set (attr "prefix_data16")
1544         (cond [(eq_attr "type" "fcmp")
1545                  (const_string "*")
1546                (eq_attr "mode" "DF")
1547                  (const_string "1")
1548               ]
1549               (const_string "0")))
1550    (set_attr "athlon_decode" "vector")
1551    (set_attr "amdfam10_decode" "direct")
1552    (set_attr "bdver1_decode" "double")])
1553
1554 (define_insn "*cmpfp_iu_sse"
1555   [(set (reg:CCFPU FLAGS_REG)
1556         (compare:CCFPU (match_operand 0 "register_operand" "x")
1557                        (match_operand 1 "nonimmediate_operand" "xm")))]
1558   "TARGET_SSE_MATH
1559    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1560    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1561   "* return output_fp_compare (insn, operands, true, true);"
1562   [(set_attr "type" "ssecomi")
1563    (set_attr "prefix" "maybe_vex")
1564    (set (attr "mode")
1565      (if_then_else (match_operand:SF 1 "" "")
1566         (const_string "SF")
1567         (const_string "DF")))
1568    (set_attr "prefix_rep" "0")
1569    (set (attr "prefix_data16")
1570         (if_then_else (eq_attr "mode" "DF")
1571                       (const_string "1")
1572                       (const_string "0")))
1573    (set_attr "athlon_decode" "vector")
1574    (set_attr "amdfam10_decode" "direct")
1575    (set_attr "bdver1_decode" "double")])
1576
1577 (define_insn "*cmpfp_iu_387"
1578   [(set (reg:CCFPU FLAGS_REG)
1579         (compare:CCFPU (match_operand 0 "register_operand" "f")
1580                        (match_operand 1 "register_operand" "f")))]
1581   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1582    && TARGET_CMOVE
1583    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1584    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1585   "* return output_fp_compare (insn, operands, true, true);"
1586   [(set_attr "type" "fcmp")
1587    (set (attr "mode")
1588      (cond [(match_operand:SF 1 "" "")
1589               (const_string "SF")
1590             (match_operand:DF 1 "" "")
1591               (const_string "DF")
1592            ]
1593            (const_string "XF")))
1594    (set_attr "athlon_decode" "vector")
1595    (set_attr "amdfam10_decode" "direct")
1596    (set_attr "bdver1_decode" "direct")])
1597 \f
1598 ;; Push/pop instructions.
1599
1600 (define_insn "*push<mode>2"
1601   [(set (match_operand:DWI 0 "push_operand" "=<")
1602         (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1603   ""
1604   "#"
1605   [(set_attr "type" "multi")
1606    (set_attr "mode" "<MODE>")])
1607
1608 (define_split
1609   [(set (match_operand:TI 0 "push_operand" "")
1610         (match_operand:TI 1 "general_operand" ""))]
1611   "TARGET_64BIT && reload_completed
1612    && !SSE_REG_P (operands[1])"
1613   [(const_int 0)]
1614   "ix86_split_long_move (operands); DONE;")
1615
1616 (define_insn "*pushdi2_rex64"
1617   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1618         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1619   "TARGET_64BIT"
1620   "@
1621    push{q}\t%1
1622    #"
1623   [(set_attr "type" "push,multi")
1624    (set_attr "mode" "DI")])
1625
1626 ;; Convert impossible pushes of immediate to existing instructions.
1627 ;; First try to get scratch register and go through it.  In case this
1628 ;; fails, push sign extended lower part first and then overwrite
1629 ;; upper part by 32bit move.
1630 (define_peephole2
1631   [(match_scratch:DI 2 "r")
1632    (set (match_operand:DI 0 "push_operand" "")
1633         (match_operand:DI 1 "immediate_operand" ""))]
1634   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1635    && !x86_64_immediate_operand (operands[1], DImode)"
1636   [(set (match_dup 2) (match_dup 1))
1637    (set (match_dup 0) (match_dup 2))])
1638
1639 ;; We need to define this as both peepholer and splitter for case
1640 ;; peephole2 pass is not run.
1641 ;; "&& 1" is needed to keep it from matching the previous pattern.
1642 (define_peephole2
1643   [(set (match_operand:DI 0 "push_operand" "")
1644         (match_operand:DI 1 "immediate_operand" ""))]
1645   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1646    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1647   [(set (match_dup 0) (match_dup 1))
1648    (set (match_dup 2) (match_dup 3))]
1649 {
1650   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1651
1652   operands[1] = gen_lowpart (DImode, operands[2]);
1653   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1654                                                    GEN_INT (4)));
1655 })
1656
1657 (define_split
1658   [(set (match_operand:DI 0 "push_operand" "")
1659         (match_operand:DI 1 "immediate_operand" ""))]
1660   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1661                     ? epilogue_completed : reload_completed)
1662    && !symbolic_operand (operands[1], DImode)
1663    && !x86_64_immediate_operand (operands[1], DImode)"
1664   [(set (match_dup 0) (match_dup 1))
1665    (set (match_dup 2) (match_dup 3))]
1666 {
1667   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1668
1669   operands[1] = gen_lowpart (DImode, operands[2]);
1670   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1671                                                    GEN_INT (4)));
1672 })
1673
1674 (define_split
1675   [(set (match_operand:DI 0 "push_operand" "")
1676         (match_operand:DI 1 "general_operand" ""))]
1677   "!TARGET_64BIT && reload_completed
1678    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1679   [(const_int 0)]
1680   "ix86_split_long_move (operands); DONE;")
1681
1682 (define_insn "*pushsi2"
1683   [(set (match_operand:SI 0 "push_operand" "=<")
1684         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1685   "!TARGET_64BIT"
1686   "push{l}\t%1"
1687   [(set_attr "type" "push")
1688    (set_attr "mode" "SI")])
1689
1690 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1691 ;; "push a byte/word".  But actually we use pushl, which has the effect
1692 ;; of rounding the amount pushed up to a word.
1693
1694 ;; For TARGET_64BIT we always round up to 8 bytes.
1695 (define_insn "*push<mode>2_rex64"
1696   [(set (match_operand:SWI124 0 "push_operand" "=X")
1697         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1698   "TARGET_64BIT"
1699   "push{q}\t%q1"
1700   [(set_attr "type" "push")
1701    (set_attr "mode" "DI")])
1702
1703 (define_insn "*push<mode>2"
1704   [(set (match_operand:SWI12 0 "push_operand" "=X")
1705         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1706   "!TARGET_64BIT"
1707   "push{l}\t%k1"
1708   [(set_attr "type" "push")
1709    (set_attr "mode" "SI")])
1710
1711 (define_insn "*push<mode>2_prologue"
1712   [(set (match_operand:P 0 "push_operand" "=<")
1713         (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1714    (clobber (mem:BLK (scratch)))]
1715   ""
1716   "push{<imodesuffix>}\t%1"
1717   [(set_attr "type" "push")
1718    (set_attr "mode" "<MODE>")])
1719
1720 (define_insn "*pop<mode>1"
1721   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1722         (match_operand:P 1 "pop_operand" ">"))]
1723   ""
1724   "pop{<imodesuffix>}\t%0"
1725   [(set_attr "type" "pop")
1726    (set_attr "mode" "<MODE>")])
1727
1728 (define_insn "*pop<mode>1_epilogue"
1729   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1730         (match_operand:P 1 "pop_operand" ">"))
1731    (clobber (mem:BLK (scratch)))]
1732   ""
1733   "pop{<imodesuffix>}\t%0"
1734   [(set_attr "type" "pop")
1735    (set_attr "mode" "<MODE>")])
1736 \f
1737 ;; Move instructions.
1738
1739 (define_expand "movoi"
1740   [(set (match_operand:OI 0 "nonimmediate_operand" "")
1741         (match_operand:OI 1 "general_operand" ""))]
1742   "TARGET_AVX"
1743   "ix86_expand_move (OImode, operands); DONE;")
1744
1745 (define_expand "movti"
1746   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1747         (match_operand:TI 1 "nonimmediate_operand" ""))]
1748   "TARGET_64BIT || TARGET_SSE"
1749 {
1750   if (TARGET_64BIT)
1751     ix86_expand_move (TImode, operands);
1752   else if (push_operand (operands[0], TImode))
1753     ix86_expand_push (TImode, operands[1]);
1754   else
1755     ix86_expand_vector_move (TImode, operands);
1756   DONE;
1757 })
1758
1759 ;; This expands to what emit_move_complex would generate if we didn't
1760 ;; have a movti pattern.  Having this avoids problems with reload on
1761 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1762 ;; to have around all the time.
1763 (define_expand "movcdi"
1764   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1765         (match_operand:CDI 1 "general_operand" ""))]
1766   ""
1767 {
1768   if (push_operand (operands[0], CDImode))
1769     emit_move_complex_push (CDImode, operands[0], operands[1]);
1770   else
1771     emit_move_complex_parts (operands[0], operands[1]);
1772   DONE;
1773 })
1774
1775 (define_expand "mov<mode>"
1776   [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1777         (match_operand:SWI1248x 1 "general_operand" ""))]
1778   ""
1779   "ix86_expand_move (<MODE>mode, operands); DONE;")
1780
1781 (define_insn "*mov<mode>_xor"
1782   [(set (match_operand:SWI48 0 "register_operand" "=r")
1783         (match_operand:SWI48 1 "const0_operand" ""))
1784    (clobber (reg:CC FLAGS_REG))]
1785   "reload_completed"
1786   "xor{l}\t%k0, %k0"
1787   [(set_attr "type" "alu1")
1788    (set_attr "mode" "SI")
1789    (set_attr "length_immediate" "0")])
1790
1791 (define_insn "*mov<mode>_or"
1792   [(set (match_operand:SWI48 0 "register_operand" "=r")
1793         (match_operand:SWI48 1 "const_int_operand" ""))
1794    (clobber (reg:CC FLAGS_REG))]
1795   "reload_completed
1796    && operands[1] == constm1_rtx"
1797   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1798   [(set_attr "type" "alu1")
1799    (set_attr "mode" "<MODE>")
1800    (set_attr "length_immediate" "1")])
1801
1802 (define_insn "*movoi_internal_avx"
1803   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1804         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1805   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1806 {
1807   switch (which_alternative)
1808     {
1809     case 0:
1810       return standard_sse_constant_opcode (insn, operands[1]);
1811     case 1:
1812     case 2:
1813       if (misaligned_operand (operands[0], OImode)
1814           || misaligned_operand (operands[1], OImode))
1815         return "vmovdqu\t{%1, %0|%0, %1}";
1816       else
1817         return "vmovdqa\t{%1, %0|%0, %1}";
1818     default:
1819       gcc_unreachable ();
1820     }
1821 }
1822   [(set_attr "type" "sselog1,ssemov,ssemov")
1823    (set_attr "prefix" "vex")
1824    (set_attr "mode" "OI")])
1825
1826 (define_insn "*movti_internal_rex64"
1827   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1828         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1829   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1830 {
1831   switch (which_alternative)
1832     {
1833     case 0:
1834     case 1:
1835       return "#";
1836     case 2:
1837       return standard_sse_constant_opcode (insn, operands[1]);
1838     case 3:
1839     case 4:
1840       /* TDmode values are passed as TImode on the stack.  Moving them
1841          to stack may result in unaligned memory access.  */
1842       if (misaligned_operand (operands[0], TImode)
1843           || misaligned_operand (operands[1], TImode))
1844         {
1845           if (get_attr_mode (insn) == MODE_V4SF)
1846             return "%vmovups\t{%1, %0|%0, %1}";
1847           else
1848             return "%vmovdqu\t{%1, %0|%0, %1}";
1849         }
1850       else
1851         {
1852           if (get_attr_mode (insn) == MODE_V4SF)
1853             return "%vmovaps\t{%1, %0|%0, %1}";
1854           else
1855             return "%vmovdqa\t{%1, %0|%0, %1}";
1856         }
1857     default:
1858       gcc_unreachable ();
1859     }
1860 }
1861   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1862    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1863    (set (attr "mode")
1864         (cond [(eq_attr "alternative" "2,3")
1865                  (if_then_else
1866                    (match_test "optimize_function_for_size_p (cfun)")
1867                    (const_string "V4SF")
1868                    (const_string "TI"))
1869                (eq_attr "alternative" "4")
1870                  (if_then_else
1871                    (ior (match_test "TARGET_SSE_TYPELESS_STORES")
1872                         (match_test "optimize_function_for_size_p (cfun)"))
1873                    (const_string "V4SF")
1874                    (const_string "TI"))]
1875                (const_string "DI")))])
1876
1877 (define_split
1878   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1879         (match_operand:TI 1 "general_operand" ""))]
1880   "reload_completed
1881    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1882   [(const_int 0)]
1883   "ix86_split_long_move (operands); DONE;")
1884
1885 (define_insn "*movti_internal_sse"
1886   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1887         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1888   "TARGET_SSE && !TARGET_64BIT
1889    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1890 {
1891   switch (which_alternative)
1892     {
1893     case 0:
1894       return standard_sse_constant_opcode (insn, operands[1]);
1895     case 1:
1896     case 2:
1897       /* TDmode values are passed as TImode on the stack.  Moving them
1898          to stack may result in unaligned memory access.  */
1899       if (misaligned_operand (operands[0], TImode)
1900           || misaligned_operand (operands[1], TImode))
1901         {
1902           if (get_attr_mode (insn) == MODE_V4SF)
1903             return "%vmovups\t{%1, %0|%0, %1}";
1904           else
1905             return "%vmovdqu\t{%1, %0|%0, %1}";
1906         }
1907       else
1908         {
1909           if (get_attr_mode (insn) == MODE_V4SF)
1910             return "%vmovaps\t{%1, %0|%0, %1}";
1911           else
1912             return "%vmovdqa\t{%1, %0|%0, %1}";
1913         }
1914     default:
1915       gcc_unreachable ();
1916     }
1917 }
1918   [(set_attr "type" "sselog1,ssemov,ssemov")
1919    (set_attr "prefix" "maybe_vex")
1920    (set (attr "mode")
1921         (cond [(ior (not (match_test "TARGET_SSE2"))
1922                     (match_test "optimize_function_for_size_p (cfun)"))
1923                  (const_string "V4SF")
1924                (and (eq_attr "alternative" "2")
1925                     (match_test "TARGET_SSE_TYPELESS_STORES"))
1926                  (const_string "V4SF")]
1927               (const_string "TI")))])
1928
1929 (define_insn "*movdi_internal_rex64"
1930   [(set (match_operand:DI 0 "nonimmediate_operand"
1931           "=r,r  ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1932         (match_operand:DI 1 "general_operand"
1933           "Z ,rem,i,re,n ,C ,*y ,m  ,*Ym,r   ,C ,*x,*x,m ,*Yi,r   ,*Ym,*x"))]
1934   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1935 {
1936   switch (get_attr_type (insn))
1937     {
1938     case TYPE_SSECVT:
1939       if (SSE_REG_P (operands[0]))
1940         return "movq2dq\t{%1, %0|%0, %1}";
1941       else
1942         return "movdq2q\t{%1, %0|%0, %1}";
1943
1944     case TYPE_SSEMOV:
1945       if (get_attr_mode (insn) == MODE_TI)
1946         return "%vmovdqa\t{%1, %0|%0, %1}";
1947       /* Handle broken assemblers that require movd instead of movq.  */
1948       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1949         return "%vmovd\t{%1, %0|%0, %1}";
1950       else
1951         return "%vmovq\t{%1, %0|%0, %1}";
1952
1953     case TYPE_MMXMOV:
1954       /* Handle broken assemblers that require movd instead of movq.  */
1955       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1956         return "movd\t{%1, %0|%0, %1}";
1957       else
1958         return "movq\t{%1, %0|%0, %1}";
1959
1960     case TYPE_SSELOG1:
1961       return standard_sse_constant_opcode (insn, operands[1]);
1962
1963     case TYPE_MMX:
1964       return "pxor\t%0, %0";
1965
1966     case TYPE_MULTI:
1967       return "#";
1968
1969     case TYPE_LEA:
1970       return "lea{q}\t{%E1, %0|%0, %E1}";
1971
1972     default:
1973       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1974       if (get_attr_mode (insn) == MODE_SI)
1975         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1976       else if (which_alternative == 2)
1977         return "movabs{q}\t{%1, %0|%0, %1}";
1978       else if (ix86_use_lea_for_mov (insn, operands))
1979         return "lea{q}\t{%E1, %0|%0, %E1}";
1980       else
1981         return "mov{q}\t{%1, %0|%0, %1}";
1982     }
1983 }
1984   [(set (attr "type")
1985      (cond [(eq_attr "alternative" "4")
1986               (const_string "multi")
1987             (eq_attr "alternative" "5")
1988               (const_string "mmx")
1989             (eq_attr "alternative" "6,7,8,9")
1990               (const_string "mmxmov")
1991             (eq_attr "alternative" "10")
1992               (const_string "sselog1")
1993             (eq_attr "alternative" "11,12,13,14,15")
1994               (const_string "ssemov")
1995             (eq_attr "alternative" "16,17")
1996               (const_string "ssecvt")
1997             (match_operand 1 "pic_32bit_operand" "")
1998               (const_string "lea")
1999            ]
2000            (const_string "imov")))
2001    (set (attr "modrm")
2002      (if_then_else
2003        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2004          (const_string "0")
2005          (const_string "*")))
2006    (set (attr "length_immediate")
2007      (if_then_else
2008        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2009          (const_string "8")
2010          (const_string "*")))
2011    (set (attr "prefix_rex")
2012      (if_then_else (eq_attr "alternative" "8,9")
2013        (const_string "1")
2014        (const_string "*")))
2015    (set (attr "prefix_data16")
2016      (if_then_else (eq_attr "alternative" "11")
2017        (const_string "1")
2018        (const_string "*")))
2019    (set (attr "prefix")
2020      (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2021        (const_string "maybe_vex")
2022        (const_string "orig")))
2023    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2024
2025 ;; Reload patterns to support multi-word load/store
2026 ;; with non-offsetable address.
2027 (define_expand "reload_noff_store"
2028   [(parallel [(match_operand 0 "memory_operand" "=m")
2029               (match_operand 1 "register_operand" "r")
2030               (match_operand:DI 2 "register_operand" "=&r")])]
2031   "TARGET_64BIT"
2032 {
2033   rtx mem = operands[0];
2034   rtx addr = XEXP (mem, 0);
2035
2036   emit_move_insn (operands[2], addr);
2037   mem = replace_equiv_address_nv (mem, operands[2]);
2038
2039   emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2040   DONE;
2041 })
2042
2043 (define_expand "reload_noff_load"
2044   [(parallel [(match_operand 0 "register_operand" "=r")
2045               (match_operand 1 "memory_operand" "m")
2046               (match_operand:DI 2 "register_operand" "=r")])]
2047   "TARGET_64BIT"
2048 {
2049   rtx mem = operands[1];
2050   rtx addr = XEXP (mem, 0);
2051
2052   emit_move_insn (operands[2], addr);
2053   mem = replace_equiv_address_nv (mem, operands[2]);
2054
2055   emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2056   DONE;
2057 })
2058
2059 ;; Convert impossible stores of immediate to existing instructions.
2060 ;; First try to get scratch register and go through it.  In case this
2061 ;; fails, move by 32bit parts.
2062 (define_peephole2
2063   [(match_scratch:DI 2 "r")
2064    (set (match_operand:DI 0 "memory_operand" "")
2065         (match_operand:DI 1 "immediate_operand" ""))]
2066   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2067    && !x86_64_immediate_operand (operands[1], DImode)"
2068   [(set (match_dup 2) (match_dup 1))
2069    (set (match_dup 0) (match_dup 2))])
2070
2071 ;; We need to define this as both peepholer and splitter for case
2072 ;; peephole2 pass is not run.
2073 ;; "&& 1" is needed to keep it from matching the previous pattern.
2074 (define_peephole2
2075   [(set (match_operand:DI 0 "memory_operand" "")
2076         (match_operand:DI 1 "immediate_operand" ""))]
2077   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2078    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2079   [(set (match_dup 2) (match_dup 3))
2080    (set (match_dup 4) (match_dup 5))]
2081   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2082
2083 (define_split
2084   [(set (match_operand:DI 0 "memory_operand" "")
2085         (match_operand:DI 1 "immediate_operand" ""))]
2086   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2087                     ? epilogue_completed : reload_completed)
2088    && !symbolic_operand (operands[1], DImode)
2089    && !x86_64_immediate_operand (operands[1], DImode)"
2090   [(set (match_dup 2) (match_dup 3))
2091    (set (match_dup 4) (match_dup 5))]
2092   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2093
2094 (define_insn "*movdi_internal"
2095   [(set (match_operand:DI 0 "nonimmediate_operand"
2096           "=r  ,o  ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2097         (match_operand:DI 1 "general_operand"
2098           "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2099   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2100 {
2101   switch (get_attr_type (insn))
2102     {
2103     case TYPE_SSECVT:
2104       if (SSE_REG_P (operands[0]))
2105         return "movq2dq\t{%1, %0|%0, %1}";
2106       else
2107         return "movdq2q\t{%1, %0|%0, %1}";
2108
2109     case TYPE_SSEMOV:
2110       switch (get_attr_mode (insn))
2111         {
2112         case MODE_TI:
2113           return "%vmovdqa\t{%1, %0|%0, %1}";
2114         case MODE_DI:
2115            return "%vmovq\t{%1, %0|%0, %1}";
2116         case MODE_V4SF:
2117           return "movaps\t{%1, %0|%0, %1}";
2118         case MODE_V2SF:
2119           return "movlps\t{%1, %0|%0, %1}";
2120         default:
2121           gcc_unreachable ();
2122         }
2123
2124     case TYPE_MMXMOV:
2125       return "movq\t{%1, %0|%0, %1}";
2126
2127     case TYPE_SSELOG1:
2128       return standard_sse_constant_opcode (insn, operands[1]);
2129
2130     case TYPE_MMX:
2131       return "pxor\t%0, %0";
2132
2133     case TYPE_MULTI:
2134       return "#";
2135
2136     default:
2137       gcc_unreachable ();
2138     }
2139 }
2140   [(set (attr "isa")
2141      (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2142               (const_string "sse2")
2143             (eq_attr "alternative" "9,10,11,12")
2144               (const_string "noavx")
2145            ]
2146            (const_string "*")))
2147    (set (attr "type")
2148      (cond [(eq_attr "alternative" "0,1")
2149               (const_string "multi")
2150             (eq_attr "alternative" "2")
2151               (const_string "mmx")
2152             (eq_attr "alternative" "3,4")
2153               (const_string "mmxmov")
2154             (eq_attr "alternative" "5,9")
2155               (const_string "sselog1")
2156             (eq_attr "alternative" "13,14")
2157               (const_string "ssecvt")
2158            ]
2159            (const_string "ssemov")))
2160    (set (attr "prefix")
2161      (if_then_else (eq_attr "alternative" "5,6,7,8")
2162        (const_string "maybe_vex")
2163        (const_string "orig")))
2164    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2165
2166 (define_split
2167   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2168         (match_operand:DI 1 "general_operand" ""))]
2169   "!TARGET_64BIT && reload_completed
2170    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2171    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2172   [(const_int 0)]
2173   "ix86_split_long_move (operands); DONE;")
2174
2175 (define_insn "*movsi_internal"
2176   [(set (match_operand:SI 0 "nonimmediate_operand"
2177                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2178         (match_operand:SI 1 "general_operand"
2179                         "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
2180   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2181 {
2182   switch (get_attr_type (insn))
2183     {
2184     case TYPE_SSELOG1:
2185       return standard_sse_constant_opcode (insn, operands[1]);
2186
2187     case TYPE_SSEMOV:
2188       switch (get_attr_mode (insn))
2189         {
2190         case MODE_TI:
2191           return "%vmovdqa\t{%1, %0|%0, %1}";
2192         case MODE_V4SF:
2193           return "%vmovaps\t{%1, %0|%0, %1}";
2194         case MODE_SI:
2195           return "%vmovd\t{%1, %0|%0, %1}";
2196         case MODE_SF:
2197           return "%vmovss\t{%1, %0|%0, %1}";
2198         default:
2199           gcc_unreachable ();
2200         }
2201
2202     case TYPE_MMX:
2203       return "pxor\t%0, %0";
2204
2205     case TYPE_MMXMOV:
2206       if (get_attr_mode (insn) == MODE_DI)
2207         return "movq\t{%1, %0|%0, %1}";
2208       return "movd\t{%1, %0|%0, %1}";
2209
2210     case TYPE_LEA:
2211       return "lea{l}\t{%E1, %0|%0, %E1}";
2212
2213     default:
2214       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2215       if (ix86_use_lea_for_mov (insn, operands))
2216         return "lea{l}\t{%E1, %0|%0, %E1}";
2217       else
2218         return "mov{l}\t{%1, %0|%0, %1}";
2219     }
2220 }
2221   [(set (attr "type")
2222      (cond [(eq_attr "alternative" "2")
2223               (const_string "mmx")
2224             (eq_attr "alternative" "3,4,5")
2225               (const_string "mmxmov")
2226             (eq_attr "alternative" "6")
2227               (const_string "sselog1")
2228             (eq_attr "alternative" "7,8,9,10,11")
2229               (const_string "ssemov")
2230             (match_operand 1 "pic_32bit_operand" "")
2231               (const_string "lea")
2232            ]
2233            (const_string "imov")))
2234    (set (attr "prefix")
2235      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2236        (const_string "orig")
2237        (const_string "maybe_vex")))
2238    (set (attr "prefix_data16")
2239      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2240        (const_string "1")
2241        (const_string "*")))
2242    (set (attr "mode")
2243      (cond [(eq_attr "alternative" "2,3")
2244               (const_string "DI")
2245             (eq_attr "alternative" "6,7")
2246               (if_then_else
2247                 (not (match_test "TARGET_SSE2"))
2248                 (const_string "V4SF")
2249                 (const_string "TI"))
2250             (and (eq_attr "alternative" "8,9,10,11")
2251                  (not (match_test "TARGET_SSE2")))
2252               (const_string "SF")
2253            ]
2254            (const_string "SI")))])
2255
2256 (define_insn "*movhi_internal"
2257   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2258         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2259   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2260 {
2261   switch (get_attr_type (insn))
2262     {
2263     case TYPE_IMOVX:
2264       /* movzwl is faster than movw on p2 due to partial word stalls,
2265          though not as fast as an aligned movl.  */
2266       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2267     default:
2268       if (get_attr_mode (insn) == MODE_SI)
2269         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2270       else
2271         return "mov{w}\t{%1, %0|%0, %1}";
2272     }
2273 }
2274   [(set (attr "type")
2275      (cond [(match_test "optimize_function_for_size_p (cfun)")
2276               (const_string "imov")
2277             (and (eq_attr "alternative" "0")
2278                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2279                       (not (match_test "TARGET_HIMODE_MATH"))))
2280               (const_string "imov")
2281             (and (eq_attr "alternative" "1,2")
2282                  (match_operand:HI 1 "aligned_operand" ""))
2283               (const_string "imov")
2284             (and (match_test "TARGET_MOVX")
2285                  (eq_attr "alternative" "0,2"))
2286               (const_string "imovx")
2287            ]
2288            (const_string "imov")))
2289     (set (attr "mode")
2290       (cond [(eq_attr "type" "imovx")
2291                (const_string "SI")
2292              (and (eq_attr "alternative" "1,2")
2293                   (match_operand:HI 1 "aligned_operand" ""))
2294                (const_string "SI")
2295              (and (eq_attr "alternative" "0")
2296                   (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2297                        (not (match_test "TARGET_HIMODE_MATH"))))
2298                (const_string "SI")
2299             ]
2300             (const_string "HI")))])
2301
2302 ;; Situation is quite tricky about when to choose full sized (SImode) move
2303 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2304 ;; partial register dependency machines (such as AMD Athlon), where QImode
2305 ;; moves issue extra dependency and for partial register stalls machines
2306 ;; that don't use QImode patterns (and QImode move cause stall on the next
2307 ;; instruction).
2308 ;;
2309 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2310 ;; register stall machines with, where we use QImode instructions, since
2311 ;; partial register stall can be caused there.  Then we use movzx.
2312 (define_insn "*movqi_internal"
2313   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2314         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2315   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2316 {
2317   switch (get_attr_type (insn))
2318     {
2319     case TYPE_IMOVX:
2320       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2321       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2322     default:
2323       if (get_attr_mode (insn) == MODE_SI)
2324         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2325       else
2326         return "mov{b}\t{%1, %0|%0, %1}";
2327     }
2328 }
2329   [(set (attr "type")
2330      (cond [(and (eq_attr "alternative" "5")
2331                  (not (match_operand:QI 1 "aligned_operand" "")))
2332               (const_string "imovx")
2333             (match_test "optimize_function_for_size_p (cfun)")
2334               (const_string "imov")
2335             (and (eq_attr "alternative" "3")
2336                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2337                       (not (match_test "TARGET_QIMODE_MATH"))))
2338               (const_string "imov")
2339             (eq_attr "alternative" "3,5")
2340               (const_string "imovx")
2341             (and (match_test "TARGET_MOVX")
2342                  (eq_attr "alternative" "2"))
2343               (const_string "imovx")
2344            ]
2345            (const_string "imov")))
2346    (set (attr "mode")
2347       (cond [(eq_attr "alternative" "3,4,5")
2348                (const_string "SI")
2349              (eq_attr "alternative" "6")
2350                (const_string "QI")
2351              (eq_attr "type" "imovx")
2352                (const_string "SI")
2353              (and (eq_attr "type" "imov")
2354                   (and (eq_attr "alternative" "0,1")
2355                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2356                             (and (not (match_test "optimize_function_for_size_p (cfun)"))
2357                                  (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2358                (const_string "SI")
2359              ;; Avoid partial register stalls when not using QImode arithmetic
2360              (and (eq_attr "type" "imov")
2361                   (and (eq_attr "alternative" "0,1")
2362                        (and (match_test "TARGET_PARTIAL_REG_STALL")
2363                             (not (match_test "TARGET_QIMODE_MATH")))))
2364                (const_string "SI")
2365            ]
2366            (const_string "QI")))])
2367
2368 ;; Stores and loads of ax to arbitrary constant address.
2369 ;; We fake an second form of instruction to force reload to load address
2370 ;; into register when rax is not available
2371 (define_insn "*movabs<mode>_1"
2372   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2373         (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2374   "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2375   "@
2376    movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2377    mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2378   [(set_attr "type" "imov")
2379    (set_attr "modrm" "0,*")
2380    (set_attr "length_address" "8,0")
2381    (set_attr "length_immediate" "0,*")
2382    (set_attr "memory" "store")
2383    (set_attr "mode" "<MODE>")])
2384
2385 (define_insn "*movabs<mode>_2"
2386   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2387         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2388   "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2389   "@
2390    movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2391    mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2392   [(set_attr "type" "imov")
2393    (set_attr "modrm" "0,*")
2394    (set_attr "length_address" "8,0")
2395    (set_attr "length_immediate" "0")
2396    (set_attr "memory" "load")
2397    (set_attr "mode" "<MODE>")])
2398
2399 (define_insn "*swap<mode>"
2400   [(set (match_operand:SWI48 0 "register_operand" "+r")
2401         (match_operand:SWI48 1 "register_operand" "+r"))
2402    (set (match_dup 1)
2403         (match_dup 0))]
2404   ""
2405   "xchg{<imodesuffix>}\t%1, %0"
2406   [(set_attr "type" "imov")
2407    (set_attr "mode" "<MODE>")
2408    (set_attr "pent_pair" "np")
2409    (set_attr "athlon_decode" "vector")
2410    (set_attr "amdfam10_decode" "double")
2411    (set_attr "bdver1_decode" "double")])
2412
2413 (define_insn "*swap<mode>_1"
2414   [(set (match_operand:SWI12 0 "register_operand" "+r")
2415         (match_operand:SWI12 1 "register_operand" "+r"))
2416    (set (match_dup 1)
2417         (match_dup 0))]
2418   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2419   "xchg{l}\t%k1, %k0"
2420   [(set_attr "type" "imov")
2421    (set_attr "mode" "SI")
2422    (set_attr "pent_pair" "np")
2423    (set_attr "athlon_decode" "vector")
2424    (set_attr "amdfam10_decode" "double")
2425    (set_attr "bdver1_decode" "double")])
2426
2427 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2428 ;; is disabled for AMDFAM10
2429 (define_insn "*swap<mode>_2"
2430   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2431         (match_operand:SWI12 1 "register_operand" "+<r>"))
2432    (set (match_dup 1)
2433         (match_dup 0))]
2434   "TARGET_PARTIAL_REG_STALL"
2435   "xchg{<imodesuffix>}\t%1, %0"
2436   [(set_attr "type" "imov")
2437    (set_attr "mode" "<MODE>")
2438    (set_attr "pent_pair" "np")
2439    (set_attr "athlon_decode" "vector")])
2440
2441 (define_expand "movstrict<mode>"
2442   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2443         (match_operand:SWI12 1 "general_operand" ""))]
2444   ""
2445 {
2446   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2447     FAIL;
2448   if (GET_CODE (operands[0]) == SUBREG
2449       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2450     FAIL;
2451   /* Don't generate memory->memory moves, go through a register */
2452   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2453     operands[1] = force_reg (<MODE>mode, operands[1]);
2454 })
2455
2456 (define_insn "*movstrict<mode>_1"
2457   [(set (strict_low_part
2458           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2459         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2460   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2461    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2462   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2463   [(set_attr "type" "imov")
2464    (set_attr "mode" "<MODE>")])
2465
2466 (define_insn "*movstrict<mode>_xor"
2467   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2468         (match_operand:SWI12 1 "const0_operand" ""))
2469    (clobber (reg:CC FLAGS_REG))]
2470   "reload_completed"
2471   "xor{<imodesuffix>}\t%0, %0"
2472   [(set_attr "type" "alu1")
2473    (set_attr "mode" "<MODE>")
2474    (set_attr "length_immediate" "0")])
2475
2476 (define_insn "*mov<mode>_extv_1"
2477   [(set (match_operand:SWI24 0 "register_operand" "=R")
2478         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2479                             (const_int 8)
2480                             (const_int 8)))]
2481   ""
2482   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2483   [(set_attr "type" "imovx")
2484    (set_attr "mode" "SI")])
2485
2486 (define_insn "*movqi_extv_1_rex64"
2487   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2488         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2489                          (const_int 8)
2490                          (const_int 8)))]
2491   "TARGET_64BIT"
2492 {
2493   switch (get_attr_type (insn))
2494     {
2495     case TYPE_IMOVX:
2496       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2497     default:
2498       return "mov{b}\t{%h1, %0|%0, %h1}";
2499     }
2500 }
2501   [(set (attr "type")
2502      (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2503                         (match_test "TARGET_MOVX"))
2504         (const_string "imovx")
2505         (const_string "imov")))
2506    (set (attr "mode")
2507      (if_then_else (eq_attr "type" "imovx")
2508         (const_string "SI")
2509         (const_string "QI")))])
2510
2511 (define_insn "*movqi_extv_1"
2512   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2513         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2514                          (const_int 8)
2515                          (const_int 8)))]
2516   "!TARGET_64BIT"
2517 {
2518   switch (get_attr_type (insn))
2519     {
2520     case TYPE_IMOVX:
2521       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2522     default:
2523       return "mov{b}\t{%h1, %0|%0, %h1}";
2524     }
2525 }
2526   [(set (attr "type")
2527      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2528                         (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2529                              (match_test "TARGET_MOVX")))
2530         (const_string "imovx")
2531         (const_string "imov")))
2532    (set (attr "mode")
2533      (if_then_else (eq_attr "type" "imovx")
2534         (const_string "SI")
2535         (const_string "QI")))])
2536
2537 (define_insn "*mov<mode>_extzv_1"
2538   [(set (match_operand:SWI48 0 "register_operand" "=R")
2539         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2540                             (const_int 8)
2541                             (const_int 8)))]
2542   ""
2543   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2544   [(set_attr "type" "imovx")
2545    (set_attr "mode" "SI")])
2546
2547 (define_insn "*movqi_extzv_2_rex64"
2548   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2549         (subreg:QI
2550           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2551                            (const_int 8)
2552                            (const_int 8)) 0))]
2553   "TARGET_64BIT"
2554 {
2555   switch (get_attr_type (insn))
2556     {
2557     case TYPE_IMOVX:
2558       return "movz{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_extzv_2"
2574   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2575         (subreg:QI
2576           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2577                            (const_int 8)
2578                            (const_int 8)) 0))]
2579   "!TARGET_64BIT"
2580 {
2581   switch (get_attr_type (insn))
2582     {
2583     case TYPE_IMOVX:
2584       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2585     default:
2586       return "mov{b}\t{%h1, %0|%0, %h1}";
2587     }
2588 }
2589   [(set (attr "type")
2590      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2591                         (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2592                              (match_test "TARGET_MOVX")))
2593         (const_string "imovx")
2594         (const_string "imov")))
2595    (set (attr "mode")
2596      (if_then_else (eq_attr "type" "imovx")
2597         (const_string "SI")
2598         (const_string "QI")))])
2599
2600 (define_expand "mov<mode>_insv_1"
2601   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2602                             (const_int 8)
2603                             (const_int 8))
2604         (match_operand:SWI48 1 "nonmemory_operand" ""))])
2605
2606 (define_insn "*mov<mode>_insv_1_rex64"
2607   [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2608                              (const_int 8)
2609                              (const_int 8))
2610         (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2611   "TARGET_64BIT"
2612 {
2613   if (CONST_INT_P (operands[1]))
2614     operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2615   return "mov{b}\t{%b1, %h0|%h0, %b1}";
2616 }
2617   [(set_attr "type" "imov")
2618    (set_attr "mode" "QI")])
2619
2620 (define_insn "*movsi_insv_1"
2621   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2622                          (const_int 8)
2623                          (const_int 8))
2624         (match_operand:SI 1 "general_operand" "Qmn"))]
2625   "!TARGET_64BIT"
2626 {
2627   if (CONST_INT_P (operands[1]))
2628     operands[1] = simplify_gen_subreg (QImode, operands[1], SImode, 0);
2629   return "mov{b}\t{%b1, %h0|%h0, %b1}";
2630 }
2631   [(set_attr "type" "imov")
2632    (set_attr "mode" "QI")])
2633
2634 (define_insn "*movqi_insv_2"
2635   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2636                          (const_int 8)
2637                          (const_int 8))
2638         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2639                      (const_int 8)))]
2640   ""
2641   "mov{b}\t{%h1, %h0|%h0, %h1}"
2642   [(set_attr "type" "imov")
2643    (set_attr "mode" "QI")])
2644 \f
2645 ;; Floating point push instructions.
2646
2647 (define_insn "*pushtf"
2648   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2649         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2650   "TARGET_SSE2"
2651 {
2652   /* This insn should be already split before reg-stack.  */
2653   gcc_unreachable ();
2654 }
2655   [(set_attr "type" "multi")
2656    (set_attr "unit" "sse,*,*")
2657    (set_attr "mode" "TF,SI,SI")])
2658
2659 ;; %%% Kill this when call knows how to work this out.
2660 (define_split
2661   [(set (match_operand:TF 0 "push_operand" "")
2662         (match_operand:TF 1 "sse_reg_operand" ""))]
2663   "TARGET_SSE2 && reload_completed"
2664   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2665    (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2666
2667 (define_insn "*pushxf"
2668   [(set (match_operand:XF 0 "push_operand" "=<,<")
2669         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2670   "optimize_function_for_speed_p (cfun)"
2671 {
2672   /* This insn should be already split before reg-stack.  */
2673   gcc_unreachable ();
2674 }
2675   [(set_attr "type" "multi")
2676    (set_attr "unit" "i387,*")
2677    (set_attr "mode" "XF,SI")])
2678
2679 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2680 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2681 ;; Pushing using integer instructions is longer except for constants
2682 ;; and direct memory references (assuming that any given constant is pushed
2683 ;; only once, but this ought to be handled elsewhere).
2684
2685 (define_insn "*pushxf_nointeger"
2686   [(set (match_operand:XF 0 "push_operand" "=<,<")
2687         (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2688   "optimize_function_for_size_p (cfun)"
2689 {
2690   /* This insn should be already split before reg-stack.  */
2691   gcc_unreachable ();
2692 }
2693   [(set_attr "type" "multi")
2694    (set_attr "unit" "i387,*")
2695    (set_attr "mode" "XF,SI")])
2696
2697 ;; %%% Kill this when call knows how to work this out.
2698 (define_split
2699   [(set (match_operand:XF 0 "push_operand" "")
2700         (match_operand:XF 1 "fp_register_operand" ""))]
2701   "reload_completed"
2702   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2703    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2704   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2705
2706 (define_insn "*pushdf_rex64"
2707   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2708         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2709   "TARGET_64BIT"
2710 {
2711   /* This insn should be already split before reg-stack.  */
2712   gcc_unreachable ();
2713 }
2714   [(set_attr "type" "multi")
2715    (set_attr "unit" "i387,*,*")
2716    (set_attr "mode" "DF,DI,DF")])
2717
2718 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2719 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2720 ;; On the average, pushdf using integers can be still shorter.
2721
2722 (define_insn "*pushdf"
2723   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2724         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2725   "!TARGET_64BIT"
2726 {
2727   /* This insn should be already split before reg-stack.  */
2728   gcc_unreachable ();
2729 }
2730   [(set_attr "isa" "*,*,sse2")
2731    (set_attr "type" "multi")
2732    (set_attr "unit" "i387,*,*")
2733    (set_attr "mode" "DF,DI,DF")])
2734
2735 ;; %%% Kill this when call knows how to work this out.
2736 (define_split
2737   [(set (match_operand:DF 0 "push_operand" "")
2738         (match_operand:DF 1 "any_fp_register_operand" ""))]
2739   "reload_completed"
2740   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2741    (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2742
2743 (define_insn "*pushsf_rex64"
2744   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2745         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2746   "TARGET_64BIT"
2747 {
2748   /* Anything else should be already split before reg-stack.  */
2749   gcc_assert (which_alternative == 1);
2750   return "push{q}\t%q1";
2751 }
2752   [(set_attr "type" "multi,push,multi")
2753    (set_attr "unit" "i387,*,*")
2754    (set_attr "mode" "SF,DI,SF")])
2755
2756 (define_insn "*pushsf"
2757   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2758         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2759   "!TARGET_64BIT"
2760 {
2761   /* Anything else should be already split before reg-stack.  */
2762   gcc_assert (which_alternative == 1);
2763   return "push{l}\t%1";
2764 }
2765   [(set_attr "type" "multi,push,multi")
2766    (set_attr "unit" "i387,*,*")
2767    (set_attr "mode" "SF,SI,SF")])
2768
2769 ;; %%% Kill this when call knows how to work this out.
2770 (define_split
2771   [(set (match_operand:SF 0 "push_operand" "")
2772         (match_operand:SF 1 "any_fp_register_operand" ""))]
2773   "reload_completed"
2774   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2775    (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2776   "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2777
2778 (define_split
2779   [(set (match_operand:SF 0 "push_operand" "")
2780         (match_operand:SF 1 "memory_operand" ""))]
2781   "reload_completed
2782    && (operands[2] = find_constant_src (insn))"
2783   [(set (match_dup 0) (match_dup 2))])
2784
2785 (define_split
2786   [(set (match_operand 0 "push_operand" "")
2787         (match_operand 1 "general_operand" ""))]
2788   "reload_completed
2789    && (GET_MODE (operands[0]) == TFmode
2790        || GET_MODE (operands[0]) == XFmode
2791        || GET_MODE (operands[0]) == DFmode)
2792    && !ANY_FP_REG_P (operands[1])"
2793   [(const_int 0)]
2794   "ix86_split_long_move (operands); DONE;")
2795 \f
2796 ;; Floating point move instructions.
2797
2798 (define_expand "movtf"
2799   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2800         (match_operand:TF 1 "nonimmediate_operand" ""))]
2801   "TARGET_SSE2"
2802 {
2803   ix86_expand_move (TFmode, operands);
2804   DONE;
2805 })
2806
2807 (define_expand "mov<mode>"
2808   [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2809         (match_operand:X87MODEF 1 "general_operand" ""))]
2810   ""
2811   "ix86_expand_move (<MODE>mode, operands); DONE;")
2812
2813 (define_insn "*movtf_internal"
2814   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2815         (match_operand:TF 1 "general_operand"      "xm,x,C,*roF,F*r"))]
2816   "TARGET_SSE2
2817    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2818    && (!can_create_pseudo_p ()
2819        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2820        || GET_CODE (operands[1]) != CONST_DOUBLE
2821        || (optimize_function_for_size_p (cfun)
2822            && standard_sse_constant_p (operands[1])
2823            && !memory_operand (operands[0], TFmode))
2824        || (!TARGET_MEMORY_MISMATCH_STALL
2825            && memory_operand (operands[0], TFmode)))"
2826 {
2827   switch (which_alternative)
2828     {
2829     case 0:
2830     case 1:
2831       /* Handle misaligned load/store since we
2832          don't have movmisaligntf pattern. */
2833       if (misaligned_operand (operands[0], TFmode)
2834           || misaligned_operand (operands[1], TFmode))
2835         {
2836           if (get_attr_mode (insn) == MODE_V4SF)
2837             return "%vmovups\t{%1, %0|%0, %1}";
2838           else
2839             return "%vmovdqu\t{%1, %0|%0, %1}";
2840         }
2841       else
2842         {
2843           if (get_attr_mode (insn) == MODE_V4SF)
2844             return "%vmovaps\t{%1, %0|%0, %1}";
2845           else
2846             return "%vmovdqa\t{%1, %0|%0, %1}";
2847         }
2848
2849     case 2:
2850       return standard_sse_constant_opcode (insn, operands[1]);
2851
2852     case 3:
2853     case 4:
2854         return "#";
2855
2856     default:
2857       gcc_unreachable ();
2858     }
2859 }
2860   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2861    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2862    (set (attr "mode")
2863         (cond [(eq_attr "alternative" "0,2")
2864                  (if_then_else
2865                    (match_test "optimize_function_for_size_p (cfun)")
2866                    (const_string "V4SF")
2867                    (const_string "TI"))
2868                (eq_attr "alternative" "1")
2869                  (if_then_else
2870                    (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2871                         (match_test "optimize_function_for_size_p (cfun)"))
2872                    (const_string "V4SF")
2873                    (const_string "TI"))]
2874                (const_string "DI")))])
2875
2876 ;; Possible store forwarding (partial memory) stall in alternative 4.
2877 (define_insn "*movxf_internal"
2878   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2879         (match_operand:XF 1 "general_operand"      "fm,f,G,Yx*roF,FYx*r"))]
2880   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2881    && (!can_create_pseudo_p ()
2882        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2883        || GET_CODE (operands[1]) != CONST_DOUBLE
2884        || (optimize_function_for_size_p (cfun)
2885            && standard_80387_constant_p (operands[1]) > 0
2886            && !memory_operand (operands[0], XFmode))
2887        || (!TARGET_MEMORY_MISMATCH_STALL
2888            && memory_operand (operands[0], XFmode)))"
2889 {
2890   switch (which_alternative)
2891     {
2892     case 0:
2893     case 1:
2894       return output_387_reg_move (insn, operands);
2895
2896     case 2:
2897       return standard_80387_constant_opcode (operands[1]);
2898
2899     case 3:
2900     case 4:
2901       return "#";
2902
2903     default:
2904       gcc_unreachable ();
2905     }
2906 }
2907   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2908    (set_attr "mode" "XF,XF,XF,SI,SI")])
2909
2910 (define_insn "*movdf_internal_rex64"
2911   [(set (match_operand:DF 0 "nonimmediate_operand"
2912                 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2913         (match_operand:DF 1 "general_operand"
2914                 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2915   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2916    && (!can_create_pseudo_p ()
2917        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2918        || GET_CODE (operands[1]) != CONST_DOUBLE
2919        || (optimize_function_for_size_p (cfun)
2920            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2921                 && standard_80387_constant_p (operands[1]) > 0)
2922                || (TARGET_SSE2 && TARGET_SSE_MATH
2923                    && standard_sse_constant_p (operands[1]))))
2924        || memory_operand (operands[0], DFmode))"
2925 {
2926   switch (which_alternative)
2927     {
2928     case 0:
2929     case 1:
2930       return output_387_reg_move (insn, operands);
2931
2932     case 2:
2933       return standard_80387_constant_opcode (operands[1]);
2934
2935     case 3:
2936     case 4:
2937       return "mov{q}\t{%1, %0|%0, %1}";
2938
2939     case 5:
2940       return "movabs{q}\t{%1, %0|%0, %1}";
2941
2942     case 6:
2943       return "#";
2944
2945     case 7:
2946       return standard_sse_constant_opcode (insn, operands[1]);
2947
2948     case 8:
2949     case 9:
2950     case 10:
2951       switch (get_attr_mode (insn))
2952         {
2953         case MODE_V2DF:
2954           if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2955             return "%vmovapd\t{%1, %0|%0, %1}";
2956         case MODE_V4SF:
2957           return "%vmovaps\t{%1, %0|%0, %1}";
2958
2959         case MODE_DI:
2960           return "%vmovq\t{%1, %0|%0, %1}";
2961         case MODE_DF:
2962           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2963             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2964           return "%vmovsd\t{%1, %0|%0, %1}";
2965         case MODE_V1DF:
2966           return "%vmovlpd\t{%1, %d0|%d0, %1}";
2967         case MODE_V2SF:
2968           return "%vmovlps\t{%1, %d0|%d0, %1}";
2969         default:
2970           gcc_unreachable ();
2971         }
2972
2973     case 11:
2974     case 12:
2975       /* Handle broken assemblers that require movd instead of movq.  */
2976       return "%vmovd\t{%1, %0|%0, %1}";
2977
2978     default:
2979       gcc_unreachable();
2980     }
2981 }
2982   [(set (attr "type")
2983         (cond [(eq_attr "alternative" "0,1,2")
2984                  (const_string "fmov")
2985                (eq_attr "alternative" "3,4,5")
2986                  (const_string "imov")
2987                (eq_attr "alternative" "6")
2988                  (const_string "multi")
2989                (eq_attr "alternative" "7")
2990                  (const_string "sselog1")
2991               ]
2992               (const_string "ssemov")))
2993    (set (attr "modrm")
2994      (if_then_else
2995        (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2996          (const_string "0")
2997          (const_string "*")))
2998    (set (attr "length_immediate")
2999      (if_then_else
3000        (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3001          (const_string "8")
3002          (const_string "*")))
3003    (set (attr "prefix")
3004      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3005        (const_string "orig")
3006        (const_string "maybe_vex")))
3007    (set (attr "prefix_data16")
3008      (if_then_else (eq_attr "mode" "V1DF")
3009        (const_string "1")
3010        (const_string "*")))
3011    (set (attr "mode")
3012         (cond [(eq_attr "alternative" "0,1,2")
3013                  (const_string "DF")
3014                (eq_attr "alternative" "3,4,5,6,11,12")
3015                  (const_string "DI")
3016
3017                /* xorps is one byte shorter.  */
3018                (eq_attr "alternative" "7")
3019                  (cond [(match_test "optimize_function_for_size_p (cfun)")
3020                           (const_string "V4SF")
3021                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3022                           (const_string "TI")
3023                        ]
3024                        (const_string "V2DF"))
3025
3026                /* For architectures resolving dependencies on
3027                   whole SSE registers use APD move to break dependency
3028                   chains, otherwise use short move to avoid extra work.
3029
3030                   movaps encodes one byte shorter.  */
3031                (eq_attr "alternative" "8")
3032                  (cond
3033                    [(match_test "optimize_function_for_size_p (cfun)")
3034                       (const_string "V4SF")
3035                     (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3036                       (const_string "V2DF")
3037                    ]
3038                    (const_string "DF"))
3039                /* For architectures resolving dependencies on register
3040                   parts we may avoid extra work to zero out upper part
3041                   of register.  */
3042                (eq_attr "alternative" "9")
3043                  (if_then_else
3044                    (match_test "TARGET_SSE_SPLIT_REGS")
3045                    (const_string "V1DF")
3046                    (const_string "DF"))
3047               ]
3048               (const_string "DF")))])
3049
3050 ;; Possible store forwarding (partial memory) stall in alternative 4.
3051 (define_insn "*movdf_internal"
3052   [(set (match_operand:DF 0 "nonimmediate_operand"
3053                 "=f,m,f,?Yd*r ,!o   ,x,x,x,m,*x,*x,*x,m")
3054         (match_operand:DF 1 "general_operand"
3055                 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3056   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3057    && (!can_create_pseudo_p ()
3058        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3059        || GET_CODE (operands[1]) != CONST_DOUBLE
3060        || (optimize_function_for_size_p (cfun)
3061            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3062                 && standard_80387_constant_p (operands[1]) > 0)
3063                || (TARGET_SSE2 && TARGET_SSE_MATH
3064                    && standard_sse_constant_p (operands[1])))
3065            && !memory_operand (operands[0], DFmode))
3066        || (!TARGET_MEMORY_MISMATCH_STALL
3067            && memory_operand (operands[0], DFmode)))"
3068 {
3069   switch (which_alternative)
3070     {
3071     case 0:
3072     case 1:
3073       return output_387_reg_move (insn, operands);
3074
3075     case 2:
3076       return standard_80387_constant_opcode (operands[1]);
3077
3078     case 3:
3079     case 4:
3080       return "#";
3081
3082     case 5:
3083     case 9:
3084       return standard_sse_constant_opcode (insn, operands[1]);
3085
3086     case 6:
3087     case 7:
3088     case 8:
3089     case 10:
3090     case 11:
3091     case 12:
3092       switch (get_attr_mode (insn))
3093         {
3094         case MODE_V2DF:
3095           if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3096             return "%vmovapd\t{%1, %0|%0, %1}";
3097         case MODE_V4SF:
3098           return "%vmovaps\t{%1, %0|%0, %1}";
3099
3100         case MODE_DI:
3101           return "%vmovq\t{%1, %0|%0, %1}";
3102         case MODE_DF:
3103           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3104             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3105           return "%vmovsd\t{%1, %0|%0, %1}";
3106         case MODE_V1DF:
3107           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3108         case MODE_V2SF:
3109           return "%vmovlps\t{%1, %d0|%d0, %1}";
3110         default:
3111           gcc_unreachable ();
3112         }
3113
3114     default:
3115       gcc_unreachable ();
3116     }
3117 }
3118   [(set (attr "isa")
3119      (if_then_else (eq_attr "alternative" "5,6,7,8")
3120        (const_string "sse2")
3121        (const_string "*")))
3122    (set (attr "type")
3123         (cond [(eq_attr "alternative" "0,1,2")
3124                  (const_string "fmov")
3125                (eq_attr "alternative" "3,4")
3126                  (const_string "multi")
3127                (eq_attr "alternative" "5,9")
3128                  (const_string "sselog1")
3129               ]
3130               (const_string "ssemov")))
3131    (set (attr "prefix")
3132      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3133        (const_string "orig")
3134        (const_string "maybe_vex")))
3135    (set (attr "prefix_data16")
3136      (if_then_else (eq_attr "mode" "V1DF")
3137        (const_string "1")
3138        (const_string "*")))
3139    (set (attr "mode")
3140         (cond [(eq_attr "alternative" "0,1,2")
3141                  (const_string "DF")
3142                (eq_attr "alternative" "3,4")
3143                  (const_string "SI")
3144
3145                /* For SSE1, we have many fewer alternatives.  */
3146                (not (match_test "TARGET_SSE2"))
3147                  (if_then_else
3148                    (eq_attr "alternative" "5,6,9,10")
3149                    (const_string "V4SF")
3150                    (const_string "V2SF"))
3151
3152                /* xorps is one byte shorter.  */
3153                (eq_attr "alternative" "5,9")
3154                  (cond [(match_test "optimize_function_for_size_p (cfun)")
3155                           (const_string "V4SF")
3156                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3157                           (const_string "TI")
3158                        ]
3159                        (const_string "V2DF"))
3160
3161                /* For architectures resolving dependencies on
3162                   whole SSE registers use APD move to break dependency
3163                   chains, otherwise use short move to avoid extra work.
3164
3165                   movaps encodes one byte shorter.  */
3166                (eq_attr "alternative" "6,10")
3167                  (cond
3168                    [(match_test "optimize_function_for_size_p (cfun)")
3169                       (const_string "V4SF")
3170                     (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3171                       (const_string "V2DF")
3172                    ]
3173                    (const_string "DF"))
3174                /* For architectures resolving dependencies on register
3175                   parts we may avoid extra work to zero out upper part
3176                   of register.  */
3177                (eq_attr "alternative" "7,11")
3178                  (if_then_else
3179                    (match_test "TARGET_SSE_SPLIT_REGS")
3180                    (const_string "V1DF")
3181                    (const_string "DF"))
3182               ]
3183               (const_string "DF")))])
3184
3185 (define_insn "*movsf_internal"
3186   [(set (match_operand:SF 0 "nonimmediate_operand"
3187           "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3188         (match_operand:SF 1 "general_operand"
3189           "fm,f,G,rmF,Fr,C,x,m,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
3190   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3191    && (!can_create_pseudo_p ()
3192        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3193        || GET_CODE (operands[1]) != CONST_DOUBLE
3194        || (optimize_function_for_size_p (cfun)
3195            && ((!TARGET_SSE_MATH
3196                 && standard_80387_constant_p (operands[1]) > 0)
3197                || (TARGET_SSE_MATH
3198                    && standard_sse_constant_p (operands[1]))))
3199        || memory_operand (operands[0], SFmode))"
3200 {
3201   switch (which_alternative)
3202     {
3203     case 0:
3204     case 1:
3205       return output_387_reg_move (insn, operands);
3206
3207     case 2:
3208       return standard_80387_constant_opcode (operands[1]);
3209
3210     case 3:
3211     case 4:
3212       return "mov{l}\t{%1, %0|%0, %1}";
3213
3214     case 5:
3215       return standard_sse_constant_opcode (insn, operands[1]);
3216
3217     case 6:
3218       if (get_attr_mode (insn) == MODE_V4SF)
3219         return "%vmovaps\t{%1, %0|%0, %1}";
3220       if (TARGET_AVX)
3221         return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3222
3223     case 7:
3224     case 8:
3225       return "%vmovss\t{%1, %0|%0, %1}";
3226
3227     case 9:
3228     case 10:
3229     case 14:
3230     case 15:
3231       return "movd\t{%1, %0|%0, %1}";
3232
3233     case 11:
3234       return "movq\t{%1, %0|%0, %1}";
3235
3236     case 12:
3237     case 13:
3238       return "%vmovd\t{%1, %0|%0, %1}";
3239
3240     default:
3241       gcc_unreachable ();
3242     }
3243 }
3244   [(set (attr "type")
3245         (cond [(eq_attr "alternative" "0,1,2")
3246                  (const_string "fmov")
3247                (eq_attr "alternative" "3,4")
3248                  (const_string "multi")
3249                (eq_attr "alternative" "5")
3250                  (const_string "sselog1")
3251                (eq_attr "alternative" "9,10,11,14,15")
3252                  (const_string "mmxmov")
3253               ]
3254               (const_string "ssemov")))
3255    (set (attr "prefix")
3256      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3257        (const_string "maybe_vex")
3258        (const_string "orig")))
3259    (set (attr "mode")
3260         (cond [(eq_attr "alternative" "3,4,9,10")
3261                  (const_string "SI")
3262                (eq_attr "alternative" "5")
3263                  (if_then_else
3264                    (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3265                              (match_test "TARGET_SSE2"))
3266                         (not (match_test "optimize_function_for_size_p (cfun)")))
3267                    (const_string "TI")
3268                    (const_string "V4SF"))
3269                /* For architectures resolving dependencies on
3270                   whole SSE registers use APS move to break dependency
3271                   chains, otherwise use short move to avoid extra work.
3272
3273                   Do the same for architectures resolving dependencies on
3274                   the parts.  While in DF mode it is better to always handle
3275                   just register parts, the SF mode is different due to lack
3276                   of instructions to load just part of the register.  It is
3277                   better to maintain the whole registers in single format
3278                   to avoid problems on using packed logical operations.  */
3279                (eq_attr "alternative" "6")
3280                  (if_then_else
3281                    (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3282                         (match_test "TARGET_SSE_SPLIT_REGS"))
3283                    (const_string "V4SF")
3284                    (const_string "SF"))
3285                (eq_attr "alternative" "11")
3286                  (const_string "DI")]
3287                (const_string "SF")))])
3288
3289 (define_split
3290   [(set (match_operand 0 "any_fp_register_operand" "")
3291         (match_operand 1 "memory_operand" ""))]
3292   "reload_completed
3293    && (GET_MODE (operands[0]) == TFmode
3294        || GET_MODE (operands[0]) == XFmode
3295        || GET_MODE (operands[0]) == DFmode
3296        || GET_MODE (operands[0]) == SFmode)
3297    && (operands[2] = find_constant_src (insn))"
3298   [(set (match_dup 0) (match_dup 2))]
3299 {
3300   rtx c = operands[2];
3301   int r = REGNO (operands[0]);
3302
3303   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3304       || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3305     FAIL;
3306 })
3307
3308 (define_split
3309   [(set (match_operand 0 "any_fp_register_operand" "")
3310         (float_extend (match_operand 1 "memory_operand" "")))]
3311   "reload_completed
3312    && (GET_MODE (operands[0]) == TFmode
3313        || GET_MODE (operands[0]) == XFmode
3314        || GET_MODE (operands[0]) == DFmode)
3315    && (operands[2] = find_constant_src (insn))"
3316   [(set (match_dup 0) (match_dup 2))]
3317 {
3318   rtx c = operands[2];
3319   int r = REGNO (operands[0]);
3320
3321   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3322       || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3323     FAIL;
3324 })
3325
3326 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3327 (define_split
3328   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3329         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3330   "reload_completed
3331    && (standard_80387_constant_p (operands[1]) == 8
3332        || standard_80387_constant_p (operands[1]) == 9)"
3333   [(set (match_dup 0)(match_dup 1))
3334    (set (match_dup 0)
3335         (neg:X87MODEF (match_dup 0)))]
3336 {
3337   REAL_VALUE_TYPE r;
3338
3339   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3340   if (real_isnegzero (&r))
3341     operands[1] = CONST0_RTX (<MODE>mode);
3342   else
3343     operands[1] = CONST1_RTX (<MODE>mode);
3344 })
3345
3346 (define_split
3347   [(set (match_operand 0 "nonimmediate_operand" "")
3348         (match_operand 1 "general_operand" ""))]
3349   "reload_completed
3350    && (GET_MODE (operands[0]) == TFmode
3351        || GET_MODE (operands[0]) == XFmode
3352        || GET_MODE (operands[0]) == DFmode)
3353    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3354   [(const_int 0)]
3355   "ix86_split_long_move (operands); DONE;")
3356
3357 (define_insn "swapxf"
3358   [(set (match_operand:XF 0 "register_operand" "+f")
3359         (match_operand:XF 1 "register_operand" "+f"))
3360    (set (match_dup 1)
3361         (match_dup 0))]
3362   "TARGET_80387"
3363 {
3364   if (STACK_TOP_P (operands[0]))
3365     return "fxch\t%1";
3366   else
3367     return "fxch\t%0";
3368 }
3369   [(set_attr "type" "fxch")
3370    (set_attr "mode" "XF")])
3371
3372 (define_insn "*swap<mode>"
3373   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3374         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3375    (set (match_dup 1)
3376         (match_dup 0))]
3377   "TARGET_80387 || reload_completed"
3378 {
3379   if (STACK_TOP_P (operands[0]))
3380     return "fxch\t%1";
3381   else
3382     return "fxch\t%0";
3383 }
3384   [(set_attr "type" "fxch")
3385    (set_attr "mode" "<MODE>")])
3386 \f
3387 ;; Zero extension instructions
3388
3389 (define_expand "zero_extendsidi2"
3390   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3391         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3392   ""
3393 {
3394   if (!TARGET_64BIT)
3395     {
3396       emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3397       DONE;
3398     }
3399 })
3400
3401 (define_insn "*zero_extendsidi2_rex64"
3402   [(set (match_operand:DI 0 "nonimmediate_operand"  "=r,o,?*Ym,?*y,?*Yi,*x")
3403         (zero_extend:DI
3404          (match_operand:SI 1 "nonimmediate_operand" "rm,0,r   ,m  ,r   ,m")))]
3405   "TARGET_64BIT"
3406   "@
3407    mov{l}\t{%1, %k0|%k0, %1}
3408    #
3409    movd\t{%1, %0|%0, %1}
3410    movd\t{%1, %0|%0, %1}
3411    %vmovd\t{%1, %0|%0, %1}
3412    %vmovd\t{%1, %0|%0, %1}"
3413   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3414    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3415    (set_attr "prefix_0f" "0,*,*,*,*,*")
3416    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3417
3418 (define_split
3419   [(set (match_operand:DI 0 "memory_operand" "")
3420         (zero_extend:DI (match_dup 0)))]
3421   "TARGET_64BIT"
3422   [(set (match_dup 4) (const_int 0))]
3423   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3424
3425 ;; %%% Kill me once multi-word ops are sane.
3426 (define_insn "zero_extendsidi2_1"
3427   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*x")
3428         (zero_extend:DI
3429          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3430    (clobber (reg:CC FLAGS_REG))]
3431   "!TARGET_64BIT"
3432   "@
3433    #
3434    #
3435    #
3436    movd\t{%1, %0|%0, %1}
3437    movd\t{%1, %0|%0, %1}
3438    %vmovd\t{%1, %0|%0, %1}
3439    %vmovd\t{%1, %0|%0, %1}"
3440   [(set_attr "isa" "*,*,*,*,*,*,sse2")
3441    (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3442    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3443    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3444
3445 (define_split
3446   [(set (match_operand:DI 0 "register_operand" "")
3447         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3448    (clobber (reg:CC FLAGS_REG))]
3449   "!TARGET_64BIT && reload_completed
3450    && true_regnum (operands[0]) == true_regnum (operands[1])"
3451   [(set (match_dup 4) (const_int 0))]
3452   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3453
3454 (define_split
3455   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3456         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3457    (clobber (reg:CC FLAGS_REG))]
3458   "!TARGET_64BIT && reload_completed
3459    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3460   [(set (match_dup 3) (match_dup 1))
3461    (set (match_dup 4) (const_int 0))]
3462   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3463
3464 (define_insn "zero_extend<mode>di2"
3465   [(set (match_operand:DI 0 "register_operand" "=r")
3466         (zero_extend:DI
3467          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3468   "TARGET_64BIT"
3469   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3470   [(set_attr "type" "imovx")
3471    (set_attr "mode" "SI")])
3472
3473 (define_expand "zero_extendhisi2"
3474   [(set (match_operand:SI 0 "register_operand" "")
3475         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3476   ""
3477 {
3478   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3479     {
3480       operands[1] = force_reg (HImode, operands[1]);
3481       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3482       DONE;
3483     }
3484 })
3485
3486 (define_insn_and_split "zero_extendhisi2_and"
3487   [(set (match_operand:SI 0 "register_operand" "=r")
3488         (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3489    (clobber (reg:CC FLAGS_REG))]
3490   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3491   "#"
3492   "&& reload_completed"
3493   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3494               (clobber (reg:CC FLAGS_REG))])]
3495   ""
3496   [(set_attr "type" "alu1")
3497    (set_attr "mode" "SI")])
3498
3499 (define_insn "*zero_extendhisi2_movzwl"
3500   [(set (match_operand:SI 0 "register_operand" "=r")
3501         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3502   "!TARGET_ZERO_EXTEND_WITH_AND
3503    || optimize_function_for_size_p (cfun)"
3504   "movz{wl|x}\t{%1, %0|%0, %1}"
3505   [(set_attr "type" "imovx")
3506    (set_attr "mode" "SI")])
3507
3508 (define_expand "zero_extendqi<mode>2"
3509   [(parallel
3510     [(set (match_operand:SWI24 0 "register_operand" "")
3511           (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3512      (clobber (reg:CC FLAGS_REG))])])
3513
3514 (define_insn "*zero_extendqi<mode>2_and"
3515   [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3516         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3517    (clobber (reg:CC FLAGS_REG))]
3518   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3519   "#"
3520   [(set_attr "type" "alu1")
3521    (set_attr "mode" "<MODE>")])
3522
3523 ;; When source and destination does not overlap, clear destination
3524 ;; first and then do the movb
3525 (define_split
3526   [(set (match_operand:SWI24 0 "register_operand" "")
3527         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3528    (clobber (reg:CC FLAGS_REG))]
3529   "reload_completed
3530    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3531    && ANY_QI_REG_P (operands[0])
3532    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3533    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3534   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3535 {
3536   operands[2] = gen_lowpart (QImode, operands[0]);
3537   ix86_expand_clear (operands[0]);
3538 })
3539
3540 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3541   [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3542         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3543    (clobber (reg:CC FLAGS_REG))]
3544   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3545   "#"
3546   [(set_attr "type" "imovx,alu1")
3547    (set_attr "mode" "<MODE>")])
3548
3549 ;; For the movzbl case strip only the clobber
3550 (define_split
3551   [(set (match_operand:SWI24 0 "register_operand" "")
3552         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3553    (clobber (reg:CC FLAGS_REG))]
3554   "reload_completed
3555    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3556    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3557   [(set (match_dup 0)
3558         (zero_extend:SWI24 (match_dup 1)))])
3559
3560 ; zero extend to SImode to avoid partial register stalls
3561 (define_insn "*zero_extendqi<mode>2_movzbl"
3562   [(set (match_operand:SWI24 0 "register_operand" "=r")
3563         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3564   "reload_completed
3565    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3566   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3567   [(set_attr "type" "imovx")
3568    (set_attr "mode" "SI")])
3569
3570 ;; Rest is handled by single and.
3571 (define_split
3572   [(set (match_operand:SWI24 0 "register_operand" "")
3573         (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3574    (clobber (reg:CC FLAGS_REG))]
3575   "reload_completed
3576    && true_regnum (operands[0]) == true_regnum (operands[1])"
3577   [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3578               (clobber (reg:CC FLAGS_REG))])])
3579 \f
3580 ;; Sign extension instructions
3581
3582 (define_expand "extendsidi2"
3583   [(set (match_operand:DI 0 "register_operand" "")
3584         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3585   ""
3586 {
3587   if (!TARGET_64BIT)
3588     {
3589       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3590       DONE;
3591     }
3592 })
3593
3594 (define_insn "*extendsidi2_rex64"
3595   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3596         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3597   "TARGET_64BIT"
3598   "@
3599    {cltq|cdqe}
3600    movs{lq|x}\t{%1, %0|%0, %1}"
3601   [(set_attr "type" "imovx")
3602    (set_attr "mode" "DI")
3603    (set_attr "prefix_0f" "0")
3604    (set_attr "modrm" "0,1")])
3605
3606 (define_insn "extendsidi2_1"
3607   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3608         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3609    (clobber (reg:CC FLAGS_REG))
3610    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3611   "!TARGET_64BIT"
3612   "#")
3613
3614 ;; Extend to memory case when source register does die.
3615 (define_split
3616   [(set (match_operand:DI 0 "memory_operand" "")
3617         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3618    (clobber (reg:CC FLAGS_REG))
3619    (clobber (match_operand:SI 2 "register_operand" ""))]
3620   "(reload_completed
3621     && dead_or_set_p (insn, operands[1])
3622     && !reg_mentioned_p (operands[1], operands[0]))"
3623   [(set (match_dup 3) (match_dup 1))
3624    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3625               (clobber (reg:CC FLAGS_REG))])
3626    (set (match_dup 4) (match_dup 1))]
3627   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3628
3629 ;; Extend to memory case when source register does not die.
3630 (define_split
3631   [(set (match_operand:DI 0 "memory_operand" "")
3632         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3633    (clobber (reg:CC FLAGS_REG))
3634    (clobber (match_operand:SI 2 "register_operand" ""))]
3635   "reload_completed"
3636   [(const_int 0)]
3637 {
3638   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3639
3640   emit_move_insn (operands[3], operands[1]);
3641
3642   /* Generate a cltd if possible and doing so it profitable.  */
3643   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3644       && true_regnum (operands[1]) == AX_REG
3645       && true_regnum (operands[2]) == DX_REG)
3646     {
3647       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3648     }
3649   else
3650     {
3651       emit_move_insn (operands[2], operands[1]);
3652       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3653     }
3654   emit_move_insn (operands[4], operands[2]);
3655   DONE;
3656 })
3657
3658 ;; Extend to register case.  Optimize case where source and destination
3659 ;; registers match and cases where we can use cltd.
3660 (define_split
3661   [(set (match_operand:DI 0 "register_operand" "")
3662         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3663    (clobber (reg:CC FLAGS_REG))
3664    (clobber (match_scratch:SI 2 ""))]
3665   "reload_completed"
3666   [(const_int 0)]
3667 {
3668   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3669
3670   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3671     emit_move_insn (operands[3], operands[1]);
3672
3673   /* Generate a cltd if possible and doing so it profitable.  */
3674   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3675       && true_regnum (operands[3]) == AX_REG
3676       && true_regnum (operands[4]) == DX_REG)
3677     {
3678       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3679       DONE;
3680     }
3681
3682   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3683     emit_move_insn (operands[4], operands[1]);
3684
3685   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3686   DONE;
3687 })
3688
3689 (define_insn "extend<mode>di2"
3690   [(set (match_operand:DI 0 "register_operand" "=r")
3691         (sign_extend:DI
3692          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3693   "TARGET_64BIT"
3694   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3695   [(set_attr "type" "imovx")
3696    (set_attr "mode" "DI")])
3697
3698 (define_insn "extendhisi2"
3699   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3700         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3701   ""
3702 {
3703   switch (get_attr_prefix_0f (insn))
3704     {
3705     case 0:
3706       return "{cwtl|cwde}";
3707     default:
3708       return "movs{wl|x}\t{%1, %0|%0, %1}";
3709     }
3710 }
3711   [(set_attr "type" "imovx")
3712    (set_attr "mode" "SI")
3713    (set (attr "prefix_0f")
3714      ;; movsx is short decodable while cwtl is vector decoded.
3715      (if_then_else (and (eq_attr "cpu" "!k6")
3716                         (eq_attr "alternative" "0"))
3717         (const_string "0")
3718         (const_string "1")))
3719    (set (attr "modrm")
3720      (if_then_else (eq_attr "prefix_0f" "0")
3721         (const_string "0")
3722         (const_string "1")))])
3723
3724 (define_insn "*extendhisi2_zext"
3725   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3726         (zero_extend:DI
3727          (sign_extend:SI
3728           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3729   "TARGET_64BIT"
3730 {
3731   switch (get_attr_prefix_0f (insn))
3732     {
3733     case 0:
3734       return "{cwtl|cwde}";
3735     default:
3736       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3737     }
3738 }
3739   [(set_attr "type" "imovx")
3740    (set_attr "mode" "SI")
3741    (set (attr "prefix_0f")
3742      ;; movsx is short decodable while cwtl is vector decoded.
3743      (if_then_else (and (eq_attr "cpu" "!k6")
3744                         (eq_attr "alternative" "0"))
3745         (const_string "0")
3746         (const_string "1")))
3747    (set (attr "modrm")
3748      (if_then_else (eq_attr "prefix_0f" "0")
3749         (const_string "0")
3750         (const_string "1")))])
3751
3752 (define_insn "extendqisi2"
3753   [(set (match_operand:SI 0 "register_operand" "=r")
3754         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3755   ""
3756   "movs{bl|x}\t{%1, %0|%0, %1}"
3757    [(set_attr "type" "imovx")
3758     (set_attr "mode" "SI")])
3759
3760 (define_insn "*extendqisi2_zext"
3761   [(set (match_operand:DI 0 "register_operand" "=r")
3762         (zero_extend:DI
3763           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3764   "TARGET_64BIT"
3765   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3766    [(set_attr "type" "imovx")
3767     (set_attr "mode" "SI")])
3768
3769 (define_insn "extendqihi2"
3770   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3771         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3772   ""
3773 {
3774   switch (get_attr_prefix_0f (insn))
3775     {
3776     case 0:
3777       return "{cbtw|cbw}";
3778     default:
3779       return "movs{bw|x}\t{%1, %0|%0, %1}";
3780     }
3781 }
3782   [(set_attr "type" "imovx")
3783    (set_attr "mode" "HI")
3784    (set (attr "prefix_0f")
3785      ;; movsx is short decodable while cwtl is vector decoded.
3786      (if_then_else (and (eq_attr "cpu" "!k6")
3787                         (eq_attr "alternative" "0"))
3788         (const_string "0")
3789         (const_string "1")))
3790    (set (attr "modrm")
3791      (if_then_else (eq_attr "prefix_0f" "0")
3792         (const_string "0")
3793         (const_string "1")))])
3794 \f
3795 ;; Conversions between float and double.
3796
3797 ;; These are all no-ops in the model used for the 80387.
3798 ;; So just emit moves.
3799
3800 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3801 (define_split
3802   [(set (match_operand:DF 0 "push_operand" "")
3803         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3804   "reload_completed"
3805   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3806    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3807
3808 (define_split
3809   [(set (match_operand:XF 0 "push_operand" "")
3810         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3811   "reload_completed"
3812   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3813    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3814   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3815
3816 (define_expand "extendsfdf2"
3817   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3818         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3819   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3820 {
3821   /* ??? Needed for compress_float_constant since all fp constants
3822      are TARGET_LEGITIMATE_CONSTANT_P.  */
3823   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3824     {
3825       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3826           && standard_80387_constant_p (operands[1]) > 0)
3827         {
3828           operands[1] = simplify_const_unary_operation
3829             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3830           emit_move_insn_1 (operands[0], operands[1]);
3831           DONE;
3832         }
3833       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3834     }
3835 })
3836
3837 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3838    cvtss2sd:
3839       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3840       cvtps2pd xmm2,xmm1
3841    We do the conversion post reload to avoid producing of 128bit spills
3842    that might lead to ICE on 32bit target.  The sequence unlikely combine
3843    anyway.  */
3844 (define_split
3845   [(set (match_operand:DF 0 "register_operand" "")
3846         (float_extend:DF
3847           (match_operand:SF 1 "nonimmediate_operand" "")))]
3848   "TARGET_USE_VECTOR_FP_CONVERTS
3849    && optimize_insn_for_speed_p ()
3850    && reload_completed && SSE_REG_P (operands[0])"
3851    [(set (match_dup 2)
3852          (float_extend:V2DF
3853            (vec_select:V2SF
3854              (match_dup 3)
3855              (parallel [(const_int 0) (const_int 1)]))))]
3856 {
3857   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3858   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3859   /* Use movss for loading from memory, unpcklps reg, reg for registers.
3860      Try to avoid move when unpacking can be done in source.  */
3861   if (REG_P (operands[1]))
3862     {
3863       /* If it is unsafe to overwrite upper half of source, we need
3864          to move to destination and unpack there.  */
3865       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3866            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3867           && true_regnum (operands[0]) != true_regnum (operands[1]))
3868         {
3869           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3870           emit_move_insn (tmp, operands[1]);
3871         }
3872       else
3873         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3874       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3875                                              operands[3]));
3876     }
3877   else
3878     emit_insn (gen_vec_setv4sf_0 (operands[3],
3879                                   CONST0_RTX (V4SFmode), operands[1]));
3880 })
3881
3882 (define_insn "*extendsfdf2_mixed"
3883   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3884         (float_extend:DF
3885           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3886   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3887 {
3888   switch (which_alternative)
3889     {
3890     case 0:
3891     case 1:
3892       return output_387_reg_move (insn, operands);
3893
3894     case 2:
3895       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3896
3897     default:
3898       gcc_unreachable ();
3899     }
3900 }
3901   [(set_attr "type" "fmov,fmov,ssecvt")
3902    (set_attr "prefix" "orig,orig,maybe_vex")
3903    (set_attr "mode" "SF,XF,DF")])
3904
3905 (define_insn "*extendsfdf2_sse"
3906   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3907         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3908   "TARGET_SSE2 && TARGET_SSE_MATH"
3909   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3910   [(set_attr "type" "ssecvt")
3911    (set_attr "prefix" "maybe_vex")
3912    (set_attr "mode" "DF")])
3913
3914 (define_insn "*extendsfdf2_i387"
3915   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3916         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3917   "TARGET_80387"
3918   "* return output_387_reg_move (insn, operands);"
3919   [(set_attr "type" "fmov")
3920    (set_attr "mode" "SF,XF")])
3921
3922 (define_expand "extend<mode>xf2"
3923   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3924         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3925   "TARGET_80387"
3926 {
3927   /* ??? Needed for compress_float_constant since all fp constants
3928      are TARGET_LEGITIMATE_CONSTANT_P.  */
3929   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3930     {
3931       if (standard_80387_constant_p (operands[1]) > 0)
3932         {
3933           operands[1] = simplify_const_unary_operation
3934             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3935           emit_move_insn_1 (operands[0], operands[1]);
3936           DONE;
3937         }
3938       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3939     }
3940 })
3941
3942 (define_insn "*extend<mode>xf2_i387"
3943   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3944         (float_extend:XF
3945           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3946   "TARGET_80387"
3947   "* return output_387_reg_move (insn, operands);"
3948   [(set_attr "type" "fmov")
3949    (set_attr "mode" "<MODE>,XF")])
3950
3951 ;; %%% This seems bad bad news.
3952 ;; This cannot output into an f-reg because there is no way to be sure
3953 ;; of truncating in that case.  Otherwise this is just like a simple move
3954 ;; insn.  So we pretend we can output to a reg in order to get better
3955 ;; register preferencing, but we really use a stack slot.
3956
3957 ;; Conversion from DFmode to SFmode.
3958
3959 (define_expand "truncdfsf2"
3960   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3961         (float_truncate:SF
3962           (match_operand:DF 1 "nonimmediate_operand" "")))]
3963   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3964 {
3965   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3966     ;
3967   else if (flag_unsafe_math_optimizations)
3968     ;
3969   else
3970     {
3971       enum ix86_stack_slot slot = (virtuals_instantiated
3972                                    ? SLOT_TEMP
3973                                    : SLOT_VIRTUAL);
3974       rtx temp = assign_386_stack_local (SFmode, slot);
3975       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3976       DONE;
3977     }
3978 })
3979
3980 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3981    cvtsd2ss:
3982       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3983       cvtpd2ps xmm2,xmm1
3984    We do the conversion post reload to avoid producing of 128bit spills
3985    that might lead to ICE on 32bit target.  The sequence unlikely combine
3986    anyway.  */
3987 (define_split
3988   [(set (match_operand:SF 0 "register_operand" "")
3989         (float_truncate:SF
3990           (match_operand:DF 1 "nonimmediate_operand" "")))]
3991   "TARGET_USE_VECTOR_FP_CONVERTS
3992    && optimize_insn_for_speed_p ()
3993    && reload_completed && SSE_REG_P (operands[0])"
3994    [(set (match_dup 2)
3995          (vec_concat:V4SF
3996            (float_truncate:V2SF
3997              (match_dup 4))
3998            (match_dup 3)))]
3999 {
4000   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4001   operands[3] = CONST0_RTX (V2SFmode);
4002   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4003   /* Use movsd for loading from memory, unpcklpd for registers.
4004      Try to avoid move when unpacking can be done in source, or SSE3
4005      movddup is available.  */
4006   if (REG_P (operands[1]))
4007     {
4008       if (!TARGET_SSE3
4009           && true_regnum (operands[0]) != true_regnum (operands[1])
4010           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4011               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4012         {
4013           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4014           emit_move_insn (tmp, operands[1]);
4015           operands[1] = tmp;
4016         }
4017       else if (!TARGET_SSE3)
4018         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4019       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4020     }
4021   else
4022     emit_insn (gen_sse2_loadlpd (operands[4],
4023                                  CONST0_RTX (V2DFmode), operands[1]));
4024 })
4025
4026 (define_expand "truncdfsf2_with_temp"
4027   [(parallel [(set (match_operand:SF 0 "" "")
4028                    (float_truncate:SF (match_operand:DF 1 "" "")))
4029               (clobber (match_operand:SF 2 "" ""))])])
4030
4031 (define_insn "*truncdfsf_fast_mixed"
4032   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4033         (float_truncate:SF
4034           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4035   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4036 {
4037   switch (which_alternative)
4038     {
4039     case 0:
4040       return output_387_reg_move (insn, operands);
4041     case 1:
4042       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4043     default:
4044       gcc_unreachable ();
4045     }
4046 }
4047   [(set_attr "type" "fmov,ssecvt")
4048    (set_attr "prefix" "orig,maybe_vex")
4049    (set_attr "mode" "SF")])
4050
4051 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4052 ;; because nothing we do here is unsafe.
4053 (define_insn "*truncdfsf_fast_sse"
4054   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4055         (float_truncate:SF
4056           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4057   "TARGET_SSE2 && TARGET_SSE_MATH"
4058   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4059   [(set_attr "type" "ssecvt")
4060    (set_attr "prefix" "maybe_vex")
4061    (set_attr "mode" "SF")])
4062
4063 (define_insn "*truncdfsf_fast_i387"
4064   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4065         (float_truncate:SF
4066           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4067   "TARGET_80387 && flag_unsafe_math_optimizations"
4068   "* return output_387_reg_move (insn, operands);"
4069   [(set_attr "type" "fmov")
4070    (set_attr "mode" "SF")])
4071
4072 (define_insn "*truncdfsf_mixed"
4073   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,x ,?f,?x,?*r")
4074         (float_truncate:SF
4075           (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4076    (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
4077   "TARGET_MIX_SSE_I387"
4078 {
4079   switch (which_alternative)
4080     {
4081     case 0:
4082       return output_387_reg_move (insn, operands);
4083     case 1:
4084       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4085
4086     default:
4087       return "#";
4088     }
4089 }
4090   [(set_attr "isa" "*,sse2,*,*,*")
4091    (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4092    (set_attr "unit" "*,*,i387,i387,i387")
4093    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4094    (set_attr "mode" "SF")])
4095
4096 (define_insn "*truncdfsf_i387"
4097   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4098         (float_truncate:SF
4099           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4100    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4101   "TARGET_80387"
4102 {
4103   switch (which_alternative)
4104     {
4105     case 0:
4106       return output_387_reg_move (insn, operands);
4107
4108     default:
4109       return "#";
4110     }
4111 }
4112   [(set_attr "type" "fmov,multi,multi,multi")
4113    (set_attr "unit" "*,i387,i387,i387")
4114    (set_attr "mode" "SF")])
4115
4116 (define_insn "*truncdfsf2_i387_1"
4117   [(set (match_operand:SF 0 "memory_operand" "=m")
4118         (float_truncate:SF
4119           (match_operand:DF 1 "register_operand" "f")))]
4120   "TARGET_80387
4121    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4122    && !TARGET_MIX_SSE_I387"
4123   "* return output_387_reg_move (insn, operands);"
4124   [(set_attr "type" "fmov")
4125    (set_attr "mode" "SF")])
4126
4127 (define_split
4128   [(set (match_operand:SF 0 "register_operand" "")
4129         (float_truncate:SF
4130          (match_operand:DF 1 "fp_register_operand" "")))
4131    (clobber (match_operand 2 "" ""))]
4132   "reload_completed"
4133   [(set (match_dup 2) (match_dup 1))
4134    (set (match_dup 0) (match_dup 2))]
4135   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4136
4137 ;; Conversion from XFmode to {SF,DF}mode
4138
4139 (define_expand "truncxf<mode>2"
4140   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4141                    (float_truncate:MODEF
4142                      (match_operand:XF 1 "register_operand" "")))
4143               (clobber (match_dup 2))])]
4144   "TARGET_80387"
4145 {
4146   if (flag_unsafe_math_optimizations)
4147     {
4148       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4149       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4150       if (reg != operands[0])
4151         emit_move_insn (operands[0], reg);
4152       DONE;
4153     }
4154   else
4155     {
4156       enum ix86_stack_slot slot = (virtuals_instantiated
4157                                    ? SLOT_TEMP
4158                                    : SLOT_VIRTUAL);
4159       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4160     }
4161 })
4162
4163 (define_insn "*truncxfsf2_mixed"
4164   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4165         (float_truncate:SF
4166           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4167    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4168   "TARGET_80387"
4169 {
4170   gcc_assert (!which_alternative);
4171   return output_387_reg_move (insn, operands);
4172 }
4173   [(set_attr "type" "fmov,multi,multi,multi")
4174    (set_attr "unit" "*,i387,i387,i387")
4175    (set_attr "mode" "SF")])
4176
4177 (define_insn "*truncxfdf2_mixed"
4178   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4179         (float_truncate:DF
4180           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4181    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4182   "TARGET_80387"
4183 {
4184   gcc_assert (!which_alternative);
4185   return output_387_reg_move (insn, operands);
4186 }
4187   [(set_attr "isa" "*,*,sse2,*")
4188    (set_attr "type" "fmov,multi,multi,multi")
4189    (set_attr "unit" "*,i387,i387,i387")
4190    (set_attr "mode" "DF")])
4191
4192 (define_insn "truncxf<mode>2_i387_noop"
4193   [(set (match_operand:MODEF 0 "register_operand" "=f")
4194         (float_truncate:MODEF
4195           (match_operand:XF 1 "register_operand" "f")))]
4196   "TARGET_80387 && flag_unsafe_math_optimizations"
4197   "* return output_387_reg_move (insn, operands);"
4198   [(set_attr "type" "fmov")
4199    (set_attr "mode" "<MODE>")])
4200
4201 (define_insn "*truncxf<mode>2_i387"
4202   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4203         (float_truncate:MODEF
4204           (match_operand:XF 1 "register_operand" "f")))]
4205   "TARGET_80387"
4206   "* return output_387_reg_move (insn, operands);"
4207   [(set_attr "type" "fmov")
4208    (set_attr "mode" "<MODE>")])
4209
4210 (define_split
4211   [(set (match_operand:MODEF 0 "register_operand" "")
4212         (float_truncate:MODEF
4213           (match_operand:XF 1 "register_operand" "")))
4214    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4215   "TARGET_80387 && reload_completed"
4216   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4217    (set (match_dup 0) (match_dup 2))])
4218
4219 (define_split
4220   [(set (match_operand:MODEF 0 "memory_operand" "")
4221         (float_truncate:MODEF
4222           (match_operand:XF 1 "register_operand" "")))
4223    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4224   "TARGET_80387"
4225   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4226 \f
4227 ;; Signed conversion to DImode.
4228
4229 (define_expand "fix_truncxfdi2"
4230   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4231                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4232               (clobber (reg:CC FLAGS_REG))])]
4233   "TARGET_80387"
4234 {
4235   if (TARGET_FISTTP)
4236    {
4237      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4238      DONE;
4239    }
4240 })
4241
4242 (define_expand "fix_trunc<mode>di2"
4243   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4244                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4245               (clobber (reg:CC FLAGS_REG))])]
4246   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4247 {
4248   if (TARGET_FISTTP
4249       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4250    {
4251      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4252      DONE;
4253    }
4254   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4255    {
4256      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4257      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4258      if (out != operands[0])
4259         emit_move_insn (operands[0], out);
4260      DONE;
4261    }
4262 })
4263
4264 ;; Signed conversion to SImode.
4265
4266 (define_expand "fix_truncxfsi2"
4267   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4268                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4269               (clobber (reg:CC FLAGS_REG))])]
4270   "TARGET_80387"
4271 {
4272   if (TARGET_FISTTP)
4273    {
4274      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4275      DONE;
4276    }
4277 })
4278
4279 (define_expand "fix_trunc<mode>si2"
4280   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4281                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4282               (clobber (reg:CC FLAGS_REG))])]
4283   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4284 {
4285   if (TARGET_FISTTP
4286       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4287    {
4288      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4289      DONE;
4290    }
4291   if (SSE_FLOAT_MODE_P (<MODE>mode))
4292    {
4293      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4294      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4295      if (out != operands[0])
4296         emit_move_insn (operands[0], out);
4297      DONE;
4298    }
4299 })
4300
4301 ;; Signed conversion to HImode.
4302
4303 (define_expand "fix_trunc<mode>hi2"
4304   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4305                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4306               (clobber (reg:CC FLAGS_REG))])]
4307   "TARGET_80387
4308    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4309 {
4310   if (TARGET_FISTTP)
4311    {
4312      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4313      DONE;
4314    }
4315 })
4316
4317 ;; Unsigned conversion to SImode.
4318
4319 (define_expand "fixuns_trunc<mode>si2"
4320   [(parallel
4321     [(set (match_operand:SI 0 "register_operand" "")
4322           (unsigned_fix:SI
4323             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4324      (use (match_dup 2))
4325      (clobber (match_scratch:<ssevecmode> 3 ""))
4326      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4327   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4328 {
4329   enum machine_mode mode = <MODE>mode;
4330   enum machine_mode vecmode = <ssevecmode>mode;
4331   REAL_VALUE_TYPE TWO31r;
4332   rtx two31;
4333
4334   if (optimize_insn_for_size_p ())
4335     FAIL;
4336
4337   real_ldexp (&TWO31r, &dconst1, 31);
4338   two31 = const_double_from_real_value (TWO31r, mode);
4339   two31 = ix86_build_const_vector (vecmode, true, two31);
4340   operands[2] = force_reg (vecmode, two31);
4341 })
4342
4343 (define_insn_and_split "*fixuns_trunc<mode>_1"
4344   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4345         (unsigned_fix:SI
4346           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4347    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4348    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4349    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4350   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4351    && optimize_function_for_speed_p (cfun)"
4352   "#"
4353   "&& reload_completed"
4354   [(const_int 0)]
4355 {
4356   ix86_split_convert_uns_si_sse (operands);
4357   DONE;
4358 })
4359
4360 ;; Unsigned conversion to HImode.
4361 ;; Without these patterns, we'll try the unsigned SI conversion which
4362 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4363
4364 (define_expand "fixuns_trunc<mode>hi2"
4365   [(set (match_dup 2)
4366         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4367    (set (match_operand:HI 0 "nonimmediate_operand" "")
4368         (subreg:HI (match_dup 2) 0))]
4369   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4370   "operands[2] = gen_reg_rtx (SImode);")
4371
4372 ;; When SSE is available, it is always faster to use it!
4373 (define_insn "fix_trunc<mode>di_sse"
4374   [(set (match_operand:DI 0 "register_operand" "=r,r")
4375         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4376   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4377    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4378   "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4379   [(set_attr "type" "sseicvt")
4380    (set_attr "prefix" "maybe_vex")
4381    (set_attr "prefix_rex" "1")
4382    (set_attr "mode" "<MODE>")
4383    (set_attr "athlon_decode" "double,vector")
4384    (set_attr "amdfam10_decode" "double,double")
4385    (set_attr "bdver1_decode" "double,double")])
4386
4387 (define_insn "fix_trunc<mode>si_sse"
4388   [(set (match_operand:SI 0 "register_operand" "=r,r")
4389         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4390   "SSE_FLOAT_MODE_P (<MODE>mode)
4391    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4392   "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4393   [(set_attr "type" "sseicvt")
4394    (set_attr "prefix" "maybe_vex")
4395    (set_attr "mode" "<MODE>")
4396    (set_attr "athlon_decode" "double,vector")
4397    (set_attr "amdfam10_decode" "double,double")
4398    (set_attr "bdver1_decode" "double,double")])
4399
4400 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4401 (define_peephole2
4402   [(set (match_operand:MODEF 0 "register_operand" "")
4403         (match_operand:MODEF 1 "memory_operand" ""))
4404    (set (match_operand:SWI48x 2 "register_operand" "")
4405         (fix:SWI48x (match_dup 0)))]
4406   "TARGET_SHORTEN_X87_SSE
4407    && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4408    && peep2_reg_dead_p (2, operands[0])"
4409   [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4410
4411 ;; Avoid vector decoded forms of the instruction.
4412 (define_peephole2
4413   [(match_scratch:DF 2 "x")
4414    (set (match_operand:SWI48x 0 "register_operand" "")
4415         (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4416   "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4417   [(set (match_dup 2) (match_dup 1))
4418    (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4419
4420 (define_peephole2
4421   [(match_scratch:SF 2 "x")
4422    (set (match_operand:SWI48x 0 "register_operand" "")
4423         (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4424   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4425   [(set (match_dup 2) (match_dup 1))
4426    (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4427
4428 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4429   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4430         (fix:SWI248x (match_operand 1 "register_operand" "")))]
4431   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4432    && TARGET_FISTTP
4433    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4434          && (TARGET_64BIT || <MODE>mode != DImode))
4435         && TARGET_SSE_MATH)
4436    && can_create_pseudo_p ()"
4437   "#"
4438   "&& 1"
4439   [(const_int 0)]
4440 {
4441   if (memory_operand (operands[0], VOIDmode))
4442     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4443   else
4444     {
4445       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4446       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4447                                                             operands[1],
4448                                                             operands[2]));
4449     }
4450   DONE;
4451 }
4452   [(set_attr "type" "fisttp")
4453    (set_attr "mode" "<MODE>")])
4454
4455 (define_insn "fix_trunc<mode>_i387_fisttp"
4456   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4457         (fix:SWI248x (match_operand 1 "register_operand" "f")))
4458    (clobber (match_scratch:XF 2 "=&1f"))]
4459   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4460    && TARGET_FISTTP
4461    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4462          && (TARGET_64BIT || <MODE>mode != DImode))
4463         && TARGET_SSE_MATH)"
4464   "* return output_fix_trunc (insn, operands, true);"
4465   [(set_attr "type" "fisttp")
4466    (set_attr "mode" "<MODE>")])
4467
4468 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4469   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4470         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4471    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4472    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4473   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4474    && TARGET_FISTTP
4475    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4476         && (TARGET_64BIT || <MODE>mode != DImode))
4477         && TARGET_SSE_MATH)"
4478   "#"
4479   [(set_attr "type" "fisttp")
4480    (set_attr "mode" "<MODE>")])
4481
4482 (define_split
4483   [(set (match_operand:SWI248x 0 "register_operand" "")
4484         (fix:SWI248x (match_operand 1 "register_operand" "")))
4485    (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4486    (clobber (match_scratch 3 ""))]
4487   "reload_completed"
4488   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4489               (clobber (match_dup 3))])
4490    (set (match_dup 0) (match_dup 2))])
4491
4492 (define_split
4493   [(set (match_operand:SWI248x 0 "memory_operand" "")
4494         (fix:SWI248x (match_operand 1 "register_operand" "")))
4495    (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4496    (clobber (match_scratch 3 ""))]
4497   "reload_completed"
4498   [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4499               (clobber (match_dup 3))])])
4500
4501 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4502 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4503 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4504 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4505 ;; function in i386.c.
4506 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4507   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4508         (fix:SWI248x (match_operand 1 "register_operand" "")))
4509    (clobber (reg:CC FLAGS_REG))]
4510   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4511    && !TARGET_FISTTP
4512    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4513          && (TARGET_64BIT || <MODE>mode != DImode))
4514    && can_create_pseudo_p ()"
4515   "#"
4516   "&& 1"
4517   [(const_int 0)]
4518 {
4519   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4520
4521   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4522   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4523   if (memory_operand (operands[0], VOIDmode))
4524     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4525                                          operands[2], operands[3]));
4526   else
4527     {
4528       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4529       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4530                                                      operands[2], operands[3],
4531                                                      operands[4]));
4532     }
4533   DONE;
4534 }
4535   [(set_attr "type" "fistp")
4536    (set_attr "i387_cw" "trunc")
4537    (set_attr "mode" "<MODE>")])
4538
4539 (define_insn "fix_truncdi_i387"
4540   [(set (match_operand:DI 0 "memory_operand" "=m")
4541         (fix:DI (match_operand 1 "register_operand" "f")))
4542    (use (match_operand:HI 2 "memory_operand" "m"))
4543    (use (match_operand:HI 3 "memory_operand" "m"))
4544    (clobber (match_scratch:XF 4 "=&1f"))]
4545   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4546    && !TARGET_FISTTP
4547    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4548   "* return output_fix_trunc (insn, operands, false);"
4549   [(set_attr "type" "fistp")
4550    (set_attr "i387_cw" "trunc")
4551    (set_attr "mode" "DI")])
4552
4553 (define_insn "fix_truncdi_i387_with_temp"
4554   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4555         (fix:DI (match_operand 1 "register_operand" "f,f")))
4556    (use (match_operand:HI 2 "memory_operand" "m,m"))
4557    (use (match_operand:HI 3 "memory_operand" "m,m"))
4558    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4559    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4560   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4561    && !TARGET_FISTTP
4562    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4563   "#"
4564   [(set_attr "type" "fistp")
4565    (set_attr "i387_cw" "trunc")
4566    (set_attr "mode" "DI")])
4567
4568 (define_split
4569   [(set (match_operand:DI 0 "register_operand" "")
4570         (fix:DI (match_operand 1 "register_operand" "")))
4571    (use (match_operand:HI 2 "memory_operand" ""))
4572    (use (match_operand:HI 3 "memory_operand" ""))
4573    (clobber (match_operand:DI 4 "memory_operand" ""))
4574    (clobber (match_scratch 5 ""))]
4575   "reload_completed"
4576   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4577               (use (match_dup 2))
4578               (use (match_dup 3))
4579               (clobber (match_dup 5))])
4580    (set (match_dup 0) (match_dup 4))])
4581
4582 (define_split
4583   [(set (match_operand:DI 0 "memory_operand" "")
4584         (fix:DI (match_operand 1 "register_operand" "")))
4585    (use (match_operand:HI 2 "memory_operand" ""))
4586    (use (match_operand:HI 3 "memory_operand" ""))
4587    (clobber (match_operand:DI 4 "memory_operand" ""))
4588    (clobber (match_scratch 5 ""))]
4589   "reload_completed"
4590   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4591               (use (match_dup 2))
4592               (use (match_dup 3))
4593               (clobber (match_dup 5))])])
4594
4595 (define_insn "fix_trunc<mode>_i387"
4596   [(set (match_operand:SWI24 0 "memory_operand" "=m")
4597         (fix:SWI24 (match_operand 1 "register_operand" "f")))
4598    (use (match_operand:HI 2 "memory_operand" "m"))
4599    (use (match_operand:HI 3 "memory_operand" "m"))]
4600   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4601    && !TARGET_FISTTP
4602    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4603   "* return output_fix_trunc (insn, operands, false);"
4604   [(set_attr "type" "fistp")
4605    (set_attr "i387_cw" "trunc")
4606    (set_attr "mode" "<MODE>")])
4607
4608 (define_insn "fix_trunc<mode>_i387_with_temp"
4609   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4610         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4611    (use (match_operand:HI 2 "memory_operand" "m,m"))
4612    (use (match_operand:HI 3 "memory_operand" "m,m"))
4613    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4614   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4615    && !TARGET_FISTTP
4616    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4617   "#"
4618   [(set_attr "type" "fistp")
4619    (set_attr "i387_cw" "trunc")
4620    (set_attr "mode" "<MODE>")])
4621
4622 (define_split
4623   [(set (match_operand:SWI24 0 "register_operand" "")
4624         (fix:SWI24 (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:SWI24 4 "memory_operand" ""))]
4628   "reload_completed"
4629   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4630               (use (match_dup 2))
4631               (use (match_dup 3))])
4632    (set (match_dup 0) (match_dup 4))])
4633
4634 (define_split
4635   [(set (match_operand:SWI24 0 "memory_operand" "")
4636         (fix:SWI24 (match_operand 1 "register_operand" "")))
4637    (use (match_operand:HI 2 "memory_operand" ""))
4638    (use (match_operand:HI 3 "memory_operand" ""))
4639    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4640   "reload_completed"
4641   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4642               (use (match_dup 2))
4643               (use (match_dup 3))])])
4644
4645 (define_insn "x86_fnstcw_1"
4646   [(set (match_operand:HI 0 "memory_operand" "=m")
4647         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4648   "TARGET_80387"
4649   "fnstcw\t%0"
4650   [(set (attr "length")
4651         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4652    (set_attr "mode" "HI")
4653    (set_attr "unit" "i387")
4654    (set_attr "bdver1_decode" "vector")])
4655
4656 (define_insn "x86_fldcw_1"
4657   [(set (reg:HI FPCR_REG)
4658         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4659   "TARGET_80387"
4660   "fldcw\t%0"
4661   [(set (attr "length")
4662         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4663    (set_attr "mode" "HI")
4664    (set_attr "unit" "i387")
4665    (set_attr "athlon_decode" "vector")
4666    (set_attr "amdfam10_decode" "vector")
4667    (set_attr "bdver1_decode" "vector")])
4668 \f
4669 ;; Conversion between fixed point and floating point.
4670
4671 ;; Even though we only accept memory inputs, the backend _really_
4672 ;; wants to be able to do this between registers.
4673
4674 (define_expand "floathi<mode>2"
4675   [(set (match_operand:X87MODEF 0 "register_operand" "")
4676         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4677   "TARGET_80387
4678    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4679        || TARGET_MIX_SSE_I387)")
4680
4681 ;; Pre-reload splitter to add memory clobber to the pattern.
4682 (define_insn_and_split "*floathi<mode>2_1"
4683   [(set (match_operand:X87MODEF 0 "register_operand" "")
4684         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4685   "TARGET_80387
4686    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4687        || TARGET_MIX_SSE_I387)
4688    && can_create_pseudo_p ()"
4689   "#"
4690   "&& 1"
4691   [(parallel [(set (match_dup 0)
4692               (float:X87MODEF (match_dup 1)))
4693    (clobber (match_dup 2))])]
4694   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4695
4696 (define_insn "*floathi<mode>2_i387_with_temp"
4697   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4698         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4699   (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4700   "TARGET_80387
4701    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4702        || TARGET_MIX_SSE_I387)"
4703   "#"
4704   [(set_attr "type" "fmov,multi")
4705    (set_attr "mode" "<MODE>")
4706    (set_attr "unit" "*,i387")
4707    (set_attr "fp_int_src" "true")])
4708
4709 (define_insn "*floathi<mode>2_i387"
4710   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4711         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4712   "TARGET_80387
4713    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4714        || TARGET_MIX_SSE_I387)"
4715   "fild%Z1\t%1"
4716   [(set_attr "type" "fmov")
4717    (set_attr "mode" "<MODE>")
4718    (set_attr "fp_int_src" "true")])
4719
4720 (define_split
4721   [(set (match_operand:X87MODEF 0 "register_operand" "")
4722         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4723    (clobber (match_operand:HI 2 "memory_operand" ""))]
4724   "TARGET_80387
4725    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4726        || TARGET_MIX_SSE_I387)
4727    && reload_completed"
4728   [(set (match_dup 2) (match_dup 1))
4729    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4730
4731 (define_split
4732   [(set (match_operand:X87MODEF 0 "register_operand" "")
4733         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4734    (clobber (match_operand:HI 2 "memory_operand" ""))]
4735    "TARGET_80387
4736     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4737         || TARGET_MIX_SSE_I387)
4738     && reload_completed"
4739   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4740
4741 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4742   [(set (match_operand:X87MODEF 0 "register_operand" "")
4743         (float:X87MODEF
4744           (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4745   "TARGET_80387
4746    || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4747        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4748 {
4749   if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4750         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4751       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4752     {
4753       rtx reg = gen_reg_rtx (XFmode);
4754       rtx (*insn)(rtx, rtx);
4755
4756       emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4757
4758       if (<X87MODEF:MODE>mode == SFmode)
4759         insn = gen_truncxfsf2;
4760       else if (<X87MODEF:MODE>mode == DFmode)
4761         insn = gen_truncxfdf2;
4762       else
4763         gcc_unreachable ();
4764
4765       emit_insn (insn (operands[0], reg));
4766       DONE;
4767     }
4768 })
4769
4770 ;; Pre-reload splitter to add memory clobber to the pattern.
4771 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4772   [(set (match_operand:X87MODEF 0 "register_operand" "")
4773         (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4774   "((TARGET_80387
4775      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4776      && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4777            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4778          || TARGET_MIX_SSE_I387))
4779     || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4780         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4781         && ((<SWI48x:MODE>mode == SImode
4782              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4783              && optimize_function_for_speed_p (cfun)
4784              && flag_trapping_math)
4785             || !(TARGET_INTER_UNIT_CONVERSIONS
4786                  || optimize_function_for_size_p (cfun)))))
4787    && can_create_pseudo_p ()"
4788   "#"
4789   "&& 1"
4790   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4791               (clobber (match_dup 2))])]
4792 {
4793   operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4794
4795   /* Avoid store forwarding (partial memory) stall penalty
4796      by passing DImode value through XMM registers.  */
4797   if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4798       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4799       && optimize_function_for_speed_p (cfun))
4800     {
4801       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4802                                                             operands[1],
4803                                                             operands[2]));
4804       DONE;
4805     }
4806 })
4807
4808 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4809   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4810         (float:MODEF
4811           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4812    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4813   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4814    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4815   "#"
4816   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4817    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4818    (set_attr "unit" "*,i387,*,*,*")
4819    (set_attr "athlon_decode" "*,*,double,direct,double")
4820    (set_attr "amdfam10_decode" "*,*,vector,double,double")
4821    (set_attr "bdver1_decode" "*,*,double,direct,double")
4822    (set_attr "fp_int_src" "true")])
4823
4824 (define_insn "*floatsi<mode>2_vector_mixed"
4825   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4826         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4827   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4828    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4829   "@
4830    fild%Z1\t%1
4831    #"
4832   [(set_attr "type" "fmov,sseicvt")
4833    (set_attr "mode" "<MODE>,<ssevecmode>")
4834    (set_attr "unit" "i387,*")
4835    (set_attr "athlon_decode" "*,direct")
4836    (set_attr "amdfam10_decode" "*,double")
4837    (set_attr "bdver1_decode" "*,direct")
4838    (set_attr "fp_int_src" "true")])
4839
4840 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4841   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4842         (float:MODEF
4843           (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4844    (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4845   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4846    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4847   "#"
4848   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4849    (set_attr "mode" "<MODEF:MODE>")
4850    (set_attr "unit" "*,i387,*,*")
4851    (set_attr "athlon_decode" "*,*,double,direct")
4852    (set_attr "amdfam10_decode" "*,*,vector,double")
4853    (set_attr "bdver1_decode" "*,*,double,direct")
4854    (set_attr "fp_int_src" "true")])
4855
4856 (define_split
4857   [(set (match_operand:MODEF 0 "register_operand" "")
4858         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4859    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4860   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4861    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4862    && TARGET_INTER_UNIT_CONVERSIONS
4863    && reload_completed
4864    && (SSE_REG_P (operands[0])
4865        || (GET_CODE (operands[0]) == SUBREG
4866            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4867   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4868
4869 (define_split
4870   [(set (match_operand:MODEF 0 "register_operand" "")
4871         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4872    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4873   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4874    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4875    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4876    && reload_completed
4877    && (SSE_REG_P (operands[0])
4878        || (GET_CODE (operands[0]) == SUBREG
4879            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4880   [(set (match_dup 2) (match_dup 1))
4881    (set (match_dup 0) (float:MODEF (match_dup 2)))])
4882
4883 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4884   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4885         (float:MODEF
4886           (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4887   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4888    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4889    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4890   "@
4891    fild%Z1\t%1
4892    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4893    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4894   [(set_attr "type" "fmov,sseicvt,sseicvt")
4895    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4896    (set_attr "mode" "<MODEF:MODE>")
4897    (set (attr "prefix_rex")
4898      (if_then_else
4899        (and (eq_attr "prefix" "maybe_vex")
4900             (match_test "<SWI48x:MODE>mode == DImode"))
4901        (const_string "1")
4902        (const_string "*")))
4903    (set_attr "unit" "i387,*,*")
4904    (set_attr "athlon_decode" "*,double,direct")
4905    (set_attr "amdfam10_decode" "*,vector,double")
4906    (set_attr "bdver1_decode" "*,double,direct")
4907    (set_attr "fp_int_src" "true")])
4908
4909 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4910   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4911         (float:MODEF
4912           (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4913   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4914    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4915    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4916   "@
4917    fild%Z1\t%1
4918    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4919   [(set_attr "type" "fmov,sseicvt")
4920    (set_attr "prefix" "orig,maybe_vex")
4921    (set_attr "mode" "<MODEF:MODE>")
4922    (set (attr "prefix_rex")
4923      (if_then_else
4924        (and (eq_attr "prefix" "maybe_vex")
4925             (match_test "<SWI48x:MODE>mode == DImode"))
4926        (const_string "1")
4927        (const_string "*")))
4928    (set_attr "athlon_decode" "*,direct")
4929    (set_attr "amdfam10_decode" "*,double")
4930    (set_attr "bdver1_decode" "*,direct")
4931    (set_attr "fp_int_src" "true")])
4932
4933 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4934   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4935         (float:MODEF
4936           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4937    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4938   "TARGET_SSE2 && TARGET_SSE_MATH
4939    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4940   "#"
4941   [(set_attr "type" "sseicvt")
4942    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4943    (set_attr "athlon_decode" "double,direct,double")
4944    (set_attr "amdfam10_decode" "vector,double,double")
4945    (set_attr "bdver1_decode" "double,direct,double")
4946    (set_attr "fp_int_src" "true")])
4947
4948 (define_insn "*floatsi<mode>2_vector_sse"
4949   [(set (match_operand:MODEF 0 "register_operand" "=x")
4950         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4951   "TARGET_SSE2 && TARGET_SSE_MATH
4952    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4953   "#"
4954   [(set_attr "type" "sseicvt")
4955    (set_attr "mode" "<MODE>")
4956    (set_attr "athlon_decode" "direct")
4957    (set_attr "amdfam10_decode" "double")
4958    (set_attr "bdver1_decode" "direct")
4959    (set_attr "fp_int_src" "true")])
4960
4961 (define_split
4962   [(set (match_operand:MODEF 0 "register_operand" "")
4963         (float:MODEF (match_operand:SI 1 "register_operand" "")))
4964    (clobber (match_operand:SI 2 "memory_operand" ""))]
4965   "TARGET_SSE2 && TARGET_SSE_MATH
4966    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4967    && reload_completed
4968    && (SSE_REG_P (operands[0])
4969        || (GET_CODE (operands[0]) == SUBREG
4970            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4971   [(const_int 0)]
4972 {
4973   rtx op1 = operands[1];
4974
4975   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4976                                      <MODE>mode, 0);
4977   if (GET_CODE (op1) == SUBREG)
4978     op1 = SUBREG_REG (op1);
4979
4980   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4981     {
4982       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4983       emit_insn (gen_sse2_loadld (operands[4],
4984                                   CONST0_RTX (V4SImode), operands[1]));
4985     }
4986   /* We can ignore possible trapping value in the
4987      high part of SSE register for non-trapping math. */
4988   else if (SSE_REG_P (op1) && !flag_trapping_math)
4989     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4990   else
4991     {
4992       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4993       emit_move_insn (operands[2], operands[1]);
4994       emit_insn (gen_sse2_loadld (operands[4],
4995                                   CONST0_RTX (V4SImode), operands[2]));
4996     }
4997   if (<ssevecmode>mode == V4SFmode)
4998     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4999   else
5000     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5001   DONE;
5002 })
5003
5004 (define_split
5005   [(set (match_operand:MODEF 0 "register_operand" "")
5006         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5007    (clobber (match_operand:SI 2 "memory_operand" ""))]
5008   "TARGET_SSE2 && TARGET_SSE_MATH
5009    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5010    && reload_completed
5011    && (SSE_REG_P (operands[0])
5012        || (GET_CODE (operands[0]) == SUBREG
5013            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5014   [(const_int 0)]
5015 {
5016   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5017                                      <MODE>mode, 0);
5018   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5019
5020   emit_insn (gen_sse2_loadld (operands[4],
5021                               CONST0_RTX (V4SImode), operands[1]));
5022   if (<ssevecmode>mode == V4SFmode)
5023     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5024   else
5025     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5026   DONE;
5027 })
5028
5029 (define_split
5030   [(set (match_operand:MODEF 0 "register_operand" "")
5031         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5032   "TARGET_SSE2 && TARGET_SSE_MATH
5033    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5034    && reload_completed
5035    && (SSE_REG_P (operands[0])
5036        || (GET_CODE (operands[0]) == SUBREG
5037            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5038   [(const_int 0)]
5039 {
5040   rtx op1 = operands[1];
5041
5042   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5043                                      <MODE>mode, 0);
5044   if (GET_CODE (op1) == SUBREG)
5045     op1 = SUBREG_REG (op1);
5046
5047   if (GENERAL_REG_P (op1))
5048     {
5049       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5050       if (TARGET_INTER_UNIT_MOVES)
5051         emit_insn (gen_sse2_loadld (operands[4],
5052                                     CONST0_RTX (V4SImode), operands[1]));
5053       else
5054         {
5055           operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5056                                               operands[1]);
5057           emit_insn (gen_sse2_loadld (operands[4],
5058                                       CONST0_RTX (V4SImode), operands[5]));
5059           ix86_free_from_memory (GET_MODE (operands[1]));
5060         }
5061     }
5062   /* We can ignore possible trapping value in the
5063      high part of SSE register for non-trapping math. */
5064   else if (SSE_REG_P (op1) && !flag_trapping_math)
5065     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5066   else
5067     gcc_unreachable ();
5068   if (<ssevecmode>mode == V4SFmode)
5069     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5070   else
5071     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5072   DONE;
5073 })
5074
5075 (define_split
5076   [(set (match_operand:MODEF 0 "register_operand" "")
5077         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5078   "TARGET_SSE2 && TARGET_SSE_MATH
5079    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5080    && reload_completed
5081    && (SSE_REG_P (operands[0])
5082        || (GET_CODE (operands[0]) == SUBREG
5083            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5084   [(const_int 0)]
5085 {
5086   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5087                                      <MODE>mode, 0);
5088   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5089
5090   emit_insn (gen_sse2_loadld (operands[4],
5091                               CONST0_RTX (V4SImode), operands[1]));
5092   if (<ssevecmode>mode == V4SFmode)
5093     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5094   else
5095     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5096   DONE;
5097 })
5098
5099 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5100   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5101         (float:MODEF
5102           (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5103   (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5104   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5105    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5106   "#"
5107   [(set_attr "type" "sseicvt")
5108    (set_attr "mode" "<MODEF:MODE>")
5109    (set_attr "athlon_decode" "double,direct")
5110    (set_attr "amdfam10_decode" "vector,double")
5111    (set_attr "bdver1_decode" "double,direct")
5112    (set_attr "fp_int_src" "true")])
5113
5114 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5115   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5116         (float:MODEF
5117           (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5118   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5119    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5120    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5121   "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5122   [(set_attr "type" "sseicvt")
5123    (set_attr "prefix" "maybe_vex")
5124    (set_attr "mode" "<MODEF:MODE>")
5125    (set (attr "prefix_rex")
5126      (if_then_else
5127        (and (eq_attr "prefix" "maybe_vex")
5128             (match_test "<SWI48x:MODE>mode == DImode"))
5129        (const_string "1")
5130        (const_string "*")))
5131    (set_attr "athlon_decode" "double,direct")
5132    (set_attr "amdfam10_decode" "vector,double")
5133    (set_attr "bdver1_decode" "double,direct")
5134    (set_attr "fp_int_src" "true")])
5135
5136 (define_split
5137   [(set (match_operand:MODEF 0 "register_operand" "")
5138         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5139    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5140   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5141    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5142    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5143    && reload_completed
5144    && (SSE_REG_P (operands[0])
5145        || (GET_CODE (operands[0]) == SUBREG
5146            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5147   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5148
5149 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5150   [(set (match_operand:MODEF 0 "register_operand" "=x")
5151         (float:MODEF
5152           (match_operand:SWI48x 1 "memory_operand" "m")))]
5153   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5154    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5155    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5156   "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5157   [(set_attr "type" "sseicvt")
5158    (set_attr "prefix" "maybe_vex")
5159    (set_attr "mode" "<MODEF:MODE>")
5160    (set (attr "prefix_rex")
5161      (if_then_else
5162        (and (eq_attr "prefix" "maybe_vex")
5163             (match_test "<SWI48x:MODE>mode == DImode"))
5164        (const_string "1")
5165        (const_string "*")))
5166    (set_attr "athlon_decode" "direct")
5167    (set_attr "amdfam10_decode" "double")
5168    (set_attr "bdver1_decode" "direct")
5169    (set_attr "fp_int_src" "true")])
5170
5171 (define_split
5172   [(set (match_operand:MODEF 0 "register_operand" "")
5173         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5174    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5175   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5176    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5177    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5178    && reload_completed
5179    && (SSE_REG_P (operands[0])
5180        || (GET_CODE (operands[0]) == SUBREG
5181            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5182   [(set (match_dup 2) (match_dup 1))
5183    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5184
5185 (define_split
5186   [(set (match_operand:MODEF 0 "register_operand" "")
5187         (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5188    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5189   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5190    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5191    && reload_completed
5192    && (SSE_REG_P (operands[0])
5193        || (GET_CODE (operands[0]) == SUBREG
5194            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5195   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5196
5197 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5198   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5199         (float:X87MODEF
5200           (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5201   (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5202   "TARGET_80387
5203    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5204   "@
5205    fild%Z1\t%1
5206    #"
5207   [(set_attr "type" "fmov,multi")
5208    (set_attr "mode" "<X87MODEF:MODE>")
5209    (set_attr "unit" "*,i387")
5210    (set_attr "fp_int_src" "true")])
5211
5212 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5213   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5214         (float:X87MODEF
5215           (match_operand:SWI48x 1 "memory_operand" "m")))]
5216   "TARGET_80387
5217    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5218   "fild%Z1\t%1"
5219   [(set_attr "type" "fmov")
5220    (set_attr "mode" "<X87MODEF:MODE>")
5221    (set_attr "fp_int_src" "true")])
5222
5223 (define_split
5224   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5225         (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5226    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5227   "TARGET_80387
5228    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5229    && reload_completed"
5230   [(set (match_dup 2) (match_dup 1))
5231    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5232
5233 (define_split
5234   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5235         (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5236    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5237   "TARGET_80387
5238    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5239    && reload_completed"
5240   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5241
5242 ;; Avoid store forwarding (partial memory) stall penalty
5243 ;; by passing DImode value through XMM registers.  */
5244
5245 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5246   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5247         (float:X87MODEF
5248           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5249    (clobber (match_scratch:V4SI 3 "=X,x"))
5250    (clobber (match_scratch:V4SI 4 "=X,x"))
5251    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5252   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5253    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5254    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5255   "#"
5256   [(set_attr "type" "multi")
5257    (set_attr "mode" "<X87MODEF:MODE>")
5258    (set_attr "unit" "i387")
5259    (set_attr "fp_int_src" "true")])
5260
5261 (define_split
5262   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5263         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5264    (clobber (match_scratch:V4SI 3 ""))
5265    (clobber (match_scratch:V4SI 4 ""))
5266    (clobber (match_operand:DI 2 "memory_operand" ""))]
5267   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5268    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5269    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5270    && reload_completed"
5271   [(set (match_dup 2) (match_dup 3))
5272    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5273 {
5274   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5275      Assemble the 64-bit DImode value in an xmm register.  */
5276   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5277                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5278   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5279                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5280   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5281                                          operands[4]));
5282
5283   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5284 })
5285
5286 (define_split
5287   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5288         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5289    (clobber (match_scratch:V4SI 3 ""))
5290    (clobber (match_scratch:V4SI 4 ""))
5291    (clobber (match_operand:DI 2 "memory_operand" ""))]
5292   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5293    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5294    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5295    && reload_completed"
5296   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5297
5298 ;; Avoid store forwarding (partial memory) stall penalty by extending
5299 ;; SImode value to DImode through XMM register instead of pushing two
5300 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5301 ;; targets benefit from this optimization. Also note that fild
5302 ;; loads from memory only.
5303
5304 (define_insn "*floatunssi<mode>2_1"
5305   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5306         (unsigned_float:X87MODEF
5307           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5308    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5309    (clobber (match_scratch:SI 3 "=X,x"))]
5310   "!TARGET_64BIT
5311    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5312    && TARGET_SSE"
5313   "#"
5314   [(set_attr "type" "multi")
5315    (set_attr "mode" "<MODE>")])
5316
5317 (define_split
5318   [(set (match_operand:X87MODEF 0 "register_operand" "")
5319         (unsigned_float:X87MODEF
5320           (match_operand:SI 1 "register_operand" "")))
5321    (clobber (match_operand:DI 2 "memory_operand" ""))
5322    (clobber (match_scratch:SI 3 ""))]
5323   "!TARGET_64BIT
5324    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5325    && TARGET_SSE
5326    && reload_completed"
5327   [(set (match_dup 2) (match_dup 1))
5328    (set (match_dup 0)
5329         (float:X87MODEF (match_dup 2)))]
5330   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5331
5332 (define_split
5333   [(set (match_operand:X87MODEF 0 "register_operand" "")
5334         (unsigned_float:X87MODEF
5335           (match_operand:SI 1 "memory_operand" "")))
5336    (clobber (match_operand:DI 2 "memory_operand" ""))
5337    (clobber (match_scratch:SI 3 ""))]
5338   "!TARGET_64BIT
5339    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5340    && TARGET_SSE
5341    && reload_completed"
5342   [(set (match_dup 2) (match_dup 3))
5343    (set (match_dup 0)
5344         (float:X87MODEF (match_dup 2)))]
5345 {
5346   emit_move_insn (operands[3], operands[1]);
5347   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5348 })
5349
5350 (define_expand "floatunssi<mode>2"
5351   [(parallel
5352      [(set (match_operand:X87MODEF 0 "register_operand" "")
5353            (unsigned_float:X87MODEF
5354              (match_operand:SI 1 "nonimmediate_operand" "")))
5355       (clobber (match_dup 2))
5356       (clobber (match_scratch:SI 3 ""))])]
5357   "!TARGET_64BIT
5358    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5359         && TARGET_SSE)
5360        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5361 {
5362   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5363     {
5364       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5365       DONE;
5366     }
5367   else
5368     {
5369       enum ix86_stack_slot slot = (virtuals_instantiated
5370                                    ? SLOT_TEMP
5371                                    : SLOT_VIRTUAL);
5372       operands[2] = assign_386_stack_local (DImode, slot);
5373     }
5374 })
5375
5376 (define_expand "floatunsdisf2"
5377   [(use (match_operand:SF 0 "register_operand" ""))
5378    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5379   "TARGET_64BIT && TARGET_SSE_MATH"
5380   "x86_emit_floatuns (operands); DONE;")
5381
5382 (define_expand "floatunsdidf2"
5383   [(use (match_operand:DF 0 "register_operand" ""))
5384    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5385   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5386    && TARGET_SSE2 && TARGET_SSE_MATH"
5387 {
5388   if (TARGET_64BIT)
5389     x86_emit_floatuns (operands);
5390   else
5391     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5392   DONE;
5393 })
5394 \f
5395 ;; Load effective address instructions
5396
5397 (define_insn_and_split "*lea<mode>"
5398   [(set (match_operand:SWI48 0 "register_operand" "=r")
5399         (match_operand:SWI48 1 "lea_address_operand" "p"))]
5400   ""
5401 {
5402   rtx addr = operands[1];
5403
5404   if (GET_CODE (addr) == SUBREG)
5405     {
5406       gcc_assert (TARGET_64BIT);
5407       gcc_assert (<MODE>mode == SImode);
5408       gcc_assert (GET_MODE (SUBREG_REG (addr)) == DImode);
5409       return "lea{l}\t{%E1, %0|%0, %E1}";
5410     }
5411   else if (GET_CODE (addr) == ZERO_EXTEND
5412            || GET_CODE (addr) == AND)
5413     {
5414       gcc_assert (TARGET_64BIT);
5415       gcc_assert (<MODE>mode == DImode);
5416       return "lea{l}\t{%E1, %k0|%k0, %E1}";
5417     }
5418   else 
5419     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5420 }
5421   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5422   [(const_int 0)]
5423 {
5424   ix86_split_lea_for_addr (operands, <MODE>mode);
5425   DONE;
5426 }
5427   [(set_attr "type" "lea")
5428    (set_attr "mode" "<MODE>")])
5429 \f
5430 ;; Add instructions
5431
5432 (define_expand "add<mode>3"
5433   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5434         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5435                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5436   ""
5437   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5438
5439 (define_insn_and_split "*add<dwi>3_doubleword"
5440   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5441         (plus:<DWI>
5442           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5443           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5444    (clobber (reg:CC FLAGS_REG))]
5445   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5446   "#"
5447   "reload_completed"
5448   [(parallel [(set (reg:CC FLAGS_REG)
5449                    (unspec:CC [(match_dup 1) (match_dup 2)]
5450                               UNSPEC_ADD_CARRY))
5451               (set (match_dup 0)
5452                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5453    (parallel [(set (match_dup 3)
5454                    (plus:DWIH
5455                      (match_dup 4)
5456                      (plus:DWIH
5457                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5458                        (match_dup 5))))
5459               (clobber (reg:CC FLAGS_REG))])]
5460   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5461
5462 (define_insn "*add<mode>3_cc"
5463   [(set (reg:CC FLAGS_REG)
5464         (unspec:CC
5465           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5466            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5467           UNSPEC_ADD_CARRY))
5468    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5469         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5470   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5471   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5472   [(set_attr "type" "alu")
5473    (set_attr "mode" "<MODE>")])
5474
5475 (define_insn "addqi3_cc"
5476   [(set (reg:CC FLAGS_REG)
5477         (unspec:CC
5478           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5479            (match_operand:QI 2 "general_operand" "qn,qm")]
5480           UNSPEC_ADD_CARRY))
5481    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5482         (plus:QI (match_dup 1) (match_dup 2)))]
5483   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5484   "add{b}\t{%2, %0|%0, %2}"
5485   [(set_attr "type" "alu")
5486    (set_attr "mode" "QI")])
5487
5488 (define_insn "*add<mode>_1"
5489   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5490         (plus:SWI48
5491           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5492           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5493    (clobber (reg:CC FLAGS_REG))]
5494   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5495 {
5496   switch (get_attr_type (insn))
5497     {
5498     case TYPE_LEA:
5499       return "#";
5500
5501     case TYPE_INCDEC:
5502       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5503       if (operands[2] == const1_rtx)
5504         return "inc{<imodesuffix>}\t%0";
5505       else
5506         {
5507           gcc_assert (operands[2] == constm1_rtx);
5508           return "dec{<imodesuffix>}\t%0";
5509         }
5510
5511     default:
5512       /* For most processors, ADD is faster than LEA.  This alternative
5513          was added to use ADD as much as possible.  */
5514       if (which_alternative == 2)
5515         {
5516           rtx tmp;
5517           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5518         }
5519         
5520       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5521       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5522         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5523
5524       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5525     }
5526 }
5527   [(set (attr "type")
5528      (cond [(eq_attr "alternative" "3")
5529               (const_string "lea")
5530             (match_operand:SWI48 2 "incdec_operand" "")
5531               (const_string "incdec")
5532            ]
5533            (const_string "alu")))
5534    (set (attr "length_immediate")
5535       (if_then_else
5536         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5537         (const_string "1")
5538         (const_string "*")))
5539    (set_attr "mode" "<MODE>")])
5540
5541 ;; It may seem that nonimmediate operand is proper one for operand 1.
5542 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5543 ;; we take care in ix86_binary_operator_ok to not allow two memory
5544 ;; operands so proper swapping will be done in reload.  This allow
5545 ;; patterns constructed from addsi_1 to match.
5546
5547 (define_insn "addsi_1_zext"
5548   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5549         (zero_extend:DI
5550           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5551                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5552    (clobber (reg:CC FLAGS_REG))]
5553   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5554 {
5555   switch (get_attr_type (insn))
5556     {
5557     case TYPE_LEA:
5558       return "#";
5559
5560     case TYPE_INCDEC:
5561       if (operands[2] == const1_rtx)
5562         return "inc{l}\t%k0";
5563       else
5564         {
5565           gcc_assert (operands[2] == constm1_rtx);
5566           return "dec{l}\t%k0";
5567         }
5568
5569     default:
5570       /* For most processors, ADD is faster than LEA.  This alternative
5571          was added to use ADD as much as possible.  */
5572       if (which_alternative == 1)
5573         {
5574           rtx tmp;
5575           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5576         }
5577
5578       if (x86_maybe_negate_const_int (&operands[2], SImode))
5579         return "sub{l}\t{%2, %k0|%k0, %2}";
5580
5581       return "add{l}\t{%2, %k0|%k0, %2}";
5582     }
5583 }
5584   [(set (attr "type")
5585      (cond [(eq_attr "alternative" "2")
5586               (const_string "lea")
5587             (match_operand:SI 2 "incdec_operand" "")
5588               (const_string "incdec")
5589            ]
5590            (const_string "alu")))
5591    (set (attr "length_immediate")
5592       (if_then_else
5593         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5594         (const_string "1")
5595         (const_string "*")))
5596    (set_attr "mode" "SI")])
5597
5598 (define_insn "*addhi_1"
5599   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5600         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5601                  (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5602    (clobber (reg:CC FLAGS_REG))]
5603   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5604 {
5605   switch (get_attr_type (insn))
5606     {
5607     case TYPE_LEA:
5608       return "#";
5609
5610     case TYPE_INCDEC:
5611       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5612       if (operands[2] == const1_rtx)
5613         return "inc{w}\t%0";
5614       else
5615         {
5616           gcc_assert (operands[2] == constm1_rtx);
5617           return "dec{w}\t%0";
5618         }
5619
5620     default:
5621       /* For most processors, ADD is faster than LEA.  This alternative
5622          was added to use ADD as much as possible.  */
5623       if (which_alternative == 2)
5624         {
5625           rtx tmp;
5626           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5627         }
5628
5629       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5630       if (x86_maybe_negate_const_int (&operands[2], HImode))
5631         return "sub{w}\t{%2, %0|%0, %2}";
5632
5633       return "add{w}\t{%2, %0|%0, %2}";
5634     }
5635 }
5636   [(set (attr "type")
5637      (cond [(eq_attr "alternative" "3")
5638               (const_string "lea")
5639             (match_operand:HI 2 "incdec_operand" "")
5640               (const_string "incdec")
5641            ]
5642            (const_string "alu")))
5643    (set (attr "length_immediate")
5644       (if_then_else
5645         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5646         (const_string "1")
5647         (const_string "*")))
5648    (set_attr "mode" "HI,HI,HI,SI")])
5649
5650 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5651 (define_insn "*addqi_1"
5652   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5653         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5654                  (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5655    (clobber (reg:CC FLAGS_REG))]
5656   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5657 {
5658   bool widen = (which_alternative == 3 || which_alternative == 4);
5659
5660   switch (get_attr_type (insn))
5661     {
5662     case TYPE_LEA:
5663       return "#";
5664
5665     case TYPE_INCDEC:
5666       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5667       if (operands[2] == const1_rtx)
5668         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5669       else
5670         {
5671           gcc_assert (operands[2] == constm1_rtx);
5672           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5673         }
5674
5675     default:
5676       /* For most processors, ADD is faster than LEA.  These alternatives
5677          were added to use ADD as much as possible.  */
5678       if (which_alternative == 2 || which_alternative == 4)
5679         {
5680           rtx tmp;
5681           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5682         }
5683
5684       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5685       if (x86_maybe_negate_const_int (&operands[2], QImode))
5686         {
5687           if (widen)
5688             return "sub{l}\t{%2, %k0|%k0, %2}";
5689           else
5690             return "sub{b}\t{%2, %0|%0, %2}";
5691         }
5692       if (widen)
5693         return "add{l}\t{%k2, %k0|%k0, %k2}";
5694       else
5695         return "add{b}\t{%2, %0|%0, %2}";
5696     }
5697 }
5698   [(set (attr "type")
5699      (cond [(eq_attr "alternative" "5")
5700               (const_string "lea")
5701             (match_operand:QI 2 "incdec_operand" "")
5702               (const_string "incdec")
5703            ]
5704            (const_string "alu")))
5705    (set (attr "length_immediate")
5706       (if_then_else
5707         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5708         (const_string "1")
5709         (const_string "*")))
5710    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5711
5712 (define_insn "*addqi_1_slp"
5713   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5714         (plus:QI (match_dup 0)
5715                  (match_operand:QI 1 "general_operand" "qn,qm")))
5716    (clobber (reg:CC FLAGS_REG))]
5717   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5718    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5719 {
5720   switch (get_attr_type (insn))
5721     {
5722     case TYPE_INCDEC:
5723       if (operands[1] == const1_rtx)
5724         return "inc{b}\t%0";
5725       else
5726         {
5727           gcc_assert (operands[1] == constm1_rtx);
5728           return "dec{b}\t%0";
5729         }
5730
5731     default:
5732       if (x86_maybe_negate_const_int (&operands[1], QImode))
5733         return "sub{b}\t{%1, %0|%0, %1}";
5734
5735       return "add{b}\t{%1, %0|%0, %1}";
5736     }
5737 }
5738   [(set (attr "type")
5739      (if_then_else (match_operand:QI 1 "incdec_operand" "")
5740         (const_string "incdec")
5741         (const_string "alu1")))
5742    (set (attr "memory")
5743      (if_then_else (match_operand 1 "memory_operand" "")
5744         (const_string "load")
5745         (const_string "none")))
5746    (set_attr "mode" "QI")])
5747
5748 ;; Split non destructive adds if we cannot use lea.
5749 (define_split
5750   [(set (match_operand:SWI48 0 "register_operand" "")
5751         (plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5752               (match_operand:SWI48 2 "nonmemory_operand" "")))
5753    (clobber (reg:CC FLAGS_REG))]
5754   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5755   [(set (match_dup 0) (match_dup 1))
5756    (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5757               (clobber (reg:CC FLAGS_REG))])])
5758
5759 ;; Convert add to the lea pattern to avoid flags dependency.
5760 (define_split
5761   [(set (match_operand:SWI 0 "register_operand" "")
5762         (plus:SWI (match_operand:SWI 1 "register_operand" "")
5763                   (match_operand:SWI 2 "<nonmemory_operand>" "")))
5764    (clobber (reg:CC FLAGS_REG))]
5765   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5766   [(const_int 0)]
5767 {
5768   enum machine_mode mode = <MODE>mode;
5769   rtx pat;
5770
5771   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5772     { 
5773       mode = SImode; 
5774       operands[0] = gen_lowpart (mode, operands[0]);
5775       operands[1] = gen_lowpart (mode, operands[1]);
5776       operands[2] = gen_lowpart (mode, operands[2]);
5777     }
5778
5779   pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5780
5781   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5782   DONE;
5783 })
5784
5785 ;; Convert add to the lea pattern to avoid flags dependency.
5786 (define_split
5787   [(set (match_operand:DI 0 "register_operand" "")
5788         (zero_extend:DI
5789           (plus:SI (match_operand:SI 1 "register_operand" "")
5790                    (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5791    (clobber (reg:CC FLAGS_REG))]
5792   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5793   [(set (match_dup 0)
5794         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5795
5796 (define_insn "*add<mode>_2"
5797   [(set (reg FLAGS_REG)
5798         (compare
5799           (plus:SWI
5800             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5801             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5802           (const_int 0)))
5803    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5804         (plus:SWI (match_dup 1) (match_dup 2)))]
5805   "ix86_match_ccmode (insn, CCGOCmode)
5806    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5807 {
5808   switch (get_attr_type (insn))
5809     {
5810     case TYPE_INCDEC:
5811       if (operands[2] == const1_rtx)
5812         return "inc{<imodesuffix>}\t%0";
5813       else
5814         {
5815           gcc_assert (operands[2] == constm1_rtx);
5816           return "dec{<imodesuffix>}\t%0";
5817         }
5818
5819     default:
5820       if (which_alternative == 2)
5821         {
5822           rtx tmp;
5823           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5824         }
5825         
5826       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5827       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5828         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5829
5830       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5831     }
5832 }
5833   [(set (attr "type")
5834      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5835         (const_string "incdec")
5836         (const_string "alu")))
5837    (set (attr "length_immediate")
5838       (if_then_else
5839         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5840         (const_string "1")
5841         (const_string "*")))
5842    (set_attr "mode" "<MODE>")])
5843
5844 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5845 (define_insn "*addsi_2_zext"
5846   [(set (reg FLAGS_REG)
5847         (compare
5848           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5849                    (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5850           (const_int 0)))
5851    (set (match_operand:DI 0 "register_operand" "=r,r")
5852         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5853   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5854    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5855 {
5856   switch (get_attr_type (insn))
5857     {
5858     case TYPE_INCDEC:
5859       if (operands[2] == const1_rtx)
5860         return "inc{l}\t%k0";
5861       else
5862         {
5863           gcc_assert (operands[2] == constm1_rtx);
5864           return "dec{l}\t%k0";
5865         }
5866
5867     default:
5868       if (which_alternative == 1)
5869         {
5870           rtx tmp;
5871           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5872         }
5873
5874       if (x86_maybe_negate_const_int (&operands[2], SImode))
5875         return "sub{l}\t{%2, %k0|%k0, %2}";
5876
5877       return "add{l}\t{%2, %k0|%k0, %2}";
5878     }
5879 }
5880   [(set (attr "type")
5881      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5882         (const_string "incdec")
5883         (const_string "alu")))
5884    (set (attr "length_immediate")
5885       (if_then_else
5886         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5887         (const_string "1")
5888         (const_string "*")))
5889    (set_attr "mode" "SI")])
5890
5891 (define_insn "*add<mode>_3"
5892   [(set (reg FLAGS_REG)
5893         (compare
5894           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5895           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5896    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5897   "ix86_match_ccmode (insn, CCZmode)
5898    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5899 {
5900   switch (get_attr_type (insn))
5901     {
5902     case TYPE_INCDEC:
5903       if (operands[2] == const1_rtx)
5904         return "inc{<imodesuffix>}\t%0";
5905       else
5906         {
5907           gcc_assert (operands[2] == constm1_rtx);
5908           return "dec{<imodesuffix>}\t%0";
5909         }
5910
5911     default:
5912       if (which_alternative == 1)
5913         {
5914           rtx tmp;
5915           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5916         }
5917
5918       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5919       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5920         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5921
5922       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5923     }
5924 }
5925   [(set (attr "type")
5926      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5927         (const_string "incdec")
5928         (const_string "alu")))
5929    (set (attr "length_immediate")
5930       (if_then_else
5931         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5932         (const_string "1")
5933         (const_string "*")))
5934    (set_attr "mode" "<MODE>")])
5935
5936 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5937 (define_insn "*addsi_3_zext"
5938   [(set (reg FLAGS_REG)
5939         (compare
5940           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5941           (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5942    (set (match_operand:DI 0 "register_operand" "=r,r")
5943         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5944   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5945    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5946 {
5947   switch (get_attr_type (insn))
5948     {
5949     case TYPE_INCDEC:
5950       if (operands[2] == const1_rtx)
5951         return "inc{l}\t%k0";
5952       else
5953         {
5954           gcc_assert (operands[2] == constm1_rtx);
5955           return "dec{l}\t%k0";
5956         }
5957
5958     default:
5959       if (which_alternative == 1)
5960         {
5961           rtx tmp;
5962           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5963         }
5964
5965       if (x86_maybe_negate_const_int (&operands[2], SImode))
5966         return "sub{l}\t{%2, %k0|%k0, %2}";
5967
5968       return "add{l}\t{%2, %k0|%k0, %2}";
5969     }
5970 }
5971   [(set (attr "type")
5972      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5973         (const_string "incdec")
5974         (const_string "alu")))
5975    (set (attr "length_immediate")
5976       (if_then_else
5977         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5978         (const_string "1")
5979         (const_string "*")))
5980    (set_attr "mode" "SI")])
5981
5982 ; For comparisons against 1, -1 and 128, we may generate better code
5983 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5984 ; is matched then.  We can't accept general immediate, because for
5985 ; case of overflows,  the result is messed up.
5986 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5987 ; only for comparisons not depending on it.
5988
5989 (define_insn "*adddi_4"
5990   [(set (reg FLAGS_REG)
5991         (compare
5992           (match_operand:DI 1 "nonimmediate_operand" "0")
5993           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5994    (clobber (match_scratch:DI 0 "=rm"))]
5995   "TARGET_64BIT
5996    && ix86_match_ccmode (insn, CCGCmode)"
5997 {
5998   switch (get_attr_type (insn))
5999     {
6000     case TYPE_INCDEC:
6001       if (operands[2] == constm1_rtx)
6002         return "inc{q}\t%0";
6003       else
6004         {
6005           gcc_assert (operands[2] == const1_rtx);
6006           return "dec{q}\t%0";
6007         }
6008
6009     default:
6010       if (x86_maybe_negate_const_int (&operands[2], DImode))
6011         return "add{q}\t{%2, %0|%0, %2}";
6012
6013       return "sub{q}\t{%2, %0|%0, %2}";
6014     }
6015 }
6016   [(set (attr "type")
6017      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6018         (const_string "incdec")
6019         (const_string "alu")))
6020    (set (attr "length_immediate")
6021       (if_then_else
6022         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6023         (const_string "1")
6024         (const_string "*")))
6025    (set_attr "mode" "DI")])
6026
6027 ; For comparisons against 1, -1 and 128, we may generate better code
6028 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6029 ; is matched then.  We can't accept general immediate, because for
6030 ; case of overflows,  the result is messed up.
6031 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6032 ; only for comparisons not depending on it.
6033
6034 (define_insn "*add<mode>_4"
6035   [(set (reg FLAGS_REG)
6036         (compare
6037           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6038           (match_operand:SWI124 2 "const_int_operand" "n")))
6039    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6040   "ix86_match_ccmode (insn, CCGCmode)"
6041 {
6042   switch (get_attr_type (insn))
6043     {
6044     case TYPE_INCDEC:
6045       if (operands[2] == constm1_rtx)
6046         return "inc{<imodesuffix>}\t%0";
6047       else
6048         {
6049           gcc_assert (operands[2] == const1_rtx);
6050           return "dec{<imodesuffix>}\t%0";
6051         }
6052
6053     default:
6054       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6055         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6056
6057       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6058     }
6059 }
6060   [(set (attr "type")
6061      (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6062         (const_string "incdec")
6063         (const_string "alu")))
6064    (set (attr "length_immediate")
6065       (if_then_else
6066         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6067         (const_string "1")
6068         (const_string "*")))
6069    (set_attr "mode" "<MODE>")])
6070
6071 (define_insn "*add<mode>_5"
6072   [(set (reg FLAGS_REG)
6073         (compare
6074           (plus:SWI
6075             (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6076             (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6077           (const_int 0)))
6078    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6079   "ix86_match_ccmode (insn, CCGOCmode)
6080    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6081 {
6082   switch (get_attr_type (insn))
6083     {
6084     case TYPE_INCDEC:
6085       if (operands[2] == const1_rtx)
6086         return "inc{<imodesuffix>}\t%0";
6087       else
6088         {
6089           gcc_assert (operands[2] == constm1_rtx);
6090           return "dec{<imodesuffix>}\t%0";
6091         }
6092
6093     default:
6094       if (which_alternative == 1)
6095         {
6096           rtx tmp;
6097           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6098         }
6099
6100       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6101       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6102         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6103
6104       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6105     }
6106 }
6107   [(set (attr "type")
6108      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6109         (const_string "incdec")
6110         (const_string "alu")))
6111    (set (attr "length_immediate")
6112       (if_then_else
6113         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6114         (const_string "1")
6115         (const_string "*")))
6116    (set_attr "mode" "<MODE>")])
6117
6118 (define_insn "*addqi_ext_1_rex64"
6119   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6120                          (const_int 8)
6121                          (const_int 8))
6122         (plus:SI
6123           (zero_extract:SI
6124             (match_operand 1 "ext_register_operand" "0")
6125             (const_int 8)
6126             (const_int 8))
6127           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6128    (clobber (reg:CC FLAGS_REG))]
6129   "TARGET_64BIT"
6130 {
6131   switch (get_attr_type (insn))
6132     {
6133     case TYPE_INCDEC:
6134       if (operands[2] == const1_rtx)
6135         return "inc{b}\t%h0";
6136       else
6137         {
6138           gcc_assert (operands[2] == constm1_rtx);
6139           return "dec{b}\t%h0";
6140         }
6141
6142     default:
6143       return "add{b}\t{%2, %h0|%h0, %2}";
6144     }
6145 }
6146   [(set (attr "type")
6147      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6148         (const_string "incdec")
6149         (const_string "alu")))
6150    (set_attr "modrm" "1")
6151    (set_attr "mode" "QI")])
6152
6153 (define_insn "addqi_ext_1"
6154   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6155                          (const_int 8)
6156                          (const_int 8))
6157         (plus:SI
6158           (zero_extract:SI
6159             (match_operand 1 "ext_register_operand" "0")
6160             (const_int 8)
6161             (const_int 8))
6162           (match_operand:QI 2 "general_operand" "Qmn")))
6163    (clobber (reg:CC FLAGS_REG))]
6164   "!TARGET_64BIT"
6165 {
6166   switch (get_attr_type (insn))
6167     {
6168     case TYPE_INCDEC:
6169       if (operands[2] == const1_rtx)
6170         return "inc{b}\t%h0";
6171       else
6172         {
6173           gcc_assert (operands[2] == constm1_rtx);
6174           return "dec{b}\t%h0";
6175         }
6176
6177     default:
6178       return "add{b}\t{%2, %h0|%h0, %2}";
6179     }
6180 }
6181   [(set (attr "type")
6182      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6183         (const_string "incdec")
6184         (const_string "alu")))
6185    (set_attr "modrm" "1")
6186    (set_attr "mode" "QI")])
6187
6188 (define_insn "*addqi_ext_2"
6189   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6190                          (const_int 8)
6191                          (const_int 8))
6192         (plus:SI
6193           (zero_extract:SI
6194             (match_operand 1 "ext_register_operand" "%0")
6195             (const_int 8)
6196             (const_int 8))
6197           (zero_extract:SI
6198             (match_operand 2 "ext_register_operand" "Q")
6199             (const_int 8)
6200             (const_int 8))))
6201    (clobber (reg:CC FLAGS_REG))]
6202   ""
6203   "add{b}\t{%h2, %h0|%h0, %h2}"
6204   [(set_attr "type" "alu")
6205    (set_attr "mode" "QI")])
6206
6207 ;; The lea patterns for modes less than 32 bits need to be matched by
6208 ;; several insns converted to real lea by splitters.
6209
6210 (define_insn_and_split "*lea_general_1"
6211   [(set (match_operand 0 "register_operand" "=r")
6212         (plus (plus (match_operand 1 "index_register_operand" "l")
6213                     (match_operand 2 "register_operand" "r"))
6214               (match_operand 3 "immediate_operand" "i")))]
6215   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6216    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6217    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6218    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6219    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6220        || GET_MODE (operands[3]) == VOIDmode)"
6221   "#"
6222   "&& reload_completed"
6223   [(const_int 0)]
6224 {
6225   enum machine_mode mode = SImode;
6226   rtx pat;
6227
6228   operands[0] = gen_lowpart (mode, operands[0]);
6229   operands[1] = gen_lowpart (mode, operands[1]);
6230   operands[2] = gen_lowpart (mode, operands[2]);
6231   operands[3] = gen_lowpart (mode, operands[3]);
6232
6233   pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6234                       operands[3]);
6235
6236   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6237   DONE;
6238 }
6239   [(set_attr "type" "lea")
6240    (set_attr "mode" "SI")])
6241
6242 (define_insn_and_split "*lea_general_2"
6243   [(set (match_operand 0 "register_operand" "=r")
6244         (plus (mult (match_operand 1 "index_register_operand" "l")
6245                     (match_operand 2 "const248_operand" "n"))
6246               (match_operand 3 "nonmemory_operand" "ri")))]
6247   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6248    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6249    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6250    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6251        || GET_MODE (operands[3]) == VOIDmode)"
6252   "#"
6253   "&& reload_completed"
6254   [(const_int 0)]
6255 {
6256   enum machine_mode mode = SImode;
6257   rtx pat;
6258
6259   operands[0] = gen_lowpart (mode, operands[0]);
6260   operands[1] = gen_lowpart (mode, operands[1]);
6261   operands[3] = gen_lowpart (mode, operands[3]);
6262
6263   pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6264                       operands[3]);
6265
6266   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6267   DONE;
6268 }
6269   [(set_attr "type" "lea")
6270    (set_attr "mode" "SI")])
6271
6272 (define_insn_and_split "*lea_general_3"
6273   [(set (match_operand 0 "register_operand" "=r")
6274         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6275                           (match_operand 2 "const248_operand" "n"))
6276                     (match_operand 3 "register_operand" "r"))
6277               (match_operand 4 "immediate_operand" "i")))]
6278   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6279    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6280    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6281    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6282   "#"
6283   "&& reload_completed"
6284   [(const_int 0)]
6285 {
6286   enum machine_mode mode = SImode;
6287   rtx pat;
6288
6289   operands[0] = gen_lowpart (mode, operands[0]);
6290   operands[1] = gen_lowpart (mode, operands[1]);
6291   operands[3] = gen_lowpart (mode, operands[3]);
6292   operands[4] = gen_lowpart (mode, operands[4]);
6293
6294   pat = gen_rtx_PLUS (mode,
6295                       gen_rtx_PLUS (mode,
6296                                     gen_rtx_MULT (mode, operands[1],
6297                                                         operands[2]),
6298                                     operands[3]),
6299                       operands[4]);
6300
6301   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6302   DONE;
6303 }
6304   [(set_attr "type" "lea")
6305    (set_attr "mode" "SI")])
6306
6307 (define_insn_and_split "*lea_general_4"
6308   [(set (match_operand 0 "register_operand" "=r")
6309         (any_or (ashift
6310                   (match_operand 1 "index_register_operand" "l")
6311                   (match_operand 2 "const_int_operand" "n"))
6312                 (match_operand 3 "const_int_operand" "n")))]
6313   "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6314       && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6315     || GET_MODE (operands[0]) == SImode
6316     || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6317    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6318    && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6319    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6320        < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6321   "#"
6322   "&& reload_completed"
6323   [(const_int 0)]
6324 {
6325   enum machine_mode mode = GET_MODE (operands[0]);
6326   rtx pat;
6327
6328   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6329     { 
6330       mode = SImode; 
6331       operands[0] = gen_lowpart (mode, operands[0]);
6332       operands[1] = gen_lowpart (mode, operands[1]);
6333     }
6334
6335   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6336
6337   pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6338                        INTVAL (operands[3]));
6339
6340   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6341   DONE;
6342 }
6343   [(set_attr "type" "lea")
6344    (set (attr "mode")
6345       (if_then_else (match_operand:DI 0 "" "")
6346         (const_string "DI")
6347         (const_string "SI")))])
6348 \f
6349 ;; Subtract instructions
6350
6351 (define_expand "sub<mode>3"
6352   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6353         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6354                      (match_operand:SDWIM 2 "<general_operand>" "")))]
6355   ""
6356   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6357
6358 (define_insn_and_split "*sub<dwi>3_doubleword"
6359   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6360         (minus:<DWI>
6361           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6362           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6363    (clobber (reg:CC FLAGS_REG))]
6364   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6365   "#"
6366   "reload_completed"
6367   [(parallel [(set (reg:CC FLAGS_REG)
6368                    (compare:CC (match_dup 1) (match_dup 2)))
6369               (set (match_dup 0)
6370                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6371    (parallel [(set (match_dup 3)
6372                    (minus:DWIH
6373                      (match_dup 4)
6374                      (plus:DWIH
6375                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6376                        (match_dup 5))))
6377               (clobber (reg:CC FLAGS_REG))])]
6378   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6379
6380 (define_insn "*sub<mode>_1"
6381   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6382         (minus:SWI
6383           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6384           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6385    (clobber (reg:CC FLAGS_REG))]
6386   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6387   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6388   [(set_attr "type" "alu")
6389    (set_attr "mode" "<MODE>")])
6390
6391 (define_insn "*subsi_1_zext"
6392   [(set (match_operand:DI 0 "register_operand" "=r")
6393         (zero_extend:DI
6394           (minus:SI (match_operand:SI 1 "register_operand" "0")
6395                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6396    (clobber (reg:CC FLAGS_REG))]
6397   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6398   "sub{l}\t{%2, %k0|%k0, %2}"
6399   [(set_attr "type" "alu")
6400    (set_attr "mode" "SI")])
6401
6402 (define_insn "*subqi_1_slp"
6403   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6404         (minus:QI (match_dup 0)
6405                   (match_operand:QI 1 "general_operand" "qn,qm")))
6406    (clobber (reg:CC FLAGS_REG))]
6407   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6408    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6409   "sub{b}\t{%1, %0|%0, %1}"
6410   [(set_attr "type" "alu1")
6411    (set_attr "mode" "QI")])
6412
6413 (define_insn "*sub<mode>_2"
6414   [(set (reg FLAGS_REG)
6415         (compare
6416           (minus:SWI
6417             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6418             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6419           (const_int 0)))
6420    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6421         (minus:SWI (match_dup 1) (match_dup 2)))]
6422   "ix86_match_ccmode (insn, CCGOCmode)
6423    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6424   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6425   [(set_attr "type" "alu")
6426    (set_attr "mode" "<MODE>")])
6427
6428 (define_insn "*subsi_2_zext"
6429   [(set (reg FLAGS_REG)
6430         (compare
6431           (minus:SI (match_operand:SI 1 "register_operand" "0")
6432                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6433           (const_int 0)))
6434    (set (match_operand:DI 0 "register_operand" "=r")
6435         (zero_extend:DI
6436           (minus:SI (match_dup 1)
6437                     (match_dup 2))))]
6438   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6439    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6440   "sub{l}\t{%2, %k0|%k0, %2}"
6441   [(set_attr "type" "alu")
6442    (set_attr "mode" "SI")])
6443
6444 (define_insn "*sub<mode>_3"
6445   [(set (reg FLAGS_REG)
6446         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6447                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6448    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6449         (minus:SWI (match_dup 1) (match_dup 2)))]
6450   "ix86_match_ccmode (insn, CCmode)
6451    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6452   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6453   [(set_attr "type" "alu")
6454    (set_attr "mode" "<MODE>")])
6455
6456 (define_insn "*subsi_3_zext"
6457   [(set (reg FLAGS_REG)
6458         (compare (match_operand:SI 1 "register_operand" "0")
6459                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6460    (set (match_operand:DI 0 "register_operand" "=r")
6461         (zero_extend:DI
6462           (minus:SI (match_dup 1)
6463                     (match_dup 2))))]
6464   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6465    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6466   "sub{l}\t{%2, %1|%1, %2}"
6467   [(set_attr "type" "alu")
6468    (set_attr "mode" "SI")])
6469 \f
6470 ;; Add with carry and subtract with borrow
6471
6472 (define_expand "<plusminus_insn><mode>3_carry"
6473   [(parallel
6474     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6475           (plusminus:SWI
6476             (match_operand:SWI 1 "nonimmediate_operand" "")
6477             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6478                        [(match_operand 3 "flags_reg_operand" "")
6479                         (const_int 0)])
6480                       (match_operand:SWI 2 "<general_operand>" ""))))
6481      (clobber (reg:CC FLAGS_REG))])]
6482   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6483
6484 (define_insn "*<plusminus_insn><mode>3_carry"
6485   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6486         (plusminus:SWI
6487           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6488           (plus:SWI
6489             (match_operator 3 "ix86_carry_flag_operator"
6490              [(reg FLAGS_REG) (const_int 0)])
6491             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6492    (clobber (reg:CC FLAGS_REG))]
6493   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6494   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6495   [(set_attr "type" "alu")
6496    (set_attr "use_carry" "1")
6497    (set_attr "pent_pair" "pu")
6498    (set_attr "mode" "<MODE>")])
6499
6500 (define_insn "*addsi3_carry_zext"
6501   [(set (match_operand:DI 0 "register_operand" "=r")
6502         (zero_extend:DI
6503           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6504                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6505                              [(reg FLAGS_REG) (const_int 0)])
6506                             (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6507    (clobber (reg:CC FLAGS_REG))]
6508   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6509   "adc{l}\t{%2, %k0|%k0, %2}"
6510   [(set_attr "type" "alu")
6511    (set_attr "use_carry" "1")
6512    (set_attr "pent_pair" "pu")
6513    (set_attr "mode" "SI")])
6514
6515 (define_insn "*subsi3_carry_zext"
6516   [(set (match_operand:DI 0 "register_operand" "=r")
6517         (zero_extend:DI
6518           (minus:SI (match_operand:SI 1 "register_operand" "0")
6519                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6520                               [(reg FLAGS_REG) (const_int 0)])
6521                              (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6522    (clobber (reg:CC FLAGS_REG))]
6523   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6524   "sbb{l}\t{%2, %k0|%k0, %2}"
6525   [(set_attr "type" "alu")
6526    (set_attr "pent_pair" "pu")
6527    (set_attr "mode" "SI")])
6528 \f
6529 ;; Overflow setting add and subtract instructions
6530
6531 (define_insn "*add<mode>3_cconly_overflow"
6532   [(set (reg:CCC FLAGS_REG)
6533         (compare:CCC
6534           (plus:SWI
6535             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6536             (match_operand:SWI 2 "<general_operand>" "<g>"))
6537           (match_dup 1)))
6538    (clobber (match_scratch:SWI 0 "=<r>"))]
6539   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6540   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6541   [(set_attr "type" "alu")
6542    (set_attr "mode" "<MODE>")])
6543
6544 (define_insn "*sub<mode>3_cconly_overflow"
6545   [(set (reg:CCC FLAGS_REG)
6546         (compare:CCC
6547           (minus:SWI
6548             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6549             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6550           (match_dup 0)))]
6551   ""
6552   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6553   [(set_attr "type" "icmp")
6554    (set_attr "mode" "<MODE>")])
6555
6556 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6557   [(set (reg:CCC FLAGS_REG)
6558         (compare:CCC
6559             (plusminus:SWI
6560                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6561                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6562             (match_dup 1)))
6563    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6564         (plusminus:SWI (match_dup 1) (match_dup 2)))]
6565   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6566   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6567   [(set_attr "type" "alu")
6568    (set_attr "mode" "<MODE>")])
6569
6570 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6571   [(set (reg:CCC FLAGS_REG)
6572         (compare:CCC
6573           (plusminus:SI
6574             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6575             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6576           (match_dup 1)))
6577    (set (match_operand:DI 0 "register_operand" "=r")
6578         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6579   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6580   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6581   [(set_attr "type" "alu")
6582    (set_attr "mode" "SI")])
6583
6584 ;; The patterns that match these are at the end of this file.
6585
6586 (define_expand "<plusminus_insn>xf3"
6587   [(set (match_operand:XF 0 "register_operand" "")
6588         (plusminus:XF
6589           (match_operand:XF 1 "register_operand" "")
6590           (match_operand:XF 2 "register_operand" "")))]
6591   "TARGET_80387")
6592
6593 (define_expand "<plusminus_insn><mode>3"
6594   [(set (match_operand:MODEF 0 "register_operand" "")
6595         (plusminus:MODEF
6596           (match_operand:MODEF 1 "register_operand" "")
6597           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6598   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6599     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6600 \f
6601 ;; Multiply instructions
6602
6603 (define_expand "mul<mode>3"
6604   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6605                    (mult:SWIM248
6606                      (match_operand:SWIM248 1 "register_operand" "")
6607                      (match_operand:SWIM248 2 "<general_operand>" "")))
6608               (clobber (reg:CC FLAGS_REG))])])
6609
6610 (define_expand "mulqi3"
6611   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6612                    (mult:QI
6613                      (match_operand:QI 1 "register_operand" "")
6614                      (match_operand:QI 2 "nonimmediate_operand" "")))
6615               (clobber (reg:CC FLAGS_REG))])]
6616   "TARGET_QIMODE_MATH")
6617
6618 ;; On AMDFAM10
6619 ;; IMUL reg32/64, reg32/64, imm8        Direct
6620 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6621 ;; IMUL reg32/64, reg32/64, imm32       Direct
6622 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6623 ;; IMUL reg32/64, reg32/64              Direct
6624 ;; IMUL reg32/64, mem32/64              Direct
6625 ;;
6626 ;; On BDVER1, all above IMULs use DirectPath
6627
6628 (define_insn "*mul<mode>3_1"
6629   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6630         (mult:SWI48
6631           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6632           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6633    (clobber (reg:CC FLAGS_REG))]
6634   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6635   "@
6636    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6637    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6638    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6639   [(set_attr "type" "imul")
6640    (set_attr "prefix_0f" "0,0,1")
6641    (set (attr "athlon_decode")
6642         (cond [(eq_attr "cpu" "athlon")
6643                   (const_string "vector")
6644                (eq_attr "alternative" "1")
6645                   (const_string "vector")
6646                (and (eq_attr "alternative" "2")
6647                     (match_operand 1 "memory_operand" ""))
6648                   (const_string "vector")]
6649               (const_string "direct")))
6650    (set (attr "amdfam10_decode")
6651         (cond [(and (eq_attr "alternative" "0,1")
6652                     (match_operand 1 "memory_operand" ""))
6653                   (const_string "vector")]
6654               (const_string "direct")))
6655    (set_attr "bdver1_decode" "direct")
6656    (set_attr "mode" "<MODE>")])
6657
6658 (define_insn "*mulsi3_1_zext"
6659   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6660         (zero_extend:DI
6661           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6662                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6663    (clobber (reg:CC FLAGS_REG))]
6664   "TARGET_64BIT
6665    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6666   "@
6667    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6668    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6669    imul{l}\t{%2, %k0|%k0, %2}"
6670   [(set_attr "type" "imul")
6671    (set_attr "prefix_0f" "0,0,1")
6672    (set (attr "athlon_decode")
6673         (cond [(eq_attr "cpu" "athlon")
6674                   (const_string "vector")
6675                (eq_attr "alternative" "1")
6676                   (const_string "vector")
6677                (and (eq_attr "alternative" "2")
6678                     (match_operand 1 "memory_operand" ""))
6679                   (const_string "vector")]
6680               (const_string "direct")))
6681    (set (attr "amdfam10_decode")
6682         (cond [(and (eq_attr "alternative" "0,1")
6683                     (match_operand 1 "memory_operand" ""))
6684                   (const_string "vector")]
6685               (const_string "direct")))
6686    (set_attr "bdver1_decode" "direct")
6687    (set_attr "mode" "SI")])
6688
6689 ;; On AMDFAM10
6690 ;; IMUL reg16, reg16, imm8      VectorPath
6691 ;; IMUL reg16, mem16, imm8      VectorPath
6692 ;; IMUL reg16, reg16, imm16     VectorPath
6693 ;; IMUL reg16, mem16, imm16     VectorPath
6694 ;; IMUL reg16, reg16            Direct
6695 ;; IMUL reg16, mem16            Direct
6696 ;;
6697 ;; On BDVER1, all HI MULs use DoublePath
6698
6699 (define_insn "*mulhi3_1"
6700   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6701         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6702                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6703    (clobber (reg:CC FLAGS_REG))]
6704   "TARGET_HIMODE_MATH
6705    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6706   "@
6707    imul{w}\t{%2, %1, %0|%0, %1, %2}
6708    imul{w}\t{%2, %1, %0|%0, %1, %2}
6709    imul{w}\t{%2, %0|%0, %2}"
6710   [(set_attr "type" "imul")
6711    (set_attr "prefix_0f" "0,0,1")
6712    (set (attr "athlon_decode")
6713         (cond [(eq_attr "cpu" "athlon")
6714                   (const_string "vector")
6715                (eq_attr "alternative" "1,2")
6716                   (const_string "vector")]
6717               (const_string "direct")))
6718    (set (attr "amdfam10_decode")
6719         (cond [(eq_attr "alternative" "0,1")
6720                   (const_string "vector")]
6721               (const_string "direct")))
6722    (set_attr "bdver1_decode" "double")
6723    (set_attr "mode" "HI")])
6724
6725 ;;On AMDFAM10 and BDVER1
6726 ;; MUL reg8     Direct
6727 ;; MUL mem8     Direct
6728
6729 (define_insn "*mulqi3_1"
6730   [(set (match_operand:QI 0 "register_operand" "=a")
6731         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6732                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6733    (clobber (reg:CC FLAGS_REG))]
6734   "TARGET_QIMODE_MATH
6735    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6736   "mul{b}\t%2"
6737   [(set_attr "type" "imul")
6738    (set_attr "length_immediate" "0")
6739    (set (attr "athlon_decode")
6740      (if_then_else (eq_attr "cpu" "athlon")
6741         (const_string "vector")
6742         (const_string "direct")))
6743    (set_attr "amdfam10_decode" "direct")
6744    (set_attr "bdver1_decode" "direct")
6745    (set_attr "mode" "QI")])
6746
6747 (define_expand "<u>mul<mode><dwi>3"
6748   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6749                    (mult:<DWI>
6750                      (any_extend:<DWI>
6751                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
6752                      (any_extend:<DWI>
6753                        (match_operand:DWIH 2 "register_operand" ""))))
6754               (clobber (reg:CC FLAGS_REG))])])
6755
6756 (define_expand "<u>mulqihi3"
6757   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6758                    (mult:HI
6759                      (any_extend:HI
6760                        (match_operand:QI 1 "nonimmediate_operand" ""))
6761                      (any_extend:HI
6762                        (match_operand:QI 2 "register_operand" ""))))
6763               (clobber (reg:CC FLAGS_REG))])]
6764   "TARGET_QIMODE_MATH")
6765
6766 (define_insn "*bmi2_umulditi3_1"
6767   [(set (match_operand:DI 0 "register_operand" "=r")
6768         (mult:DI
6769           (match_operand:DI 2 "nonimmediate_operand" "%d")
6770           (match_operand:DI 3 "nonimmediate_operand" "rm")))
6771    (set (match_operand:DI 1 "register_operand" "=r")
6772         (truncate:DI
6773           (lshiftrt:TI
6774             (mult:TI (zero_extend:TI (match_dup 2))
6775                      (zero_extend:TI (match_dup 3)))
6776             (const_int 64))))]
6777   "TARGET_64BIT && TARGET_BMI2
6778    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6779   "mulx\t{%3, %0, %1|%1, %0, %3}"
6780   [(set_attr "type" "imulx")
6781    (set_attr "prefix" "vex")
6782    (set_attr "mode" "DI")])
6783
6784 (define_insn "*bmi2_umulsidi3_1"
6785   [(set (match_operand:SI 0 "register_operand" "=r")
6786         (mult:SI
6787           (match_operand:SI 2 "nonimmediate_operand" "%d")
6788           (match_operand:SI 3 "nonimmediate_operand" "rm")))
6789    (set (match_operand:SI 1 "register_operand" "=r")
6790         (truncate:SI
6791           (lshiftrt:DI
6792             (mult:DI (zero_extend:DI (match_dup 2))
6793                      (zero_extend:DI (match_dup 3)))
6794             (const_int 32))))]
6795   "!TARGET_64BIT && TARGET_BMI2
6796    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6797   "mulx\t{%3, %0, %1|%1, %0, %3}"
6798   [(set_attr "type" "imulx")
6799    (set_attr "prefix" "vex")
6800    (set_attr "mode" "SI")])
6801
6802 (define_insn "*umul<mode><dwi>3_1"
6803   [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6804         (mult:<DWI>
6805           (zero_extend:<DWI>
6806             (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6807           (zero_extend:<DWI>
6808             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6809    (clobber (reg:CC FLAGS_REG))]
6810   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6811   "@
6812    mul{<imodesuffix>}\t%2
6813    #"
6814   [(set_attr "isa" "*,bmi2")
6815    (set_attr "type" "imul,imulx")
6816    (set_attr "length_immediate" "0,*")
6817    (set (attr "athlon_decode")
6818         (cond [(eq_attr "alternative" "0")
6819                  (if_then_else (eq_attr "cpu" "athlon")
6820                    (const_string "vector")
6821                    (const_string "double"))]
6822               (const_string "*")))
6823    (set_attr "amdfam10_decode" "double,*")
6824    (set_attr "bdver1_decode" "direct,*")
6825    (set_attr "prefix" "orig,vex")
6826    (set_attr "mode" "<MODE>")])
6827
6828 ;; Convert mul to the mulx pattern to avoid flags dependency.
6829 (define_split
6830  [(set (match_operand:<DWI> 0 "register_operand" "")
6831        (mult:<DWI>
6832          (zero_extend:<DWI>
6833            (match_operand:DWIH 1 "register_operand" ""))
6834          (zero_extend:<DWI>
6835            (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6836   (clobber (reg:CC FLAGS_REG))]
6837  "TARGET_BMI2 && reload_completed
6838   && true_regnum (operands[1]) == DX_REG"
6839   [(parallel [(set (match_dup 3)
6840                    (mult:DWIH (match_dup 1) (match_dup 2)))
6841               (set (match_dup 4)
6842                    (truncate:DWIH
6843                      (lshiftrt:<DWI>
6844                        (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6845                                    (zero_extend:<DWI> (match_dup 2)))
6846                        (match_dup 5))))])]
6847 {
6848   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6849
6850   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6851 })
6852
6853 (define_insn "*mul<mode><dwi>3_1"
6854   [(set (match_operand:<DWI> 0 "register_operand" "=A")
6855         (mult:<DWI>
6856           (sign_extend:<DWI>
6857             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6858           (sign_extend:<DWI>
6859             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6860    (clobber (reg:CC FLAGS_REG))]
6861   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6862   "imul{<imodesuffix>}\t%2"
6863   [(set_attr "type" "imul")
6864    (set_attr "length_immediate" "0")
6865    (set (attr "athlon_decode")
6866      (if_then_else (eq_attr "cpu" "athlon")
6867         (const_string "vector")
6868         (const_string "double")))
6869    (set_attr "amdfam10_decode" "double")
6870    (set_attr "bdver1_decode" "direct")
6871    (set_attr "mode" "<MODE>")])
6872
6873 (define_insn "*<u>mulqihi3_1"
6874   [(set (match_operand:HI 0 "register_operand" "=a")
6875         (mult:HI
6876           (any_extend:HI
6877             (match_operand:QI 1 "nonimmediate_operand" "%0"))
6878           (any_extend:HI
6879             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6880    (clobber (reg:CC FLAGS_REG))]
6881   "TARGET_QIMODE_MATH
6882    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6883   "<sgnprefix>mul{b}\t%2"
6884   [(set_attr "type" "imul")
6885    (set_attr "length_immediate" "0")
6886    (set (attr "athlon_decode")
6887      (if_then_else (eq_attr "cpu" "athlon")
6888         (const_string "vector")
6889         (const_string "direct")))
6890    (set_attr "amdfam10_decode" "direct")
6891    (set_attr "bdver1_decode" "direct")
6892    (set_attr "mode" "QI")])
6893
6894 (define_expand "<s>mul<mode>3_highpart"
6895   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6896                    (truncate:SWI48
6897                      (lshiftrt:<DWI>
6898                        (mult:<DWI>
6899                          (any_extend:<DWI>
6900                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
6901                          (any_extend:<DWI>
6902                            (match_operand:SWI48 2 "register_operand" "")))
6903                        (match_dup 4))))
6904               (clobber (match_scratch:SWI48 3 ""))
6905               (clobber (reg:CC FLAGS_REG))])]
6906   ""
6907   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6908
6909 (define_insn "*<s>muldi3_highpart_1"
6910   [(set (match_operand:DI 0 "register_operand" "=d")
6911         (truncate:DI
6912           (lshiftrt:TI
6913             (mult:TI
6914               (any_extend:TI
6915                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6916               (any_extend:TI
6917                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6918             (const_int 64))))
6919    (clobber (match_scratch:DI 3 "=1"))
6920    (clobber (reg:CC FLAGS_REG))]
6921   "TARGET_64BIT
6922    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6923   "<sgnprefix>mul{q}\t%2"
6924   [(set_attr "type" "imul")
6925    (set_attr "length_immediate" "0")
6926    (set (attr "athlon_decode")
6927      (if_then_else (eq_attr "cpu" "athlon")
6928         (const_string "vector")
6929         (const_string "double")))
6930    (set_attr "amdfam10_decode" "double")
6931    (set_attr "bdver1_decode" "direct")
6932    (set_attr "mode" "DI")])
6933
6934 (define_insn "*<s>mulsi3_highpart_1"
6935   [(set (match_operand:SI 0 "register_operand" "=d")
6936         (truncate:SI
6937           (lshiftrt:DI
6938             (mult:DI
6939               (any_extend:DI
6940                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6941               (any_extend:DI
6942                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6943             (const_int 32))))
6944    (clobber (match_scratch:SI 3 "=1"))
6945    (clobber (reg:CC FLAGS_REG))]
6946   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6947   "<sgnprefix>mul{l}\t%2"
6948   [(set_attr "type" "imul")
6949    (set_attr "length_immediate" "0")
6950    (set (attr "athlon_decode")
6951      (if_then_else (eq_attr "cpu" "athlon")
6952         (const_string "vector")
6953         (const_string "double")))
6954    (set_attr "amdfam10_decode" "double")
6955    (set_attr "bdver1_decode" "direct")
6956    (set_attr "mode" "SI")])
6957
6958 (define_insn "*<s>mulsi3_highpart_zext"
6959   [(set (match_operand:DI 0 "register_operand" "=d")
6960         (zero_extend:DI (truncate:SI
6961           (lshiftrt:DI
6962             (mult:DI (any_extend:DI
6963                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
6964                      (any_extend:DI
6965                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
6966             (const_int 32)))))
6967    (clobber (match_scratch:SI 3 "=1"))
6968    (clobber (reg:CC FLAGS_REG))]
6969   "TARGET_64BIT
6970    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6971   "<sgnprefix>mul{l}\t%2"
6972   [(set_attr "type" "imul")
6973    (set_attr "length_immediate" "0")
6974    (set (attr "athlon_decode")
6975      (if_then_else (eq_attr "cpu" "athlon")
6976         (const_string "vector")
6977         (const_string "double")))
6978    (set_attr "amdfam10_decode" "double")
6979    (set_attr "bdver1_decode" "direct")
6980    (set_attr "mode" "SI")])
6981
6982 ;; The patterns that match these are at the end of this file.
6983
6984 (define_expand "mulxf3"
6985   [(set (match_operand:XF 0 "register_operand" "")
6986         (mult:XF (match_operand:XF 1 "register_operand" "")
6987                  (match_operand:XF 2 "register_operand" "")))]
6988   "TARGET_80387")
6989
6990 (define_expand "mul<mode>3"
6991   [(set (match_operand:MODEF 0 "register_operand" "")
6992         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
6993                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6994   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6995     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6996 \f
6997 ;; Divide instructions
6998
6999 ;; The patterns that match these are at the end of this file.
7000
7001 (define_expand "divxf3"
7002   [(set (match_operand:XF 0 "register_operand" "")
7003         (div:XF (match_operand:XF 1 "register_operand" "")
7004                 (match_operand:XF 2 "register_operand" "")))]
7005   "TARGET_80387")
7006
7007 (define_expand "divdf3"
7008   [(set (match_operand:DF 0 "register_operand" "")
7009         (div:DF (match_operand:DF 1 "register_operand" "")
7010                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7011    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7012     || (TARGET_SSE2 && TARGET_SSE_MATH)")
7013
7014 (define_expand "divsf3"
7015   [(set (match_operand:SF 0 "register_operand" "")
7016         (div:SF (match_operand:SF 1 "register_operand" "")
7017                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7018   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7019     || TARGET_SSE_MATH"
7020 {
7021   if (TARGET_SSE_MATH
7022       && TARGET_RECIP_DIV
7023       && optimize_insn_for_speed_p ()
7024       && flag_finite_math_only && !flag_trapping_math
7025       && flag_unsafe_math_optimizations)
7026     {
7027       ix86_emit_swdivsf (operands[0], operands[1],
7028                          operands[2], SFmode);
7029       DONE;
7030     }
7031 })
7032 \f
7033 ;; Divmod instructions.
7034
7035 (define_expand "divmod<mode>4"
7036   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7037                    (div:SWIM248
7038                      (match_operand:SWIM248 1 "register_operand" "")
7039                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7040               (set (match_operand:SWIM248 3 "register_operand" "")
7041                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7042               (clobber (reg:CC FLAGS_REG))])])
7043
7044 ;; Split with 8bit unsigned divide:
7045 ;;      if (dividend an divisor are in [0-255])
7046 ;;         use 8bit unsigned integer divide
7047 ;;       else
7048 ;;         use original integer divide
7049 (define_split
7050   [(set (match_operand:SWI48 0 "register_operand" "")
7051         (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7052                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7053    (set (match_operand:SWI48 1 "register_operand" "")
7054         (mod:SWI48 (match_dup 2) (match_dup 3)))
7055    (clobber (reg:CC FLAGS_REG))]
7056   "TARGET_USE_8BIT_IDIV
7057    && TARGET_QIMODE_MATH
7058    && can_create_pseudo_p ()
7059    && !optimize_insn_for_size_p ()"
7060   [(const_int 0)]
7061   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7062
7063 (define_insn_and_split "divmod<mode>4_1"
7064   [(set (match_operand:SWI48 0 "register_operand" "=a")
7065         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7066                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7067    (set (match_operand:SWI48 1 "register_operand" "=&d")
7068         (mod:SWI48 (match_dup 2) (match_dup 3)))
7069    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7070    (clobber (reg:CC FLAGS_REG))]
7071   ""
7072   "#"
7073   "reload_completed"
7074   [(parallel [(set (match_dup 1)
7075                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7076               (clobber (reg:CC FLAGS_REG))])
7077    (parallel [(set (match_dup 0)
7078                    (div:SWI48 (match_dup 2) (match_dup 3)))
7079               (set (match_dup 1)
7080                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7081               (use (match_dup 1))
7082               (clobber (reg:CC FLAGS_REG))])]
7083 {
7084   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7085
7086   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7087     operands[4] = operands[2];
7088   else
7089     {
7090       /* Avoid use of cltd in favor of a mov+shift.  */
7091       emit_move_insn (operands[1], operands[2]);
7092       operands[4] = operands[1];
7093     }
7094 }
7095   [(set_attr "type" "multi")
7096    (set_attr "mode" "<MODE>")])
7097
7098 (define_insn_and_split "*divmod<mode>4"
7099   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7100         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7101                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7102    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7103         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7104    (clobber (reg:CC FLAGS_REG))]
7105   ""
7106   "#"
7107   "reload_completed"
7108   [(parallel [(set (match_dup 1)
7109                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7110               (clobber (reg:CC FLAGS_REG))])
7111    (parallel [(set (match_dup 0)
7112                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7113               (set (match_dup 1)
7114                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7115               (use (match_dup 1))
7116               (clobber (reg:CC FLAGS_REG))])]
7117 {
7118   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7119
7120   if (<MODE>mode != HImode
7121       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7122     operands[4] = operands[2];
7123   else
7124     {
7125       /* Avoid use of cltd in favor of a mov+shift.  */
7126       emit_move_insn (operands[1], operands[2]);
7127       operands[4] = operands[1];
7128     }
7129 }
7130   [(set_attr "type" "multi")
7131    (set_attr "mode" "<MODE>")])
7132
7133 (define_insn "*divmod<mode>4_noext"
7134   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7135         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7136                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7137    (set (match_operand:SWIM248 1 "register_operand" "=d")
7138         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7139    (use (match_operand:SWIM248 4 "register_operand" "1"))
7140    (clobber (reg:CC FLAGS_REG))]
7141   ""
7142   "idiv{<imodesuffix>}\t%3"
7143   [(set_attr "type" "idiv")
7144    (set_attr "mode" "<MODE>")])
7145
7146 (define_expand "divmodqi4"
7147   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7148                    (div:QI
7149                      (match_operand:QI 1 "register_operand" "")
7150                      (match_operand:QI 2 "nonimmediate_operand" "")))
7151               (set (match_operand:QI 3 "register_operand" "")
7152                    (mod:QI (match_dup 1) (match_dup 2)))
7153               (clobber (reg:CC FLAGS_REG))])]
7154   "TARGET_QIMODE_MATH"
7155 {
7156   rtx div, mod, insn;
7157   rtx tmp0, tmp1;
7158   
7159   tmp0 = gen_reg_rtx (HImode);
7160   tmp1 = gen_reg_rtx (HImode);
7161
7162   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7163      in AX.  */
7164   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7165   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7166
7167   /* Extract remainder from AH.  */
7168   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7169   insn = emit_move_insn (operands[3], tmp1);
7170
7171   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7172   set_unique_reg_note (insn, REG_EQUAL, mod);
7173
7174   /* Extract quotient from AL.  */
7175   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7176
7177   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7178   set_unique_reg_note (insn, REG_EQUAL, div);
7179
7180   DONE;
7181 })
7182
7183 ;; Divide AX by r/m8, with result stored in
7184 ;; AL <- Quotient
7185 ;; AH <- Remainder
7186 ;; Change div/mod to HImode and extend the second argument to HImode
7187 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7188 ;; combine may fail.
7189 (define_insn "divmodhiqi3"
7190   [(set (match_operand:HI 0 "register_operand" "=a")
7191         (ior:HI
7192           (ashift:HI
7193             (zero_extend:HI
7194               (truncate:QI
7195                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7196                         (sign_extend:HI
7197                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7198             (const_int 8))
7199           (zero_extend:HI
7200             (truncate:QI
7201               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7202    (clobber (reg:CC FLAGS_REG))]
7203   "TARGET_QIMODE_MATH"
7204   "idiv{b}\t%2"
7205   [(set_attr "type" "idiv")
7206    (set_attr "mode" "QI")])
7207
7208 (define_expand "udivmod<mode>4"
7209   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7210                    (udiv:SWIM248
7211                      (match_operand:SWIM248 1 "register_operand" "")
7212                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7213               (set (match_operand:SWIM248 3 "register_operand" "")
7214                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7215               (clobber (reg:CC FLAGS_REG))])])
7216
7217 ;; Split with 8bit unsigned divide:
7218 ;;      if (dividend an divisor are in [0-255])
7219 ;;         use 8bit unsigned integer divide
7220 ;;       else
7221 ;;         use original integer divide
7222 (define_split
7223   [(set (match_operand:SWI48 0 "register_operand" "")
7224         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7225                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7226    (set (match_operand:SWI48 1 "register_operand" "")
7227         (umod:SWI48 (match_dup 2) (match_dup 3)))
7228    (clobber (reg:CC FLAGS_REG))]
7229   "TARGET_USE_8BIT_IDIV
7230    && TARGET_QIMODE_MATH
7231    && can_create_pseudo_p ()
7232    && !optimize_insn_for_size_p ()"
7233   [(const_int 0)]
7234   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7235
7236 (define_insn_and_split "udivmod<mode>4_1"
7237   [(set (match_operand:SWI48 0 "register_operand" "=a")
7238         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7239                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7240    (set (match_operand:SWI48 1 "register_operand" "=&d")
7241         (umod:SWI48 (match_dup 2) (match_dup 3)))
7242    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7243    (clobber (reg:CC FLAGS_REG))]
7244   ""
7245   "#"
7246   "reload_completed"
7247   [(set (match_dup 1) (const_int 0))
7248    (parallel [(set (match_dup 0)
7249                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7250               (set (match_dup 1)
7251                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7252               (use (match_dup 1))
7253               (clobber (reg:CC FLAGS_REG))])]
7254   ""
7255   [(set_attr "type" "multi")
7256    (set_attr "mode" "<MODE>")])
7257
7258 (define_insn_and_split "*udivmod<mode>4"
7259   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7260         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7261                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7262    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7263         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7264    (clobber (reg:CC FLAGS_REG))]
7265   ""
7266   "#"
7267   "reload_completed"
7268   [(set (match_dup 1) (const_int 0))
7269    (parallel [(set (match_dup 0)
7270                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7271               (set (match_dup 1)
7272                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7273               (use (match_dup 1))
7274               (clobber (reg:CC FLAGS_REG))])]
7275   ""
7276   [(set_attr "type" "multi")
7277    (set_attr "mode" "<MODE>")])
7278
7279 (define_insn "*udivmod<mode>4_noext"
7280   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7281         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7282                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7283    (set (match_operand:SWIM248 1 "register_operand" "=d")
7284         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7285    (use (match_operand:SWIM248 4 "register_operand" "1"))
7286    (clobber (reg:CC FLAGS_REG))]
7287   ""
7288   "div{<imodesuffix>}\t%3"
7289   [(set_attr "type" "idiv")
7290    (set_attr "mode" "<MODE>")])
7291
7292 (define_expand "udivmodqi4"
7293   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7294                    (udiv:QI
7295                      (match_operand:QI 1 "register_operand" "")
7296                      (match_operand:QI 2 "nonimmediate_operand" "")))
7297               (set (match_operand:QI 3 "register_operand" "")
7298                    (umod:QI (match_dup 1) (match_dup 2)))
7299               (clobber (reg:CC FLAGS_REG))])]
7300   "TARGET_QIMODE_MATH"
7301 {
7302   rtx div, mod, insn;
7303   rtx tmp0, tmp1;
7304   
7305   tmp0 = gen_reg_rtx (HImode);
7306   tmp1 = gen_reg_rtx (HImode);
7307
7308   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7309      in AX.  */
7310   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7311   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7312
7313   /* Extract remainder from AH.  */
7314   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7315   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7316   insn = emit_move_insn (operands[3], tmp1);
7317
7318   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7319   set_unique_reg_note (insn, REG_EQUAL, mod);
7320
7321   /* Extract quotient from AL.  */
7322   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7323
7324   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7325   set_unique_reg_note (insn, REG_EQUAL, div);
7326
7327   DONE;
7328 })
7329
7330 (define_insn "udivmodhiqi3"
7331   [(set (match_operand:HI 0 "register_operand" "=a")
7332         (ior:HI
7333           (ashift:HI
7334             (zero_extend:HI
7335               (truncate:QI
7336                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7337                         (zero_extend:HI
7338                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7339             (const_int 8))
7340           (zero_extend:HI
7341             (truncate:QI
7342               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7343    (clobber (reg:CC FLAGS_REG))]
7344   "TARGET_QIMODE_MATH"
7345   "div{b}\t%2"
7346   [(set_attr "type" "idiv")
7347    (set_attr "mode" "QI")])
7348
7349 ;; We cannot use div/idiv for double division, because it causes
7350 ;; "division by zero" on the overflow and that's not what we expect
7351 ;; from truncate.  Because true (non truncating) double division is
7352 ;; never generated, we can't create this insn anyway.
7353 ;
7354 ;(define_insn ""
7355 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7356 ;       (truncate:SI
7357 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7358 ;                  (zero_extend:DI
7359 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7360 ;   (set (match_operand:SI 3 "register_operand" "=d")
7361 ;       (truncate:SI
7362 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7363 ;   (clobber (reg:CC FLAGS_REG))]
7364 ;  ""
7365 ;  "div{l}\t{%2, %0|%0, %2}"
7366 ;  [(set_attr "type" "idiv")])
7367 \f
7368 ;;- Logical AND instructions
7369
7370 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7371 ;; Note that this excludes ah.
7372
7373 (define_expand "testsi_ccno_1"
7374   [(set (reg:CCNO FLAGS_REG)
7375         (compare:CCNO
7376           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7377                   (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7378           (const_int 0)))])
7379
7380 (define_expand "testqi_ccz_1"
7381   [(set (reg:CCZ FLAGS_REG)
7382         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7383                              (match_operand:QI 1 "nonmemory_operand" ""))
7384                  (const_int 0)))])
7385
7386 (define_expand "testdi_ccno_1"
7387   [(set (reg:CCNO FLAGS_REG)
7388         (compare:CCNO
7389           (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7390                   (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7391           (const_int 0)))]
7392   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7393
7394 (define_insn "*testdi_1"
7395   [(set (reg FLAGS_REG)
7396         (compare
7397          (and:DI
7398           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7399           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7400          (const_int 0)))]
7401   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7402    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7403   "@
7404    test{l}\t{%k1, %k0|%k0, %k1}
7405    test{l}\t{%k1, %k0|%k0, %k1}
7406    test{q}\t{%1, %0|%0, %1}
7407    test{q}\t{%1, %0|%0, %1}
7408    test{q}\t{%1, %0|%0, %1}"
7409   [(set_attr "type" "test")
7410    (set_attr "modrm" "0,1,0,1,1")
7411    (set_attr "mode" "SI,SI,DI,DI,DI")])
7412
7413 (define_insn "*testqi_1_maybe_si"
7414   [(set (reg FLAGS_REG)
7415         (compare
7416           (and:QI
7417             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7418             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7419           (const_int 0)))]
7420    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7421     && ix86_match_ccmode (insn,
7422                          CONST_INT_P (operands[1])
7423                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7424 {
7425   if (which_alternative == 3)
7426     {
7427       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7428         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7429       return "test{l}\t{%1, %k0|%k0, %1}";
7430     }
7431   return "test{b}\t{%1, %0|%0, %1}";
7432 }
7433   [(set_attr "type" "test")
7434    (set_attr "modrm" "0,1,1,1")
7435    (set_attr "mode" "QI,QI,QI,SI")
7436    (set_attr "pent_pair" "uv,np,uv,np")])
7437
7438 (define_insn "*test<mode>_1"
7439   [(set (reg FLAGS_REG)
7440         (compare
7441          (and:SWI124
7442           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7443           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7444          (const_int 0)))]
7445   "ix86_match_ccmode (insn, CCNOmode)
7446    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7447   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7448   [(set_attr "type" "test")
7449    (set_attr "modrm" "0,1,1")
7450    (set_attr "mode" "<MODE>")
7451    (set_attr "pent_pair" "uv,np,uv")])
7452
7453 (define_expand "testqi_ext_ccno_0"
7454   [(set (reg:CCNO FLAGS_REG)
7455         (compare:CCNO
7456           (and:SI
7457             (zero_extract:SI
7458               (match_operand 0 "ext_register_operand" "")
7459               (const_int 8)
7460               (const_int 8))
7461             (match_operand 1 "const_int_operand" ""))
7462           (const_int 0)))])
7463
7464 (define_insn "*testqi_ext_0"
7465   [(set (reg FLAGS_REG)
7466         (compare
7467           (and:SI
7468             (zero_extract:SI
7469               (match_operand 0 "ext_register_operand" "Q")
7470               (const_int 8)
7471               (const_int 8))
7472             (match_operand 1 "const_int_operand" "n"))
7473           (const_int 0)))]
7474   "ix86_match_ccmode (insn, CCNOmode)"
7475   "test{b}\t{%1, %h0|%h0, %1}"
7476   [(set_attr "type" "test")
7477    (set_attr "mode" "QI")
7478    (set_attr "length_immediate" "1")
7479    (set_attr "modrm" "1")
7480    (set_attr "pent_pair" "np")])
7481
7482 (define_insn "*testqi_ext_1_rex64"
7483   [(set (reg FLAGS_REG)
7484         (compare
7485           (and:SI
7486             (zero_extract:SI
7487               (match_operand 0 "ext_register_operand" "Q")
7488               (const_int 8)
7489               (const_int 8))
7490             (zero_extend:SI
7491               (match_operand:QI 1 "register_operand" "Q")))
7492           (const_int 0)))]
7493   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7494   "test{b}\t{%1, %h0|%h0, %1}"
7495   [(set_attr "type" "test")
7496    (set_attr "mode" "QI")])
7497
7498 (define_insn "*testqi_ext_1"
7499   [(set (reg FLAGS_REG)
7500         (compare
7501           (and:SI
7502             (zero_extract:SI
7503               (match_operand 0 "ext_register_operand" "Q")
7504               (const_int 8)
7505               (const_int 8))
7506             (zero_extend:SI
7507               (match_operand:QI 1 "general_operand" "Qm")))
7508           (const_int 0)))]
7509   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7510   "test{b}\t{%1, %h0|%h0, %1}"
7511   [(set_attr "type" "test")
7512    (set_attr "mode" "QI")])
7513
7514 (define_insn "*testqi_ext_2"
7515   [(set (reg FLAGS_REG)
7516         (compare
7517           (and:SI
7518             (zero_extract:SI
7519               (match_operand 0 "ext_register_operand" "Q")
7520               (const_int 8)
7521               (const_int 8))
7522             (zero_extract:SI
7523               (match_operand 1 "ext_register_operand" "Q")
7524               (const_int 8)
7525               (const_int 8)))
7526           (const_int 0)))]
7527   "ix86_match_ccmode (insn, CCNOmode)"
7528   "test{b}\t{%h1, %h0|%h0, %h1}"
7529   [(set_attr "type" "test")
7530    (set_attr "mode" "QI")])
7531
7532 (define_insn "*testqi_ext_3_rex64"
7533   [(set (reg FLAGS_REG)
7534         (compare (zero_extract:DI
7535                    (match_operand 0 "nonimmediate_operand" "rm")
7536                    (match_operand:DI 1 "const_int_operand" "")
7537                    (match_operand:DI 2 "const_int_operand" ""))
7538                  (const_int 0)))]
7539   "TARGET_64BIT
7540    && ix86_match_ccmode (insn, CCNOmode)
7541    && INTVAL (operands[1]) > 0
7542    && INTVAL (operands[2]) >= 0
7543    /* Ensure that resulting mask is zero or sign extended operand.  */
7544    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7545        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7546            && INTVAL (operands[1]) > 32))
7547    && (GET_MODE (operands[0]) == SImode
7548        || GET_MODE (operands[0]) == DImode
7549        || GET_MODE (operands[0]) == HImode
7550        || GET_MODE (operands[0]) == QImode)"
7551   "#")
7552
7553 ;; Combine likes to form bit extractions for some tests.  Humor it.
7554 (define_insn "*testqi_ext_3"
7555   [(set (reg FLAGS_REG)
7556         (compare (zero_extract:SI
7557                    (match_operand 0 "nonimmediate_operand" "rm")
7558                    (match_operand:SI 1 "const_int_operand" "")
7559                    (match_operand:SI 2 "const_int_operand" ""))
7560                  (const_int 0)))]
7561   "ix86_match_ccmode (insn, CCNOmode)
7562    && INTVAL (operands[1]) > 0
7563    && INTVAL (operands[2]) >= 0
7564    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7565    && (GET_MODE (operands[0]) == SImode
7566        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7567        || GET_MODE (operands[0]) == HImode
7568        || GET_MODE (operands[0]) == QImode)"
7569   "#")
7570
7571 (define_split
7572   [(set (match_operand 0 "flags_reg_operand" "")
7573         (match_operator 1 "compare_operator"
7574           [(zero_extract
7575              (match_operand 2 "nonimmediate_operand" "")
7576              (match_operand 3 "const_int_operand" "")
7577              (match_operand 4 "const_int_operand" ""))
7578            (const_int 0)]))]
7579   "ix86_match_ccmode (insn, CCNOmode)"
7580   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7581 {
7582   rtx val = operands[2];
7583   HOST_WIDE_INT len = INTVAL (operands[3]);
7584   HOST_WIDE_INT pos = INTVAL (operands[4]);
7585   HOST_WIDE_INT mask;
7586   enum machine_mode mode, submode;
7587
7588   mode = GET_MODE (val);
7589   if (MEM_P (val))
7590     {
7591       /* ??? Combine likes to put non-volatile mem extractions in QImode
7592          no matter the size of the test.  So find a mode that works.  */
7593       if (! MEM_VOLATILE_P (val))
7594         {
7595           mode = smallest_mode_for_size (pos + len, MODE_INT);
7596           val = adjust_address (val, mode, 0);
7597         }
7598     }
7599   else if (GET_CODE (val) == SUBREG
7600            && (submode = GET_MODE (SUBREG_REG (val)),
7601                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7602            && pos + len <= GET_MODE_BITSIZE (submode)
7603            && GET_MODE_CLASS (submode) == MODE_INT)
7604     {
7605       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7606       mode = submode;
7607       val = SUBREG_REG (val);
7608     }
7609   else if (mode == HImode && pos + len <= 8)
7610     {
7611       /* Small HImode tests can be converted to QImode.  */
7612       mode = QImode;
7613       val = gen_lowpart (QImode, val);
7614     }
7615
7616   if (len == HOST_BITS_PER_WIDE_INT)
7617     mask = -1;
7618   else
7619     mask = ((HOST_WIDE_INT)1 << len) - 1;
7620   mask <<= pos;
7621
7622   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7623 })
7624
7625 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7626 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7627 ;; this is relatively important trick.
7628 ;; Do the conversion only post-reload to avoid limiting of the register class
7629 ;; to QI regs.
7630 (define_split
7631   [(set (match_operand 0 "flags_reg_operand" "")
7632         (match_operator 1 "compare_operator"
7633           [(and (match_operand 2 "register_operand" "")
7634                 (match_operand 3 "const_int_operand" ""))
7635            (const_int 0)]))]
7636    "reload_completed
7637     && QI_REG_P (operands[2])
7638     && GET_MODE (operands[2]) != QImode
7639     && ((ix86_match_ccmode (insn, CCZmode)
7640          && !(INTVAL (operands[3]) & ~(255 << 8)))
7641         || (ix86_match_ccmode (insn, CCNOmode)
7642             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7643   [(set (match_dup 0)
7644         (match_op_dup 1
7645           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7646                    (match_dup 3))
7647            (const_int 0)]))]
7648 {
7649   operands[2] = gen_lowpart (SImode, operands[2]);
7650   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7651 })
7652
7653 (define_split
7654   [(set (match_operand 0 "flags_reg_operand" "")
7655         (match_operator 1 "compare_operator"
7656           [(and (match_operand 2 "nonimmediate_operand" "")
7657                 (match_operand 3 "const_int_operand" ""))
7658            (const_int 0)]))]
7659    "reload_completed
7660     && GET_MODE (operands[2]) != QImode
7661     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7662     && ((ix86_match_ccmode (insn, CCZmode)
7663          && !(INTVAL (operands[3]) & ~255))
7664         || (ix86_match_ccmode (insn, CCNOmode)
7665             && !(INTVAL (operands[3]) & ~127)))"
7666   [(set (match_dup 0)
7667         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7668                          (const_int 0)]))]
7669 {
7670   operands[2] = gen_lowpart (QImode, operands[2]);
7671   operands[3] = gen_lowpart (QImode, operands[3]);
7672 })
7673
7674 ;; %%% This used to optimize known byte-wide and operations to memory,
7675 ;; and sometimes to QImode registers.  If this is considered useful,
7676 ;; it should be done with splitters.
7677
7678 (define_expand "and<mode>3"
7679   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7680         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7681                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7682   ""
7683 {
7684   if (<MODE>mode == DImode
7685       && GET_CODE (operands[2]) == CONST_INT
7686       && INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff
7687       && REG_P (operands[1]))
7688     emit_insn (gen_zero_extendsidi2 (operands[0],
7689                                      gen_lowpart (SImode, operands[1])));
7690   else
7691     ix86_expand_binary_operator (AND, <MODE>mode, operands);
7692   DONE;
7693 })
7694
7695 (define_insn "*anddi_1"
7696   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7697         (and:DI
7698          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7699          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7700    (clobber (reg:CC FLAGS_REG))]
7701   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7702 {
7703   switch (get_attr_type (insn))
7704     {
7705     case TYPE_IMOVX:
7706       {
7707         enum machine_mode mode;
7708
7709         gcc_assert (CONST_INT_P (operands[2]));
7710         if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff)
7711           mode = SImode;
7712         else if (INTVAL (operands[2]) == 0xffff)
7713           mode = HImode;
7714         else
7715           {
7716             gcc_assert (INTVAL (operands[2]) == 0xff);
7717             mode = QImode;
7718           }
7719
7720         operands[1] = gen_lowpart (mode, operands[1]);
7721         if (mode == SImode)
7722           return "mov{l}\t{%1, %k0|%k0, %1}";
7723         else if (mode == HImode)
7724           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7725         else
7726           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7727       }
7728
7729     default:
7730       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7731       if (get_attr_mode (insn) == MODE_SI)
7732         return "and{l}\t{%k2, %k0|%k0, %k2}";
7733       else
7734         return "and{q}\t{%2, %0|%0, %2}";
7735     }
7736 }
7737   [(set_attr "type" "alu,alu,alu,imovx")
7738    (set_attr "length_immediate" "*,*,*,0")
7739    (set (attr "prefix_rex")
7740      (if_then_else
7741        (and (eq_attr "type" "imovx")
7742             (and (match_test "INTVAL (operands[2]) == 0xff")
7743                  (match_operand 1 "ext_QIreg_operand" "")))
7744        (const_string "1")
7745        (const_string "*")))
7746    (set_attr "mode" "SI,DI,DI,SI")])
7747
7748 (define_insn "*andsi_1"
7749   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7750         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7751                 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7752    (clobber (reg:CC FLAGS_REG))]
7753   "ix86_binary_operator_ok (AND, SImode, operands)"
7754 {
7755   switch (get_attr_type (insn))
7756     {
7757     case TYPE_IMOVX:
7758       {
7759         enum machine_mode mode;
7760
7761         gcc_assert (CONST_INT_P (operands[2]));
7762         if (INTVAL (operands[2]) == 0xffff)
7763           mode = HImode;
7764         else
7765           {
7766             gcc_assert (INTVAL (operands[2]) == 0xff);
7767             mode = QImode;
7768           }
7769
7770         operands[1] = gen_lowpart (mode, operands[1]);
7771         if (mode == HImode)
7772           return "movz{wl|x}\t{%1, %0|%0, %1}";
7773         else
7774           return "movz{bl|x}\t{%1, %0|%0, %1}";
7775       }
7776
7777     default:
7778       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7779       return "and{l}\t{%2, %0|%0, %2}";
7780     }
7781 }
7782   [(set_attr "type" "alu,alu,imovx")
7783    (set (attr "prefix_rex")
7784      (if_then_else
7785        (and (eq_attr "type" "imovx")
7786             (and (match_test "INTVAL (operands[2]) == 0xff")
7787                  (match_operand 1 "ext_QIreg_operand" "")))
7788        (const_string "1")
7789        (const_string "*")))
7790    (set_attr "length_immediate" "*,*,0")
7791    (set_attr "mode" "SI")])
7792
7793 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7794 (define_insn "*andsi_1_zext"
7795   [(set (match_operand:DI 0 "register_operand" "=r")
7796         (zero_extend:DI
7797           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7798                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7799    (clobber (reg:CC FLAGS_REG))]
7800   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7801   "and{l}\t{%2, %k0|%k0, %2}"
7802   [(set_attr "type" "alu")
7803    (set_attr "mode" "SI")])
7804
7805 (define_insn "*andhi_1"
7806   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7807         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7808                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7809    (clobber (reg:CC FLAGS_REG))]
7810   "ix86_binary_operator_ok (AND, HImode, operands)"
7811 {
7812   switch (get_attr_type (insn))
7813     {
7814     case TYPE_IMOVX:
7815       gcc_assert (CONST_INT_P (operands[2]));
7816       gcc_assert (INTVAL (operands[2]) == 0xff);
7817       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7818
7819     default:
7820       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7821
7822       return "and{w}\t{%2, %0|%0, %2}";
7823     }
7824 }
7825   [(set_attr "type" "alu,alu,imovx")
7826    (set_attr "length_immediate" "*,*,0")
7827    (set (attr "prefix_rex")
7828      (if_then_else
7829        (and (eq_attr "type" "imovx")
7830             (match_operand 1 "ext_QIreg_operand" ""))
7831        (const_string "1")
7832        (const_string "*")))
7833    (set_attr "mode" "HI,HI,SI")])
7834
7835 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7836 (define_insn "*andqi_1"
7837   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7838         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7839                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7840    (clobber (reg:CC FLAGS_REG))]
7841   "ix86_binary_operator_ok (AND, QImode, operands)"
7842   "@
7843    and{b}\t{%2, %0|%0, %2}
7844    and{b}\t{%2, %0|%0, %2}
7845    and{l}\t{%k2, %k0|%k0, %k2}"
7846   [(set_attr "type" "alu")
7847    (set_attr "mode" "QI,QI,SI")])
7848
7849 (define_insn "*andqi_1_slp"
7850   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7851         (and:QI (match_dup 0)
7852                 (match_operand:QI 1 "general_operand" "qn,qmn")))
7853    (clobber (reg:CC FLAGS_REG))]
7854   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7855    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7856   "and{b}\t{%1, %0|%0, %1}"
7857   [(set_attr "type" "alu1")
7858    (set_attr "mode" "QI")])
7859
7860 (define_split
7861   [(set (match_operand 0 "register_operand" "")
7862         (and (match_dup 0)
7863              (const_int -65536)))
7864    (clobber (reg:CC FLAGS_REG))]
7865   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7866     || optimize_function_for_size_p (cfun)"
7867   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7868   "operands[1] = gen_lowpart (HImode, operands[0]);")
7869
7870 (define_split
7871   [(set (match_operand 0 "ext_register_operand" "")
7872         (and (match_dup 0)
7873              (const_int -256)))
7874    (clobber (reg:CC FLAGS_REG))]
7875   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7876    && reload_completed"
7877   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7878   "operands[1] = gen_lowpart (QImode, operands[0]);")
7879
7880 (define_split
7881   [(set (match_operand 0 "ext_register_operand" "")
7882         (and (match_dup 0)
7883              (const_int -65281)))
7884    (clobber (reg:CC FLAGS_REG))]
7885   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7886    && reload_completed"
7887   [(parallel [(set (zero_extract:SI (match_dup 0)
7888                                     (const_int 8)
7889                                     (const_int 8))
7890                    (xor:SI
7891                      (zero_extract:SI (match_dup 0)
7892                                       (const_int 8)
7893                                       (const_int 8))
7894                      (zero_extract:SI (match_dup 0)
7895                                       (const_int 8)
7896                                       (const_int 8))))
7897               (clobber (reg:CC FLAGS_REG))])]
7898   "operands[0] = gen_lowpart (SImode, operands[0]);")
7899
7900 (define_insn "*anddi_2"
7901   [(set (reg FLAGS_REG)
7902         (compare
7903          (and:DI
7904           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7905           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7906          (const_int 0)))
7907    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7908         (and:DI (match_dup 1) (match_dup 2)))]
7909   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7910    && ix86_binary_operator_ok (AND, DImode, operands)"
7911   "@
7912    and{l}\t{%k2, %k0|%k0, %k2}
7913    and{q}\t{%2, %0|%0, %2}
7914    and{q}\t{%2, %0|%0, %2}"
7915   [(set_attr "type" "alu")
7916    (set_attr "mode" "SI,DI,DI")])
7917
7918 (define_insn "*andqi_2_maybe_si"
7919   [(set (reg FLAGS_REG)
7920         (compare (and:QI
7921                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7922                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7923                  (const_int 0)))
7924    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7925         (and:QI (match_dup 1) (match_dup 2)))]
7926   "ix86_binary_operator_ok (AND, QImode, operands)
7927    && ix86_match_ccmode (insn,
7928                          CONST_INT_P (operands[2])
7929                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7930 {
7931   if (which_alternative == 2)
7932     {
7933       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7934         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7935       return "and{l}\t{%2, %k0|%k0, %2}";
7936     }
7937   return "and{b}\t{%2, %0|%0, %2}";
7938 }
7939   [(set_attr "type" "alu")
7940    (set_attr "mode" "QI,QI,SI")])
7941
7942 (define_insn "*and<mode>_2"
7943   [(set (reg FLAGS_REG)
7944         (compare (and:SWI124
7945                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7946                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7947                  (const_int 0)))
7948    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7949         (and:SWI124 (match_dup 1) (match_dup 2)))]
7950   "ix86_match_ccmode (insn, CCNOmode)
7951    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7952   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7953   [(set_attr "type" "alu")
7954    (set_attr "mode" "<MODE>")])
7955
7956 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7957 (define_insn "*andsi_2_zext"
7958   [(set (reg FLAGS_REG)
7959         (compare (and:SI
7960                   (match_operand:SI 1 "nonimmediate_operand" "%0")
7961                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
7962                  (const_int 0)))
7963    (set (match_operand:DI 0 "register_operand" "=r")
7964         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7965   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7966    && ix86_binary_operator_ok (AND, SImode, operands)"
7967   "and{l}\t{%2, %k0|%k0, %2}"
7968   [(set_attr "type" "alu")
7969    (set_attr "mode" "SI")])
7970
7971 (define_insn "*andqi_2_slp"
7972   [(set (reg FLAGS_REG)
7973         (compare (and:QI
7974                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7975                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7976                  (const_int 0)))
7977    (set (strict_low_part (match_dup 0))
7978         (and:QI (match_dup 0) (match_dup 1)))]
7979   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7980    && ix86_match_ccmode (insn, CCNOmode)
7981    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7982   "and{b}\t{%1, %0|%0, %1}"
7983   [(set_attr "type" "alu1")
7984    (set_attr "mode" "QI")])
7985
7986 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7987 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
7988 ;; for a QImode operand, which of course failed.
7989 (define_insn "andqi_ext_0"
7990   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7991                          (const_int 8)
7992                          (const_int 8))
7993         (and:SI
7994           (zero_extract:SI
7995             (match_operand 1 "ext_register_operand" "0")
7996             (const_int 8)
7997             (const_int 8))
7998           (match_operand 2 "const_int_operand" "n")))
7999    (clobber (reg:CC FLAGS_REG))]
8000   ""
8001   "and{b}\t{%2, %h0|%h0, %2}"
8002   [(set_attr "type" "alu")
8003    (set_attr "length_immediate" "1")
8004    (set_attr "modrm" "1")
8005    (set_attr "mode" "QI")])
8006
8007 ;; Generated by peephole translating test to and.  This shows up
8008 ;; often in fp comparisons.
8009 (define_insn "*andqi_ext_0_cc"
8010   [(set (reg FLAGS_REG)
8011         (compare
8012           (and:SI
8013             (zero_extract:SI
8014               (match_operand 1 "ext_register_operand" "0")
8015               (const_int 8)
8016               (const_int 8))
8017             (match_operand 2 "const_int_operand" "n"))
8018           (const_int 0)))
8019    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8020                          (const_int 8)
8021                          (const_int 8))
8022         (and:SI
8023           (zero_extract:SI
8024             (match_dup 1)
8025             (const_int 8)
8026             (const_int 8))
8027           (match_dup 2)))]
8028   "ix86_match_ccmode (insn, CCNOmode)"
8029   "and{b}\t{%2, %h0|%h0, %2}"
8030   [(set_attr "type" "alu")
8031    (set_attr "length_immediate" "1")
8032    (set_attr "modrm" "1")
8033    (set_attr "mode" "QI")])
8034
8035 (define_insn "*andqi_ext_1_rex64"
8036   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8037                          (const_int 8)
8038                          (const_int 8))
8039         (and:SI
8040           (zero_extract:SI
8041             (match_operand 1 "ext_register_operand" "0")
8042             (const_int 8)
8043             (const_int 8))
8044           (zero_extend:SI
8045             (match_operand 2 "ext_register_operand" "Q"))))
8046    (clobber (reg:CC FLAGS_REG))]
8047   "TARGET_64BIT"
8048   "and{b}\t{%2, %h0|%h0, %2}"
8049   [(set_attr "type" "alu")
8050    (set_attr "length_immediate" "0")
8051    (set_attr "mode" "QI")])
8052
8053 (define_insn "*andqi_ext_1"
8054   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8055                          (const_int 8)
8056                          (const_int 8))
8057         (and:SI
8058           (zero_extract:SI
8059             (match_operand 1 "ext_register_operand" "0")
8060             (const_int 8)
8061             (const_int 8))
8062           (zero_extend:SI
8063             (match_operand:QI 2 "general_operand" "Qm"))))
8064    (clobber (reg:CC FLAGS_REG))]
8065   "!TARGET_64BIT"
8066   "and{b}\t{%2, %h0|%h0, %2}"
8067   [(set_attr "type" "alu")
8068    (set_attr "length_immediate" "0")
8069    (set_attr "mode" "QI")])
8070
8071 (define_insn "*andqi_ext_2"
8072   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8073                          (const_int 8)
8074                          (const_int 8))
8075         (and:SI
8076           (zero_extract:SI
8077             (match_operand 1 "ext_register_operand" "%0")
8078             (const_int 8)
8079             (const_int 8))
8080           (zero_extract:SI
8081             (match_operand 2 "ext_register_operand" "Q")
8082             (const_int 8)
8083             (const_int 8))))
8084    (clobber (reg:CC FLAGS_REG))]
8085   ""
8086   "and{b}\t{%h2, %h0|%h0, %h2}"
8087   [(set_attr "type" "alu")
8088    (set_attr "length_immediate" "0")
8089    (set_attr "mode" "QI")])
8090
8091 ;; Convert wide AND instructions with immediate operand to shorter QImode
8092 ;; equivalents when possible.
8093 ;; Don't do the splitting with memory operands, since it introduces risk
8094 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8095 ;; for size, but that can (should?) be handled by generic code instead.
8096 (define_split
8097   [(set (match_operand 0 "register_operand" "")
8098         (and (match_operand 1 "register_operand" "")
8099              (match_operand 2 "const_int_operand" "")))
8100    (clobber (reg:CC FLAGS_REG))]
8101    "reload_completed
8102     && QI_REG_P (operands[0])
8103     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8104     && !(~INTVAL (operands[2]) & ~(255 << 8))
8105     && GET_MODE (operands[0]) != QImode"
8106   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8107                    (and:SI (zero_extract:SI (match_dup 1)
8108                                             (const_int 8) (const_int 8))
8109                            (match_dup 2)))
8110               (clobber (reg:CC FLAGS_REG))])]
8111 {
8112   operands[0] = gen_lowpart (SImode, operands[0]);
8113   operands[1] = gen_lowpart (SImode, operands[1]);
8114   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8115 })
8116
8117 ;; Since AND can be encoded with sign extended immediate, this is only
8118 ;; profitable when 7th bit is not set.
8119 (define_split
8120   [(set (match_operand 0 "register_operand" "")
8121         (and (match_operand 1 "general_operand" "")
8122              (match_operand 2 "const_int_operand" "")))
8123    (clobber (reg:CC FLAGS_REG))]
8124    "reload_completed
8125     && ANY_QI_REG_P (operands[0])
8126     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8127     && !(~INTVAL (operands[2]) & ~255)
8128     && !(INTVAL (operands[2]) & 128)
8129     && GET_MODE (operands[0]) != QImode"
8130   [(parallel [(set (strict_low_part (match_dup 0))
8131                    (and:QI (match_dup 1)
8132                            (match_dup 2)))
8133               (clobber (reg:CC FLAGS_REG))])]
8134 {
8135   operands[0] = gen_lowpart (QImode, operands[0]);
8136   operands[1] = gen_lowpart (QImode, operands[1]);
8137   operands[2] = gen_lowpart (QImode, operands[2]);
8138 })
8139 \f
8140 ;; Logical inclusive and exclusive OR instructions
8141
8142 ;; %%% This used to optimize known byte-wide and operations to memory.
8143 ;; If this is considered useful, it should be done with splitters.
8144
8145 (define_expand "<code><mode>3"
8146   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8147         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8148                      (match_operand:SWIM 2 "<general_operand>" "")))]
8149   ""
8150   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8151
8152 (define_insn "*<code><mode>_1"
8153   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8154         (any_or:SWI248
8155          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8156          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8157    (clobber (reg:CC FLAGS_REG))]
8158   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8159   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8160   [(set_attr "type" "alu")
8161    (set_attr "mode" "<MODE>")])
8162
8163 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8164 (define_insn "*<code>qi_1"
8165   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8166         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8167                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8168    (clobber (reg:CC FLAGS_REG))]
8169   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8170   "@
8171    <logic>{b}\t{%2, %0|%0, %2}
8172    <logic>{b}\t{%2, %0|%0, %2}
8173    <logic>{l}\t{%k2, %k0|%k0, %k2}"
8174   [(set_attr "type" "alu")
8175    (set_attr "mode" "QI,QI,SI")])
8176
8177 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8178 (define_insn "*<code>si_1_zext"
8179   [(set (match_operand:DI 0 "register_operand" "=r")
8180         (zero_extend:DI
8181          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8182                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8183    (clobber (reg:CC FLAGS_REG))]
8184   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8185   "<logic>{l}\t{%2, %k0|%k0, %2}"
8186   [(set_attr "type" "alu")
8187    (set_attr "mode" "SI")])
8188
8189 (define_insn "*<code>si_1_zext_imm"
8190   [(set (match_operand:DI 0 "register_operand" "=r")
8191         (any_or:DI
8192          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8193          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8194    (clobber (reg:CC FLAGS_REG))]
8195   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8196   "<logic>{l}\t{%2, %k0|%k0, %2}"
8197   [(set_attr "type" "alu")
8198    (set_attr "mode" "SI")])
8199
8200 (define_insn "*<code>qi_1_slp"
8201   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8202         (any_or:QI (match_dup 0)
8203                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8204    (clobber (reg:CC FLAGS_REG))]
8205   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8206    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8207   "<logic>{b}\t{%1, %0|%0, %1}"
8208   [(set_attr "type" "alu1")
8209    (set_attr "mode" "QI")])
8210
8211 (define_insn "*<code><mode>_2"
8212   [(set (reg FLAGS_REG)
8213         (compare (any_or:SWI
8214                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8215                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8216                  (const_int 0)))
8217    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8218         (any_or:SWI (match_dup 1) (match_dup 2)))]
8219   "ix86_match_ccmode (insn, CCNOmode)
8220    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8221   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8222   [(set_attr "type" "alu")
8223    (set_attr "mode" "<MODE>")])
8224
8225 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8226 ;; ??? Special case for immediate operand is missing - it is tricky.
8227 (define_insn "*<code>si_2_zext"
8228   [(set (reg FLAGS_REG)
8229         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8230                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
8231                  (const_int 0)))
8232    (set (match_operand:DI 0 "register_operand" "=r")
8233         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8234   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8235    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8236   "<logic>{l}\t{%2, %k0|%k0, %2}"
8237   [(set_attr "type" "alu")
8238    (set_attr "mode" "SI")])
8239
8240 (define_insn "*<code>si_2_zext_imm"
8241   [(set (reg FLAGS_REG)
8242         (compare (any_or:SI
8243                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8244                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8245                  (const_int 0)))
8246    (set (match_operand:DI 0 "register_operand" "=r")
8247         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8248   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8249    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8250   "<logic>{l}\t{%2, %k0|%k0, %2}"
8251   [(set_attr "type" "alu")
8252    (set_attr "mode" "SI")])
8253
8254 (define_insn "*<code>qi_2_slp"
8255   [(set (reg FLAGS_REG)
8256         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8257                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8258                  (const_int 0)))
8259    (set (strict_low_part (match_dup 0))
8260         (any_or:QI (match_dup 0) (match_dup 1)))]
8261   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8262    && ix86_match_ccmode (insn, CCNOmode)
8263    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8264   "<logic>{b}\t{%1, %0|%0, %1}"
8265   [(set_attr "type" "alu1")
8266    (set_attr "mode" "QI")])
8267
8268 (define_insn "*<code><mode>_3"
8269   [(set (reg FLAGS_REG)
8270         (compare (any_or:SWI
8271                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8272                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8273                  (const_int 0)))
8274    (clobber (match_scratch:SWI 0 "=<r>"))]
8275   "ix86_match_ccmode (insn, CCNOmode)
8276    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8277   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8278   [(set_attr "type" "alu")
8279    (set_attr "mode" "<MODE>")])
8280
8281 (define_insn "*<code>qi_ext_0"
8282   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8283                          (const_int 8)
8284                          (const_int 8))
8285         (any_or:SI
8286           (zero_extract:SI
8287             (match_operand 1 "ext_register_operand" "0")
8288             (const_int 8)
8289             (const_int 8))
8290           (match_operand 2 "const_int_operand" "n")))
8291    (clobber (reg:CC FLAGS_REG))]
8292   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8293   "<logic>{b}\t{%2, %h0|%h0, %2}"
8294   [(set_attr "type" "alu")
8295    (set_attr "length_immediate" "1")
8296    (set_attr "modrm" "1")
8297    (set_attr "mode" "QI")])
8298
8299 (define_insn "*<code>qi_ext_1_rex64"
8300   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8301                          (const_int 8)
8302                          (const_int 8))
8303         (any_or:SI
8304           (zero_extract:SI
8305             (match_operand 1 "ext_register_operand" "0")
8306             (const_int 8)
8307             (const_int 8))
8308           (zero_extend:SI
8309             (match_operand 2 "ext_register_operand" "Q"))))
8310    (clobber (reg:CC FLAGS_REG))]
8311   "TARGET_64BIT
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" "0")
8316    (set_attr "mode" "QI")])
8317
8318 (define_insn "*<code>qi_ext_1"
8319   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8320                          (const_int 8)
8321                          (const_int 8))
8322         (any_or:SI
8323           (zero_extract:SI
8324             (match_operand 1 "ext_register_operand" "0")
8325             (const_int 8)
8326             (const_int 8))
8327           (zero_extend:SI
8328             (match_operand:QI 2 "general_operand" "Qm"))))
8329    (clobber (reg:CC FLAGS_REG))]
8330   "!TARGET_64BIT
8331    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8332   "<logic>{b}\t{%2, %h0|%h0, %2}"
8333   [(set_attr "type" "alu")
8334    (set_attr "length_immediate" "0")
8335    (set_attr "mode" "QI")])
8336
8337 (define_insn "*<code>qi_ext_2"
8338   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8339                          (const_int 8)
8340                          (const_int 8))
8341         (any_or:SI
8342           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8343                            (const_int 8)
8344                            (const_int 8))
8345           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8346                            (const_int 8)
8347                            (const_int 8))))
8348    (clobber (reg:CC FLAGS_REG))]
8349   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8350   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8351   [(set_attr "type" "alu")
8352    (set_attr "length_immediate" "0")
8353    (set_attr "mode" "QI")])
8354
8355 (define_split
8356   [(set (match_operand 0 "register_operand" "")
8357         (any_or (match_operand 1 "register_operand" "")
8358                 (match_operand 2 "const_int_operand" "")))
8359    (clobber (reg:CC FLAGS_REG))]
8360    "reload_completed
8361     && QI_REG_P (operands[0])
8362     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8363     && !(INTVAL (operands[2]) & ~(255 << 8))
8364     && GET_MODE (operands[0]) != QImode"
8365   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8366                    (any_or:SI (zero_extract:SI (match_dup 1)
8367                                                (const_int 8) (const_int 8))
8368                               (match_dup 2)))
8369               (clobber (reg:CC FLAGS_REG))])]
8370 {
8371   operands[0] = gen_lowpart (SImode, operands[0]);
8372   operands[1] = gen_lowpart (SImode, operands[1]);
8373   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8374 })
8375
8376 ;; Since OR can be encoded with sign extended immediate, this is only
8377 ;; profitable when 7th bit is set.
8378 (define_split
8379   [(set (match_operand 0 "register_operand" "")
8380         (any_or (match_operand 1 "general_operand" "")
8381                 (match_operand 2 "const_int_operand" "")))
8382    (clobber (reg:CC FLAGS_REG))]
8383    "reload_completed
8384     && ANY_QI_REG_P (operands[0])
8385     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8386     && !(INTVAL (operands[2]) & ~255)
8387     && (INTVAL (operands[2]) & 128)
8388     && GET_MODE (operands[0]) != QImode"
8389   [(parallel [(set (strict_low_part (match_dup 0))
8390                    (any_or:QI (match_dup 1)
8391                               (match_dup 2)))
8392               (clobber (reg:CC FLAGS_REG))])]
8393 {
8394   operands[0] = gen_lowpart (QImode, operands[0]);
8395   operands[1] = gen_lowpart (QImode, operands[1]);
8396   operands[2] = gen_lowpart (QImode, operands[2]);
8397 })
8398
8399 (define_expand "xorqi_cc_ext_1"
8400   [(parallel [
8401      (set (reg:CCNO FLAGS_REG)
8402           (compare:CCNO
8403             (xor:SI
8404               (zero_extract:SI
8405                 (match_operand 1 "ext_register_operand" "")
8406                 (const_int 8)
8407                 (const_int 8))
8408               (match_operand:QI 2 "general_operand" ""))
8409             (const_int 0)))
8410      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8411                            (const_int 8)
8412                            (const_int 8))
8413           (xor:SI
8414             (zero_extract:SI
8415              (match_dup 1)
8416              (const_int 8)
8417              (const_int 8))
8418             (match_dup 2)))])])
8419
8420 (define_insn "*xorqi_cc_ext_1_rex64"
8421   [(set (reg FLAGS_REG)
8422         (compare
8423           (xor:SI
8424             (zero_extract:SI
8425               (match_operand 1 "ext_register_operand" "0")
8426               (const_int 8)
8427               (const_int 8))
8428             (match_operand:QI 2 "nonmemory_operand" "Qn"))
8429           (const_int 0)))
8430    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8431                          (const_int 8)
8432                          (const_int 8))
8433         (xor:SI
8434           (zero_extract:SI
8435            (match_dup 1)
8436            (const_int 8)
8437            (const_int 8))
8438           (match_dup 2)))]
8439   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8440   "xor{b}\t{%2, %h0|%h0, %2}"
8441   [(set_attr "type" "alu")
8442    (set_attr "modrm" "1")
8443    (set_attr "mode" "QI")])
8444
8445 (define_insn "*xorqi_cc_ext_1"
8446   [(set (reg FLAGS_REG)
8447         (compare
8448           (xor:SI
8449             (zero_extract:SI
8450               (match_operand 1 "ext_register_operand" "0")
8451               (const_int 8)
8452               (const_int 8))
8453             (match_operand:QI 2 "general_operand" "qmn"))
8454           (const_int 0)))
8455    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8456                          (const_int 8)
8457                          (const_int 8))
8458         (xor:SI
8459           (zero_extract:SI
8460            (match_dup 1)
8461            (const_int 8)
8462            (const_int 8))
8463           (match_dup 2)))]
8464   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8465   "xor{b}\t{%2, %h0|%h0, %2}"
8466   [(set_attr "type" "alu")
8467    (set_attr "modrm" "1")
8468    (set_attr "mode" "QI")])
8469 \f
8470 ;; Negation instructions
8471
8472 (define_expand "neg<mode>2"
8473   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8474         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8475   ""
8476   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8477
8478 (define_insn_and_split "*neg<dwi>2_doubleword"
8479   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8480         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8481    (clobber (reg:CC FLAGS_REG))]
8482   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8483   "#"
8484   "reload_completed"
8485   [(parallel
8486     [(set (reg:CCZ FLAGS_REG)
8487           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8488      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8489    (parallel
8490     [(set (match_dup 2)
8491           (plus:DWIH (match_dup 3)
8492                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8493                                 (const_int 0))))
8494      (clobber (reg:CC FLAGS_REG))])
8495    (parallel
8496     [(set (match_dup 2)
8497           (neg:DWIH (match_dup 2)))
8498      (clobber (reg:CC FLAGS_REG))])]
8499   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8500
8501 (define_insn "*neg<mode>2_1"
8502   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8503         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8504    (clobber (reg:CC FLAGS_REG))]
8505   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8506   "neg{<imodesuffix>}\t%0"
8507   [(set_attr "type" "negnot")
8508    (set_attr "mode" "<MODE>")])
8509
8510 ;; Combine is quite creative about this pattern.
8511 (define_insn "*negsi2_1_zext"
8512   [(set (match_operand:DI 0 "register_operand" "=r")
8513         (lshiftrt:DI
8514           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8515                              (const_int 32)))
8516         (const_int 32)))
8517    (clobber (reg:CC FLAGS_REG))]
8518   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8519   "neg{l}\t%k0"
8520   [(set_attr "type" "negnot")
8521    (set_attr "mode" "SI")])
8522
8523 ;; The problem with neg is that it does not perform (compare x 0),
8524 ;; it really performs (compare 0 x), which leaves us with the zero
8525 ;; flag being the only useful item.
8526
8527 (define_insn "*neg<mode>2_cmpz"
8528   [(set (reg:CCZ FLAGS_REG)
8529         (compare:CCZ
8530           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8531                    (const_int 0)))
8532    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8533         (neg:SWI (match_dup 1)))]
8534   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8535   "neg{<imodesuffix>}\t%0"
8536   [(set_attr "type" "negnot")
8537    (set_attr "mode" "<MODE>")])
8538
8539 (define_insn "*negsi2_cmpz_zext"
8540   [(set (reg:CCZ FLAGS_REG)
8541         (compare:CCZ
8542           (lshiftrt:DI
8543             (neg:DI (ashift:DI
8544                       (match_operand:DI 1 "register_operand" "0")
8545                       (const_int 32)))
8546             (const_int 32))
8547           (const_int 0)))
8548    (set (match_operand:DI 0 "register_operand" "=r")
8549         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8550                                         (const_int 32)))
8551                      (const_int 32)))]
8552   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8553   "neg{l}\t%k0"
8554   [(set_attr "type" "negnot")
8555    (set_attr "mode" "SI")])
8556
8557 ;; Changing of sign for FP values is doable using integer unit too.
8558
8559 (define_expand "<code><mode>2"
8560   [(set (match_operand:X87MODEF 0 "register_operand" "")
8561         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8562   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8563   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8564
8565 (define_insn "*absneg<mode>2_mixed"
8566   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8567         (match_operator:MODEF 3 "absneg_operator"
8568           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8569    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8570    (clobber (reg:CC FLAGS_REG))]
8571   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8572   "#")
8573
8574 (define_insn "*absneg<mode>2_sse"
8575   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8576         (match_operator:MODEF 3 "absneg_operator"
8577           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8578    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8579    (clobber (reg:CC FLAGS_REG))]
8580   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8581   "#")
8582
8583 (define_insn "*absneg<mode>2_i387"
8584   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8585         (match_operator:X87MODEF 3 "absneg_operator"
8586           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8587    (use (match_operand 2 "" ""))
8588    (clobber (reg:CC FLAGS_REG))]
8589   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8590   "#")
8591
8592 (define_expand "<code>tf2"
8593   [(set (match_operand:TF 0 "register_operand" "")
8594         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8595   "TARGET_SSE2"
8596   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8597
8598 (define_insn "*absnegtf2_sse"
8599   [(set (match_operand:TF 0 "register_operand" "=x,x")
8600         (match_operator:TF 3 "absneg_operator"
8601           [(match_operand:TF 1 "register_operand" "0,x")]))
8602    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8603    (clobber (reg:CC FLAGS_REG))]
8604   "TARGET_SSE2"
8605   "#")
8606
8607 ;; Splitters for fp abs and neg.
8608
8609 (define_split
8610   [(set (match_operand 0 "fp_register_operand" "")
8611         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8612    (use (match_operand 2 "" ""))
8613    (clobber (reg:CC FLAGS_REG))]
8614   "reload_completed"
8615   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8616
8617 (define_split
8618   [(set (match_operand 0 "register_operand" "")
8619         (match_operator 3 "absneg_operator"
8620           [(match_operand 1 "register_operand" "")]))
8621    (use (match_operand 2 "nonimmediate_operand" ""))
8622    (clobber (reg:CC FLAGS_REG))]
8623   "reload_completed && SSE_REG_P (operands[0])"
8624   [(set (match_dup 0) (match_dup 3))]
8625 {
8626   enum machine_mode mode = GET_MODE (operands[0]);
8627   enum machine_mode vmode = GET_MODE (operands[2]);
8628   rtx tmp;
8629
8630   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8631   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8632   if (operands_match_p (operands[0], operands[2]))
8633     {
8634       tmp = operands[1];
8635       operands[1] = operands[2];
8636       operands[2] = tmp;
8637     }
8638   if (GET_CODE (operands[3]) == ABS)
8639     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8640   else
8641     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8642   operands[3] = tmp;
8643 })
8644
8645 (define_split
8646   [(set (match_operand:SF 0 "register_operand" "")
8647         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8648    (use (match_operand:V4SF 2 "" ""))
8649    (clobber (reg:CC FLAGS_REG))]
8650   "reload_completed"
8651   [(parallel [(set (match_dup 0) (match_dup 1))
8652               (clobber (reg:CC FLAGS_REG))])]
8653 {
8654   rtx tmp;
8655   operands[0] = gen_lowpart (SImode, operands[0]);
8656   if (GET_CODE (operands[1]) == ABS)
8657     {
8658       tmp = gen_int_mode (0x7fffffff, SImode);
8659       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8660     }
8661   else
8662     {
8663       tmp = gen_int_mode (0x80000000, SImode);
8664       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8665     }
8666   operands[1] = tmp;
8667 })
8668
8669 (define_split
8670   [(set (match_operand:DF 0 "register_operand" "")
8671         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8672    (use (match_operand 2 "" ""))
8673    (clobber (reg:CC FLAGS_REG))]
8674   "reload_completed"
8675   [(parallel [(set (match_dup 0) (match_dup 1))
8676               (clobber (reg:CC FLAGS_REG))])]
8677 {
8678   rtx tmp;
8679   if (TARGET_64BIT)
8680     {
8681       tmp = gen_lowpart (DImode, operands[0]);
8682       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8683       operands[0] = tmp;
8684
8685       if (GET_CODE (operands[1]) == ABS)
8686         tmp = const0_rtx;
8687       else
8688         tmp = gen_rtx_NOT (DImode, tmp);
8689     }
8690   else
8691     {
8692       operands[0] = gen_highpart (SImode, operands[0]);
8693       if (GET_CODE (operands[1]) == ABS)
8694         {
8695           tmp = gen_int_mode (0x7fffffff, SImode);
8696           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8697         }
8698       else
8699         {
8700           tmp = gen_int_mode (0x80000000, SImode);
8701           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8702         }
8703     }
8704   operands[1] = tmp;
8705 })
8706
8707 (define_split
8708   [(set (match_operand:XF 0 "register_operand" "")
8709         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8710    (use (match_operand 2 "" ""))
8711    (clobber (reg:CC FLAGS_REG))]
8712   "reload_completed"
8713   [(parallel [(set (match_dup 0) (match_dup 1))
8714               (clobber (reg:CC FLAGS_REG))])]
8715 {
8716   rtx tmp;
8717   operands[0] = gen_rtx_REG (SImode,
8718                              true_regnum (operands[0])
8719                              + (TARGET_64BIT ? 1 : 2));
8720   if (GET_CODE (operands[1]) == ABS)
8721     {
8722       tmp = GEN_INT (0x7fff);
8723       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8724     }
8725   else
8726     {
8727       tmp = GEN_INT (0x8000);
8728       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8729     }
8730   operands[1] = tmp;
8731 })
8732
8733 ;; Conditionalize these after reload. If they match before reload, we
8734 ;; lose the clobber and ability to use integer instructions.
8735
8736 (define_insn "*<code><mode>2_1"
8737   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8738         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8739   "TARGET_80387
8740    && (reload_completed
8741        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8742   "f<absneg_mnemonic>"
8743   [(set_attr "type" "fsgn")
8744    (set_attr "mode" "<MODE>")])
8745
8746 (define_insn "*<code>extendsfdf2"
8747   [(set (match_operand:DF 0 "register_operand" "=f")
8748         (absneg:DF (float_extend:DF
8749                      (match_operand:SF 1 "register_operand" "0"))))]
8750   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8751   "f<absneg_mnemonic>"
8752   [(set_attr "type" "fsgn")
8753    (set_attr "mode" "DF")])
8754
8755 (define_insn "*<code>extendsfxf2"
8756   [(set (match_operand:XF 0 "register_operand" "=f")
8757         (absneg:XF (float_extend:XF
8758                      (match_operand:SF 1 "register_operand" "0"))))]
8759   "TARGET_80387"
8760   "f<absneg_mnemonic>"
8761   [(set_attr "type" "fsgn")
8762    (set_attr "mode" "XF")])
8763
8764 (define_insn "*<code>extenddfxf2"
8765   [(set (match_operand:XF 0 "register_operand" "=f")
8766         (absneg:XF (float_extend:XF
8767                      (match_operand:DF 1 "register_operand" "0"))))]
8768   "TARGET_80387"
8769   "f<absneg_mnemonic>"
8770   [(set_attr "type" "fsgn")
8771    (set_attr "mode" "XF")])
8772
8773 ;; Copysign instructions
8774
8775 (define_mode_iterator CSGNMODE [SF DF TF])
8776 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8777
8778 (define_expand "copysign<mode>3"
8779   [(match_operand:CSGNMODE 0 "register_operand" "")
8780    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8781    (match_operand:CSGNMODE 2 "register_operand" "")]
8782   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8783    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8784   "ix86_expand_copysign (operands); DONE;")
8785
8786 (define_insn_and_split "copysign<mode>3_const"
8787   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8788         (unspec:CSGNMODE
8789           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8790            (match_operand:CSGNMODE 2 "register_operand" "0")
8791            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8792           UNSPEC_COPYSIGN))]
8793   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8794    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8795   "#"
8796   "&& reload_completed"
8797   [(const_int 0)]
8798   "ix86_split_copysign_const (operands); DONE;")
8799
8800 (define_insn "copysign<mode>3_var"
8801   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8802         (unspec:CSGNMODE
8803           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8804            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8805            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8806            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8807           UNSPEC_COPYSIGN))
8808    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8809   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8810    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8811   "#")
8812
8813 (define_split
8814   [(set (match_operand:CSGNMODE 0 "register_operand" "")
8815         (unspec:CSGNMODE
8816           [(match_operand:CSGNMODE 2 "register_operand" "")
8817            (match_operand:CSGNMODE 3 "register_operand" "")
8818            (match_operand:<CSGNVMODE> 4 "" "")
8819            (match_operand:<CSGNVMODE> 5 "" "")]
8820           UNSPEC_COPYSIGN))
8821    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8822   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8823     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8824    && reload_completed"
8825   [(const_int 0)]
8826   "ix86_split_copysign_var (operands); DONE;")
8827 \f
8828 ;; One complement instructions
8829
8830 (define_expand "one_cmpl<mode>2"
8831   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8832         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8833   ""
8834   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8835
8836 (define_insn "*one_cmpl<mode>2_1"
8837   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8838         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8839   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8840   "not{<imodesuffix>}\t%0"
8841   [(set_attr "type" "negnot")
8842    (set_attr "mode" "<MODE>")])
8843
8844 ;; %%% Potential partial reg stall on alternative 1.  What to do?
8845 (define_insn "*one_cmplqi2_1"
8846   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8847         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8848   "ix86_unary_operator_ok (NOT, QImode, operands)"
8849   "@
8850    not{b}\t%0
8851    not{l}\t%k0"
8852   [(set_attr "type" "negnot")
8853    (set_attr "mode" "QI,SI")])
8854
8855 ;; ??? Currently never generated - xor is used instead.
8856 (define_insn "*one_cmplsi2_1_zext"
8857   [(set (match_operand:DI 0 "register_operand" "=r")
8858         (zero_extend:DI
8859           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8860   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8861   "not{l}\t%k0"
8862   [(set_attr "type" "negnot")
8863    (set_attr "mode" "SI")])
8864
8865 (define_insn "*one_cmpl<mode>2_2"
8866   [(set (reg FLAGS_REG)
8867         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8868                  (const_int 0)))
8869    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8870         (not:SWI (match_dup 1)))]
8871   "ix86_match_ccmode (insn, CCNOmode)
8872    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8873   "#"
8874   [(set_attr "type" "alu1")
8875    (set_attr "mode" "<MODE>")])
8876
8877 (define_split
8878   [(set (match_operand 0 "flags_reg_operand" "")
8879         (match_operator 2 "compare_operator"
8880           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8881            (const_int 0)]))
8882    (set (match_operand:SWI 1 "nonimmediate_operand" "")
8883         (not:SWI (match_dup 3)))]
8884   "ix86_match_ccmode (insn, CCNOmode)"
8885   [(parallel [(set (match_dup 0)
8886                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8887                                     (const_int 0)]))
8888               (set (match_dup 1)
8889                    (xor:SWI (match_dup 3) (const_int -1)))])])
8890
8891 ;; ??? Currently never generated - xor is used instead.
8892 (define_insn "*one_cmplsi2_2_zext"
8893   [(set (reg FLAGS_REG)
8894         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8895                  (const_int 0)))
8896    (set (match_operand:DI 0 "register_operand" "=r")
8897         (zero_extend:DI (not:SI (match_dup 1))))]
8898   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8899    && ix86_unary_operator_ok (NOT, SImode, operands)"
8900   "#"
8901   [(set_attr "type" "alu1")
8902    (set_attr "mode" "SI")])
8903
8904 (define_split
8905   [(set (match_operand 0 "flags_reg_operand" "")
8906         (match_operator 2 "compare_operator"
8907           [(not:SI (match_operand:SI 3 "register_operand" ""))
8908            (const_int 0)]))
8909    (set (match_operand:DI 1 "register_operand" "")
8910         (zero_extend:DI (not:SI (match_dup 3))))]
8911   "ix86_match_ccmode (insn, CCNOmode)"
8912   [(parallel [(set (match_dup 0)
8913                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8914                                     (const_int 0)]))
8915               (set (match_dup 1)
8916                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8917 \f
8918 ;; Shift instructions
8919
8920 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8921 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
8922 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8923 ;; from the assembler input.
8924 ;;
8925 ;; This instruction shifts the target reg/mem as usual, but instead of
8926 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
8927 ;; is a left shift double, bits are taken from the high order bits of
8928 ;; reg, else if the insn is a shift right double, bits are taken from the
8929 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
8930 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8931 ;;
8932 ;; Since sh[lr]d does not change the `reg' operand, that is done
8933 ;; separately, making all shifts emit pairs of shift double and normal
8934 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
8935 ;; support a 63 bit shift, each shift where the count is in a reg expands
8936 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8937 ;;
8938 ;; If the shift count is a constant, we need never emit more than one
8939 ;; shift pair, instead using moves and sign extension for counts greater
8940 ;; than 31.
8941
8942 (define_expand "ashl<mode>3"
8943   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8944         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8945                       (match_operand:QI 2 "nonmemory_operand" "")))]
8946   ""
8947   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8948
8949 (define_insn "*ashl<mode>3_doubleword"
8950   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8951         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8952                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8953    (clobber (reg:CC FLAGS_REG))]
8954   ""
8955   "#"
8956   [(set_attr "type" "multi")])
8957
8958 (define_split
8959   [(set (match_operand:DWI 0 "register_operand" "")
8960         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8961                     (match_operand:QI 2 "nonmemory_operand" "")))
8962    (clobber (reg:CC FLAGS_REG))]
8963   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8964   [(const_int 0)]
8965   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8966
8967 ;; By default we don't ask for a scratch register, because when DWImode
8968 ;; values are manipulated, registers are already at a premium.  But if
8969 ;; we have one handy, we won't turn it away.
8970
8971 (define_peephole2
8972   [(match_scratch:DWIH 3 "r")
8973    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8974                    (ashift:<DWI>
8975                      (match_operand:<DWI> 1 "nonmemory_operand" "")
8976                      (match_operand:QI 2 "nonmemory_operand" "")))
8977               (clobber (reg:CC FLAGS_REG))])
8978    (match_dup 3)]
8979   "TARGET_CMOVE"
8980   [(const_int 0)]
8981   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8982
8983 (define_insn "x86_64_shld"
8984   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8985         (ior:DI (ashift:DI (match_dup 0)
8986                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
8987                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8988                   (minus:QI (const_int 64) (match_dup 2)))))
8989    (clobber (reg:CC FLAGS_REG))]
8990   "TARGET_64BIT"
8991   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8992   [(set_attr "type" "ishift")
8993    (set_attr "prefix_0f" "1")
8994    (set_attr "mode" "DI")
8995    (set_attr "athlon_decode" "vector")
8996    (set_attr "amdfam10_decode" "vector")
8997    (set_attr "bdver1_decode" "vector")])
8998
8999 (define_insn "x86_shld"
9000   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9001         (ior:SI (ashift:SI (match_dup 0)
9002                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9003                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9004                   (minus:QI (const_int 32) (match_dup 2)))))
9005    (clobber (reg:CC FLAGS_REG))]
9006   ""
9007   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9008   [(set_attr "type" "ishift")
9009    (set_attr "prefix_0f" "1")
9010    (set_attr "mode" "SI")
9011    (set_attr "pent_pair" "np")
9012    (set_attr "athlon_decode" "vector")
9013    (set_attr "amdfam10_decode" "vector")
9014    (set_attr "bdver1_decode" "vector")])
9015
9016 (define_expand "x86_shift<mode>_adj_1"
9017   [(set (reg:CCZ FLAGS_REG)
9018         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9019                              (match_dup 4))
9020                      (const_int 0)))
9021    (set (match_operand:SWI48 0 "register_operand" "")
9022         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9023                             (match_operand:SWI48 1 "register_operand" "")
9024                             (match_dup 0)))
9025    (set (match_dup 1)
9026         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9027                             (match_operand:SWI48 3 "register_operand" "")
9028                             (match_dup 1)))]
9029   "TARGET_CMOVE"
9030   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9031
9032 (define_expand "x86_shift<mode>_adj_2"
9033   [(use (match_operand:SWI48 0 "register_operand" ""))
9034    (use (match_operand:SWI48 1 "register_operand" ""))
9035    (use (match_operand:QI 2 "register_operand" ""))]
9036   ""
9037 {
9038   rtx label = gen_label_rtx ();
9039   rtx tmp;
9040
9041   emit_insn (gen_testqi_ccz_1 (operands[2],
9042                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9043
9044   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9045   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9046   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9047                               gen_rtx_LABEL_REF (VOIDmode, label),
9048                               pc_rtx);
9049   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9050   JUMP_LABEL (tmp) = label;
9051
9052   emit_move_insn (operands[0], operands[1]);
9053   ix86_expand_clear (operands[1]);
9054
9055   emit_label (label);
9056   LABEL_NUSES (label) = 1;
9057
9058   DONE;
9059 })
9060
9061 ;; Avoid useless masking of count operand.
9062 (define_insn_and_split "*ashl<mode>3_mask"
9063   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9064         (ashift:SWI48
9065           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9066           (subreg:QI
9067             (and:SI
9068               (match_operand:SI 2 "nonimmediate_operand" "c")
9069               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9070    (clobber (reg:CC FLAGS_REG))]
9071   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9072    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9073       == GET_MODE_BITSIZE (<MODE>mode)-1"
9074   "#"
9075   "&& 1"
9076   [(parallel [(set (match_dup 0)
9077                    (ashift:SWI48 (match_dup 1) (match_dup 2)))
9078               (clobber (reg:CC FLAGS_REG))])]
9079 {
9080   if (can_create_pseudo_p ())
9081     operands [2] = force_reg (SImode, operands[2]);
9082
9083   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9084 }
9085   [(set_attr "type" "ishift")
9086    (set_attr "mode" "<MODE>")])
9087
9088 (define_insn "*bmi2_ashl<mode>3_1"
9089   [(set (match_operand:SWI48 0 "register_operand" "=r")
9090         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9091                       (match_operand:SWI48 2 "register_operand" "r")))]
9092   "TARGET_BMI2"
9093   "shlx\t{%2, %1, %0|%0, %1, %2}"
9094   [(set_attr "type" "ishiftx")
9095    (set_attr "mode" "<MODE>")])
9096
9097 (define_insn "*ashl<mode>3_1"
9098   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9099         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9100                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9101    (clobber (reg:CC FLAGS_REG))]
9102   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9103 {
9104   switch (get_attr_type (insn))
9105     {
9106     case TYPE_LEA:
9107     case TYPE_ISHIFTX:
9108       return "#";
9109
9110     case TYPE_ALU:
9111       gcc_assert (operands[2] == const1_rtx);
9112       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9113       return "add{<imodesuffix>}\t%0, %0";
9114
9115     default:
9116       if (operands[2] == const1_rtx
9117           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9118         return "sal{<imodesuffix>}\t%0";
9119       else
9120         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9121     }
9122 }
9123   [(set_attr "isa" "*,*,bmi2")
9124    (set (attr "type")
9125      (cond [(eq_attr "alternative" "1")
9126               (const_string "lea")
9127             (eq_attr "alternative" "2")
9128               (const_string "ishiftx")
9129             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9130                       (match_operand 0 "register_operand" ""))
9131                  (match_operand 2 "const1_operand" ""))
9132               (const_string "alu")
9133            ]
9134            (const_string "ishift")))
9135    (set (attr "length_immediate")
9136      (if_then_else
9137        (ior (eq_attr "type" "alu")
9138             (and (eq_attr "type" "ishift")
9139                  (and (match_operand 2 "const1_operand" "")
9140                       (ior (match_test "TARGET_SHIFT1")
9141                            (match_test "optimize_function_for_size_p (cfun)")))))
9142        (const_string "0")
9143        (const_string "*")))
9144    (set_attr "mode" "<MODE>")])
9145
9146 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9147 (define_split
9148   [(set (match_operand:SWI48 0 "register_operand" "")
9149         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9150                       (match_operand:QI 2 "register_operand" "")))
9151    (clobber (reg:CC FLAGS_REG))]
9152   "TARGET_BMI2 && reload_completed"
9153   [(set (match_dup 0)
9154         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9155   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9156
9157 (define_insn "*bmi2_ashlsi3_1_zext"
9158   [(set (match_operand:DI 0 "register_operand" "=r")
9159         (zero_extend:DI
9160           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9161                      (match_operand:SI 2 "register_operand" "r"))))]
9162   "TARGET_64BIT && TARGET_BMI2"
9163   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9164   [(set_attr "type" "ishiftx")
9165    (set_attr "mode" "SI")])
9166
9167 (define_insn "*ashlsi3_1_zext"
9168   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9169         (zero_extend:DI
9170           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9171                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9172    (clobber (reg:CC FLAGS_REG))]
9173   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9174 {
9175   switch (get_attr_type (insn))
9176     {
9177     case TYPE_LEA:
9178     case TYPE_ISHIFTX:
9179       return "#";
9180
9181     case TYPE_ALU:
9182       gcc_assert (operands[2] == const1_rtx);
9183       return "add{l}\t%k0, %k0";
9184
9185     default:
9186       if (operands[2] == const1_rtx
9187           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9188         return "sal{l}\t%k0";
9189       else
9190         return "sal{l}\t{%2, %k0|%k0, %2}";
9191     }
9192 }
9193   [(set_attr "isa" "*,*,bmi2")
9194    (set (attr "type")
9195      (cond [(eq_attr "alternative" "1")
9196               (const_string "lea")
9197             (eq_attr "alternative" "2")
9198               (const_string "ishiftx")
9199             (and (match_test "TARGET_DOUBLE_WITH_ADD")
9200                  (match_operand 2 "const1_operand" ""))
9201               (const_string "alu")
9202            ]
9203            (const_string "ishift")))
9204    (set (attr "length_immediate")
9205      (if_then_else
9206        (ior (eq_attr "type" "alu")
9207             (and (eq_attr "type" "ishift")
9208                  (and (match_operand 2 "const1_operand" "")
9209                       (ior (match_test "TARGET_SHIFT1")
9210                            (match_test "optimize_function_for_size_p (cfun)")))))
9211        (const_string "0")
9212        (const_string "*")))
9213    (set_attr "mode" "SI")])
9214
9215 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9216 (define_split
9217   [(set (match_operand:DI 0 "register_operand" "")
9218         (zero_extend:DI
9219           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9220                      (match_operand:QI 2 "register_operand" ""))))
9221    (clobber (reg:CC FLAGS_REG))]
9222   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9223   [(set (match_dup 0)
9224         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9225   "operands[2] = gen_lowpart (SImode, operands[2]);")
9226
9227 (define_insn "*ashlhi3_1"
9228   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9229         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9230                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9231    (clobber (reg:CC FLAGS_REG))]
9232   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9233 {
9234   switch (get_attr_type (insn))
9235     {
9236     case TYPE_LEA:
9237       return "#";
9238
9239     case TYPE_ALU:
9240       gcc_assert (operands[2] == const1_rtx);
9241       return "add{w}\t%0, %0";
9242
9243     default:
9244       if (operands[2] == const1_rtx
9245           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9246         return "sal{w}\t%0";
9247       else
9248         return "sal{w}\t{%2, %0|%0, %2}";
9249     }
9250 }
9251   [(set (attr "type")
9252      (cond [(eq_attr "alternative" "1")
9253               (const_string "lea")
9254             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9255                       (match_operand 0 "register_operand" ""))
9256                  (match_operand 2 "const1_operand" ""))
9257               (const_string "alu")
9258            ]
9259            (const_string "ishift")))
9260    (set (attr "length_immediate")
9261      (if_then_else
9262        (ior (eq_attr "type" "alu")
9263             (and (eq_attr "type" "ishift")
9264                  (and (match_operand 2 "const1_operand" "")
9265                       (ior (match_test "TARGET_SHIFT1")
9266                            (match_test "optimize_function_for_size_p (cfun)")))))
9267        (const_string "0")
9268        (const_string "*")))
9269    (set_attr "mode" "HI,SI")])
9270
9271 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9272 (define_insn "*ashlqi3_1"
9273   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9274         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9275                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9276    (clobber (reg:CC FLAGS_REG))]
9277   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9278 {
9279   switch (get_attr_type (insn))
9280     {
9281     case TYPE_LEA:
9282       return "#";
9283
9284     case TYPE_ALU:
9285       gcc_assert (operands[2] == const1_rtx);
9286       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9287         return "add{l}\t%k0, %k0";
9288       else
9289         return "add{b}\t%0, %0";
9290
9291     default:
9292       if (operands[2] == const1_rtx
9293           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9294         {
9295           if (get_attr_mode (insn) == MODE_SI)
9296             return "sal{l}\t%k0";
9297           else
9298             return "sal{b}\t%0";
9299         }
9300       else
9301         {
9302           if (get_attr_mode (insn) == MODE_SI)
9303             return "sal{l}\t{%2, %k0|%k0, %2}";
9304           else
9305             return "sal{b}\t{%2, %0|%0, %2}";
9306         }
9307     }
9308 }
9309   [(set (attr "type")
9310      (cond [(eq_attr "alternative" "2")
9311               (const_string "lea")
9312             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9313                       (match_operand 0 "register_operand" ""))
9314                  (match_operand 2 "const1_operand" ""))
9315               (const_string "alu")
9316            ]
9317            (const_string "ishift")))
9318    (set (attr "length_immediate")
9319      (if_then_else
9320        (ior (eq_attr "type" "alu")
9321             (and (eq_attr "type" "ishift")
9322                  (and (match_operand 2 "const1_operand" "")
9323                       (ior (match_test "TARGET_SHIFT1")
9324                            (match_test "optimize_function_for_size_p (cfun)")))))
9325        (const_string "0")
9326        (const_string "*")))
9327    (set_attr "mode" "QI,SI,SI")])
9328
9329 (define_insn "*ashlqi3_1_slp"
9330   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9331         (ashift:QI (match_dup 0)
9332                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9333    (clobber (reg:CC FLAGS_REG))]
9334   "(optimize_function_for_size_p (cfun)
9335     || !TARGET_PARTIAL_FLAG_REG_STALL
9336     || (operands[1] == const1_rtx
9337         && (TARGET_SHIFT1
9338             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9339 {
9340   switch (get_attr_type (insn))
9341     {
9342     case TYPE_ALU:
9343       gcc_assert (operands[1] == const1_rtx);
9344       return "add{b}\t%0, %0";
9345
9346     default:
9347       if (operands[1] == const1_rtx
9348           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9349         return "sal{b}\t%0";
9350       else
9351         return "sal{b}\t{%1, %0|%0, %1}";
9352     }
9353 }
9354   [(set (attr "type")
9355      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9356                       (match_operand 0 "register_operand" ""))
9357                  (match_operand 1 "const1_operand" ""))
9358               (const_string "alu")
9359            ]
9360            (const_string "ishift1")))
9361    (set (attr "length_immediate")
9362      (if_then_else
9363        (ior (eq_attr "type" "alu")
9364             (and (eq_attr "type" "ishift1")
9365                  (and (match_operand 1 "const1_operand" "")
9366                       (ior (match_test "TARGET_SHIFT1")
9367                            (match_test "optimize_function_for_size_p (cfun)")))))
9368        (const_string "0")
9369        (const_string "*")))
9370    (set_attr "mode" "QI")])
9371
9372 ;; Convert ashift to the lea pattern to avoid flags dependency.
9373 (define_split
9374   [(set (match_operand 0 "register_operand" "")
9375         (ashift (match_operand 1 "index_register_operand" "")
9376                 (match_operand:QI 2 "const_int_operand" "")))
9377    (clobber (reg:CC FLAGS_REG))]
9378   "GET_MODE (operands[0]) == GET_MODE (operands[1])
9379    && reload_completed
9380    && true_regnum (operands[0]) != true_regnum (operands[1])"
9381   [(const_int 0)]
9382 {
9383   enum machine_mode mode = GET_MODE (operands[0]);
9384   rtx pat;
9385
9386   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9387     { 
9388       mode = SImode; 
9389       operands[0] = gen_lowpart (mode, operands[0]);
9390       operands[1] = gen_lowpart (mode, operands[1]);
9391     }
9392
9393   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9394
9395   pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9396
9397   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9398   DONE;
9399 })
9400
9401 ;; Convert ashift to the lea pattern to avoid flags dependency.
9402 (define_split
9403   [(set (match_operand:DI 0 "register_operand" "")
9404         (zero_extend:DI
9405           (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9406                      (match_operand:QI 2 "const_int_operand" ""))))
9407    (clobber (reg:CC FLAGS_REG))]
9408   "TARGET_64BIT && reload_completed
9409    && true_regnum (operands[0]) != true_regnum (operands[1])"
9410   [(set (match_dup 0)
9411         (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9412 {
9413   operands[1] = gen_lowpart (DImode, operands[1]);
9414   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9415 })
9416
9417 ;; This pattern can't accept a variable shift count, since shifts by
9418 ;; zero don't affect the flags.  We assume that shifts by constant
9419 ;; zero are optimized away.
9420 (define_insn "*ashl<mode>3_cmp"
9421   [(set (reg FLAGS_REG)
9422         (compare
9423           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9424                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9425           (const_int 0)))
9426    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9427         (ashift:SWI (match_dup 1) (match_dup 2)))]
9428   "(optimize_function_for_size_p (cfun)
9429     || !TARGET_PARTIAL_FLAG_REG_STALL
9430     || (operands[2] == const1_rtx
9431         && (TARGET_SHIFT1
9432             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9433    && ix86_match_ccmode (insn, CCGOCmode)
9434    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9435 {
9436   switch (get_attr_type (insn))
9437     {
9438     case TYPE_ALU:
9439       gcc_assert (operands[2] == const1_rtx);
9440       return "add{<imodesuffix>}\t%0, %0";
9441
9442     default:
9443       if (operands[2] == const1_rtx
9444           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9445         return "sal{<imodesuffix>}\t%0";
9446       else
9447         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9448     }
9449 }
9450   [(set (attr "type")
9451      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9452                       (match_operand 0 "register_operand" ""))
9453                  (match_operand 2 "const1_operand" ""))
9454               (const_string "alu")
9455            ]
9456            (const_string "ishift")))
9457    (set (attr "length_immediate")
9458      (if_then_else
9459        (ior (eq_attr "type" "alu")
9460             (and (eq_attr "type" "ishift")
9461                  (and (match_operand 2 "const1_operand" "")
9462                       (ior (match_test "TARGET_SHIFT1")
9463                            (match_test "optimize_function_for_size_p (cfun)")))))
9464        (const_string "0")
9465        (const_string "*")))
9466    (set_attr "mode" "<MODE>")])
9467
9468 (define_insn "*ashlsi3_cmp_zext"
9469   [(set (reg FLAGS_REG)
9470         (compare
9471           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9472                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9473           (const_int 0)))
9474    (set (match_operand:DI 0 "register_operand" "=r")
9475         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9476   "TARGET_64BIT
9477    && (optimize_function_for_size_p (cfun)
9478        || !TARGET_PARTIAL_FLAG_REG_STALL
9479        || (operands[2] == const1_rtx
9480            && (TARGET_SHIFT1
9481                || TARGET_DOUBLE_WITH_ADD)))
9482    && ix86_match_ccmode (insn, CCGOCmode)
9483    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9484 {
9485   switch (get_attr_type (insn))
9486     {
9487     case TYPE_ALU:
9488       gcc_assert (operands[2] == const1_rtx);
9489       return "add{l}\t%k0, %k0";
9490
9491     default:
9492       if (operands[2] == const1_rtx
9493           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9494         return "sal{l}\t%k0";
9495       else
9496         return "sal{l}\t{%2, %k0|%k0, %2}";
9497     }
9498 }
9499   [(set (attr "type")
9500      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9501                  (match_operand 2 "const1_operand" ""))
9502               (const_string "alu")
9503            ]
9504            (const_string "ishift")))
9505    (set (attr "length_immediate")
9506      (if_then_else
9507        (ior (eq_attr "type" "alu")
9508             (and (eq_attr "type" "ishift")
9509                  (and (match_operand 2 "const1_operand" "")
9510                       (ior (match_test "TARGET_SHIFT1")
9511                            (match_test "optimize_function_for_size_p (cfun)")))))
9512        (const_string "0")
9513        (const_string "*")))
9514    (set_attr "mode" "SI")])
9515
9516 (define_insn "*ashl<mode>3_cconly"
9517   [(set (reg FLAGS_REG)
9518         (compare
9519           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9520                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9521           (const_int 0)))
9522    (clobber (match_scratch:SWI 0 "=<r>"))]
9523   "(optimize_function_for_size_p (cfun)
9524     || !TARGET_PARTIAL_FLAG_REG_STALL
9525     || (operands[2] == const1_rtx
9526         && (TARGET_SHIFT1
9527             || TARGET_DOUBLE_WITH_ADD)))
9528    && ix86_match_ccmode (insn, CCGOCmode)"
9529 {
9530   switch (get_attr_type (insn))
9531     {
9532     case TYPE_ALU:
9533       gcc_assert (operands[2] == const1_rtx);
9534       return "add{<imodesuffix>}\t%0, %0";
9535
9536     default:
9537       if (operands[2] == const1_rtx
9538           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9539         return "sal{<imodesuffix>}\t%0";
9540       else
9541         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9542     }
9543 }
9544   [(set (attr "type")
9545      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9546                       (match_operand 0 "register_operand" ""))
9547                  (match_operand 2 "const1_operand" ""))
9548               (const_string "alu")
9549            ]
9550            (const_string "ishift")))
9551    (set (attr "length_immediate")
9552      (if_then_else
9553        (ior (eq_attr "type" "alu")
9554             (and (eq_attr "type" "ishift")
9555                  (and (match_operand 2 "const1_operand" "")
9556                       (ior (match_test "TARGET_SHIFT1")
9557                            (match_test "optimize_function_for_size_p (cfun)")))))
9558        (const_string "0")
9559        (const_string "*")))
9560    (set_attr "mode" "<MODE>")])
9561
9562 ;; See comment above `ashl<mode>3' about how this works.
9563
9564 (define_expand "<shift_insn><mode>3"
9565   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9566         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9567                            (match_operand:QI 2 "nonmemory_operand" "")))]
9568   ""
9569   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9570
9571 ;; Avoid useless masking of count operand.
9572 (define_insn_and_split "*<shift_insn><mode>3_mask"
9573   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9574         (any_shiftrt:SWI48
9575           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9576           (subreg:QI
9577             (and:SI
9578               (match_operand:SI 2 "nonimmediate_operand" "c")
9579               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9580    (clobber (reg:CC FLAGS_REG))]
9581   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9582    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9583       == GET_MODE_BITSIZE (<MODE>mode)-1"
9584   "#"
9585   "&& 1"
9586   [(parallel [(set (match_dup 0)
9587                    (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9588               (clobber (reg:CC FLAGS_REG))])]
9589 {
9590   if (can_create_pseudo_p ())
9591     operands [2] = force_reg (SImode, operands[2]);
9592
9593   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9594 }
9595   [(set_attr "type" "ishift")
9596    (set_attr "mode" "<MODE>")])
9597
9598 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9599   [(set (match_operand:DWI 0 "register_operand" "=r")
9600         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9601                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9602    (clobber (reg:CC FLAGS_REG))]
9603   ""
9604   "#"
9605   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9606   [(const_int 0)]
9607   "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9608   [(set_attr "type" "multi")])
9609
9610 ;; By default we don't ask for a scratch register, because when DWImode
9611 ;; values are manipulated, registers are already at a premium.  But if
9612 ;; we have one handy, we won't turn it away.
9613
9614 (define_peephole2
9615   [(match_scratch:DWIH 3 "r")
9616    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9617                    (any_shiftrt:<DWI>
9618                      (match_operand:<DWI> 1 "register_operand" "")
9619                      (match_operand:QI 2 "nonmemory_operand" "")))
9620               (clobber (reg:CC FLAGS_REG))])
9621    (match_dup 3)]
9622   "TARGET_CMOVE"
9623   [(const_int 0)]
9624   "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9625
9626 (define_insn "x86_64_shrd"
9627   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9628         (ior:DI (ashiftrt:DI (match_dup 0)
9629                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9630                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9631                   (minus:QI (const_int 64) (match_dup 2)))))
9632    (clobber (reg:CC FLAGS_REG))]
9633   "TARGET_64BIT"
9634   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9635   [(set_attr "type" "ishift")
9636    (set_attr "prefix_0f" "1")
9637    (set_attr "mode" "DI")
9638    (set_attr "athlon_decode" "vector")
9639    (set_attr "amdfam10_decode" "vector")
9640    (set_attr "bdver1_decode" "vector")])
9641
9642 (define_insn "x86_shrd"
9643   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9644         (ior:SI (ashiftrt:SI (match_dup 0)
9645                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9646                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9647                   (minus:QI (const_int 32) (match_dup 2)))))
9648    (clobber (reg:CC FLAGS_REG))]
9649   ""
9650   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9651   [(set_attr "type" "ishift")
9652    (set_attr "prefix_0f" "1")
9653    (set_attr "mode" "SI")
9654    (set_attr "pent_pair" "np")
9655    (set_attr "athlon_decode" "vector")
9656    (set_attr "amdfam10_decode" "vector")
9657    (set_attr "bdver1_decode" "vector")])
9658
9659 (define_insn "ashrdi3_cvt"
9660   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9661         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9662                      (match_operand:QI 2 "const_int_operand" "")))
9663    (clobber (reg:CC FLAGS_REG))]
9664   "TARGET_64BIT && INTVAL (operands[2]) == 63
9665    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9666    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9667   "@
9668    {cqto|cqo}
9669    sar{q}\t{%2, %0|%0, %2}"
9670   [(set_attr "type" "imovx,ishift")
9671    (set_attr "prefix_0f" "0,*")
9672    (set_attr "length_immediate" "0,*")
9673    (set_attr "modrm" "0,1")
9674    (set_attr "mode" "DI")])
9675
9676 (define_insn "ashrsi3_cvt"
9677   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9678         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9679                      (match_operand:QI 2 "const_int_operand" "")))
9680    (clobber (reg:CC FLAGS_REG))]
9681   "INTVAL (operands[2]) == 31
9682    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9683    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9684   "@
9685    {cltd|cdq}
9686    sar{l}\t{%2, %0|%0, %2}"
9687   [(set_attr "type" "imovx,ishift")
9688    (set_attr "prefix_0f" "0,*")
9689    (set_attr "length_immediate" "0,*")
9690    (set_attr "modrm" "0,1")
9691    (set_attr "mode" "SI")])
9692
9693 (define_insn "*ashrsi3_cvt_zext"
9694   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9695         (zero_extend:DI
9696           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9697                        (match_operand:QI 2 "const_int_operand" ""))))
9698    (clobber (reg:CC FLAGS_REG))]
9699   "TARGET_64BIT && INTVAL (operands[2]) == 31
9700    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9701    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9702   "@
9703    {cltd|cdq}
9704    sar{l}\t{%2, %k0|%k0, %2}"
9705   [(set_attr "type" "imovx,ishift")
9706    (set_attr "prefix_0f" "0,*")
9707    (set_attr "length_immediate" "0,*")
9708    (set_attr "modrm" "0,1")
9709    (set_attr "mode" "SI")])
9710
9711 (define_expand "x86_shift<mode>_adj_3"
9712   [(use (match_operand:SWI48 0 "register_operand" ""))
9713    (use (match_operand:SWI48 1 "register_operand" ""))
9714    (use (match_operand:QI 2 "register_operand" ""))]
9715   ""
9716 {
9717   rtx label = gen_label_rtx ();
9718   rtx tmp;
9719
9720   emit_insn (gen_testqi_ccz_1 (operands[2],
9721                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9722
9723   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9724   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9725   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9726                               gen_rtx_LABEL_REF (VOIDmode, label),
9727                               pc_rtx);
9728   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9729   JUMP_LABEL (tmp) = label;
9730
9731   emit_move_insn (operands[0], operands[1]);
9732   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9733                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9734   emit_label (label);
9735   LABEL_NUSES (label) = 1;
9736
9737   DONE;
9738 })
9739
9740 (define_insn "*bmi2_<shift_insn><mode>3_1"
9741   [(set (match_operand:SWI48 0 "register_operand" "=r")
9742         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9743                            (match_operand:SWI48 2 "register_operand" "r")))]
9744   "TARGET_BMI2"
9745   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9746   [(set_attr "type" "ishiftx")
9747    (set_attr "mode" "<MODE>")])
9748
9749 (define_insn "*<shift_insn><mode>3_1"
9750   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9751         (any_shiftrt:SWI48
9752           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9753           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9754    (clobber (reg:CC FLAGS_REG))]
9755   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9756 {
9757   switch (get_attr_type (insn))
9758     {
9759     case TYPE_ISHIFTX:
9760       return "#";
9761
9762     default:
9763       if (operands[2] == const1_rtx
9764           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9765         return "<shift>{<imodesuffix>}\t%0";
9766       else
9767         return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9768     }
9769 }
9770   [(set_attr "isa" "*,bmi2")
9771    (set_attr "type" "ishift,ishiftx")
9772    (set (attr "length_immediate")
9773      (if_then_else
9774        (and (match_operand 2 "const1_operand" "")
9775             (ior (match_test "TARGET_SHIFT1")
9776                  (match_test "optimize_function_for_size_p (cfun)")))
9777        (const_string "0")
9778        (const_string "*")))
9779    (set_attr "mode" "<MODE>")])
9780
9781 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9782 (define_split
9783   [(set (match_operand:SWI48 0 "register_operand" "")
9784         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9785                            (match_operand:QI 2 "register_operand" "")))
9786    (clobber (reg:CC FLAGS_REG))]
9787   "TARGET_BMI2 && reload_completed"
9788   [(set (match_dup 0)
9789         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9790   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9791
9792 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9793   [(set (match_operand:DI 0 "register_operand" "=r")
9794         (zero_extend:DI
9795           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9796                           (match_operand:SI 2 "register_operand" "r"))))]
9797   "TARGET_64BIT && TARGET_BMI2"
9798   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9799   [(set_attr "type" "ishiftx")
9800    (set_attr "mode" "SI")])
9801
9802 (define_insn "*<shift_insn>si3_1_zext"
9803   [(set (match_operand:DI 0 "register_operand" "=r,r")
9804         (zero_extend:DI
9805           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9806                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9807    (clobber (reg:CC FLAGS_REG))]
9808   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9809 {
9810   switch (get_attr_type (insn))
9811     {
9812     case TYPE_ISHIFTX:
9813       return "#";
9814
9815     default:
9816       if (operands[2] == const1_rtx
9817           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9818         return "<shift>{l}\t%k0";
9819       else
9820         return "<shift>{l}\t{%2, %k0|%k0, %2}";
9821     }
9822 }
9823   [(set_attr "isa" "*,bmi2")
9824    (set_attr "type" "ishift,ishiftx")
9825    (set (attr "length_immediate")
9826      (if_then_else
9827        (and (match_operand 2 "const1_operand" "")
9828             (ior (match_test "TARGET_SHIFT1")
9829                  (match_test "optimize_function_for_size_p (cfun)")))
9830        (const_string "0")
9831        (const_string "*")))
9832    (set_attr "mode" "SI")])
9833
9834 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9835 (define_split
9836   [(set (match_operand:DI 0 "register_operand" "")
9837         (zero_extend:DI
9838           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9839                           (match_operand:QI 2 "register_operand" ""))))
9840    (clobber (reg:CC FLAGS_REG))]
9841   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9842   [(set (match_dup 0)
9843         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9844   "operands[2] = gen_lowpart (SImode, operands[2]);")
9845
9846 (define_insn "*<shift_insn><mode>3_1"
9847   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9848         (any_shiftrt:SWI12
9849           (match_operand:SWI12 1 "nonimmediate_operand" "0")
9850           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9851    (clobber (reg:CC FLAGS_REG))]
9852   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9853 {
9854   if (operands[2] == const1_rtx
9855       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9856     return "<shift>{<imodesuffix>}\t%0";
9857   else
9858     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9859 }
9860   [(set_attr "type" "ishift")
9861    (set (attr "length_immediate")
9862      (if_then_else
9863        (and (match_operand 2 "const1_operand" "")
9864             (ior (match_test "TARGET_SHIFT1")
9865                  (match_test "optimize_function_for_size_p (cfun)")))
9866        (const_string "0")
9867        (const_string "*")))
9868    (set_attr "mode" "<MODE>")])
9869
9870 (define_insn "*<shift_insn>qi3_1_slp"
9871   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9872         (any_shiftrt:QI (match_dup 0)
9873                         (match_operand:QI 1 "nonmemory_operand" "cI")))
9874    (clobber (reg:CC FLAGS_REG))]
9875   "(optimize_function_for_size_p (cfun)
9876     || !TARGET_PARTIAL_REG_STALL
9877     || (operands[1] == const1_rtx
9878         && TARGET_SHIFT1))"
9879 {
9880   if (operands[1] == const1_rtx
9881       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9882     return "<shift>{b}\t%0";
9883   else
9884     return "<shift>{b}\t{%1, %0|%0, %1}";
9885 }
9886   [(set_attr "type" "ishift1")
9887    (set (attr "length_immediate")
9888      (if_then_else
9889        (and (match_operand 1 "const1_operand" "")
9890             (ior (match_test "TARGET_SHIFT1")
9891                  (match_test "optimize_function_for_size_p (cfun)")))
9892        (const_string "0")
9893        (const_string "*")))
9894    (set_attr "mode" "QI")])
9895
9896 ;; This pattern can't accept a variable shift count, since shifts by
9897 ;; zero don't affect the flags.  We assume that shifts by constant
9898 ;; zero are optimized away.
9899 (define_insn "*<shift_insn><mode>3_cmp"
9900   [(set (reg FLAGS_REG)
9901         (compare
9902           (any_shiftrt:SWI
9903             (match_operand:SWI 1 "nonimmediate_operand" "0")
9904             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9905           (const_int 0)))
9906    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9907         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9908   "(optimize_function_for_size_p (cfun)
9909     || !TARGET_PARTIAL_FLAG_REG_STALL
9910     || (operands[2] == const1_rtx
9911         && TARGET_SHIFT1))
9912    && ix86_match_ccmode (insn, CCGOCmode)
9913    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9914 {
9915   if (operands[2] == const1_rtx
9916       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9917     return "<shift>{<imodesuffix>}\t%0";
9918   else
9919     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9920 }
9921   [(set_attr "type" "ishift")
9922    (set (attr "length_immediate")
9923      (if_then_else
9924        (and (match_operand 2 "const1_operand" "")
9925             (ior (match_test "TARGET_SHIFT1")
9926                  (match_test "optimize_function_for_size_p (cfun)")))
9927        (const_string "0")
9928        (const_string "*")))
9929    (set_attr "mode" "<MODE>")])
9930
9931 (define_insn "*<shift_insn>si3_cmp_zext"
9932   [(set (reg FLAGS_REG)
9933         (compare
9934           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9935                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
9936           (const_int 0)))
9937    (set (match_operand:DI 0 "register_operand" "=r")
9938         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9939   "TARGET_64BIT
9940    && (optimize_function_for_size_p (cfun)
9941        || !TARGET_PARTIAL_FLAG_REG_STALL
9942        || (operands[2] == const1_rtx
9943            && TARGET_SHIFT1))
9944    && ix86_match_ccmode (insn, CCGOCmode)
9945    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9946 {
9947   if (operands[2] == const1_rtx
9948       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9949     return "<shift>{l}\t%k0";
9950   else
9951     return "<shift>{l}\t{%2, %k0|%k0, %2}";
9952 }
9953   [(set_attr "type" "ishift")
9954    (set (attr "length_immediate")
9955      (if_then_else
9956        (and (match_operand 2 "const1_operand" "")
9957             (ior (match_test "TARGET_SHIFT1")
9958                  (match_test "optimize_function_for_size_p (cfun)")))
9959        (const_string "0")
9960        (const_string "*")))
9961    (set_attr "mode" "SI")])
9962
9963 (define_insn "*<shift_insn><mode>3_cconly"
9964   [(set (reg FLAGS_REG)
9965         (compare
9966           (any_shiftrt:SWI
9967             (match_operand:SWI 1 "register_operand" "0")
9968             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9969           (const_int 0)))
9970    (clobber (match_scratch:SWI 0 "=<r>"))]
9971   "(optimize_function_for_size_p (cfun)
9972     || !TARGET_PARTIAL_FLAG_REG_STALL
9973     || (operands[2] == const1_rtx
9974         && TARGET_SHIFT1))
9975    && ix86_match_ccmode (insn, CCGOCmode)"
9976 {
9977   if (operands[2] == const1_rtx
9978       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9979     return "<shift>{<imodesuffix>}\t%0";
9980   else
9981     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9982 }
9983   [(set_attr "type" "ishift")
9984    (set (attr "length_immediate")
9985      (if_then_else
9986        (and (match_operand 2 "const1_operand" "")
9987             (ior (match_test "TARGET_SHIFT1")
9988                  (match_test "optimize_function_for_size_p (cfun)")))
9989        (const_string "0")
9990        (const_string "*")))
9991    (set_attr "mode" "<MODE>")])
9992 \f
9993 ;; Rotate instructions
9994
9995 (define_expand "<rotate_insn>ti3"
9996   [(set (match_operand:TI 0 "register_operand" "")
9997         (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9998                        (match_operand:QI 2 "nonmemory_operand" "")))]
9999   "TARGET_64BIT"
10000 {
10001   if (const_1_to_63_operand (operands[2], VOIDmode))
10002     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10003                 (operands[0], operands[1], operands[2]));
10004   else
10005     FAIL;
10006
10007   DONE;
10008 })
10009
10010 (define_expand "<rotate_insn>di3"
10011   [(set (match_operand:DI 0 "shiftdi_operand" "")
10012         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10013                        (match_operand:QI 2 "nonmemory_operand" "")))]
10014  ""
10015 {
10016   if (TARGET_64BIT)
10017     ix86_expand_binary_operator (<CODE>, DImode, operands);
10018   else if (const_1_to_31_operand (operands[2], VOIDmode))
10019     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10020                 (operands[0], operands[1], operands[2]));
10021   else
10022     FAIL;
10023
10024   DONE;
10025 })
10026
10027 (define_expand "<rotate_insn><mode>3"
10028   [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10029         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10030                             (match_operand:QI 2 "nonmemory_operand" "")))]
10031   ""
10032   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10033
10034 ;; Avoid useless masking of count operand.
10035 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10036   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10037         (any_rotate:SWI48
10038           (match_operand:SWI48 1 "nonimmediate_operand" "0")
10039           (subreg:QI
10040             (and:SI
10041               (match_operand:SI 2 "nonimmediate_operand" "c")
10042               (match_operand:SI 3 "const_int_operand" "n")) 0)))
10043    (clobber (reg:CC FLAGS_REG))]
10044   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10045    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10046       == GET_MODE_BITSIZE (<MODE>mode)-1"
10047   "#"
10048   "&& 1"
10049   [(parallel [(set (match_dup 0)
10050                    (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10051               (clobber (reg:CC FLAGS_REG))])]
10052 {
10053   if (can_create_pseudo_p ())
10054     operands [2] = force_reg (SImode, operands[2]);
10055
10056   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10057 }
10058   [(set_attr "type" "rotate")
10059    (set_attr "mode" "<MODE>")])
10060
10061 ;; Implement rotation using two double-precision
10062 ;; shift instructions and a scratch register.
10063
10064 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10065  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10066        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10067                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10068   (clobber (reg:CC FLAGS_REG))
10069   (clobber (match_scratch:DWIH 3 "=&r"))]
10070  ""
10071  "#"
10072  "reload_completed"
10073  [(set (match_dup 3) (match_dup 4))
10074   (parallel
10075    [(set (match_dup 4)
10076          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10077                    (lshiftrt:DWIH (match_dup 5)
10078                                   (minus:QI (match_dup 6) (match_dup 2)))))
10079     (clobber (reg:CC FLAGS_REG))])
10080   (parallel
10081    [(set (match_dup 5)
10082          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10083                    (lshiftrt:DWIH (match_dup 3)
10084                                   (minus:QI (match_dup 6) (match_dup 2)))))
10085     (clobber (reg:CC FLAGS_REG))])]
10086 {
10087   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10088
10089   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10090 })
10091
10092 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10093  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10094        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10095                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10096   (clobber (reg:CC FLAGS_REG))
10097   (clobber (match_scratch:DWIH 3 "=&r"))]
10098  ""
10099  "#"
10100  "reload_completed"
10101  [(set (match_dup 3) (match_dup 4))
10102   (parallel
10103    [(set (match_dup 4)
10104          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10105                    (ashift:DWIH (match_dup 5)
10106                                 (minus:QI (match_dup 6) (match_dup 2)))))
10107     (clobber (reg:CC FLAGS_REG))])
10108   (parallel
10109    [(set (match_dup 5)
10110          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10111                    (ashift:DWIH (match_dup 3)
10112                                 (minus:QI (match_dup 6) (match_dup 2)))))
10113     (clobber (reg:CC FLAGS_REG))])]
10114 {
10115   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10116
10117   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10118 })
10119
10120 (define_insn "*bmi2_rorx<mode>3_1"
10121   [(set (match_operand:SWI48 0 "register_operand" "=r")
10122         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10123                         (match_operand:QI 2 "immediate_operand" "<S>")))]
10124   "TARGET_BMI2"
10125   "rorx\t{%2, %1, %0|%0, %1, %2}"
10126   [(set_attr "type" "rotatex")
10127    (set_attr "mode" "<MODE>")])
10128
10129 (define_insn "*<rotate_insn><mode>3_1"
10130   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10131         (any_rotate:SWI48
10132           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10133           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10134    (clobber (reg:CC FLAGS_REG))]
10135   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10136 {
10137   switch (get_attr_type (insn))
10138     {
10139     case TYPE_ROTATEX:
10140       return "#";
10141
10142     default:
10143       if (operands[2] == const1_rtx
10144           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10145         return "<rotate>{<imodesuffix>}\t%0";
10146       else
10147         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10148     }
10149 }
10150   [(set_attr "isa" "*,bmi2")
10151    (set_attr "type" "rotate,rotatex")
10152    (set (attr "length_immediate")
10153      (if_then_else
10154        (and (eq_attr "type" "rotate")
10155             (and (match_operand 2 "const1_operand" "")
10156                  (ior (match_test "TARGET_SHIFT1")
10157                       (match_test "optimize_function_for_size_p (cfun)"))))
10158        (const_string "0")
10159        (const_string "*")))
10160    (set_attr "mode" "<MODE>")])
10161
10162 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10163 (define_split
10164   [(set (match_operand:SWI48 0 "register_operand" "")
10165         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10166                       (match_operand:QI 2 "immediate_operand" "")))
10167    (clobber (reg:CC FLAGS_REG))]
10168   "TARGET_BMI2 && reload_completed"
10169   [(set (match_dup 0)
10170         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10171 {
10172   operands[2]
10173     = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10174 })
10175
10176 (define_split
10177   [(set (match_operand:SWI48 0 "register_operand" "")
10178         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10179                         (match_operand:QI 2 "immediate_operand" "")))
10180    (clobber (reg:CC FLAGS_REG))]
10181   "TARGET_BMI2 && reload_completed"
10182   [(set (match_dup 0)
10183         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10184
10185 (define_insn "*bmi2_rorxsi3_1_zext"
10186   [(set (match_operand:DI 0 "register_operand" "=r")
10187         (zero_extend:DI
10188           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10189                        (match_operand:QI 2 "immediate_operand" "I"))))]
10190   "TARGET_64BIT && TARGET_BMI2"
10191   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10192   [(set_attr "type" "rotatex")
10193    (set_attr "mode" "SI")])
10194
10195 (define_insn "*<rotate_insn>si3_1_zext"
10196   [(set (match_operand:DI 0 "register_operand" "=r,r")
10197         (zero_extend:DI
10198           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10199                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10200    (clobber (reg:CC FLAGS_REG))]
10201   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10202 {
10203   switch (get_attr_type (insn))
10204     {
10205     case TYPE_ROTATEX:
10206       return "#";
10207
10208     default:
10209       if (operands[2] == const1_rtx
10210           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10211         return "<rotate>{l}\t%k0";
10212       else
10213         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10214     }
10215 }
10216   [(set_attr "isa" "*,bmi2")
10217    (set_attr "type" "rotate,rotatex")
10218    (set (attr "length_immediate")
10219      (if_then_else
10220        (and (eq_attr "type" "rotate")
10221             (and (match_operand 2 "const1_operand" "")
10222                  (ior (match_test "TARGET_SHIFT1")
10223                       (match_test "optimize_function_for_size_p (cfun)"))))
10224        (const_string "0")
10225        (const_string "*")))
10226    (set_attr "mode" "SI")])
10227
10228 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10229 (define_split
10230   [(set (match_operand:DI 0 "register_operand" "")
10231         (zero_extend:DI
10232           (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10233                      (match_operand:QI 2 "immediate_operand" ""))))
10234    (clobber (reg:CC FLAGS_REG))]
10235   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10236   [(set (match_dup 0)
10237         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10238 {
10239   operands[2]
10240     = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10241 })
10242
10243 (define_split
10244   [(set (match_operand:DI 0 "register_operand" "")
10245         (zero_extend:DI
10246           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10247                        (match_operand:QI 2 "immediate_operand" ""))))
10248    (clobber (reg:CC FLAGS_REG))]
10249   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10250   [(set (match_dup 0)
10251         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10252
10253 (define_insn "*<rotate_insn><mode>3_1"
10254   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10255         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10256                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10257    (clobber (reg:CC FLAGS_REG))]
10258   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10259 {
10260   if (operands[2] == const1_rtx
10261       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10262     return "<rotate>{<imodesuffix>}\t%0";
10263   else
10264     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10265 }
10266   [(set_attr "type" "rotate")
10267    (set (attr "length_immediate")
10268      (if_then_else
10269        (and (match_operand 2 "const1_operand" "")
10270             (ior (match_test "TARGET_SHIFT1")
10271                  (match_test "optimize_function_for_size_p (cfun)")))
10272        (const_string "0")
10273        (const_string "*")))
10274    (set_attr "mode" "<MODE>")])
10275
10276 (define_insn "*<rotate_insn>qi3_1_slp"
10277   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10278         (any_rotate:QI (match_dup 0)
10279                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10280    (clobber (reg:CC FLAGS_REG))]
10281   "(optimize_function_for_size_p (cfun)
10282     || !TARGET_PARTIAL_REG_STALL
10283     || (operands[1] == const1_rtx
10284         && TARGET_SHIFT1))"
10285 {
10286   if (operands[1] == const1_rtx
10287       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10288     return "<rotate>{b}\t%0";
10289   else
10290     return "<rotate>{b}\t{%1, %0|%0, %1}";
10291 }
10292   [(set_attr "type" "rotate1")
10293    (set (attr "length_immediate")
10294      (if_then_else
10295        (and (match_operand 1 "const1_operand" "")
10296             (ior (match_test "TARGET_SHIFT1")
10297                  (match_test "optimize_function_for_size_p (cfun)")))
10298        (const_string "0")
10299        (const_string "*")))
10300    (set_attr "mode" "QI")])
10301
10302 (define_split
10303  [(set (match_operand:HI 0 "register_operand" "")
10304        (any_rotate:HI (match_dup 0) (const_int 8)))
10305   (clobber (reg:CC FLAGS_REG))]
10306  "reload_completed
10307   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10308  [(parallel [(set (strict_low_part (match_dup 0))
10309                   (bswap:HI (match_dup 0)))
10310              (clobber (reg:CC FLAGS_REG))])])
10311 \f
10312 ;; Bit set / bit test instructions
10313
10314 (define_expand "extv"
10315   [(set (match_operand:SI 0 "register_operand" "")
10316         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10317                          (match_operand:SI 2 "const8_operand" "")
10318                          (match_operand:SI 3 "const8_operand" "")))]
10319   ""
10320 {
10321   /* Handle extractions from %ah et al.  */
10322   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10323     FAIL;
10324
10325   /* From mips.md: extract_bit_field doesn't verify that our source
10326      matches the predicate, so check it again here.  */
10327   if (! ext_register_operand (operands[1], VOIDmode))
10328     FAIL;
10329 })
10330
10331 (define_expand "extzv"
10332   [(set (match_operand:SI 0 "register_operand" "")
10333         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10334                          (match_operand:SI 2 "const8_operand" "")
10335                          (match_operand:SI 3 "const8_operand" "")))]
10336   ""
10337 {
10338   /* Handle extractions from %ah et al.  */
10339   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10340     FAIL;
10341
10342   /* From mips.md: extract_bit_field doesn't verify that our source
10343      matches the predicate, so check it again here.  */
10344   if (! ext_register_operand (operands[1], VOIDmode))
10345     FAIL;
10346 })
10347
10348 (define_expand "insv"
10349   [(set (zero_extract (match_operand 0 "register_operand" "")
10350                       (match_operand 1 "const_int_operand" "")
10351                       (match_operand 2 "const_int_operand" ""))
10352         (match_operand 3 "register_operand" ""))]
10353   ""
10354 {
10355   rtx (*gen_mov_insv_1) (rtx, rtx);
10356
10357   if (ix86_expand_pinsr (operands))
10358     DONE;
10359
10360   /* Handle insertions to %ah et al.  */
10361   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10362     FAIL;
10363
10364   /* From mips.md: insert_bit_field doesn't verify that our source
10365      matches the predicate, so check it again here.  */
10366   if (! ext_register_operand (operands[0], VOIDmode))
10367     FAIL;
10368
10369   gen_mov_insv_1 = (TARGET_64BIT
10370                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10371
10372   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10373   DONE;
10374 })
10375
10376 ;; %%% bts, btr, btc, bt.
10377 ;; In general these instructions are *slow* when applied to memory,
10378 ;; since they enforce atomic operation.  When applied to registers,
10379 ;; it depends on the cpu implementation.  They're never faster than
10380 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10381 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10382 ;; within the instruction itself, so operating on bits in the high
10383 ;; 32-bits of a register becomes easier.
10384 ;;
10385 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10386 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10387 ;; negdf respectively, so they can never be disabled entirely.
10388
10389 (define_insn "*btsq"
10390   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10391                          (const_int 1)
10392                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10393         (const_int 1))
10394    (clobber (reg:CC FLAGS_REG))]
10395   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10396   "bts{q}\t{%1, %0|%0, %1}"
10397   [(set_attr "type" "alu1")
10398    (set_attr "prefix_0f" "1")
10399    (set_attr "mode" "DI")])
10400
10401 (define_insn "*btrq"
10402   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10403                          (const_int 1)
10404                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10405         (const_int 0))
10406    (clobber (reg:CC FLAGS_REG))]
10407   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10408   "btr{q}\t{%1, %0|%0, %1}"
10409   [(set_attr "type" "alu1")
10410    (set_attr "prefix_0f" "1")
10411    (set_attr "mode" "DI")])
10412
10413 (define_insn "*btcq"
10414   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10415                          (const_int 1)
10416                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10417         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10418    (clobber (reg:CC FLAGS_REG))]
10419   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10420   "btc{q}\t{%1, %0|%0, %1}"
10421   [(set_attr "type" "alu1")
10422    (set_attr "prefix_0f" "1")
10423    (set_attr "mode" "DI")])
10424
10425 ;; Allow Nocona to avoid these instructions if a register is available.
10426
10427 (define_peephole2
10428   [(match_scratch:DI 2 "r")
10429    (parallel [(set (zero_extract:DI
10430                      (match_operand:DI 0 "register_operand" "")
10431                      (const_int 1)
10432                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10433                    (const_int 1))
10434               (clobber (reg:CC FLAGS_REG))])]
10435   "TARGET_64BIT && !TARGET_USE_BT"
10436   [(const_int 0)]
10437 {
10438   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10439   rtx op1;
10440
10441   if (HOST_BITS_PER_WIDE_INT >= 64)
10442     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10443   else if (i < HOST_BITS_PER_WIDE_INT)
10444     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10445   else
10446     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10447
10448   op1 = immed_double_const (lo, hi, DImode);
10449   if (i >= 31)
10450     {
10451       emit_move_insn (operands[2], op1);
10452       op1 = operands[2];
10453     }
10454
10455   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10456   DONE;
10457 })
10458
10459 (define_peephole2
10460   [(match_scratch:DI 2 "r")
10461    (parallel [(set (zero_extract:DI
10462                      (match_operand:DI 0 "register_operand" "")
10463                      (const_int 1)
10464                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10465                    (const_int 0))
10466               (clobber (reg:CC FLAGS_REG))])]
10467   "TARGET_64BIT && !TARGET_USE_BT"
10468   [(const_int 0)]
10469 {
10470   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10471   rtx op1;
10472
10473   if (HOST_BITS_PER_WIDE_INT >= 64)
10474     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10475   else if (i < HOST_BITS_PER_WIDE_INT)
10476     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10477   else
10478     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10479
10480   op1 = immed_double_const (~lo, ~hi, DImode);
10481   if (i >= 32)
10482     {
10483       emit_move_insn (operands[2], op1);
10484       op1 = operands[2];
10485     }
10486
10487   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10488   DONE;
10489 })
10490
10491 (define_peephole2
10492   [(match_scratch:DI 2 "r")
10493    (parallel [(set (zero_extract:DI
10494                      (match_operand:DI 0 "register_operand" "")
10495                      (const_int 1)
10496                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10497               (not:DI (zero_extract:DI
10498                         (match_dup 0) (const_int 1) (match_dup 1))))
10499               (clobber (reg:CC FLAGS_REG))])]
10500   "TARGET_64BIT && !TARGET_USE_BT"
10501   [(const_int 0)]
10502 {
10503   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10504   rtx op1;
10505
10506   if (HOST_BITS_PER_WIDE_INT >= 64)
10507     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10508   else if (i < HOST_BITS_PER_WIDE_INT)
10509     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10510   else
10511     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10512
10513   op1 = immed_double_const (lo, hi, DImode);
10514   if (i >= 31)
10515     {
10516       emit_move_insn (operands[2], op1);
10517       op1 = operands[2];
10518     }
10519
10520   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10521   DONE;
10522 })
10523
10524 (define_insn "*bt<mode>"
10525   [(set (reg:CCC FLAGS_REG)
10526         (compare:CCC
10527           (zero_extract:SWI48
10528             (match_operand:SWI48 0 "register_operand" "r")
10529             (const_int 1)
10530             (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10531           (const_int 0)))]
10532   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10533   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10534   [(set_attr "type" "alu1")
10535    (set_attr "prefix_0f" "1")
10536    (set_attr "mode" "<MODE>")])
10537 \f
10538 ;; Store-flag instructions.
10539
10540 ;; For all sCOND expanders, also expand the compare or test insn that
10541 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10542
10543 (define_insn_and_split "*setcc_di_1"
10544   [(set (match_operand:DI 0 "register_operand" "=q")
10545         (match_operator:DI 1 "ix86_comparison_operator"
10546           [(reg FLAGS_REG) (const_int 0)]))]
10547   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10548   "#"
10549   "&& reload_completed"
10550   [(set (match_dup 2) (match_dup 1))
10551    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10552 {
10553   PUT_MODE (operands[1], QImode);
10554   operands[2] = gen_lowpart (QImode, operands[0]);
10555 })
10556
10557 (define_insn_and_split "*setcc_si_1_and"
10558   [(set (match_operand:SI 0 "register_operand" "=q")
10559         (match_operator:SI 1 "ix86_comparison_operator"
10560           [(reg FLAGS_REG) (const_int 0)]))
10561    (clobber (reg:CC FLAGS_REG))]
10562   "!TARGET_PARTIAL_REG_STALL
10563    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10564   "#"
10565   "&& reload_completed"
10566   [(set (match_dup 2) (match_dup 1))
10567    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10568               (clobber (reg:CC FLAGS_REG))])]
10569 {
10570   PUT_MODE (operands[1], QImode);
10571   operands[2] = gen_lowpart (QImode, operands[0]);
10572 })
10573
10574 (define_insn_and_split "*setcc_si_1_movzbl"
10575   [(set (match_operand:SI 0 "register_operand" "=q")
10576         (match_operator:SI 1 "ix86_comparison_operator"
10577           [(reg FLAGS_REG) (const_int 0)]))]
10578   "!TARGET_PARTIAL_REG_STALL
10579    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10580   "#"
10581   "&& reload_completed"
10582   [(set (match_dup 2) (match_dup 1))
10583    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10584 {
10585   PUT_MODE (operands[1], QImode);
10586   operands[2] = gen_lowpart (QImode, operands[0]);
10587 })
10588
10589 (define_insn "*setcc_qi"
10590   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10591         (match_operator:QI 1 "ix86_comparison_operator"
10592           [(reg FLAGS_REG) (const_int 0)]))]
10593   ""
10594   "set%C1\t%0"
10595   [(set_attr "type" "setcc")
10596    (set_attr "mode" "QI")])
10597
10598 (define_insn "*setcc_qi_slp"
10599   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10600         (match_operator:QI 1 "ix86_comparison_operator"
10601           [(reg FLAGS_REG) (const_int 0)]))]
10602   ""
10603   "set%C1\t%0"
10604   [(set_attr "type" "setcc")
10605    (set_attr "mode" "QI")])
10606
10607 ;; In general it is not safe to assume too much about CCmode registers,
10608 ;; so simplify-rtx stops when it sees a second one.  Under certain
10609 ;; conditions this is safe on x86, so help combine not create
10610 ;;
10611 ;;      seta    %al
10612 ;;      testb   %al, %al
10613 ;;      sete    %al
10614
10615 (define_split
10616   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10617         (ne:QI (match_operator 1 "ix86_comparison_operator"
10618                  [(reg FLAGS_REG) (const_int 0)])
10619             (const_int 0)))]
10620   ""
10621   [(set (match_dup 0) (match_dup 1))]
10622   "PUT_MODE (operands[1], QImode);")
10623
10624 (define_split
10625   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10626         (ne:QI (match_operator 1 "ix86_comparison_operator"
10627                  [(reg FLAGS_REG) (const_int 0)])
10628             (const_int 0)))]
10629   ""
10630   [(set (match_dup 0) (match_dup 1))]
10631   "PUT_MODE (operands[1], QImode);")
10632
10633 (define_split
10634   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10635         (eq:QI (match_operator 1 "ix86_comparison_operator"
10636                  [(reg FLAGS_REG) (const_int 0)])
10637             (const_int 0)))]
10638   ""
10639   [(set (match_dup 0) (match_dup 1))]
10640 {
10641   rtx new_op1 = copy_rtx (operands[1]);
10642   operands[1] = new_op1;
10643   PUT_MODE (new_op1, QImode);
10644   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10645                                              GET_MODE (XEXP (new_op1, 0))));
10646
10647   /* Make sure that (a) the CCmode we have for the flags is strong
10648      enough for the reversed compare or (b) we have a valid FP compare.  */
10649   if (! ix86_comparison_operator (new_op1, VOIDmode))
10650     FAIL;
10651 })
10652
10653 (define_split
10654   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10655         (eq:QI (match_operator 1 "ix86_comparison_operator"
10656                  [(reg FLAGS_REG) (const_int 0)])
10657             (const_int 0)))]
10658   ""
10659   [(set (match_dup 0) (match_dup 1))]
10660 {
10661   rtx new_op1 = copy_rtx (operands[1]);
10662   operands[1] = new_op1;
10663   PUT_MODE (new_op1, QImode);
10664   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10665                                              GET_MODE (XEXP (new_op1, 0))));
10666
10667   /* Make sure that (a) the CCmode we have for the flags is strong
10668      enough for the reversed compare or (b) we have a valid FP compare.  */
10669   if (! ix86_comparison_operator (new_op1, VOIDmode))
10670     FAIL;
10671 })
10672
10673 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10674 ;; subsequent logical operations are used to imitate conditional moves.
10675 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10676 ;; it directly.
10677
10678 (define_insn "setcc_<mode>_sse"
10679   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10680         (match_operator:MODEF 3 "sse_comparison_operator"
10681           [(match_operand:MODEF 1 "register_operand" "0,x")
10682            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10683   "SSE_FLOAT_MODE_P (<MODE>mode)"
10684   "@
10685    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10686    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10687   [(set_attr "isa" "noavx,avx")
10688    (set_attr "type" "ssecmp")
10689    (set_attr "length_immediate" "1")
10690    (set_attr "prefix" "orig,vex")
10691    (set_attr "mode" "<MODE>")])
10692 \f
10693 ;; Basic conditional jump instructions.
10694 ;; We ignore the overflow flag for signed branch instructions.
10695
10696 (define_insn "*jcc_1"
10697   [(set (pc)
10698         (if_then_else (match_operator 1 "ix86_comparison_operator"
10699                                       [(reg FLAGS_REG) (const_int 0)])
10700                       (label_ref (match_operand 0 "" ""))
10701                       (pc)))]
10702   ""
10703   "%+j%C1\t%l0"
10704   [(set_attr "type" "ibr")
10705    (set_attr "modrm" "0")
10706    (set (attr "length")
10707            (if_then_else (and (ge (minus (match_dup 0) (pc))
10708                                   (const_int -126))
10709                               (lt (minus (match_dup 0) (pc))
10710                                   (const_int 128)))
10711              (const_int 2)
10712              (const_int 6)))])
10713
10714 (define_insn "*jcc_2"
10715   [(set (pc)
10716         (if_then_else (match_operator 1 "ix86_comparison_operator"
10717                                       [(reg FLAGS_REG) (const_int 0)])
10718                       (pc)
10719                       (label_ref (match_operand 0 "" ""))))]
10720   ""
10721   "%+j%c1\t%l0"
10722   [(set_attr "type" "ibr")
10723    (set_attr "modrm" "0")
10724    (set (attr "length")
10725            (if_then_else (and (ge (minus (match_dup 0) (pc))
10726                                   (const_int -126))
10727                               (lt (minus (match_dup 0) (pc))
10728                                   (const_int 128)))
10729              (const_int 2)
10730              (const_int 6)))])
10731
10732 ;; In general it is not safe to assume too much about CCmode registers,
10733 ;; so simplify-rtx stops when it sees a second one.  Under certain
10734 ;; conditions this is safe on x86, so help combine not create
10735 ;;
10736 ;;      seta    %al
10737 ;;      testb   %al, %al
10738 ;;      je      Lfoo
10739
10740 (define_split
10741   [(set (pc)
10742         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10743                                       [(reg FLAGS_REG) (const_int 0)])
10744                           (const_int 0))
10745                       (label_ref (match_operand 1 "" ""))
10746                       (pc)))]
10747   ""
10748   [(set (pc)
10749         (if_then_else (match_dup 0)
10750                       (label_ref (match_dup 1))
10751                       (pc)))]
10752   "PUT_MODE (operands[0], VOIDmode);")
10753
10754 (define_split
10755   [(set (pc)
10756         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10757                                       [(reg FLAGS_REG) (const_int 0)])
10758                           (const_int 0))
10759                       (label_ref (match_operand 1 "" ""))
10760                       (pc)))]
10761   ""
10762   [(set (pc)
10763         (if_then_else (match_dup 0)
10764                       (label_ref (match_dup 1))
10765                       (pc)))]
10766 {
10767   rtx new_op0 = copy_rtx (operands[0]);
10768   operands[0] = new_op0;
10769   PUT_MODE (new_op0, VOIDmode);
10770   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10771                                              GET_MODE (XEXP (new_op0, 0))));
10772
10773   /* Make sure that (a) the CCmode we have for the flags is strong
10774      enough for the reversed compare or (b) we have a valid FP compare.  */
10775   if (! ix86_comparison_operator (new_op0, VOIDmode))
10776     FAIL;
10777 })
10778
10779 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10780 ;; pass generates from shift insn with QImode operand.  Actually, the mode
10781 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10782 ;; appropriate modulo of the bit offset value.
10783
10784 (define_insn_and_split "*jcc_bt<mode>"
10785   [(set (pc)
10786         (if_then_else (match_operator 0 "bt_comparison_operator"
10787                         [(zero_extract:SWI48
10788                            (match_operand:SWI48 1 "register_operand" "r")
10789                            (const_int 1)
10790                            (zero_extend:SI
10791                              (match_operand:QI 2 "register_operand" "r")))
10792                          (const_int 0)])
10793                       (label_ref (match_operand 3 "" ""))
10794                       (pc)))
10795    (clobber (reg:CC FLAGS_REG))]
10796   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10797   "#"
10798   "&& 1"
10799   [(set (reg:CCC FLAGS_REG)
10800         (compare:CCC
10801           (zero_extract:SWI48
10802             (match_dup 1)
10803             (const_int 1)
10804             (match_dup 2))
10805           (const_int 0)))
10806    (set (pc)
10807         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10808                       (label_ref (match_dup 3))
10809                       (pc)))]
10810 {
10811   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10812
10813   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10814 })
10815
10816 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10817 ;; also for DImode, this is what combine produces.
10818 (define_insn_and_split "*jcc_bt<mode>_mask"
10819   [(set (pc)
10820         (if_then_else (match_operator 0 "bt_comparison_operator"
10821                         [(zero_extract:SWI48
10822                            (match_operand:SWI48 1 "register_operand" "r")
10823                            (const_int 1)
10824                            (and:SI
10825                              (match_operand:SI 2 "register_operand" "r")
10826                              (match_operand:SI 3 "const_int_operand" "n")))])
10827                       (label_ref (match_operand 4 "" ""))
10828                       (pc)))
10829    (clobber (reg:CC FLAGS_REG))]
10830   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10831    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10832       == GET_MODE_BITSIZE (<MODE>mode)-1"
10833   "#"
10834   "&& 1"
10835   [(set (reg:CCC FLAGS_REG)
10836         (compare:CCC
10837           (zero_extract:SWI48
10838             (match_dup 1)
10839             (const_int 1)
10840             (match_dup 2))
10841           (const_int 0)))
10842    (set (pc)
10843         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10844                       (label_ref (match_dup 4))
10845                       (pc)))]
10846 {
10847   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10848
10849   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10850 })
10851
10852 (define_insn_and_split "*jcc_btsi_1"
10853   [(set (pc)
10854         (if_then_else (match_operator 0 "bt_comparison_operator"
10855                         [(and:SI
10856                            (lshiftrt:SI
10857                              (match_operand:SI 1 "register_operand" "r")
10858                              (match_operand:QI 2 "register_operand" "r"))
10859                            (const_int 1))
10860                          (const_int 0)])
10861                       (label_ref (match_operand 3 "" ""))
10862                       (pc)))
10863    (clobber (reg:CC FLAGS_REG))]
10864   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10865   "#"
10866   "&& 1"
10867   [(set (reg:CCC FLAGS_REG)
10868         (compare:CCC
10869           (zero_extract:SI
10870             (match_dup 1)
10871             (const_int 1)
10872             (match_dup 2))
10873           (const_int 0)))
10874    (set (pc)
10875         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10876                       (label_ref (match_dup 3))
10877                       (pc)))]
10878 {
10879   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10880
10881   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10882 })
10883
10884 ;; avoid useless masking of bit offset operand
10885 (define_insn_and_split "*jcc_btsi_mask_1"
10886   [(set (pc)
10887         (if_then_else
10888           (match_operator 0 "bt_comparison_operator"
10889             [(and:SI
10890                (lshiftrt:SI
10891                  (match_operand:SI 1 "register_operand" "r")
10892                  (subreg:QI
10893                    (and:SI
10894                      (match_operand:SI 2 "register_operand" "r")
10895                      (match_operand:SI 3 "const_int_operand" "n")) 0))
10896                (const_int 1))
10897              (const_int 0)])
10898           (label_ref (match_operand 4 "" ""))
10899           (pc)))
10900    (clobber (reg:CC FLAGS_REG))]
10901   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10902    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10903   "#"
10904   "&& 1"
10905   [(set (reg:CCC FLAGS_REG)
10906         (compare:CCC
10907           (zero_extract:SI
10908             (match_dup 1)
10909             (const_int 1)
10910             (match_dup 2))
10911           (const_int 0)))
10912    (set (pc)
10913         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10914                       (label_ref (match_dup 4))
10915                       (pc)))]
10916   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10917
10918 ;; Define combination compare-and-branch fp compare instructions to help
10919 ;; combine.
10920
10921 (define_insn "*fp_jcc_1_387"
10922   [(set (pc)
10923         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10924                         [(match_operand 1 "register_operand" "f")
10925                          (match_operand 2 "nonimmediate_operand" "fm")])
10926           (label_ref (match_operand 3 "" ""))
10927           (pc)))
10928    (clobber (reg:CCFP FPSR_REG))
10929    (clobber (reg:CCFP FLAGS_REG))
10930    (clobber (match_scratch:HI 4 "=a"))]
10931   "TARGET_80387
10932    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10933    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10934    && SELECT_CC_MODE (GET_CODE (operands[0]),
10935                       operands[1], operands[2]) == CCFPmode
10936    && !TARGET_CMOVE"
10937   "#")
10938
10939 (define_insn "*fp_jcc_1r_387"
10940   [(set (pc)
10941         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10942                         [(match_operand 1 "register_operand" "f")
10943                          (match_operand 2 "nonimmediate_operand" "fm")])
10944           (pc)
10945           (label_ref (match_operand 3 "" ""))))
10946    (clobber (reg:CCFP FPSR_REG))
10947    (clobber (reg:CCFP FLAGS_REG))
10948    (clobber (match_scratch:HI 4 "=a"))]
10949   "TARGET_80387
10950    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10951    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10952    && SELECT_CC_MODE (GET_CODE (operands[0]),
10953                       operands[1], operands[2]) == CCFPmode
10954    && !TARGET_CMOVE"
10955   "#")
10956
10957 (define_insn "*fp_jcc_2_387"
10958   [(set (pc)
10959         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10960                         [(match_operand 1 "register_operand" "f")
10961                          (match_operand 2 "register_operand" "f")])
10962           (label_ref (match_operand 3 "" ""))
10963           (pc)))
10964    (clobber (reg:CCFP FPSR_REG))
10965    (clobber (reg:CCFP FLAGS_REG))
10966    (clobber (match_scratch:HI 4 "=a"))]
10967   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10968    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10969    && !TARGET_CMOVE"
10970   "#")
10971
10972 (define_insn "*fp_jcc_2r_387"
10973   [(set (pc)
10974         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10975                         [(match_operand 1 "register_operand" "f")
10976                          (match_operand 2 "register_operand" "f")])
10977           (pc)
10978           (label_ref (match_operand 3 "" ""))))
10979    (clobber (reg:CCFP FPSR_REG))
10980    (clobber (reg:CCFP FLAGS_REG))
10981    (clobber (match_scratch:HI 4 "=a"))]
10982   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10983    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10984    && !TARGET_CMOVE"
10985   "#")
10986
10987 (define_insn "*fp_jcc_3_387"
10988   [(set (pc)
10989         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10990                         [(match_operand 1 "register_operand" "f")
10991                          (match_operand 2 "const0_operand" "")])
10992           (label_ref (match_operand 3 "" ""))
10993           (pc)))
10994    (clobber (reg:CCFP FPSR_REG))
10995    (clobber (reg:CCFP FLAGS_REG))
10996    (clobber (match_scratch:HI 4 "=a"))]
10997   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10998    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10999    && SELECT_CC_MODE (GET_CODE (operands[0]),
11000                       operands[1], operands[2]) == CCFPmode
11001    && !TARGET_CMOVE"
11002   "#")
11003
11004 (define_split
11005   [(set (pc)
11006         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11007                         [(match_operand 1 "register_operand" "")
11008                          (match_operand 2 "nonimmediate_operand" "")])
11009           (match_operand 3 "" "")
11010           (match_operand 4 "" "")))
11011    (clobber (reg:CCFP FPSR_REG))
11012    (clobber (reg:CCFP FLAGS_REG))]
11013   "reload_completed"
11014   [(const_int 0)]
11015 {
11016   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11017                         operands[3], operands[4], NULL_RTX, NULL_RTX);
11018   DONE;
11019 })
11020
11021 (define_split
11022   [(set (pc)
11023         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11024                         [(match_operand 1 "register_operand" "")
11025                          (match_operand 2 "general_operand" "")])
11026           (match_operand 3 "" "")
11027           (match_operand 4 "" "")))
11028    (clobber (reg:CCFP FPSR_REG))
11029    (clobber (reg:CCFP FLAGS_REG))
11030    (clobber (match_scratch:HI 5 "=a"))]
11031   "reload_completed"
11032   [(const_int 0)]
11033 {
11034   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11035                         operands[3], operands[4], operands[5], NULL_RTX);
11036   DONE;
11037 })
11038
11039 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11040 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11041 ;; with a precedence over other operators and is always put in the first
11042 ;; place. Swap condition and operands to match ficom instruction.
11043
11044 (define_insn "*fp_jcc_4_<mode>_387"
11045   [(set (pc)
11046         (if_then_else
11047           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11048             [(match_operator 1 "float_operator"
11049               [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11050              (match_operand 3 "register_operand" "f,f")])
11051           (label_ref (match_operand 4 "" ""))
11052           (pc)))
11053    (clobber (reg:CCFP FPSR_REG))
11054    (clobber (reg:CCFP FLAGS_REG))
11055    (clobber (match_scratch:HI 5 "=a,a"))]
11056   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11057    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11058    && GET_MODE (operands[1]) == GET_MODE (operands[3])
11059    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11060    && !TARGET_CMOVE"
11061   "#")
11062
11063 (define_split
11064   [(set (pc)
11065         (if_then_else
11066           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11067             [(match_operator 1 "float_operator"
11068               [(match_operand:SWI24 2 "memory_operand" "")])
11069              (match_operand 3 "register_operand" "")])
11070           (match_operand 4 "" "")
11071           (match_operand 5 "" "")))
11072    (clobber (reg:CCFP FPSR_REG))
11073    (clobber (reg:CCFP FLAGS_REG))
11074    (clobber (match_scratch:HI 6 "=a"))]
11075   "reload_completed"
11076   [(const_int 0)]
11077 {
11078   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11079
11080   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11081                         operands[3], operands[7],
11082                         operands[4], operands[5], operands[6], NULL_RTX);
11083   DONE;
11084 })
11085
11086 ;; %%% Kill this when reload knows how to do it.
11087 (define_split
11088   [(set (pc)
11089         (if_then_else
11090           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11091             [(match_operator 1 "float_operator"
11092               [(match_operand:SWI24 2 "register_operand" "")])
11093              (match_operand 3 "register_operand" "")])
11094           (match_operand 4 "" "")
11095           (match_operand 5 "" "")))
11096    (clobber (reg:CCFP FPSR_REG))
11097    (clobber (reg:CCFP FLAGS_REG))
11098    (clobber (match_scratch:HI 6 "=a"))]
11099   "reload_completed"
11100   [(const_int 0)]
11101 {
11102   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11103   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11104
11105   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11106                         operands[3], operands[7],
11107                         operands[4], operands[5], operands[6], operands[2]);
11108   DONE;
11109 })
11110 \f
11111 ;; Unconditional and other jump instructions
11112
11113 (define_insn "jump"
11114   [(set (pc)
11115         (label_ref (match_operand 0 "" "")))]
11116   ""
11117   "jmp\t%l0"
11118   [(set_attr "type" "ibr")
11119    (set (attr "length")
11120            (if_then_else (and (ge (minus (match_dup 0) (pc))
11121                                   (const_int -126))
11122                               (lt (minus (match_dup 0) (pc))
11123                                   (const_int 128)))
11124              (const_int 2)
11125              (const_int 5)))
11126    (set_attr "modrm" "0")])
11127
11128 (define_expand "indirect_jump"
11129   [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11130
11131 (define_insn "*indirect_jump"
11132   [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11133   ""
11134   "jmp\t%A0"
11135   [(set_attr "type" "ibr")
11136    (set_attr "length_immediate" "0")])
11137
11138 (define_expand "tablejump"
11139   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11140               (use (label_ref (match_operand 1 "" "")))])]
11141   ""
11142 {
11143   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11144      relative.  Convert the relative address to an absolute address.  */
11145   if (flag_pic)
11146     {
11147       rtx op0, op1;
11148       enum rtx_code code;
11149
11150       /* We can't use @GOTOFF for text labels on VxWorks;
11151          see gotoff_operand.  */
11152       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11153         {
11154           code = PLUS;
11155           op0 = operands[0];
11156           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11157         }
11158       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11159         {
11160           code = PLUS;
11161           op0 = operands[0];
11162           op1 = pic_offset_table_rtx;
11163         }
11164       else
11165         {
11166           code = MINUS;
11167           op0 = pic_offset_table_rtx;
11168           op1 = operands[0];
11169         }
11170
11171       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11172                                          OPTAB_DIRECT);
11173     }
11174   else if (TARGET_X32)
11175     operands[0] = convert_memory_address (Pmode, operands[0]);
11176 })
11177
11178 (define_insn "*tablejump_1"
11179   [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11180    (use (label_ref (match_operand 1 "" "")))]
11181   ""
11182   "jmp\t%A0"
11183   [(set_attr "type" "ibr")
11184    (set_attr "length_immediate" "0")])
11185 \f
11186 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11187
11188 (define_peephole2
11189   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11190    (set (match_operand:QI 1 "register_operand" "")
11191         (match_operator:QI 2 "ix86_comparison_operator"
11192           [(reg FLAGS_REG) (const_int 0)]))
11193    (set (match_operand 3 "q_regs_operand" "")
11194         (zero_extend (match_dup 1)))]
11195   "(peep2_reg_dead_p (3, operands[1])
11196     || operands_match_p (operands[1], operands[3]))
11197    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11198   [(set (match_dup 4) (match_dup 0))
11199    (set (strict_low_part (match_dup 5))
11200         (match_dup 2))]
11201 {
11202   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11203   operands[5] = gen_lowpart (QImode, operands[3]);
11204   ix86_expand_clear (operands[3]);
11205 })
11206
11207 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11208
11209 (define_peephole2
11210   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11211    (set (match_operand:QI 1 "register_operand" "")
11212         (match_operator:QI 2 "ix86_comparison_operator"
11213           [(reg FLAGS_REG) (const_int 0)]))
11214    (parallel [(set (match_operand 3 "q_regs_operand" "")
11215                    (zero_extend (match_dup 1)))
11216               (clobber (reg:CC FLAGS_REG))])]
11217   "(peep2_reg_dead_p (3, operands[1])
11218     || operands_match_p (operands[1], operands[3]))
11219    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11220   [(set (match_dup 4) (match_dup 0))
11221    (set (strict_low_part (match_dup 5))
11222         (match_dup 2))]
11223 {
11224   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11225   operands[5] = gen_lowpart (QImode, operands[3]);
11226   ix86_expand_clear (operands[3]);
11227 })
11228 \f
11229 ;; Call instructions.
11230
11231 ;; The predicates normally associated with named expanders are not properly
11232 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11233 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11234
11235 ;; P6 processors will jump to the address after the decrement when %esp
11236 ;; is used as a call operand, so they will execute return address as a code.
11237 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11238
11239 ;; Register constraint for call instruction.
11240 (define_mode_attr c [(SI "l") (DI "r")])
11241
11242 ;; Call subroutine returning no value.
11243
11244 (define_expand "call"
11245   [(call (match_operand:QI 0 "" "")
11246          (match_operand 1 "" ""))
11247    (use (match_operand 2 "" ""))]
11248   ""
11249 {
11250   ix86_expand_call (NULL, operands[0], operands[1],
11251                     operands[2], NULL, false);
11252   DONE;
11253 })
11254
11255 (define_expand "sibcall"
11256   [(call (match_operand:QI 0 "" "")
11257          (match_operand 1 "" ""))
11258    (use (match_operand 2 "" ""))]
11259   ""
11260 {
11261   ix86_expand_call (NULL, operands[0], operands[1],
11262                     operands[2], NULL, true);
11263   DONE;
11264 })
11265
11266 (define_insn_and_split "*call_vzeroupper"
11267   [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11268          (match_operand 1 "" ""))
11269    (unspec [(match_operand 2 "const_int_operand" "")]
11270            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11271   "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11272   "#"
11273   "&& reload_completed"
11274   [(const_int 0)]
11275   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11276   [(set_attr "type" "call")])
11277
11278 (define_insn "*call"
11279   [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11280          (match_operand 1 "" ""))]
11281   "!SIBLING_CALL_P (insn)"
11282   "* return ix86_output_call_insn (insn, operands[0]);"
11283   [(set_attr "type" "call")])
11284
11285 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11286   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11287          (match_operand 1 "" ""))
11288    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11289    (clobber (reg:TI XMM6_REG))
11290    (clobber (reg:TI XMM7_REG))
11291    (clobber (reg:TI XMM8_REG))
11292    (clobber (reg:TI XMM9_REG))
11293    (clobber (reg:TI XMM10_REG))
11294    (clobber (reg:TI XMM11_REG))
11295    (clobber (reg:TI XMM12_REG))
11296    (clobber (reg:TI XMM13_REG))
11297    (clobber (reg:TI XMM14_REG))
11298    (clobber (reg:TI XMM15_REG))
11299    (clobber (reg:DI SI_REG))
11300    (clobber (reg:DI DI_REG))
11301    (unspec [(match_operand 2 "const_int_operand" "")]
11302            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11303   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11304   "#"
11305   "&& reload_completed"
11306   [(const_int 0)]
11307   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11308   [(set_attr "type" "call")])
11309
11310 (define_insn "*call_rex64_ms_sysv"
11311   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11312          (match_operand 1 "" ""))
11313    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11314    (clobber (reg:TI XMM6_REG))
11315    (clobber (reg:TI XMM7_REG))
11316    (clobber (reg:TI XMM8_REG))
11317    (clobber (reg:TI XMM9_REG))
11318    (clobber (reg:TI XMM10_REG))
11319    (clobber (reg:TI XMM11_REG))
11320    (clobber (reg:TI XMM12_REG))
11321    (clobber (reg:TI XMM13_REG))
11322    (clobber (reg:TI XMM14_REG))
11323    (clobber (reg:TI XMM15_REG))
11324    (clobber (reg:DI SI_REG))
11325    (clobber (reg:DI DI_REG))]
11326   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11327   "* return ix86_output_call_insn (insn, operands[0]);"
11328   [(set_attr "type" "call")])
11329
11330 (define_insn_and_split "*sibcall_vzeroupper"
11331   [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11332          (match_operand 1 "" ""))
11333    (unspec [(match_operand 2 "const_int_operand" "")]
11334            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11335   "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11336   "#"
11337   "&& reload_completed"
11338   [(const_int 0)]
11339   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11340   [(set_attr "type" "call")])
11341
11342 (define_insn "*sibcall"
11343   [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11344          (match_operand 1 "" ""))]
11345   "SIBLING_CALL_P (insn)"
11346   "* return ix86_output_call_insn (insn, operands[0]);"
11347   [(set_attr "type" "call")])
11348
11349 (define_expand "call_pop"
11350   [(parallel [(call (match_operand:QI 0 "" "")
11351                     (match_operand:SI 1 "" ""))
11352               (set (reg:SI SP_REG)
11353                    (plus:SI (reg:SI SP_REG)
11354                             (match_operand:SI 3 "" "")))])]
11355   "!TARGET_64BIT"
11356 {
11357   ix86_expand_call (NULL, operands[0], operands[1],
11358                     operands[2], operands[3], false);
11359   DONE;
11360 })
11361
11362 (define_insn_and_split "*call_pop_vzeroupper"
11363   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11364          (match_operand:SI 1 "" ""))
11365    (set (reg:SI SP_REG)
11366         (plus:SI (reg:SI SP_REG)
11367                  (match_operand:SI 2 "immediate_operand" "i")))
11368    (unspec [(match_operand 3 "const_int_operand" "")]
11369            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11370   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11371   "#"
11372   "&& reload_completed"
11373   [(const_int 0)]
11374   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11375   [(set_attr "type" "call")])
11376
11377 (define_insn "*call_pop"
11378   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11379          (match_operand 1 "" ""))
11380    (set (reg:SI SP_REG)
11381         (plus:SI (reg:SI SP_REG)
11382                  (match_operand:SI 2 "immediate_operand" "i")))]
11383   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11384   "* return ix86_output_call_insn (insn, operands[0]);"
11385   [(set_attr "type" "call")])
11386
11387 (define_insn_and_split "*sibcall_pop_vzeroupper"
11388   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11389          (match_operand 1 "" ""))
11390    (set (reg:SI SP_REG)
11391         (plus:SI (reg:SI SP_REG)
11392                  (match_operand:SI 2 "immediate_operand" "i")))
11393    (unspec [(match_operand 3 "const_int_operand" "")]
11394            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11395   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11396   "#"
11397   "&& reload_completed"
11398   [(const_int 0)]
11399   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11400   [(set_attr "type" "call")])
11401
11402 (define_insn "*sibcall_pop"
11403   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11404          (match_operand 1 "" ""))
11405    (set (reg:SI SP_REG)
11406         (plus:SI (reg:SI SP_REG)
11407                  (match_operand:SI 2 "immediate_operand" "i")))]
11408   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11409   "* return ix86_output_call_insn (insn, operands[0]);"
11410   [(set_attr "type" "call")])
11411
11412 ;; Call subroutine, returning value in operand 0
11413
11414 (define_expand "call_value"
11415   [(set (match_operand 0 "" "")
11416         (call (match_operand:QI 1 "" "")
11417               (match_operand 2 "" "")))
11418    (use (match_operand 3 "" ""))]
11419   ""
11420 {
11421   ix86_expand_call (operands[0], operands[1], operands[2],
11422                     operands[3], NULL, false);
11423   DONE;
11424 })
11425
11426 (define_expand "sibcall_value"
11427   [(set (match_operand 0 "" "")
11428         (call (match_operand:QI 1 "" "")
11429               (match_operand 2 "" "")))
11430    (use (match_operand 3 "" ""))]
11431   ""
11432 {
11433   ix86_expand_call (operands[0], operands[1], operands[2],
11434                     operands[3], NULL, true);
11435   DONE;
11436 })
11437
11438 (define_insn_and_split "*call_value_vzeroupper"
11439   [(set (match_operand 0 "" "")
11440         (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11441               (match_operand 2 "" "")))
11442    (unspec [(match_operand 3 "const_int_operand" "")]
11443            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11444   "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11445   "#"
11446   "&& reload_completed"
11447   [(const_int 0)]
11448   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11449   [(set_attr "type" "callv")])
11450
11451 (define_insn "*call_value"
11452   [(set (match_operand 0 "" "")
11453         (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11454               (match_operand 2 "" "")))]
11455   "!SIBLING_CALL_P (insn)"
11456   "* return ix86_output_call_insn (insn, operands[1]);"
11457   [(set_attr "type" "callv")])
11458
11459 (define_insn_and_split "*sibcall_value_vzeroupper"
11460   [(set (match_operand 0 "" "")
11461         (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11462               (match_operand 2 "" "")))
11463    (unspec [(match_operand 3 "const_int_operand" "")]
11464            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11465   "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11466   "#"
11467   "&& reload_completed"
11468   [(const_int 0)]
11469   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11470   [(set_attr "type" "callv")])
11471
11472 (define_insn "*sibcall_value"
11473   [(set (match_operand 0 "" "")
11474         (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11475               (match_operand 2 "" "")))]
11476   "SIBLING_CALL_P (insn)"
11477   "* return ix86_output_call_insn (insn, operands[1]);"
11478   [(set_attr "type" "callv")])
11479
11480 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11481   [(set (match_operand 0 "" "")
11482         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11483               (match_operand 2 "" "")))
11484    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11485    (clobber (reg:TI XMM6_REG))
11486    (clobber (reg:TI XMM7_REG))
11487    (clobber (reg:TI XMM8_REG))
11488    (clobber (reg:TI XMM9_REG))
11489    (clobber (reg:TI XMM10_REG))
11490    (clobber (reg:TI XMM11_REG))
11491    (clobber (reg:TI XMM12_REG))
11492    (clobber (reg:TI XMM13_REG))
11493    (clobber (reg:TI XMM14_REG))
11494    (clobber (reg:TI XMM15_REG))
11495    (clobber (reg:DI SI_REG))
11496    (clobber (reg:DI DI_REG))
11497    (unspec [(match_operand 3 "const_int_operand" "")]
11498            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11499   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11500   "#"
11501   "&& reload_completed"
11502   [(const_int 0)]
11503   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11504   [(set_attr "type" "callv")])
11505
11506 (define_insn "*call_value_rex64_ms_sysv"
11507   [(set (match_operand 0 "" "")
11508         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11509               (match_operand 2 "" "")))
11510    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11511    (clobber (reg:TI XMM6_REG))
11512    (clobber (reg:TI XMM7_REG))
11513    (clobber (reg:TI XMM8_REG))
11514    (clobber (reg:TI XMM9_REG))
11515    (clobber (reg:TI XMM10_REG))
11516    (clobber (reg:TI XMM11_REG))
11517    (clobber (reg:TI XMM12_REG))
11518    (clobber (reg:TI XMM13_REG))
11519    (clobber (reg:TI XMM14_REG))
11520    (clobber (reg:TI XMM15_REG))
11521    (clobber (reg:DI SI_REG))
11522    (clobber (reg:DI DI_REG))]
11523   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11524   "* return ix86_output_call_insn (insn, operands[1]);"
11525   [(set_attr "type" "callv")])
11526
11527 (define_expand "call_value_pop"
11528   [(parallel [(set (match_operand 0 "" "")
11529                    (call (match_operand:QI 1 "" "")
11530                          (match_operand:SI 2 "" "")))
11531               (set (reg:SI SP_REG)
11532                    (plus:SI (reg:SI SP_REG)
11533                             (match_operand:SI 4 "" "")))])]
11534   "!TARGET_64BIT"
11535 {
11536   ix86_expand_call (operands[0], operands[1], operands[2],
11537                     operands[3], operands[4], false);
11538   DONE;
11539 })
11540
11541 (define_insn_and_split "*call_value_pop_vzeroupper"
11542   [(set (match_operand 0 "" "")
11543         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11544               (match_operand 2 "" "")))
11545    (set (reg:SI SP_REG)
11546         (plus:SI (reg:SI SP_REG)
11547                  (match_operand:SI 3 "immediate_operand" "i")))
11548    (unspec [(match_operand 4 "const_int_operand" "")]
11549            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11550   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11551   "#"
11552   "&& reload_completed"
11553   [(const_int 0)]
11554   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11555   [(set_attr "type" "callv")])
11556
11557 (define_insn "*call_value_pop"
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   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11565   "* return ix86_output_call_insn (insn, operands[1]);"
11566   [(set_attr "type" "callv")])
11567
11568 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11569   [(set (match_operand 0 "" "")
11570         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11571               (match_operand 2 "" "")))
11572    (set (reg:SI SP_REG)
11573         (plus:SI (reg:SI SP_REG)
11574                  (match_operand:SI 3 "immediate_operand" "i")))
11575    (unspec [(match_operand 4 "const_int_operand" "")]
11576            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11577   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11578   "#"
11579   "&& reload_completed"
11580   [(const_int 0)]
11581   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11582   [(set_attr "type" "callv")])
11583
11584 (define_insn "*sibcall_value_pop"
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   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11592   "* return ix86_output_call_insn (insn, operands[1]);"
11593   [(set_attr "type" "callv")])
11594
11595 ;; Call subroutine returning any type.
11596
11597 (define_expand "untyped_call"
11598   [(parallel [(call (match_operand 0 "" "")
11599                     (const_int 0))
11600               (match_operand 1 "" "")
11601               (match_operand 2 "" "")])]
11602   ""
11603 {
11604   int i;
11605
11606   /* In order to give reg-stack an easier job in validating two
11607      coprocessor registers as containing a possible return value,
11608      simply pretend the untyped call returns a complex long double
11609      value. 
11610
11611      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11612      and should have the default ABI.  */
11613
11614   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11615                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11616                     operands[0], const0_rtx,
11617                     GEN_INT ((TARGET_64BIT
11618                               ? (ix86_abi == SYSV_ABI
11619                                  ? X86_64_SSE_REGPARM_MAX
11620                                  : X86_64_MS_SSE_REGPARM_MAX)
11621                               : X86_32_SSE_REGPARM_MAX)
11622                              - 1),
11623                     NULL, false);
11624
11625   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11626     {
11627       rtx set = XVECEXP (operands[2], 0, i);
11628       emit_move_insn (SET_DEST (set), SET_SRC (set));
11629     }
11630
11631   /* The optimizer does not know that the call sets the function value
11632      registers we stored in the result block.  We avoid problems by
11633      claiming that all hard registers are used and clobbered at this
11634      point.  */
11635   emit_insn (gen_blockage ());
11636
11637   DONE;
11638 })
11639 \f
11640 ;; Prologue and epilogue instructions
11641
11642 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11643 ;; all of memory.  This blocks insns from being moved across this point.
11644
11645 (define_insn "blockage"
11646   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11647   ""
11648   ""
11649   [(set_attr "length" "0")])
11650
11651 ;; Do not schedule instructions accessing memory across this point.
11652
11653 (define_expand "memory_blockage"
11654   [(set (match_dup 0)
11655         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11656   ""
11657 {
11658   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11659   MEM_VOLATILE_P (operands[0]) = 1;
11660 })
11661
11662 (define_insn "*memory_blockage"
11663   [(set (match_operand:BLK 0 "" "")
11664         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11665   ""
11666   ""
11667   [(set_attr "length" "0")])
11668
11669 ;; As USE insns aren't meaningful after reload, this is used instead
11670 ;; to prevent deleting instructions setting registers for PIC code
11671 (define_insn "prologue_use"
11672   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11673   ""
11674   ""
11675   [(set_attr "length" "0")])
11676
11677 ;; Insn emitted into the body of a function to return from a function.
11678 ;; This is only done if the function's epilogue is known to be simple.
11679 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11680
11681 (define_expand "return"
11682   [(simple_return)]
11683   "ix86_can_use_return_insn_p ()"
11684 {
11685   ix86_maybe_emit_epilogue_vzeroupper ();
11686   if (crtl->args.pops_args)
11687     {
11688       rtx popc = GEN_INT (crtl->args.pops_args);
11689       emit_jump_insn (gen_simple_return_pop_internal (popc));
11690       DONE;
11691     }
11692 })
11693
11694 ;; We need to disable this for TARGET_SEH, as otherwise
11695 ;; shrink-wrapped prologue gets enabled too.  This might exceed
11696 ;; the maximum size of prologue in unwind information.
11697
11698 (define_expand "simple_return"
11699   [(simple_return)]
11700   "!TARGET_SEH"
11701 {
11702   ix86_maybe_emit_epilogue_vzeroupper ();
11703   if (crtl->args.pops_args)
11704     {
11705       rtx popc = GEN_INT (crtl->args.pops_args);
11706       emit_jump_insn (gen_simple_return_pop_internal (popc));
11707       DONE;
11708     }
11709 })
11710
11711 (define_insn "simple_return_internal"
11712   [(simple_return)]
11713   "reload_completed"
11714   "ret"
11715   [(set_attr "length" "1")
11716    (set_attr "atom_unit" "jeu")
11717    (set_attr "length_immediate" "0")
11718    (set_attr "modrm" "0")])
11719
11720 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11721 ;; instruction Athlon and K8 have.
11722
11723 (define_insn "simple_return_internal_long"
11724   [(simple_return)
11725    (unspec [(const_int 0)] UNSPEC_REP)]
11726   "reload_completed"
11727   "rep\;ret"
11728   [(set_attr "length" "2")
11729    (set_attr "atom_unit" "jeu")
11730    (set_attr "length_immediate" "0")
11731    (set_attr "prefix_rep" "1")
11732    (set_attr "modrm" "0")])
11733
11734 (define_insn "simple_return_pop_internal"
11735   [(simple_return)
11736    (use (match_operand:SI 0 "const_int_operand" ""))]
11737   "reload_completed"
11738   "ret\t%0"
11739   [(set_attr "length" "3")
11740    (set_attr "atom_unit" "jeu")
11741    (set_attr "length_immediate" "2")
11742    (set_attr "modrm" "0")])
11743
11744 (define_insn "simple_return_indirect_internal"
11745   [(simple_return)
11746    (use (match_operand:SI 0 "register_operand" "r"))]
11747   "reload_completed"
11748   "jmp\t%A0"
11749   [(set_attr "type" "ibr")
11750    (set_attr "length_immediate" "0")])
11751
11752 (define_insn "nop"
11753   [(const_int 0)]
11754   ""
11755   "nop"
11756   [(set_attr "length" "1")
11757    (set_attr "length_immediate" "0")
11758    (set_attr "modrm" "0")])
11759
11760 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
11761 (define_insn "nops"
11762   [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11763                     UNSPECV_NOPS)]
11764   "reload_completed"
11765 {
11766   int num = INTVAL (operands[0]);
11767
11768   gcc_assert (num >= 1 && num <= 8);
11769
11770   while (num--)
11771     fputs ("\tnop\n", asm_out_file);
11772
11773   return "";
11774 }
11775   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11776    (set_attr "length_immediate" "0")
11777    (set_attr "modrm" "0")])
11778
11779 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11780 ;; branch prediction penalty for the third jump in a 16-byte
11781 ;; block on K8.
11782
11783 (define_insn "pad"
11784   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11785   ""
11786 {
11787 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11788   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11789 #else
11790   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11791      The align insn is used to avoid 3 jump instructions in the row to improve
11792      branch prediction and the benefits hardly outweigh the cost of extra 8
11793      nops on the average inserted by full alignment pseudo operation.  */
11794 #endif
11795   return "";
11796 }
11797   [(set_attr "length" "16")])
11798
11799 (define_expand "prologue"
11800   [(const_int 0)]
11801   ""
11802   "ix86_expand_prologue (); DONE;")
11803
11804 (define_insn "set_got"
11805   [(set (match_operand:SI 0 "register_operand" "=r")
11806         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11807    (clobber (reg:CC FLAGS_REG))]
11808   "!TARGET_64BIT"
11809   "* return output_set_got (operands[0], NULL_RTX);"
11810   [(set_attr "type" "multi")
11811    (set_attr "length" "12")])
11812
11813 (define_insn "set_got_labelled"
11814   [(set (match_operand:SI 0 "register_operand" "=r")
11815         (unspec:SI [(label_ref (match_operand 1 "" ""))]
11816          UNSPEC_SET_GOT))
11817    (clobber (reg:CC FLAGS_REG))]
11818   "!TARGET_64BIT"
11819   "* return output_set_got (operands[0], operands[1]);"
11820   [(set_attr "type" "multi")
11821    (set_attr "length" "12")])
11822
11823 (define_insn "set_got_rex64"
11824   [(set (match_operand:DI 0 "register_operand" "=r")
11825         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11826   "TARGET_64BIT"
11827   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11828   [(set_attr "type" "lea")
11829    (set_attr "length_address" "4")
11830    (set_attr "mode" "DI")])
11831
11832 (define_insn "set_rip_rex64"
11833   [(set (match_operand:DI 0 "register_operand" "=r")
11834         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11835   "TARGET_64BIT"
11836   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11837   [(set_attr "type" "lea")
11838    (set_attr "length_address" "4")
11839    (set_attr "mode" "DI")])
11840
11841 (define_insn "set_got_offset_rex64"
11842   [(set (match_operand:DI 0 "register_operand" "=r")
11843         (unspec:DI
11844           [(label_ref (match_operand 1 "" ""))]
11845           UNSPEC_SET_GOT_OFFSET))]
11846   "TARGET_LP64"
11847   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11848   [(set_attr "type" "imov")
11849    (set_attr "length_immediate" "0")
11850    (set_attr "length_address" "8")
11851    (set_attr "mode" "DI")])
11852
11853 (define_expand "epilogue"
11854   [(const_int 0)]
11855   ""
11856   "ix86_expand_epilogue (1); DONE;")
11857
11858 (define_expand "sibcall_epilogue"
11859   [(const_int 0)]
11860   ""
11861   "ix86_expand_epilogue (0); DONE;")
11862
11863 (define_expand "eh_return"
11864   [(use (match_operand 0 "register_operand" ""))]
11865   ""
11866 {
11867   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11868
11869   /* Tricky bit: we write the address of the handler to which we will
11870      be returning into someone else's stack frame, one word below the
11871      stack address we wish to restore.  */
11872   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11873   tmp = plus_constant (tmp, -UNITS_PER_WORD);
11874   tmp = gen_rtx_MEM (Pmode, tmp);
11875   emit_move_insn (tmp, ra);
11876
11877   emit_jump_insn (gen_eh_return_internal ());
11878   emit_barrier ();
11879   DONE;
11880 })
11881
11882 (define_insn_and_split "eh_return_internal"
11883   [(eh_return)]
11884   ""
11885   "#"
11886   "epilogue_completed"
11887   [(const_int 0)]
11888   "ix86_expand_epilogue (2); DONE;")
11889
11890 (define_insn "leave"
11891   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11892    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11893    (clobber (mem:BLK (scratch)))]
11894   "!TARGET_64BIT"
11895   "leave"
11896   [(set_attr "type" "leave")])
11897
11898 (define_insn "leave_rex64"
11899   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11900    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11901    (clobber (mem:BLK (scratch)))]
11902   "TARGET_64BIT"
11903   "leave"
11904   [(set_attr "type" "leave")])
11905 \f
11906 ;; Handle -fsplit-stack.
11907
11908 (define_expand "split_stack_prologue"
11909   [(const_int 0)]
11910   ""
11911 {
11912   ix86_expand_split_stack_prologue ();
11913   DONE;
11914 })
11915
11916 ;; In order to support the call/return predictor, we use a return
11917 ;; instruction which the middle-end doesn't see.
11918 (define_insn "split_stack_return"
11919   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11920                      UNSPECV_SPLIT_STACK_RETURN)]
11921   ""
11922 {
11923   if (operands[0] == const0_rtx)
11924     return "ret";
11925   else
11926     return "ret\t%0";
11927 }
11928   [(set_attr "atom_unit" "jeu")
11929    (set_attr "modrm" "0")
11930    (set (attr "length")
11931         (if_then_else (match_operand:SI 0 "const0_operand" "")
11932                       (const_int 1)
11933                       (const_int 3)))
11934    (set (attr "length_immediate")
11935         (if_then_else (match_operand:SI 0 "const0_operand" "")
11936                       (const_int 0)
11937                       (const_int 2)))])
11938
11939 ;; If there are operand 0 bytes available on the stack, jump to
11940 ;; operand 1.
11941
11942 (define_expand "split_stack_space_check"
11943   [(set (pc) (if_then_else
11944               (ltu (minus (reg SP_REG)
11945                           (match_operand 0 "register_operand" ""))
11946                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11947               (label_ref (match_operand 1 "" ""))
11948               (pc)))]
11949   ""
11950 {
11951   rtx reg, size, limit;
11952
11953   reg = gen_reg_rtx (Pmode);
11954   size = force_reg (Pmode, operands[0]);
11955   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11956   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11957                           UNSPEC_STACK_CHECK);
11958   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11959   ix86_expand_branch (GEU, reg, limit, operands[1]);
11960
11961   DONE;
11962 })
11963 \f
11964 ;; Bit manipulation instructions.
11965
11966 (define_expand "ffs<mode>2"
11967   [(set (match_dup 2) (const_int -1))
11968    (parallel [(set (reg:CCZ FLAGS_REG)
11969                    (compare:CCZ
11970                      (match_operand:SWI48 1 "nonimmediate_operand" "")
11971                      (const_int 0)))
11972               (set (match_operand:SWI48 0 "register_operand" "")
11973                    (ctz:SWI48 (match_dup 1)))])
11974    (set (match_dup 0) (if_then_else:SWI48
11975                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
11976                         (match_dup 2)
11977                         (match_dup 0)))
11978    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11979               (clobber (reg:CC FLAGS_REG))])]
11980   ""
11981 {
11982   if (<MODE>mode == SImode && !TARGET_CMOVE)
11983     {
11984       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11985       DONE;
11986     }
11987   operands[2] = gen_reg_rtx (<MODE>mode);
11988 })
11989
11990 (define_insn_and_split "ffssi2_no_cmove"
11991   [(set (match_operand:SI 0 "register_operand" "=r")
11992         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11993    (clobber (match_scratch:SI 2 "=&q"))
11994    (clobber (reg:CC FLAGS_REG))]
11995   "!TARGET_CMOVE"
11996   "#"
11997   "&& reload_completed"
11998   [(parallel [(set (reg:CCZ FLAGS_REG)
11999                    (compare:CCZ (match_dup 1) (const_int 0)))
12000               (set (match_dup 0) (ctz:SI (match_dup 1)))])
12001    (set (strict_low_part (match_dup 3))
12002         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12003    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12004               (clobber (reg:CC FLAGS_REG))])
12005    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12006               (clobber (reg:CC FLAGS_REG))])
12007    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12008               (clobber (reg:CC FLAGS_REG))])]
12009 {
12010   operands[3] = gen_lowpart (QImode, operands[2]);
12011   ix86_expand_clear (operands[2]);
12012 })
12013
12014 (define_insn "*ffs<mode>_1"
12015   [(set (reg:CCZ FLAGS_REG)
12016         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12017                      (const_int 0)))
12018    (set (match_operand:SWI48 0 "register_operand" "=r")
12019         (ctz:SWI48 (match_dup 1)))]
12020   ""
12021   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12022   [(set_attr "type" "alu1")
12023    (set_attr "prefix_0f" "1")
12024    (set_attr "mode" "<MODE>")])
12025
12026 (define_insn "ctz<mode>2"
12027   [(set (match_operand:SWI248 0 "register_operand" "=r")
12028         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12029    (clobber (reg:CC FLAGS_REG))]
12030   ""
12031 {
12032   if (TARGET_BMI)
12033     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12034   else
12035     return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12036 }
12037   [(set_attr "type" "alu1")
12038    (set_attr "prefix_0f" "1")
12039    (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12040    (set_attr "mode" "<MODE>")])
12041
12042 (define_expand "clz<mode>2"
12043   [(parallel
12044      [(set (match_operand:SWI248 0 "register_operand" "")
12045            (minus:SWI248
12046              (match_dup 2)
12047              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12048       (clobber (reg:CC FLAGS_REG))])
12049    (parallel
12050      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12051       (clobber (reg:CC FLAGS_REG))])]
12052   ""
12053 {
12054   if (TARGET_LZCNT)
12055     {
12056       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12057       DONE;
12058     }
12059   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12060 })
12061
12062 (define_insn "clz<mode>2_lzcnt"
12063   [(set (match_operand:SWI248 0 "register_operand" "=r")
12064         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12065    (clobber (reg:CC FLAGS_REG))]
12066   "TARGET_LZCNT"
12067   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12068   [(set_attr "prefix_rep" "1")
12069    (set_attr "type" "bitmanip")
12070    (set_attr "mode" "<MODE>")])
12071
12072 ;; BMI instructions.
12073 (define_insn "*bmi_andn_<mode>"
12074   [(set (match_operand:SWI48 0 "register_operand" "=r")
12075         (and:SWI48
12076           (not:SWI48
12077             (match_operand:SWI48 1 "register_operand" "r"))
12078             (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12079    (clobber (reg:CC FLAGS_REG))]
12080   "TARGET_BMI"
12081   "andn\t{%2, %1, %0|%0, %1, %2}"
12082   [(set_attr "type" "bitmanip")
12083    (set_attr "mode" "<MODE>")])
12084
12085 (define_insn "bmi_bextr_<mode>"
12086   [(set (match_operand:SWI48 0 "register_operand" "=r")
12087         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12088                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12089                        UNSPEC_BEXTR))
12090    (clobber (reg:CC FLAGS_REG))]
12091   "TARGET_BMI"
12092   "bextr\t{%2, %1, %0|%0, %1, %2}"
12093   [(set_attr "type" "bitmanip")
12094    (set_attr "mode" "<MODE>")])
12095
12096 (define_insn "*bmi_blsi_<mode>"
12097   [(set (match_operand:SWI48 0 "register_operand" "=r")
12098         (and:SWI48
12099           (neg:SWI48
12100             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12101           (match_dup 1)))
12102    (clobber (reg:CC FLAGS_REG))]
12103   "TARGET_BMI"
12104   "blsi\t{%1, %0|%0, %1}"
12105   [(set_attr "type" "bitmanip")
12106    (set_attr "mode" "<MODE>")])
12107
12108 (define_insn "*bmi_blsmsk_<mode>"
12109   [(set (match_operand:SWI48 0 "register_operand" "=r")
12110         (xor:SWI48
12111           (plus:SWI48
12112             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12113             (const_int -1))
12114           (match_dup 1)))
12115    (clobber (reg:CC FLAGS_REG))]
12116   "TARGET_BMI"
12117   "blsmsk\t{%1, %0|%0, %1}"
12118   [(set_attr "type" "bitmanip")
12119    (set_attr "mode" "<MODE>")])
12120
12121 (define_insn "*bmi_blsr_<mode>"
12122   [(set (match_operand:SWI48 0 "register_operand" "=r")
12123         (and:SWI48
12124           (plus:SWI48
12125             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12126             (const_int -1))
12127           (match_dup 1)))
12128    (clobber (reg:CC FLAGS_REG))]
12129    "TARGET_BMI"
12130    "blsr\t{%1, %0|%0, %1}"
12131   [(set_attr "type" "bitmanip")
12132    (set_attr "mode" "<MODE>")])
12133
12134 ;; BMI2 instructions.
12135 (define_insn "bmi2_bzhi_<mode>3"
12136   [(set (match_operand:SWI48 0 "register_operand" "=r")
12137         (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12138                    (lshiftrt:SWI48 (const_int -1)
12139                                    (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12140    (clobber (reg:CC FLAGS_REG))]
12141   "TARGET_BMI2"
12142   "bzhi\t{%2, %1, %0|%0, %1, %2}"
12143   [(set_attr "type" "bitmanip")
12144    (set_attr "prefix" "vex")
12145    (set_attr "mode" "<MODE>")])
12146
12147 (define_insn "bmi2_pdep_<mode>3"
12148   [(set (match_operand:SWI48 0 "register_operand" "=r")
12149         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12150                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12151                        UNSPEC_PDEP))]
12152   "TARGET_BMI2"
12153   "pdep\t{%2, %1, %0|%0, %1, %2}"
12154   [(set_attr "type" "bitmanip")
12155    (set_attr "prefix" "vex")
12156    (set_attr "mode" "<MODE>")])
12157
12158 (define_insn "bmi2_pext_<mode>3"
12159   [(set (match_operand:SWI48 0 "register_operand" "=r")
12160         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12161                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12162                        UNSPEC_PEXT))]
12163   "TARGET_BMI2"
12164   "pext\t{%2, %1, %0|%0, %1, %2}"
12165   [(set_attr "type" "bitmanip")
12166    (set_attr "prefix" "vex")
12167    (set_attr "mode" "<MODE>")])
12168
12169 ;; TBM instructions.
12170 (define_insn "tbm_bextri_<mode>"
12171   [(set (match_operand:SWI48 0 "register_operand" "=r")
12172         (zero_extract:SWI48
12173           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12174           (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12175           (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12176    (clobber (reg:CC FLAGS_REG))]
12177    "TARGET_TBM"
12178 {
12179   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12180   return "bextr\t{%2, %1, %0|%0, %1, %2}";
12181 }
12182   [(set_attr "type" "bitmanip")
12183    (set_attr "mode" "<MODE>")])
12184
12185 (define_insn "*tbm_blcfill_<mode>"
12186   [(set (match_operand:SWI48 0 "register_operand" "=r")
12187         (and:SWI48
12188           (plus:SWI48
12189             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12190             (const_int 1))
12191           (match_dup 1)))
12192    (clobber (reg:CC FLAGS_REG))]
12193    "TARGET_TBM"
12194    "blcfill\t{%1, %0|%0, %1}"
12195   [(set_attr "type" "bitmanip")
12196    (set_attr "mode" "<MODE>")])
12197
12198 (define_insn "*tbm_blci_<mode>"
12199   [(set (match_operand:SWI48 0 "register_operand" "=r")
12200         (ior:SWI48
12201           (not:SWI48
12202             (plus:SWI48
12203               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12204               (const_int 1)))
12205           (match_dup 1)))
12206    (clobber (reg:CC FLAGS_REG))]
12207    "TARGET_TBM"
12208    "blci\t{%1, %0|%0, %1}"
12209   [(set_attr "type" "bitmanip")
12210    (set_attr "mode" "<MODE>")])
12211
12212 (define_insn "*tbm_blcic_<mode>"
12213   [(set (match_operand:SWI48 0 "register_operand" "=r")
12214         (and:SWI48
12215           (plus:SWI48
12216             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12217             (const_int 1))
12218           (not:SWI48
12219             (match_dup 1))))
12220    (clobber (reg:CC FLAGS_REG))]
12221    "TARGET_TBM"
12222    "blcic\t{%1, %0|%0, %1}"
12223   [(set_attr "type" "bitmanip")
12224    (set_attr "mode" "<MODE>")])
12225
12226 (define_insn "*tbm_blcmsk_<mode>"
12227   [(set (match_operand:SWI48 0 "register_operand" "=r")
12228         (xor:SWI48
12229           (plus:SWI48
12230             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12231             (const_int 1))
12232           (match_dup 1)))
12233    (clobber (reg:CC FLAGS_REG))]
12234    "TARGET_TBM"
12235    "blcmsk\t{%1, %0|%0, %1}"
12236   [(set_attr "type" "bitmanip")
12237    (set_attr "mode" "<MODE>")])
12238
12239 (define_insn "*tbm_blcs_<mode>"
12240   [(set (match_operand:SWI48 0 "register_operand" "=r")
12241         (ior:SWI48
12242           (plus:SWI48
12243             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12244             (const_int 1))
12245           (match_dup 1)))
12246    (clobber (reg:CC FLAGS_REG))]
12247    "TARGET_TBM"
12248    "blcs\t{%1, %0|%0, %1}"
12249   [(set_attr "type" "bitmanip")
12250    (set_attr "mode" "<MODE>")])
12251
12252 (define_insn "*tbm_blsfill_<mode>"
12253   [(set (match_operand:SWI48 0 "register_operand" "=r")
12254         (ior:SWI48
12255           (plus:SWI48
12256             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12257             (const_int -1))
12258           (match_dup 1)))
12259    (clobber (reg:CC FLAGS_REG))]
12260    "TARGET_TBM"
12261    "blsfill\t{%1, %0|%0, %1}"
12262   [(set_attr "type" "bitmanip")
12263    (set_attr "mode" "<MODE>")])
12264
12265 (define_insn "*tbm_blsic_<mode>"
12266   [(set (match_operand:SWI48 0 "register_operand" "=r")
12267         (ior:SWI48
12268           (plus:SWI48
12269             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12270             (const_int -1))
12271           (not:SWI48
12272             (match_dup 1))))
12273    (clobber (reg:CC FLAGS_REG))]
12274    "TARGET_TBM"
12275    "blsic\t{%1, %0|%0, %1}"
12276   [(set_attr "type" "bitmanip")
12277    (set_attr "mode" "<MODE>")])
12278
12279 (define_insn "*tbm_t1mskc_<mode>"
12280   [(set (match_operand:SWI48 0 "register_operand" "=r")
12281         (ior:SWI48
12282           (plus:SWI48
12283             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12284             (const_int 1))
12285           (not:SWI48
12286             (match_dup 1))))
12287    (clobber (reg:CC FLAGS_REG))]
12288    "TARGET_TBM"
12289    "t1mskc\t{%1, %0|%0, %1}"
12290   [(set_attr "type" "bitmanip")
12291    (set_attr "mode" "<MODE>")])
12292
12293 (define_insn "*tbm_tzmsk_<mode>"
12294   [(set (match_operand:SWI48 0 "register_operand" "=r")
12295         (and:SWI48
12296           (plus:SWI48
12297             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12298             (const_int -1))
12299           (not:SWI48
12300             (match_dup 1))))
12301    (clobber (reg:CC FLAGS_REG))]
12302    "TARGET_TBM"
12303    "tzmsk\t{%1, %0|%0, %1}"
12304   [(set_attr "type" "bitmanip")
12305    (set_attr "mode" "<MODE>")])
12306
12307 (define_insn "bsr_rex64"
12308   [(set (match_operand:DI 0 "register_operand" "=r")
12309         (minus:DI (const_int 63)
12310                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12311    (clobber (reg:CC FLAGS_REG))]
12312   "TARGET_64BIT"
12313   "bsr{q}\t{%1, %0|%0, %1}"
12314   [(set_attr "type" "alu1")
12315    (set_attr "prefix_0f" "1")
12316    (set_attr "mode" "DI")])
12317
12318 (define_insn "bsr"
12319   [(set (match_operand:SI 0 "register_operand" "=r")
12320         (minus:SI (const_int 31)
12321                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12322    (clobber (reg:CC FLAGS_REG))]
12323   ""
12324   "bsr{l}\t{%1, %0|%0, %1}"
12325   [(set_attr "type" "alu1")
12326    (set_attr "prefix_0f" "1")
12327    (set_attr "mode" "SI")])
12328
12329 (define_insn "*bsrhi"
12330   [(set (match_operand:HI 0 "register_operand" "=r")
12331         (minus:HI (const_int 15)
12332                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12333    (clobber (reg:CC FLAGS_REG))]
12334   ""
12335   "bsr{w}\t{%1, %0|%0, %1}"
12336   [(set_attr "type" "alu1")
12337    (set_attr "prefix_0f" "1")
12338    (set_attr "mode" "HI")])
12339
12340 (define_insn "popcount<mode>2"
12341   [(set (match_operand:SWI248 0 "register_operand" "=r")
12342         (popcount:SWI248
12343           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12344    (clobber (reg:CC FLAGS_REG))]
12345   "TARGET_POPCNT"
12346 {
12347 #if TARGET_MACHO
12348   return "popcnt\t{%1, %0|%0, %1}";
12349 #else
12350   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12351 #endif
12352 }
12353   [(set_attr "prefix_rep" "1")
12354    (set_attr "type" "bitmanip")
12355    (set_attr "mode" "<MODE>")])
12356
12357 (define_insn "*popcount<mode>2_cmp"
12358   [(set (reg FLAGS_REG)
12359         (compare
12360           (popcount:SWI248
12361             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12362           (const_int 0)))
12363    (set (match_operand:SWI248 0 "register_operand" "=r")
12364         (popcount:SWI248 (match_dup 1)))]
12365   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12366 {
12367 #if TARGET_MACHO
12368   return "popcnt\t{%1, %0|%0, %1}";
12369 #else
12370   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12371 #endif
12372 }
12373   [(set_attr "prefix_rep" "1")
12374    (set_attr "type" "bitmanip")
12375    (set_attr "mode" "<MODE>")])
12376
12377 (define_insn "*popcountsi2_cmp_zext"
12378   [(set (reg FLAGS_REG)
12379         (compare
12380           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12381           (const_int 0)))
12382    (set (match_operand:DI 0 "register_operand" "=r")
12383         (zero_extend:DI(popcount:SI (match_dup 1))))]
12384   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12385 {
12386 #if TARGET_MACHO
12387   return "popcnt\t{%1, %0|%0, %1}";
12388 #else
12389   return "popcnt{l}\t{%1, %0|%0, %1}";
12390 #endif
12391 }
12392   [(set_attr "prefix_rep" "1")
12393    (set_attr "type" "bitmanip")
12394    (set_attr "mode" "SI")])
12395
12396 (define_expand "bswap<mode>2"
12397   [(set (match_operand:SWI48 0 "register_operand" "")
12398         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12399   ""
12400 {
12401   if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12402     {
12403       rtx x = operands[0];
12404
12405       emit_move_insn (x, operands[1]);
12406       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12407       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12408       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12409       DONE;
12410     }
12411 })
12412
12413 (define_insn "*bswap<mode>2_movbe"
12414   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12415         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12416   "TARGET_MOVBE
12417    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12418   "@
12419     bswap\t%0
12420     movbe\t{%1, %0|%0, %1}
12421     movbe\t{%1, %0|%0, %1}"
12422   [(set_attr "type" "bitmanip,imov,imov")
12423    (set_attr "modrm" "0,1,1")
12424    (set_attr "prefix_0f" "*,1,1")
12425    (set_attr "prefix_extra" "*,1,1")
12426    (set_attr "mode" "<MODE>")])
12427
12428 (define_insn "*bswap<mode>2_1"
12429   [(set (match_operand:SWI48 0 "register_operand" "=r")
12430         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12431   "TARGET_BSWAP"
12432   "bswap\t%0"
12433   [(set_attr "type" "bitmanip")
12434    (set_attr "modrm" "0")
12435    (set_attr "mode" "<MODE>")])
12436
12437 (define_insn "*bswaphi_lowpart_1"
12438   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12439         (bswap:HI (match_dup 0)))
12440    (clobber (reg:CC FLAGS_REG))]
12441   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12442   "@
12443     xchg{b}\t{%h0, %b0|%b0, %h0}
12444     rol{w}\t{$8, %0|%0, 8}"
12445   [(set_attr "length" "2,4")
12446    (set_attr "mode" "QI,HI")])
12447
12448 (define_insn "bswaphi_lowpart"
12449   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12450         (bswap:HI (match_dup 0)))
12451    (clobber (reg:CC FLAGS_REG))]
12452   ""
12453   "rol{w}\t{$8, %0|%0, 8}"
12454   [(set_attr "length" "4")
12455    (set_attr "mode" "HI")])
12456
12457 (define_expand "paritydi2"
12458   [(set (match_operand:DI 0 "register_operand" "")
12459         (parity:DI (match_operand:DI 1 "register_operand" "")))]
12460   "! TARGET_POPCNT"
12461 {
12462   rtx scratch = gen_reg_rtx (QImode);
12463   rtx cond;
12464
12465   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12466                                 NULL_RTX, operands[1]));
12467
12468   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12469                          gen_rtx_REG (CCmode, FLAGS_REG),
12470                          const0_rtx);
12471   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12472
12473   if (TARGET_64BIT)
12474     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12475   else
12476     {
12477       rtx tmp = gen_reg_rtx (SImode);
12478
12479       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12480       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12481     }
12482   DONE;
12483 })
12484
12485 (define_expand "paritysi2"
12486   [(set (match_operand:SI 0 "register_operand" "")
12487         (parity:SI (match_operand:SI 1 "register_operand" "")))]
12488   "! TARGET_POPCNT"
12489 {
12490   rtx scratch = gen_reg_rtx (QImode);
12491   rtx cond;
12492
12493   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12494
12495   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12496                          gen_rtx_REG (CCmode, FLAGS_REG),
12497                          const0_rtx);
12498   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12499
12500   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12501   DONE;
12502 })
12503
12504 (define_insn_and_split "paritydi2_cmp"
12505   [(set (reg:CC FLAGS_REG)
12506         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12507                    UNSPEC_PARITY))
12508    (clobber (match_scratch:DI 0 "=r"))
12509    (clobber (match_scratch:SI 1 "=&r"))
12510    (clobber (match_scratch:HI 2 "=Q"))]
12511   "! TARGET_POPCNT"
12512   "#"
12513   "&& reload_completed"
12514   [(parallel
12515      [(set (match_dup 1)
12516            (xor:SI (match_dup 1) (match_dup 4)))
12517       (clobber (reg:CC FLAGS_REG))])
12518    (parallel
12519      [(set (reg:CC FLAGS_REG)
12520            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12521       (clobber (match_dup 1))
12522       (clobber (match_dup 2))])]
12523 {
12524   operands[4] = gen_lowpart (SImode, operands[3]);
12525
12526   if (TARGET_64BIT)
12527     {
12528       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12529       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12530     }
12531   else
12532     operands[1] = gen_highpart (SImode, operands[3]);
12533 })
12534
12535 (define_insn_and_split "paritysi2_cmp"
12536   [(set (reg:CC FLAGS_REG)
12537         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12538                    UNSPEC_PARITY))
12539    (clobber (match_scratch:SI 0 "=r"))
12540    (clobber (match_scratch:HI 1 "=&Q"))]
12541   "! TARGET_POPCNT"
12542   "#"
12543   "&& reload_completed"
12544   [(parallel
12545      [(set (match_dup 1)
12546            (xor:HI (match_dup 1) (match_dup 3)))
12547       (clobber (reg:CC FLAGS_REG))])
12548    (parallel
12549      [(set (reg:CC FLAGS_REG)
12550            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12551       (clobber (match_dup 1))])]
12552 {
12553   operands[3] = gen_lowpart (HImode, operands[2]);
12554
12555   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12556   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12557 })
12558
12559 (define_insn "*parityhi2_cmp"
12560   [(set (reg:CC FLAGS_REG)
12561         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12562                    UNSPEC_PARITY))
12563    (clobber (match_scratch:HI 0 "=Q"))]
12564   "! TARGET_POPCNT"
12565   "xor{b}\t{%h0, %b0|%b0, %h0}"
12566   [(set_attr "length" "2")
12567    (set_attr "mode" "HI")])
12568
12569 \f
12570 ;; Thread-local storage patterns for ELF.
12571 ;;
12572 ;; Note that these code sequences must appear exactly as shown
12573 ;; in order to allow linker relaxation.
12574
12575 (define_insn "*tls_global_dynamic_32_gnu"
12576   [(set (match_operand:SI 0 "register_operand" "=a")
12577         (unspec:SI
12578          [(match_operand:SI 1 "register_operand" "b")
12579           (match_operand:SI 2 "tls_symbolic_operand" "")
12580           (match_operand:SI 3 "constant_call_address_operand" "z")]
12581          UNSPEC_TLS_GD))
12582    (clobber (match_scratch:SI 4 "=d"))
12583    (clobber (match_scratch:SI 5 "=c"))
12584    (clobber (reg:CC FLAGS_REG))]
12585   "!TARGET_64BIT && TARGET_GNU_TLS"
12586 {
12587   output_asm_insn
12588     ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12589   if (TARGET_SUN_TLS)
12590 #ifdef HAVE_AS_IX86_TLSGDPLT
12591     return "call\t%a2@tlsgdplt";
12592 #else
12593     return "call\t%p3@plt";
12594 #endif
12595   return "call\t%P3";
12596 }
12597   [(set_attr "type" "multi")
12598    (set_attr "length" "12")])
12599
12600 (define_expand "tls_global_dynamic_32"
12601   [(parallel
12602     [(set (match_operand:SI 0 "register_operand" "")
12603           (unspec:SI [(match_operand:SI 2 "register_operand" "")
12604                       (match_operand:SI 1 "tls_symbolic_operand" "")
12605                       (match_operand:SI 3 "constant_call_address_operand" "")]
12606                      UNSPEC_TLS_GD))
12607      (clobber (match_scratch:SI 4 ""))
12608      (clobber (match_scratch:SI 5 ""))
12609      (clobber (reg:CC FLAGS_REG))])])
12610
12611 (define_insn "*tls_global_dynamic_64"
12612   [(set (match_operand:DI 0 "register_operand" "=a")
12613         (call:DI
12614          (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12615          (match_operand:DI 3 "" "")))
12616    (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12617               UNSPEC_TLS_GD)]
12618   "TARGET_64BIT"
12619 {
12620   if (!TARGET_X32)
12621     fputs (ASM_BYTE "0x66\n", asm_out_file);
12622   output_asm_insn
12623     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12624   fputs (ASM_SHORT "0x6666\n", asm_out_file);
12625   fputs ("\trex64\n", asm_out_file);
12626   if (TARGET_SUN_TLS)
12627     return "call\t%p2@plt";
12628   return "call\t%P2";
12629 }
12630   [(set_attr "type" "multi")
12631    (set (attr "length")
12632         (symbol_ref "TARGET_X32 ? 15 : 16"))])
12633
12634 (define_expand "tls_global_dynamic_64"
12635   [(parallel
12636     [(set (match_operand:DI 0 "register_operand" "")
12637           (call:DI
12638            (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12639            (const_int 0)))
12640      (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12641                 UNSPEC_TLS_GD)])])
12642
12643 (define_insn "*tls_local_dynamic_base_32_gnu"
12644   [(set (match_operand:SI 0 "register_operand" "=a")
12645         (unspec:SI
12646          [(match_operand:SI 1 "register_operand" "b")
12647           (match_operand:SI 2 "constant_call_address_operand" "z")]
12648          UNSPEC_TLS_LD_BASE))
12649    (clobber (match_scratch:SI 3 "=d"))
12650    (clobber (match_scratch:SI 4 "=c"))
12651    (clobber (reg:CC FLAGS_REG))]
12652   "!TARGET_64BIT && TARGET_GNU_TLS"
12653 {
12654   output_asm_insn
12655     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12656   if (TARGET_SUN_TLS)
12657 #ifdef HAVE_AS_IX86_TLSLDMPLT
12658     return "call\t%&@tlsldmplt";
12659 #else
12660     return "call\t%p2@plt";
12661 #endif
12662   return "call\t%P2";
12663 }
12664   [(set_attr "type" "multi")
12665    (set_attr "length" "11")])
12666
12667 (define_expand "tls_local_dynamic_base_32"
12668   [(parallel
12669      [(set (match_operand:SI 0 "register_operand" "")
12670            (unspec:SI
12671             [(match_operand:SI 1 "register_operand" "")
12672              (match_operand:SI 2 "constant_call_address_operand" "")]
12673             UNSPEC_TLS_LD_BASE))
12674       (clobber (match_scratch:SI 3 ""))
12675       (clobber (match_scratch:SI 4 ""))
12676       (clobber (reg:CC FLAGS_REG))])])
12677
12678 (define_insn "*tls_local_dynamic_base_64"
12679   [(set (match_operand:DI 0 "register_operand" "=a")
12680         (call:DI
12681          (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12682          (match_operand:DI 2 "" "")))
12683    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12684   "TARGET_64BIT"
12685 {
12686   output_asm_insn
12687     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12688   if (TARGET_SUN_TLS)
12689     return "call\t%p1@plt";
12690   return "call\t%P1";
12691 }
12692   [(set_attr "type" "multi")
12693    (set_attr "length" "12")])
12694
12695 (define_expand "tls_local_dynamic_base_64"
12696   [(parallel
12697      [(set (match_operand:DI 0 "register_operand" "")
12698            (call:DI
12699             (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12700             (const_int 0)))
12701       (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12702
12703 ;; Local dynamic of a single variable is a lose.  Show combine how
12704 ;; to convert that back to global dynamic.
12705
12706 (define_insn_and_split "*tls_local_dynamic_32_once"
12707   [(set (match_operand:SI 0 "register_operand" "=a")
12708         (plus:SI
12709          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12710                      (match_operand:SI 2 "constant_call_address_operand" "z")]
12711                     UNSPEC_TLS_LD_BASE)
12712          (const:SI (unspec:SI
12713                     [(match_operand:SI 3 "tls_symbolic_operand" "")]
12714                     UNSPEC_DTPOFF))))
12715    (clobber (match_scratch:SI 4 "=d"))
12716    (clobber (match_scratch:SI 5 "=c"))
12717    (clobber (reg:CC FLAGS_REG))]
12718   ""
12719   "#"
12720   ""
12721   [(parallel
12722      [(set (match_dup 0)
12723            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12724                       UNSPEC_TLS_GD))
12725       (clobber (match_dup 4))
12726       (clobber (match_dup 5))
12727       (clobber (reg:CC FLAGS_REG))])])
12728
12729 ;; Segment register for the thread base ptr load
12730 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12731
12732 ;; Load and add the thread base pointer from %<tp_seg>:0.
12733 (define_insn "*load_tp_x32"
12734   [(set (match_operand:SI 0 "register_operand" "=r")
12735         (unspec:SI [(const_int 0)] UNSPEC_TP))]
12736   "TARGET_X32"
12737   "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12738   [(set_attr "type" "imov")
12739    (set_attr "modrm" "0")
12740    (set_attr "length" "7")
12741    (set_attr "memory" "load")
12742    (set_attr "imm_disp" "false")])
12743
12744 (define_insn "*load_tp_x32_zext"
12745   [(set (match_operand:DI 0 "register_operand" "=r")
12746         (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12747   "TARGET_X32"
12748   "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12749   [(set_attr "type" "imov")
12750    (set_attr "modrm" "0")
12751    (set_attr "length" "7")
12752    (set_attr "memory" "load")
12753    (set_attr "imm_disp" "false")])
12754
12755 (define_insn "*load_tp_<mode>"
12756   [(set (match_operand:P 0 "register_operand" "=r")
12757         (unspec:P [(const_int 0)] UNSPEC_TP))]
12758   "!TARGET_X32"
12759   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12760   [(set_attr "type" "imov")
12761    (set_attr "modrm" "0")
12762    (set_attr "length" "7")
12763    (set_attr "memory" "load")
12764    (set_attr "imm_disp" "false")])
12765
12766 (define_insn "*add_tp_x32"
12767   [(set (match_operand:SI 0 "register_operand" "=r")
12768         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12769                  (match_operand:SI 1 "register_operand" "0")))
12770    (clobber (reg:CC FLAGS_REG))]
12771   "TARGET_X32"
12772   "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12773   [(set_attr "type" "alu")
12774    (set_attr "modrm" "0")
12775    (set_attr "length" "7")
12776    (set_attr "memory" "load")
12777    (set_attr "imm_disp" "false")])
12778
12779 (define_insn "*add_tp_x32_zext"
12780   [(set (match_operand:DI 0 "register_operand" "=r")
12781         (zero_extend:DI
12782           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12783                    (match_operand:SI 1 "register_operand" "0"))))
12784    (clobber (reg:CC FLAGS_REG))]
12785   "TARGET_X32"
12786   "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12787   [(set_attr "type" "alu")
12788    (set_attr "modrm" "0")
12789    (set_attr "length" "7")
12790    (set_attr "memory" "load")
12791    (set_attr "imm_disp" "false")])
12792
12793 (define_insn "*add_tp_<mode>"
12794   [(set (match_operand:P 0 "register_operand" "=r")
12795         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12796                 (match_operand:P 1 "register_operand" "0")))
12797    (clobber (reg:CC FLAGS_REG))]
12798   "!TARGET_X32"
12799   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12800   [(set_attr "type" "alu")
12801    (set_attr "modrm" "0")
12802    (set_attr "length" "7")
12803    (set_attr "memory" "load")
12804    (set_attr "imm_disp" "false")])
12805
12806 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12807 ;; %rax as destination of the initial executable code sequence.
12808 (define_insn "tls_initial_exec_64_sun"
12809   [(set (match_operand:DI 0 "register_operand" "=a")
12810         (unspec:DI
12811          [(match_operand:DI 1 "tls_symbolic_operand" "")]
12812          UNSPEC_TLS_IE_SUN))
12813    (clobber (reg:CC FLAGS_REG))]
12814   "TARGET_64BIT && TARGET_SUN_TLS"
12815 {
12816   output_asm_insn
12817     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12818   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12819 }
12820   [(set_attr "type" "multi")])
12821
12822 ;; GNU2 TLS patterns can be split.
12823
12824 (define_expand "tls_dynamic_gnu2_32"
12825   [(set (match_dup 3)
12826         (plus:SI (match_operand:SI 2 "register_operand" "")
12827                  (const:SI
12828                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12829                              UNSPEC_TLSDESC))))
12830    (parallel
12831     [(set (match_operand:SI 0 "register_operand" "")
12832           (unspec:SI [(match_dup 1) (match_dup 3)
12833                       (match_dup 2) (reg:SI SP_REG)]
12834                       UNSPEC_TLSDESC))
12835      (clobber (reg:CC FLAGS_REG))])]
12836   "!TARGET_64BIT && TARGET_GNU2_TLS"
12837 {
12838   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12839   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12840 })
12841
12842 (define_insn "*tls_dynamic_gnu2_lea_32"
12843   [(set (match_operand:SI 0 "register_operand" "=r")
12844         (plus:SI (match_operand:SI 1 "register_operand" "b")
12845                  (const:SI
12846                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12847                               UNSPEC_TLSDESC))))]
12848   "!TARGET_64BIT && TARGET_GNU2_TLS"
12849   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
12850   [(set_attr "type" "lea")
12851    (set_attr "mode" "SI")
12852    (set_attr "length" "6")
12853    (set_attr "length_address" "4")])
12854
12855 (define_insn "*tls_dynamic_gnu2_call_32"
12856   [(set (match_operand:SI 0 "register_operand" "=a")
12857         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12858                     (match_operand:SI 2 "register_operand" "0")
12859                     ;; we have to make sure %ebx still points to the GOT
12860                     (match_operand:SI 3 "register_operand" "b")
12861                     (reg:SI SP_REG)]
12862                    UNSPEC_TLSDESC))
12863    (clobber (reg:CC FLAGS_REG))]
12864   "!TARGET_64BIT && TARGET_GNU2_TLS"
12865   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12866   [(set_attr "type" "call")
12867    (set_attr "length" "2")
12868    (set_attr "length_address" "0")])
12869
12870 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12871   [(set (match_operand:SI 0 "register_operand" "=&a")
12872         (plus:SI
12873          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12874                      (match_operand:SI 4 "" "")
12875                      (match_operand:SI 2 "register_operand" "b")
12876                      (reg:SI SP_REG)]
12877                     UNSPEC_TLSDESC)
12878          (const:SI (unspec:SI
12879                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
12880                     UNSPEC_DTPOFF))))
12881    (clobber (reg:CC FLAGS_REG))]
12882   "!TARGET_64BIT && TARGET_GNU2_TLS"
12883   "#"
12884   ""
12885   [(set (match_dup 0) (match_dup 5))]
12886 {
12887   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12888   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12889 })
12890
12891 (define_expand "tls_dynamic_gnu2_64"
12892   [(set (match_dup 2)
12893         (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12894                    UNSPEC_TLSDESC))
12895    (parallel
12896     [(set (match_operand:DI 0 "register_operand" "")
12897           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12898                      UNSPEC_TLSDESC))
12899      (clobber (reg:CC FLAGS_REG))])]
12900   "TARGET_64BIT && TARGET_GNU2_TLS"
12901 {
12902   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12903   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12904 })
12905
12906 (define_insn "*tls_dynamic_gnu2_lea_64"
12907   [(set (match_operand:DI 0 "register_operand" "=r")
12908         (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12909                    UNSPEC_TLSDESC))]
12910   "TARGET_64BIT && TARGET_GNU2_TLS"
12911   "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
12912   [(set_attr "type" "lea")
12913    (set_attr "mode" "DI")
12914    (set_attr "length" "7")
12915    (set_attr "length_address" "4")])
12916
12917 (define_insn "*tls_dynamic_gnu2_call_64"
12918   [(set (match_operand:DI 0 "register_operand" "=a")
12919         (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12920                     (match_operand:DI 2 "register_operand" "0")
12921                     (reg:DI SP_REG)]
12922                    UNSPEC_TLSDESC))
12923    (clobber (reg:CC FLAGS_REG))]
12924   "TARGET_64BIT && TARGET_GNU2_TLS"
12925   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12926   [(set_attr "type" "call")
12927    (set_attr "length" "2")
12928    (set_attr "length_address" "0")])
12929
12930 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12931   [(set (match_operand:DI 0 "register_operand" "=&a")
12932         (plus:DI
12933          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12934                      (match_operand:DI 3 "" "")
12935                      (reg:DI SP_REG)]
12936                     UNSPEC_TLSDESC)
12937          (const:DI (unspec:DI
12938                     [(match_operand 1 "tls_symbolic_operand" "")]
12939                     UNSPEC_DTPOFF))))
12940    (clobber (reg:CC FLAGS_REG))]
12941   "TARGET_64BIT && TARGET_GNU2_TLS"
12942   "#"
12943   ""
12944   [(set (match_dup 0) (match_dup 4))]
12945 {
12946   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12947   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12948 })
12949 \f
12950 ;; These patterns match the binary 387 instructions for addM3, subM3,
12951 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
12952 ;; SFmode.  The first is the normal insn, the second the same insn but
12953 ;; with one operand a conversion, and the third the same insn but with
12954 ;; the other operand a conversion.  The conversion may be SFmode or
12955 ;; SImode if the target mode DFmode, but only SImode if the target mode
12956 ;; is SFmode.
12957
12958 ;; Gcc is slightly more smart about handling normal two address instructions
12959 ;; so use special patterns for add and mull.
12960
12961 (define_insn "*fop_<mode>_comm_mixed"
12962   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12963         (match_operator:MODEF 3 "binary_fp_operator"
12964           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12965            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12966   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12967    && COMMUTATIVE_ARITH_P (operands[3])
12968    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12969   "* return output_387_binary_op (insn, operands);"
12970   [(set (attr "type")
12971         (if_then_else (eq_attr "alternative" "1,2")
12972            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12973               (const_string "ssemul")
12974               (const_string "sseadd"))
12975            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12976               (const_string "fmul")
12977               (const_string "fop"))))
12978    (set_attr "isa" "*,noavx,avx")
12979    (set_attr "prefix" "orig,orig,vex")
12980    (set_attr "mode" "<MODE>")])
12981
12982 (define_insn "*fop_<mode>_comm_sse"
12983   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12984         (match_operator:MODEF 3 "binary_fp_operator"
12985           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12986            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12987   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12988    && COMMUTATIVE_ARITH_P (operands[3])
12989    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12990   "* return output_387_binary_op (insn, operands);"
12991   [(set (attr "type")
12992         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12993            (const_string "ssemul")
12994            (const_string "sseadd")))
12995    (set_attr "isa" "noavx,avx")
12996    (set_attr "prefix" "orig,vex")
12997    (set_attr "mode" "<MODE>")])
12998
12999 (define_insn "*fop_<mode>_comm_i387"
13000   [(set (match_operand:MODEF 0 "register_operand" "=f")
13001         (match_operator:MODEF 3 "binary_fp_operator"
13002           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13003            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13004   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13005    && COMMUTATIVE_ARITH_P (operands[3])
13006    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13007   "* return output_387_binary_op (insn, operands);"
13008   [(set (attr "type")
13009         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13010            (const_string "fmul")
13011            (const_string "fop")))
13012    (set_attr "mode" "<MODE>")])
13013
13014 (define_insn "*fop_<mode>_1_mixed"
13015   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13016         (match_operator:MODEF 3 "binary_fp_operator"
13017           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13018            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13019   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13020    && !COMMUTATIVE_ARITH_P (operands[3])
13021    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13022   "* return output_387_binary_op (insn, operands);"
13023   [(set (attr "type")
13024         (cond [(and (eq_attr "alternative" "2,3")
13025                     (match_operand:MODEF 3 "mult_operator" ""))
13026                  (const_string "ssemul")
13027                (and (eq_attr "alternative" "2,3")
13028                     (match_operand:MODEF 3 "div_operator" ""))
13029                  (const_string "ssediv")
13030                (eq_attr "alternative" "2,3")
13031                  (const_string "sseadd")
13032                (match_operand:MODEF 3 "mult_operator" "")
13033                  (const_string "fmul")
13034                (match_operand:MODEF 3 "div_operator" "")
13035                  (const_string "fdiv")
13036               ]
13037               (const_string "fop")))
13038    (set_attr "isa" "*,*,noavx,avx")
13039    (set_attr "prefix" "orig,orig,orig,vex")
13040    (set_attr "mode" "<MODE>")])
13041
13042 (define_insn "*rcpsf2_sse"
13043   [(set (match_operand:SF 0 "register_operand" "=x")
13044         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13045                    UNSPEC_RCP))]
13046   "TARGET_SSE_MATH"
13047   "%vrcpss\t{%1, %d0|%d0, %1}"
13048   [(set_attr "type" "sse")
13049    (set_attr "atom_sse_attr" "rcp")
13050    (set_attr "prefix" "maybe_vex")
13051    (set_attr "mode" "SF")])
13052
13053 (define_insn "*fop_<mode>_1_sse"
13054   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13055         (match_operator:MODEF 3 "binary_fp_operator"
13056           [(match_operand:MODEF 1 "register_operand" "0,x")
13057            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13058   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13059    && !COMMUTATIVE_ARITH_P (operands[3])"
13060   "* return output_387_binary_op (insn, operands);"
13061   [(set (attr "type")
13062         (cond [(match_operand:MODEF 3 "mult_operator" "")
13063                  (const_string "ssemul")
13064                (match_operand:MODEF 3 "div_operator" "")
13065                  (const_string "ssediv")
13066               ]
13067               (const_string "sseadd")))
13068    (set_attr "isa" "noavx,avx")
13069    (set_attr "prefix" "orig,vex")
13070    (set_attr "mode" "<MODE>")])
13071
13072 ;; This pattern is not fully shadowed by the pattern above.
13073 (define_insn "*fop_<mode>_1_i387"
13074   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13075         (match_operator:MODEF 3 "binary_fp_operator"
13076           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13077            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13078   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13079    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13080    && !COMMUTATIVE_ARITH_P (operands[3])
13081    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13082   "* return output_387_binary_op (insn, operands);"
13083   [(set (attr "type")
13084         (cond [(match_operand:MODEF 3 "mult_operator" "")
13085                  (const_string "fmul")
13086                (match_operand:MODEF 3 "div_operator" "")
13087                  (const_string "fdiv")
13088               ]
13089               (const_string "fop")))
13090    (set_attr "mode" "<MODE>")])
13091
13092 ;; ??? Add SSE splitters for these!
13093 (define_insn "*fop_<MODEF:mode>_2_i387"
13094   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13095         (match_operator:MODEF 3 "binary_fp_operator"
13096           [(float:MODEF
13097              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13098            (match_operand:MODEF 2 "register_operand" "0,0")]))]
13099   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13100    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13101    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13102   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13103   [(set (attr "type")
13104         (cond [(match_operand:MODEF 3 "mult_operator" "")
13105                  (const_string "fmul")
13106                (match_operand:MODEF 3 "div_operator" "")
13107                  (const_string "fdiv")
13108               ]
13109               (const_string "fop")))
13110    (set_attr "fp_int_src" "true")
13111    (set_attr "mode" "<SWI24:MODE>")])
13112
13113 (define_insn "*fop_<MODEF:mode>_3_i387"
13114   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13115         (match_operator:MODEF 3 "binary_fp_operator"
13116           [(match_operand:MODEF 1 "register_operand" "0,0")
13117            (float:MODEF
13118              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13119   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13120    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13121    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13122   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13123   [(set (attr "type")
13124         (cond [(match_operand:MODEF 3 "mult_operator" "")
13125                  (const_string "fmul")
13126                (match_operand:MODEF 3 "div_operator" "")
13127                  (const_string "fdiv")
13128               ]
13129               (const_string "fop")))
13130    (set_attr "fp_int_src" "true")
13131    (set_attr "mode" "<MODE>")])
13132
13133 (define_insn "*fop_df_4_i387"
13134   [(set (match_operand:DF 0 "register_operand" "=f,f")
13135         (match_operator:DF 3 "binary_fp_operator"
13136            [(float_extend:DF
13137              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13138             (match_operand:DF 2 "register_operand" "0,f")]))]
13139   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13140    && !(TARGET_SSE2 && TARGET_SSE_MATH)
13141    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13142   "* return output_387_binary_op (insn, operands);"
13143   [(set (attr "type")
13144         (cond [(match_operand:DF 3 "mult_operator" "")
13145                  (const_string "fmul")
13146                (match_operand:DF 3 "div_operator" "")
13147                  (const_string "fdiv")
13148               ]
13149               (const_string "fop")))
13150    (set_attr "mode" "SF")])
13151
13152 (define_insn "*fop_df_5_i387"
13153   [(set (match_operand:DF 0 "register_operand" "=f,f")
13154         (match_operator:DF 3 "binary_fp_operator"
13155           [(match_operand:DF 1 "register_operand" "0,f")
13156            (float_extend:DF
13157             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13158   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13159    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13160   "* return output_387_binary_op (insn, operands);"
13161   [(set (attr "type")
13162         (cond [(match_operand:DF 3 "mult_operator" "")
13163                  (const_string "fmul")
13164                (match_operand:DF 3 "div_operator" "")
13165                  (const_string "fdiv")
13166               ]
13167               (const_string "fop")))
13168    (set_attr "mode" "SF")])
13169
13170 (define_insn "*fop_df_6_i387"
13171   [(set (match_operand:DF 0 "register_operand" "=f,f")
13172         (match_operator:DF 3 "binary_fp_operator"
13173           [(float_extend:DF
13174             (match_operand:SF 1 "register_operand" "0,f"))
13175            (float_extend:DF
13176             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13177   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13178    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13179   "* return output_387_binary_op (insn, operands);"
13180   [(set (attr "type")
13181         (cond [(match_operand:DF 3 "mult_operator" "")
13182                  (const_string "fmul")
13183                (match_operand:DF 3 "div_operator" "")
13184                  (const_string "fdiv")
13185               ]
13186               (const_string "fop")))
13187    (set_attr "mode" "SF")])
13188
13189 (define_insn "*fop_xf_comm_i387"
13190   [(set (match_operand:XF 0 "register_operand" "=f")
13191         (match_operator:XF 3 "binary_fp_operator"
13192                         [(match_operand:XF 1 "register_operand" "%0")
13193                          (match_operand:XF 2 "register_operand" "f")]))]
13194   "TARGET_80387
13195    && COMMUTATIVE_ARITH_P (operands[3])"
13196   "* return output_387_binary_op (insn, operands);"
13197   [(set (attr "type")
13198         (if_then_else (match_operand:XF 3 "mult_operator" "")
13199            (const_string "fmul")
13200            (const_string "fop")))
13201    (set_attr "mode" "XF")])
13202
13203 (define_insn "*fop_xf_1_i387"
13204   [(set (match_operand:XF 0 "register_operand" "=f,f")
13205         (match_operator:XF 3 "binary_fp_operator"
13206                         [(match_operand:XF 1 "register_operand" "0,f")
13207                          (match_operand:XF 2 "register_operand" "f,0")]))]
13208   "TARGET_80387
13209    && !COMMUTATIVE_ARITH_P (operands[3])"
13210   "* return output_387_binary_op (insn, operands);"
13211   [(set (attr "type")
13212         (cond [(match_operand:XF 3 "mult_operator" "")
13213                  (const_string "fmul")
13214                (match_operand:XF 3 "div_operator" "")
13215                  (const_string "fdiv")
13216               ]
13217               (const_string "fop")))
13218    (set_attr "mode" "XF")])
13219
13220 (define_insn "*fop_xf_2_i387"
13221   [(set (match_operand:XF 0 "register_operand" "=f,f")
13222         (match_operator:XF 3 "binary_fp_operator"
13223           [(float:XF
13224              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13225            (match_operand:XF 2 "register_operand" "0,0")]))]
13226   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13227   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13228   [(set (attr "type")
13229         (cond [(match_operand:XF 3 "mult_operator" "")
13230                  (const_string "fmul")
13231                (match_operand:XF 3 "div_operator" "")
13232                  (const_string "fdiv")
13233               ]
13234               (const_string "fop")))
13235    (set_attr "fp_int_src" "true")
13236    (set_attr "mode" "<MODE>")])
13237
13238 (define_insn "*fop_xf_3_i387"
13239   [(set (match_operand:XF 0 "register_operand" "=f,f")
13240         (match_operator:XF 3 "binary_fp_operator"
13241           [(match_operand:XF 1 "register_operand" "0,0")
13242            (float:XF
13243              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13244   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13245   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13246   [(set (attr "type")
13247         (cond [(match_operand:XF 3 "mult_operator" "")
13248                  (const_string "fmul")
13249                (match_operand:XF 3 "div_operator" "")
13250                  (const_string "fdiv")
13251               ]
13252               (const_string "fop")))
13253    (set_attr "fp_int_src" "true")
13254    (set_attr "mode" "<MODE>")])
13255
13256 (define_insn "*fop_xf_4_i387"
13257   [(set (match_operand:XF 0 "register_operand" "=f,f")
13258         (match_operator:XF 3 "binary_fp_operator"
13259            [(float_extend:XF
13260               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13261             (match_operand:XF 2 "register_operand" "0,f")]))]
13262   "TARGET_80387"
13263   "* return output_387_binary_op (insn, operands);"
13264   [(set (attr "type")
13265         (cond [(match_operand:XF 3 "mult_operator" "")
13266                  (const_string "fmul")
13267                (match_operand:XF 3 "div_operator" "")
13268                  (const_string "fdiv")
13269               ]
13270               (const_string "fop")))
13271    (set_attr "mode" "<MODE>")])
13272
13273 (define_insn "*fop_xf_5_i387"
13274   [(set (match_operand:XF 0 "register_operand" "=f,f")
13275         (match_operator:XF 3 "binary_fp_operator"
13276           [(match_operand:XF 1 "register_operand" "0,f")
13277            (float_extend:XF
13278              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13279   "TARGET_80387"
13280   "* return output_387_binary_op (insn, operands);"
13281   [(set (attr "type")
13282         (cond [(match_operand:XF 3 "mult_operator" "")
13283                  (const_string "fmul")
13284                (match_operand:XF 3 "div_operator" "")
13285                  (const_string "fdiv")
13286               ]
13287               (const_string "fop")))
13288    (set_attr "mode" "<MODE>")])
13289
13290 (define_insn "*fop_xf_6_i387"
13291   [(set (match_operand:XF 0 "register_operand" "=f,f")
13292         (match_operator:XF 3 "binary_fp_operator"
13293           [(float_extend:XF
13294              (match_operand:MODEF 1 "register_operand" "0,f"))
13295            (float_extend:XF
13296              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13297   "TARGET_80387"
13298   "* return output_387_binary_op (insn, operands);"
13299   [(set (attr "type")
13300         (cond [(match_operand:XF 3 "mult_operator" "")
13301                  (const_string "fmul")
13302                (match_operand:XF 3 "div_operator" "")
13303                  (const_string "fdiv")
13304               ]
13305               (const_string "fop")))
13306    (set_attr "mode" "<MODE>")])
13307
13308 (define_split
13309   [(set (match_operand 0 "register_operand" "")
13310         (match_operator 3 "binary_fp_operator"
13311            [(float (match_operand:SWI24 1 "register_operand" ""))
13312             (match_operand 2 "register_operand" "")]))]
13313   "reload_completed
13314    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13315    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13316   [(const_int 0)]
13317 {
13318   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13319   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13320   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13321                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13322                                           GET_MODE (operands[3]),
13323                                           operands[4],
13324                                           operands[2])));
13325   ix86_free_from_memory (GET_MODE (operands[1]));
13326   DONE;
13327 })
13328
13329 (define_split
13330   [(set (match_operand 0 "register_operand" "")
13331         (match_operator 3 "binary_fp_operator"
13332            [(match_operand 1 "register_operand" "")
13333             (float (match_operand:SWI24 2 "register_operand" ""))]))]
13334   "reload_completed
13335    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13336    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13337   [(const_int 0)]
13338 {
13339   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13340   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13341   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13342                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13343                                           GET_MODE (operands[3]),
13344                                           operands[1],
13345                                           operands[4])));
13346   ix86_free_from_memory (GET_MODE (operands[2]));
13347   DONE;
13348 })
13349 \f
13350 ;; FPU special functions.
13351
13352 ;; This pattern implements a no-op XFmode truncation for
13353 ;; all fancy i386 XFmode math functions.
13354
13355 (define_insn "truncxf<mode>2_i387_noop_unspec"
13356   [(set (match_operand:MODEF 0 "register_operand" "=f")
13357         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13358         UNSPEC_TRUNC_NOOP))]
13359   "TARGET_USE_FANCY_MATH_387"
13360   "* return output_387_reg_move (insn, operands);"
13361   [(set_attr "type" "fmov")
13362    (set_attr "mode" "<MODE>")])
13363
13364 (define_insn "sqrtxf2"
13365   [(set (match_operand:XF 0 "register_operand" "=f")
13366         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13367   "TARGET_USE_FANCY_MATH_387"
13368   "fsqrt"
13369   [(set_attr "type" "fpspc")
13370    (set_attr "mode" "XF")
13371    (set_attr "athlon_decode" "direct")
13372    (set_attr "amdfam10_decode" "direct")
13373    (set_attr "bdver1_decode" "direct")])
13374
13375 (define_insn "sqrt_extend<mode>xf2_i387"
13376   [(set (match_operand:XF 0 "register_operand" "=f")
13377         (sqrt:XF
13378           (float_extend:XF
13379             (match_operand:MODEF 1 "register_operand" "0"))))]
13380   "TARGET_USE_FANCY_MATH_387"
13381   "fsqrt"
13382   [(set_attr "type" "fpspc")
13383    (set_attr "mode" "XF")
13384    (set_attr "athlon_decode" "direct")
13385    (set_attr "amdfam10_decode" "direct")
13386    (set_attr "bdver1_decode" "direct")])
13387
13388 (define_insn "*rsqrtsf2_sse"
13389   [(set (match_operand:SF 0 "register_operand" "=x")
13390         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13391                    UNSPEC_RSQRT))]
13392   "TARGET_SSE_MATH"
13393   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13394   [(set_attr "type" "sse")
13395    (set_attr "atom_sse_attr" "rcp")
13396    (set_attr "prefix" "maybe_vex")
13397    (set_attr "mode" "SF")])
13398
13399 (define_expand "rsqrtsf2"
13400   [(set (match_operand:SF 0 "register_operand" "")
13401         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13402                    UNSPEC_RSQRT))]
13403   "TARGET_SSE_MATH"
13404 {
13405   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13406   DONE;
13407 })
13408
13409 (define_insn "*sqrt<mode>2_sse"
13410   [(set (match_operand:MODEF 0 "register_operand" "=x")
13411         (sqrt:MODEF
13412           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13413   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13414   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13415   [(set_attr "type" "sse")
13416    (set_attr "atom_sse_attr" "sqrt")
13417    (set_attr "prefix" "maybe_vex")
13418    (set_attr "mode" "<MODE>")
13419    (set_attr "athlon_decode" "*")
13420    (set_attr "amdfam10_decode" "*")
13421    (set_attr "bdver1_decode" "*")])
13422
13423 (define_expand "sqrt<mode>2"
13424   [(set (match_operand:MODEF 0 "register_operand" "")
13425         (sqrt:MODEF
13426           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13427   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13428    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13429 {
13430   if (<MODE>mode == SFmode
13431       && TARGET_SSE_MATH
13432       && TARGET_RECIP_SQRT
13433       && !optimize_function_for_size_p (cfun)
13434       && flag_finite_math_only && !flag_trapping_math
13435       && flag_unsafe_math_optimizations)
13436     {
13437       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13438       DONE;
13439     }
13440
13441   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13442     {
13443       rtx op0 = gen_reg_rtx (XFmode);
13444       rtx op1 = force_reg (<MODE>mode, operands[1]);
13445
13446       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13447       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13448       DONE;
13449    }
13450 })
13451
13452 (define_insn "fpremxf4_i387"
13453   [(set (match_operand:XF 0 "register_operand" "=f")
13454         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13455                     (match_operand:XF 3 "register_operand" "1")]
13456                    UNSPEC_FPREM_F))
13457    (set (match_operand:XF 1 "register_operand" "=u")
13458         (unspec:XF [(match_dup 2) (match_dup 3)]
13459                    UNSPEC_FPREM_U))
13460    (set (reg:CCFP FPSR_REG)
13461         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13462                      UNSPEC_C2_FLAG))]
13463   "TARGET_USE_FANCY_MATH_387"
13464   "fprem"
13465   [(set_attr "type" "fpspc")
13466    (set_attr "mode" "XF")])
13467
13468 (define_expand "fmodxf3"
13469   [(use (match_operand:XF 0 "register_operand" ""))
13470    (use (match_operand:XF 1 "general_operand" ""))
13471    (use (match_operand:XF 2 "general_operand" ""))]
13472   "TARGET_USE_FANCY_MATH_387"
13473 {
13474   rtx label = gen_label_rtx ();
13475
13476   rtx op1 = gen_reg_rtx (XFmode);
13477   rtx op2 = gen_reg_rtx (XFmode);
13478
13479   emit_move_insn (op2, operands[2]);
13480   emit_move_insn (op1, operands[1]);
13481
13482   emit_label (label);
13483   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13484   ix86_emit_fp_unordered_jump (label);
13485   LABEL_NUSES (label) = 1;
13486
13487   emit_move_insn (operands[0], op1);
13488   DONE;
13489 })
13490
13491 (define_expand "fmod<mode>3"
13492   [(use (match_operand:MODEF 0 "register_operand" ""))
13493    (use (match_operand:MODEF 1 "general_operand" ""))
13494    (use (match_operand:MODEF 2 "general_operand" ""))]
13495   "TARGET_USE_FANCY_MATH_387"
13496 {
13497   rtx (*gen_truncxf) (rtx, rtx);
13498
13499   rtx label = gen_label_rtx ();
13500
13501   rtx op1 = gen_reg_rtx (XFmode);
13502   rtx op2 = gen_reg_rtx (XFmode);
13503
13504   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13505   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13506
13507   emit_label (label);
13508   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13509   ix86_emit_fp_unordered_jump (label);
13510   LABEL_NUSES (label) = 1;
13511
13512   /* Truncate the result properly for strict SSE math.  */
13513   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13514       && !TARGET_MIX_SSE_I387)
13515     gen_truncxf = gen_truncxf<mode>2;
13516   else
13517     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13518
13519   emit_insn (gen_truncxf (operands[0], op1));
13520   DONE;
13521 })
13522
13523 (define_insn "fprem1xf4_i387"
13524   [(set (match_operand:XF 0 "register_operand" "=f")
13525         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13526                     (match_operand:XF 3 "register_operand" "1")]
13527                    UNSPEC_FPREM1_F))
13528    (set (match_operand:XF 1 "register_operand" "=u")
13529         (unspec:XF [(match_dup 2) (match_dup 3)]
13530                    UNSPEC_FPREM1_U))
13531    (set (reg:CCFP FPSR_REG)
13532         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13533                      UNSPEC_C2_FLAG))]
13534   "TARGET_USE_FANCY_MATH_387"
13535   "fprem1"
13536   [(set_attr "type" "fpspc")
13537    (set_attr "mode" "XF")])
13538
13539 (define_expand "remainderxf3"
13540   [(use (match_operand:XF 0 "register_operand" ""))
13541    (use (match_operand:XF 1 "general_operand" ""))
13542    (use (match_operand:XF 2 "general_operand" ""))]
13543   "TARGET_USE_FANCY_MATH_387"
13544 {
13545   rtx label = gen_label_rtx ();
13546
13547   rtx op1 = gen_reg_rtx (XFmode);
13548   rtx op2 = gen_reg_rtx (XFmode);
13549
13550   emit_move_insn (op2, operands[2]);
13551   emit_move_insn (op1, operands[1]);
13552
13553   emit_label (label);
13554   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13555   ix86_emit_fp_unordered_jump (label);
13556   LABEL_NUSES (label) = 1;
13557
13558   emit_move_insn (operands[0], op1);
13559   DONE;
13560 })
13561
13562 (define_expand "remainder<mode>3"
13563   [(use (match_operand:MODEF 0 "register_operand" ""))
13564    (use (match_operand:MODEF 1 "general_operand" ""))
13565    (use (match_operand:MODEF 2 "general_operand" ""))]
13566   "TARGET_USE_FANCY_MATH_387"
13567 {
13568   rtx (*gen_truncxf) (rtx, rtx);
13569
13570   rtx label = gen_label_rtx ();
13571
13572   rtx op1 = gen_reg_rtx (XFmode);
13573   rtx op2 = gen_reg_rtx (XFmode);
13574
13575   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13576   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13577
13578   emit_label (label);
13579
13580   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13581   ix86_emit_fp_unordered_jump (label);
13582   LABEL_NUSES (label) = 1;
13583
13584   /* Truncate the result properly for strict SSE math.  */
13585   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13586       && !TARGET_MIX_SSE_I387)
13587     gen_truncxf = gen_truncxf<mode>2;
13588   else
13589     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13590
13591   emit_insn (gen_truncxf (operands[0], op1));
13592   DONE;
13593 })
13594
13595 (define_insn "*sinxf2_i387"
13596   [(set (match_operand:XF 0 "register_operand" "=f")
13597         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13598   "TARGET_USE_FANCY_MATH_387
13599    && flag_unsafe_math_optimizations"
13600   "fsin"
13601   [(set_attr "type" "fpspc")
13602    (set_attr "mode" "XF")])
13603
13604 (define_insn "*sin_extend<mode>xf2_i387"
13605   [(set (match_operand:XF 0 "register_operand" "=f")
13606         (unspec:XF [(float_extend:XF
13607                       (match_operand:MODEF 1 "register_operand" "0"))]
13608                    UNSPEC_SIN))]
13609   "TARGET_USE_FANCY_MATH_387
13610    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13611        || TARGET_MIX_SSE_I387)
13612    && flag_unsafe_math_optimizations"
13613   "fsin"
13614   [(set_attr "type" "fpspc")
13615    (set_attr "mode" "XF")])
13616
13617 (define_insn "*cosxf2_i387"
13618   [(set (match_operand:XF 0 "register_operand" "=f")
13619         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13620   "TARGET_USE_FANCY_MATH_387
13621    && flag_unsafe_math_optimizations"
13622   "fcos"
13623   [(set_attr "type" "fpspc")
13624    (set_attr "mode" "XF")])
13625
13626 (define_insn "*cos_extend<mode>xf2_i387"
13627   [(set (match_operand:XF 0 "register_operand" "=f")
13628         (unspec:XF [(float_extend:XF
13629                       (match_operand:MODEF 1 "register_operand" "0"))]
13630                    UNSPEC_COS))]
13631   "TARGET_USE_FANCY_MATH_387
13632    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13633        || TARGET_MIX_SSE_I387)
13634    && flag_unsafe_math_optimizations"
13635   "fcos"
13636   [(set_attr "type" "fpspc")
13637    (set_attr "mode" "XF")])
13638
13639 ;; When sincos pattern is defined, sin and cos builtin functions will be
13640 ;; expanded to sincos pattern with one of its outputs left unused.
13641 ;; CSE pass will figure out if two sincos patterns can be combined,
13642 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13643 ;; depending on the unused output.
13644
13645 (define_insn "sincosxf3"
13646   [(set (match_operand:XF 0 "register_operand" "=f")
13647         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13648                    UNSPEC_SINCOS_COS))
13649    (set (match_operand:XF 1 "register_operand" "=u")
13650         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13651   "TARGET_USE_FANCY_MATH_387
13652    && flag_unsafe_math_optimizations"
13653   "fsincos"
13654   [(set_attr "type" "fpspc")
13655    (set_attr "mode" "XF")])
13656
13657 (define_split
13658   [(set (match_operand:XF 0 "register_operand" "")
13659         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13660                    UNSPEC_SINCOS_COS))
13661    (set (match_operand:XF 1 "register_operand" "")
13662         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13663   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13664    && can_create_pseudo_p ()"
13665   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13666
13667 (define_split
13668   [(set (match_operand:XF 0 "register_operand" "")
13669         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13670                    UNSPEC_SINCOS_COS))
13671    (set (match_operand:XF 1 "register_operand" "")
13672         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13673   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13674    && can_create_pseudo_p ()"
13675   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13676
13677 (define_insn "sincos_extend<mode>xf3_i387"
13678   [(set (match_operand:XF 0 "register_operand" "=f")
13679         (unspec:XF [(float_extend:XF
13680                       (match_operand:MODEF 2 "register_operand" "0"))]
13681                    UNSPEC_SINCOS_COS))
13682    (set (match_operand:XF 1 "register_operand" "=u")
13683         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13684   "TARGET_USE_FANCY_MATH_387
13685    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13686        || TARGET_MIX_SSE_I387)
13687    && flag_unsafe_math_optimizations"
13688   "fsincos"
13689   [(set_attr "type" "fpspc")
13690    (set_attr "mode" "XF")])
13691
13692 (define_split
13693   [(set (match_operand:XF 0 "register_operand" "")
13694         (unspec:XF [(float_extend:XF
13695                       (match_operand:MODEF 2 "register_operand" ""))]
13696                    UNSPEC_SINCOS_COS))
13697    (set (match_operand:XF 1 "register_operand" "")
13698         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13699   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13700    && can_create_pseudo_p ()"
13701   [(set (match_dup 1)
13702         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13703
13704 (define_split
13705   [(set (match_operand:XF 0 "register_operand" "")
13706         (unspec:XF [(float_extend:XF
13707                       (match_operand:MODEF 2 "register_operand" ""))]
13708                    UNSPEC_SINCOS_COS))
13709    (set (match_operand:XF 1 "register_operand" "")
13710         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13711   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13712    && can_create_pseudo_p ()"
13713   [(set (match_dup 0)
13714         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13715
13716 (define_expand "sincos<mode>3"
13717   [(use (match_operand:MODEF 0 "register_operand" ""))
13718    (use (match_operand:MODEF 1 "register_operand" ""))
13719    (use (match_operand:MODEF 2 "register_operand" ""))]
13720   "TARGET_USE_FANCY_MATH_387
13721    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13722        || TARGET_MIX_SSE_I387)
13723    && flag_unsafe_math_optimizations"
13724 {
13725   rtx op0 = gen_reg_rtx (XFmode);
13726   rtx op1 = gen_reg_rtx (XFmode);
13727
13728   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13729   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13730   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13731   DONE;
13732 })
13733
13734 (define_insn "fptanxf4_i387"
13735   [(set (match_operand:XF 0 "register_operand" "=f")
13736         (match_operand:XF 3 "const_double_operand" "F"))
13737    (set (match_operand:XF 1 "register_operand" "=u")
13738         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13739                    UNSPEC_TAN))]
13740   "TARGET_USE_FANCY_MATH_387
13741    && flag_unsafe_math_optimizations
13742    && standard_80387_constant_p (operands[3]) == 2"
13743   "fptan"
13744   [(set_attr "type" "fpspc")
13745    (set_attr "mode" "XF")])
13746
13747 (define_insn "fptan_extend<mode>xf4_i387"
13748   [(set (match_operand:MODEF 0 "register_operand" "=f")
13749         (match_operand:MODEF 3 "const_double_operand" "F"))
13750    (set (match_operand:XF 1 "register_operand" "=u")
13751         (unspec:XF [(float_extend:XF
13752                       (match_operand:MODEF 2 "register_operand" "0"))]
13753                    UNSPEC_TAN))]
13754   "TARGET_USE_FANCY_MATH_387
13755    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13756        || TARGET_MIX_SSE_I387)
13757    && flag_unsafe_math_optimizations
13758    && standard_80387_constant_p (operands[3]) == 2"
13759   "fptan"
13760   [(set_attr "type" "fpspc")
13761    (set_attr "mode" "XF")])
13762
13763 (define_expand "tanxf2"
13764   [(use (match_operand:XF 0 "register_operand" ""))
13765    (use (match_operand:XF 1 "register_operand" ""))]
13766   "TARGET_USE_FANCY_MATH_387
13767    && flag_unsafe_math_optimizations"
13768 {
13769   rtx one = gen_reg_rtx (XFmode);
13770   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13771
13772   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13773   DONE;
13774 })
13775
13776 (define_expand "tan<mode>2"
13777   [(use (match_operand:MODEF 0 "register_operand" ""))
13778    (use (match_operand:MODEF 1 "register_operand" ""))]
13779   "TARGET_USE_FANCY_MATH_387
13780    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13781        || TARGET_MIX_SSE_I387)
13782    && flag_unsafe_math_optimizations"
13783 {
13784   rtx op0 = gen_reg_rtx (XFmode);
13785
13786   rtx one = gen_reg_rtx (<MODE>mode);
13787   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13788
13789   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13790                                              operands[1], op2));
13791   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13792   DONE;
13793 })
13794
13795 (define_insn "*fpatanxf3_i387"
13796   [(set (match_operand:XF 0 "register_operand" "=f")
13797         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13798                     (match_operand:XF 2 "register_operand" "u")]
13799                    UNSPEC_FPATAN))
13800    (clobber (match_scratch:XF 3 "=2"))]
13801   "TARGET_USE_FANCY_MATH_387
13802    && flag_unsafe_math_optimizations"
13803   "fpatan"
13804   [(set_attr "type" "fpspc")
13805    (set_attr "mode" "XF")])
13806
13807 (define_insn "fpatan_extend<mode>xf3_i387"
13808   [(set (match_operand:XF 0 "register_operand" "=f")
13809         (unspec:XF [(float_extend:XF
13810                       (match_operand:MODEF 1 "register_operand" "0"))
13811                     (float_extend:XF
13812                       (match_operand:MODEF 2 "register_operand" "u"))]
13813                    UNSPEC_FPATAN))
13814    (clobber (match_scratch:XF 3 "=2"))]
13815   "TARGET_USE_FANCY_MATH_387
13816    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13817        || TARGET_MIX_SSE_I387)
13818    && flag_unsafe_math_optimizations"
13819   "fpatan"
13820   [(set_attr "type" "fpspc")
13821    (set_attr "mode" "XF")])
13822
13823 (define_expand "atan2xf3"
13824   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13825                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
13826                                (match_operand:XF 1 "register_operand" "")]
13827                               UNSPEC_FPATAN))
13828               (clobber (match_scratch:XF 3 ""))])]
13829   "TARGET_USE_FANCY_MATH_387
13830    && flag_unsafe_math_optimizations")
13831
13832 (define_expand "atan2<mode>3"
13833   [(use (match_operand:MODEF 0 "register_operand" ""))
13834    (use (match_operand:MODEF 1 "register_operand" ""))
13835    (use (match_operand:MODEF 2 "register_operand" ""))]
13836   "TARGET_USE_FANCY_MATH_387
13837    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13838        || TARGET_MIX_SSE_I387)
13839    && flag_unsafe_math_optimizations"
13840 {
13841   rtx op0 = gen_reg_rtx (XFmode);
13842
13843   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13844   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13845   DONE;
13846 })
13847
13848 (define_expand "atanxf2"
13849   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13850                    (unspec:XF [(match_dup 2)
13851                                (match_operand:XF 1 "register_operand" "")]
13852                               UNSPEC_FPATAN))
13853               (clobber (match_scratch:XF 3 ""))])]
13854   "TARGET_USE_FANCY_MATH_387
13855    && flag_unsafe_math_optimizations"
13856 {
13857   operands[2] = gen_reg_rtx (XFmode);
13858   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13859 })
13860
13861 (define_expand "atan<mode>2"
13862   [(use (match_operand:MODEF 0 "register_operand" ""))
13863    (use (match_operand:MODEF 1 "register_operand" ""))]
13864   "TARGET_USE_FANCY_MATH_387
13865    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13866        || TARGET_MIX_SSE_I387)
13867    && flag_unsafe_math_optimizations"
13868 {
13869   rtx op0 = gen_reg_rtx (XFmode);
13870
13871   rtx op2 = gen_reg_rtx (<MODE>mode);
13872   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13873
13874   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13875   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13876   DONE;
13877 })
13878
13879 (define_expand "asinxf2"
13880   [(set (match_dup 2)
13881         (mult:XF (match_operand:XF 1 "register_operand" "")
13882                  (match_dup 1)))
13883    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13884    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13885    (parallel [(set (match_operand:XF 0 "register_operand" "")
13886                    (unspec:XF [(match_dup 5) (match_dup 1)]
13887                               UNSPEC_FPATAN))
13888               (clobber (match_scratch:XF 6 ""))])]
13889   "TARGET_USE_FANCY_MATH_387
13890    && flag_unsafe_math_optimizations"
13891 {
13892   int i;
13893
13894   if (optimize_insn_for_size_p ())
13895     FAIL;
13896
13897   for (i = 2; i < 6; i++)
13898     operands[i] = gen_reg_rtx (XFmode);
13899
13900   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13901 })
13902
13903 (define_expand "asin<mode>2"
13904   [(use (match_operand:MODEF 0 "register_operand" ""))
13905    (use (match_operand:MODEF 1 "general_operand" ""))]
13906  "TARGET_USE_FANCY_MATH_387
13907    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13908        || TARGET_MIX_SSE_I387)
13909    && flag_unsafe_math_optimizations"
13910 {
13911   rtx op0 = gen_reg_rtx (XFmode);
13912   rtx op1 = gen_reg_rtx (XFmode);
13913
13914   if (optimize_insn_for_size_p ())
13915     FAIL;
13916
13917   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13918   emit_insn (gen_asinxf2 (op0, op1));
13919   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13920   DONE;
13921 })
13922
13923 (define_expand "acosxf2"
13924   [(set (match_dup 2)
13925         (mult:XF (match_operand:XF 1 "register_operand" "")
13926                  (match_dup 1)))
13927    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13928    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13929    (parallel [(set (match_operand:XF 0 "register_operand" "")
13930                    (unspec:XF [(match_dup 1) (match_dup 5)]
13931                               UNSPEC_FPATAN))
13932               (clobber (match_scratch:XF 6 ""))])]
13933   "TARGET_USE_FANCY_MATH_387
13934    && flag_unsafe_math_optimizations"
13935 {
13936   int i;
13937
13938   if (optimize_insn_for_size_p ())
13939     FAIL;
13940
13941   for (i = 2; i < 6; i++)
13942     operands[i] = gen_reg_rtx (XFmode);
13943
13944   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13945 })
13946
13947 (define_expand "acos<mode>2"
13948   [(use (match_operand:MODEF 0 "register_operand" ""))
13949    (use (match_operand:MODEF 1 "general_operand" ""))]
13950  "TARGET_USE_FANCY_MATH_387
13951    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13952        || TARGET_MIX_SSE_I387)
13953    && flag_unsafe_math_optimizations"
13954 {
13955   rtx op0 = gen_reg_rtx (XFmode);
13956   rtx op1 = gen_reg_rtx (XFmode);
13957
13958   if (optimize_insn_for_size_p ())
13959     FAIL;
13960
13961   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13962   emit_insn (gen_acosxf2 (op0, op1));
13963   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13964   DONE;
13965 })
13966
13967 (define_insn "fyl2xxf3_i387"
13968   [(set (match_operand:XF 0 "register_operand" "=f")
13969         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13970                     (match_operand:XF 2 "register_operand" "u")]
13971                    UNSPEC_FYL2X))
13972    (clobber (match_scratch:XF 3 "=2"))]
13973   "TARGET_USE_FANCY_MATH_387
13974    && flag_unsafe_math_optimizations"
13975   "fyl2x"
13976   [(set_attr "type" "fpspc")
13977    (set_attr "mode" "XF")])
13978
13979 (define_insn "fyl2x_extend<mode>xf3_i387"
13980   [(set (match_operand:XF 0 "register_operand" "=f")
13981         (unspec:XF [(float_extend:XF
13982                       (match_operand:MODEF 1 "register_operand" "0"))
13983                     (match_operand:XF 2 "register_operand" "u")]
13984                    UNSPEC_FYL2X))
13985    (clobber (match_scratch:XF 3 "=2"))]
13986   "TARGET_USE_FANCY_MATH_387
13987    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13988        || TARGET_MIX_SSE_I387)
13989    && flag_unsafe_math_optimizations"
13990   "fyl2x"
13991   [(set_attr "type" "fpspc")
13992    (set_attr "mode" "XF")])
13993
13994 (define_expand "logxf2"
13995   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13996                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13997                                (match_dup 2)] UNSPEC_FYL2X))
13998               (clobber (match_scratch:XF 3 ""))])]
13999   "TARGET_USE_FANCY_MATH_387
14000    && flag_unsafe_math_optimizations"
14001 {
14002   operands[2] = gen_reg_rtx (XFmode);
14003   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14004 })
14005
14006 (define_expand "log<mode>2"
14007   [(use (match_operand:MODEF 0 "register_operand" ""))
14008    (use (match_operand:MODEF 1 "register_operand" ""))]
14009   "TARGET_USE_FANCY_MATH_387
14010    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14011        || TARGET_MIX_SSE_I387)
14012    && flag_unsafe_math_optimizations"
14013 {
14014   rtx op0 = gen_reg_rtx (XFmode);
14015
14016   rtx op2 = gen_reg_rtx (XFmode);
14017   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14018
14019   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14020   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14021   DONE;
14022 })
14023
14024 (define_expand "log10xf2"
14025   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14026                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14027                                (match_dup 2)] UNSPEC_FYL2X))
14028               (clobber (match_scratch:XF 3 ""))])]
14029   "TARGET_USE_FANCY_MATH_387
14030    && flag_unsafe_math_optimizations"
14031 {
14032   operands[2] = gen_reg_rtx (XFmode);
14033   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14034 })
14035
14036 (define_expand "log10<mode>2"
14037   [(use (match_operand:MODEF 0 "register_operand" ""))
14038    (use (match_operand:MODEF 1 "register_operand" ""))]
14039   "TARGET_USE_FANCY_MATH_387
14040    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14041        || TARGET_MIX_SSE_I387)
14042    && flag_unsafe_math_optimizations"
14043 {
14044   rtx op0 = gen_reg_rtx (XFmode);
14045
14046   rtx op2 = gen_reg_rtx (XFmode);
14047   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14048
14049   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14050   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14051   DONE;
14052 })
14053
14054 (define_expand "log2xf2"
14055   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14056                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14057                                (match_dup 2)] UNSPEC_FYL2X))
14058               (clobber (match_scratch:XF 3 ""))])]
14059   "TARGET_USE_FANCY_MATH_387
14060    && flag_unsafe_math_optimizations"
14061 {
14062   operands[2] = gen_reg_rtx (XFmode);
14063   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14064 })
14065
14066 (define_expand "log2<mode>2"
14067   [(use (match_operand:MODEF 0 "register_operand" ""))
14068    (use (match_operand:MODEF 1 "register_operand" ""))]
14069   "TARGET_USE_FANCY_MATH_387
14070    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14071        || TARGET_MIX_SSE_I387)
14072    && flag_unsafe_math_optimizations"
14073 {
14074   rtx op0 = gen_reg_rtx (XFmode);
14075
14076   rtx op2 = gen_reg_rtx (XFmode);
14077   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14078
14079   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14080   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14081   DONE;
14082 })
14083
14084 (define_insn "fyl2xp1xf3_i387"
14085   [(set (match_operand:XF 0 "register_operand" "=f")
14086         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14087                     (match_operand:XF 2 "register_operand" "u")]
14088                    UNSPEC_FYL2XP1))
14089    (clobber (match_scratch:XF 3 "=2"))]
14090   "TARGET_USE_FANCY_MATH_387
14091    && flag_unsafe_math_optimizations"
14092   "fyl2xp1"
14093   [(set_attr "type" "fpspc")
14094    (set_attr "mode" "XF")])
14095
14096 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14097   [(set (match_operand:XF 0 "register_operand" "=f")
14098         (unspec:XF [(float_extend:XF
14099                       (match_operand:MODEF 1 "register_operand" "0"))
14100                     (match_operand:XF 2 "register_operand" "u")]
14101                    UNSPEC_FYL2XP1))
14102    (clobber (match_scratch:XF 3 "=2"))]
14103   "TARGET_USE_FANCY_MATH_387
14104    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14105        || TARGET_MIX_SSE_I387)
14106    && flag_unsafe_math_optimizations"
14107   "fyl2xp1"
14108   [(set_attr "type" "fpspc")
14109    (set_attr "mode" "XF")])
14110
14111 (define_expand "log1pxf2"
14112   [(use (match_operand:XF 0 "register_operand" ""))
14113    (use (match_operand:XF 1 "register_operand" ""))]
14114   "TARGET_USE_FANCY_MATH_387
14115    && flag_unsafe_math_optimizations"
14116 {
14117   if (optimize_insn_for_size_p ())
14118     FAIL;
14119
14120   ix86_emit_i387_log1p (operands[0], operands[1]);
14121   DONE;
14122 })
14123
14124 (define_expand "log1p<mode>2"
14125   [(use (match_operand:MODEF 0 "register_operand" ""))
14126    (use (match_operand:MODEF 1 "register_operand" ""))]
14127   "TARGET_USE_FANCY_MATH_387
14128    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14129        || TARGET_MIX_SSE_I387)
14130    && flag_unsafe_math_optimizations"
14131 {
14132   rtx op0;
14133
14134   if (optimize_insn_for_size_p ())
14135     FAIL;
14136
14137   op0 = gen_reg_rtx (XFmode);
14138
14139   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14140
14141   ix86_emit_i387_log1p (op0, operands[1]);
14142   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14143   DONE;
14144 })
14145
14146 (define_insn "fxtractxf3_i387"
14147   [(set (match_operand:XF 0 "register_operand" "=f")
14148         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14149                    UNSPEC_XTRACT_FRACT))
14150    (set (match_operand:XF 1 "register_operand" "=u")
14151         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14152   "TARGET_USE_FANCY_MATH_387
14153    && flag_unsafe_math_optimizations"
14154   "fxtract"
14155   [(set_attr "type" "fpspc")
14156    (set_attr "mode" "XF")])
14157
14158 (define_insn "fxtract_extend<mode>xf3_i387"
14159   [(set (match_operand:XF 0 "register_operand" "=f")
14160         (unspec:XF [(float_extend:XF
14161                       (match_operand:MODEF 2 "register_operand" "0"))]
14162                    UNSPEC_XTRACT_FRACT))
14163    (set (match_operand:XF 1 "register_operand" "=u")
14164         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14165   "TARGET_USE_FANCY_MATH_387
14166    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14167        || TARGET_MIX_SSE_I387)
14168    && flag_unsafe_math_optimizations"
14169   "fxtract"
14170   [(set_attr "type" "fpspc")
14171    (set_attr "mode" "XF")])
14172
14173 (define_expand "logbxf2"
14174   [(parallel [(set (match_dup 2)
14175                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14176                               UNSPEC_XTRACT_FRACT))
14177               (set (match_operand:XF 0 "register_operand" "")
14178                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14179   "TARGET_USE_FANCY_MATH_387
14180    && flag_unsafe_math_optimizations"
14181   "operands[2] = gen_reg_rtx (XFmode);")
14182
14183 (define_expand "logb<mode>2"
14184   [(use (match_operand:MODEF 0 "register_operand" ""))
14185    (use (match_operand:MODEF 1 "register_operand" ""))]
14186   "TARGET_USE_FANCY_MATH_387
14187    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14188        || TARGET_MIX_SSE_I387)
14189    && flag_unsafe_math_optimizations"
14190 {
14191   rtx op0 = gen_reg_rtx (XFmode);
14192   rtx op1 = gen_reg_rtx (XFmode);
14193
14194   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14195   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14196   DONE;
14197 })
14198
14199 (define_expand "ilogbxf2"
14200   [(use (match_operand:SI 0 "register_operand" ""))
14201    (use (match_operand:XF 1 "register_operand" ""))]
14202   "TARGET_USE_FANCY_MATH_387
14203    && flag_unsafe_math_optimizations"
14204 {
14205   rtx op0, op1;
14206
14207   if (optimize_insn_for_size_p ())
14208     FAIL;
14209
14210   op0 = gen_reg_rtx (XFmode);
14211   op1 = gen_reg_rtx (XFmode);
14212
14213   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14214   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14215   DONE;
14216 })
14217
14218 (define_expand "ilogb<mode>2"
14219   [(use (match_operand:SI 0 "register_operand" ""))
14220    (use (match_operand:MODEF 1 "register_operand" ""))]
14221   "TARGET_USE_FANCY_MATH_387
14222    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14223        || TARGET_MIX_SSE_I387)
14224    && flag_unsafe_math_optimizations"
14225 {
14226   rtx op0, op1;
14227
14228   if (optimize_insn_for_size_p ())
14229     FAIL;
14230
14231   op0 = gen_reg_rtx (XFmode);
14232   op1 = gen_reg_rtx (XFmode);
14233
14234   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14235   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14236   DONE;
14237 })
14238
14239 (define_insn "*f2xm1xf2_i387"
14240   [(set (match_operand:XF 0 "register_operand" "=f")
14241         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14242                    UNSPEC_F2XM1))]
14243   "TARGET_USE_FANCY_MATH_387
14244    && flag_unsafe_math_optimizations"
14245   "f2xm1"
14246   [(set_attr "type" "fpspc")
14247    (set_attr "mode" "XF")])
14248
14249 (define_insn "*fscalexf4_i387"
14250   [(set (match_operand:XF 0 "register_operand" "=f")
14251         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14252                     (match_operand:XF 3 "register_operand" "1")]
14253                    UNSPEC_FSCALE_FRACT))
14254    (set (match_operand:XF 1 "register_operand" "=u")
14255         (unspec:XF [(match_dup 2) (match_dup 3)]
14256                    UNSPEC_FSCALE_EXP))]
14257   "TARGET_USE_FANCY_MATH_387
14258    && flag_unsafe_math_optimizations"
14259   "fscale"
14260   [(set_attr "type" "fpspc")
14261    (set_attr "mode" "XF")])
14262
14263 (define_expand "expNcorexf3"
14264   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14265                                (match_operand:XF 2 "register_operand" "")))
14266    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14267    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14268    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14269    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14270    (parallel [(set (match_operand:XF 0 "register_operand" "")
14271                    (unspec:XF [(match_dup 8) (match_dup 4)]
14272                               UNSPEC_FSCALE_FRACT))
14273               (set (match_dup 9)
14274                    (unspec:XF [(match_dup 8) (match_dup 4)]
14275                               UNSPEC_FSCALE_EXP))])]
14276   "TARGET_USE_FANCY_MATH_387
14277    && flag_unsafe_math_optimizations"
14278 {
14279   int i;
14280
14281   if (optimize_insn_for_size_p ())
14282     FAIL;
14283
14284   for (i = 3; i < 10; i++)
14285     operands[i] = gen_reg_rtx (XFmode);
14286
14287   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14288 })
14289
14290 (define_expand "expxf2"
14291   [(use (match_operand:XF 0 "register_operand" ""))
14292    (use (match_operand:XF 1 "register_operand" ""))]
14293   "TARGET_USE_FANCY_MATH_387
14294    && flag_unsafe_math_optimizations"
14295 {
14296   rtx op2;
14297
14298   if (optimize_insn_for_size_p ())
14299     FAIL;
14300
14301   op2 = gen_reg_rtx (XFmode);
14302   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14303
14304   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14305   DONE;
14306 })
14307
14308 (define_expand "exp<mode>2"
14309   [(use (match_operand:MODEF 0 "register_operand" ""))
14310    (use (match_operand:MODEF 1 "general_operand" ""))]
14311  "TARGET_USE_FANCY_MATH_387
14312    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14313        || TARGET_MIX_SSE_I387)
14314    && flag_unsafe_math_optimizations"
14315 {
14316   rtx op0, op1;
14317
14318   if (optimize_insn_for_size_p ())
14319     FAIL;
14320
14321   op0 = gen_reg_rtx (XFmode);
14322   op1 = gen_reg_rtx (XFmode);
14323
14324   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14325   emit_insn (gen_expxf2 (op0, op1));
14326   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14327   DONE;
14328 })
14329
14330 (define_expand "exp10xf2"
14331   [(use (match_operand:XF 0 "register_operand" ""))
14332    (use (match_operand:XF 1 "register_operand" ""))]
14333   "TARGET_USE_FANCY_MATH_387
14334    && flag_unsafe_math_optimizations"
14335 {
14336   rtx op2;
14337
14338   if (optimize_insn_for_size_p ())
14339     FAIL;
14340
14341   op2 = gen_reg_rtx (XFmode);
14342   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14343
14344   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14345   DONE;
14346 })
14347
14348 (define_expand "exp10<mode>2"
14349   [(use (match_operand:MODEF 0 "register_operand" ""))
14350    (use (match_operand:MODEF 1 "general_operand" ""))]
14351  "TARGET_USE_FANCY_MATH_387
14352    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14353        || TARGET_MIX_SSE_I387)
14354    && flag_unsafe_math_optimizations"
14355 {
14356   rtx op0, op1;
14357
14358   if (optimize_insn_for_size_p ())
14359     FAIL;
14360
14361   op0 = gen_reg_rtx (XFmode);
14362   op1 = gen_reg_rtx (XFmode);
14363
14364   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14365   emit_insn (gen_exp10xf2 (op0, op1));
14366   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14367   DONE;
14368 })
14369
14370 (define_expand "exp2xf2"
14371   [(use (match_operand:XF 0 "register_operand" ""))
14372    (use (match_operand:XF 1 "register_operand" ""))]
14373   "TARGET_USE_FANCY_MATH_387
14374    && flag_unsafe_math_optimizations"
14375 {
14376   rtx op2;
14377
14378   if (optimize_insn_for_size_p ())
14379     FAIL;
14380
14381   op2 = gen_reg_rtx (XFmode);
14382   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14383
14384   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14385   DONE;
14386 })
14387
14388 (define_expand "exp2<mode>2"
14389   [(use (match_operand:MODEF 0 "register_operand" ""))
14390    (use (match_operand:MODEF 1 "general_operand" ""))]
14391  "TARGET_USE_FANCY_MATH_387
14392    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14393        || TARGET_MIX_SSE_I387)
14394    && flag_unsafe_math_optimizations"
14395 {
14396   rtx op0, op1;
14397
14398   if (optimize_insn_for_size_p ())
14399     FAIL;
14400
14401   op0 = gen_reg_rtx (XFmode);
14402   op1 = gen_reg_rtx (XFmode);
14403
14404   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14405   emit_insn (gen_exp2xf2 (op0, op1));
14406   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14407   DONE;
14408 })
14409
14410 (define_expand "expm1xf2"
14411   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14412                                (match_dup 2)))
14413    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14414    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14415    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14416    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14417    (parallel [(set (match_dup 7)
14418                    (unspec:XF [(match_dup 6) (match_dup 4)]
14419                               UNSPEC_FSCALE_FRACT))
14420               (set (match_dup 8)
14421                    (unspec:XF [(match_dup 6) (match_dup 4)]
14422                               UNSPEC_FSCALE_EXP))])
14423    (parallel [(set (match_dup 10)
14424                    (unspec:XF [(match_dup 9) (match_dup 8)]
14425                               UNSPEC_FSCALE_FRACT))
14426               (set (match_dup 11)
14427                    (unspec:XF [(match_dup 9) (match_dup 8)]
14428                               UNSPEC_FSCALE_EXP))])
14429    (set (match_dup 12) (minus:XF (match_dup 10)
14430                                  (float_extend:XF (match_dup 13))))
14431    (set (match_operand:XF 0 "register_operand" "")
14432         (plus:XF (match_dup 12) (match_dup 7)))]
14433   "TARGET_USE_FANCY_MATH_387
14434    && flag_unsafe_math_optimizations"
14435 {
14436   int i;
14437
14438   if (optimize_insn_for_size_p ())
14439     FAIL;
14440
14441   for (i = 2; i < 13; i++)
14442     operands[i] = gen_reg_rtx (XFmode);
14443
14444   operands[13]
14445     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14446
14447   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14448 })
14449
14450 (define_expand "expm1<mode>2"
14451   [(use (match_operand:MODEF 0 "register_operand" ""))
14452    (use (match_operand:MODEF 1 "general_operand" ""))]
14453  "TARGET_USE_FANCY_MATH_387
14454    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14455        || TARGET_MIX_SSE_I387)
14456    && flag_unsafe_math_optimizations"
14457 {
14458   rtx op0, op1;
14459
14460   if (optimize_insn_for_size_p ())
14461     FAIL;
14462
14463   op0 = gen_reg_rtx (XFmode);
14464   op1 = gen_reg_rtx (XFmode);
14465
14466   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14467   emit_insn (gen_expm1xf2 (op0, op1));
14468   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14469   DONE;
14470 })
14471
14472 (define_expand "ldexpxf3"
14473   [(set (match_dup 3)
14474         (float:XF (match_operand:SI 2 "register_operand" "")))
14475    (parallel [(set (match_operand:XF 0 " register_operand" "")
14476                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14477                                (match_dup 3)]
14478                               UNSPEC_FSCALE_FRACT))
14479               (set (match_dup 4)
14480                    (unspec:XF [(match_dup 1) (match_dup 3)]
14481                               UNSPEC_FSCALE_EXP))])]
14482   "TARGET_USE_FANCY_MATH_387
14483    && flag_unsafe_math_optimizations"
14484 {
14485   if (optimize_insn_for_size_p ())
14486     FAIL;
14487
14488   operands[3] = gen_reg_rtx (XFmode);
14489   operands[4] = gen_reg_rtx (XFmode);
14490 })
14491
14492 (define_expand "ldexp<mode>3"
14493   [(use (match_operand:MODEF 0 "register_operand" ""))
14494    (use (match_operand:MODEF 1 "general_operand" ""))
14495    (use (match_operand:SI 2 "register_operand" ""))]
14496  "TARGET_USE_FANCY_MATH_387
14497    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14498        || TARGET_MIX_SSE_I387)
14499    && flag_unsafe_math_optimizations"
14500 {
14501   rtx op0, op1;
14502
14503   if (optimize_insn_for_size_p ())
14504     FAIL;
14505
14506   op0 = gen_reg_rtx (XFmode);
14507   op1 = gen_reg_rtx (XFmode);
14508
14509   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14510   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14511   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14512   DONE;
14513 })
14514
14515 (define_expand "scalbxf3"
14516   [(parallel [(set (match_operand:XF 0 " register_operand" "")
14517                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14518                                (match_operand:XF 2 "register_operand" "")]
14519                               UNSPEC_FSCALE_FRACT))
14520               (set (match_dup 3)
14521                    (unspec:XF [(match_dup 1) (match_dup 2)]
14522                               UNSPEC_FSCALE_EXP))])]
14523   "TARGET_USE_FANCY_MATH_387
14524    && flag_unsafe_math_optimizations"
14525 {
14526   if (optimize_insn_for_size_p ())
14527     FAIL;
14528
14529   operands[3] = gen_reg_rtx (XFmode);
14530 })
14531
14532 (define_expand "scalb<mode>3"
14533   [(use (match_operand:MODEF 0 "register_operand" ""))
14534    (use (match_operand:MODEF 1 "general_operand" ""))
14535    (use (match_operand:MODEF 2 "general_operand" ""))]
14536  "TARGET_USE_FANCY_MATH_387
14537    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14538        || TARGET_MIX_SSE_I387)
14539    && flag_unsafe_math_optimizations"
14540 {
14541   rtx op0, op1, op2;
14542
14543   if (optimize_insn_for_size_p ())
14544     FAIL;
14545
14546   op0 = gen_reg_rtx (XFmode);
14547   op1 = gen_reg_rtx (XFmode);
14548   op2 = gen_reg_rtx (XFmode);
14549
14550   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14551   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14552   emit_insn (gen_scalbxf3 (op0, op1, op2));
14553   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14554   DONE;
14555 })
14556
14557 (define_expand "significandxf2"
14558   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14559                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14560                               UNSPEC_XTRACT_FRACT))
14561               (set (match_dup 2)
14562                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14563   "TARGET_USE_FANCY_MATH_387
14564    && flag_unsafe_math_optimizations"
14565   "operands[2] = gen_reg_rtx (XFmode);")
14566
14567 (define_expand "significand<mode>2"
14568   [(use (match_operand:MODEF 0 "register_operand" ""))
14569    (use (match_operand:MODEF 1 "register_operand" ""))]
14570   "TARGET_USE_FANCY_MATH_387
14571    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14572        || TARGET_MIX_SSE_I387)
14573    && flag_unsafe_math_optimizations"
14574 {
14575   rtx op0 = gen_reg_rtx (XFmode);
14576   rtx op1 = gen_reg_rtx (XFmode);
14577
14578   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14579   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14580   DONE;
14581 })
14582 \f
14583
14584 (define_insn "sse4_1_round<mode>2"
14585   [(set (match_operand:MODEF 0 "register_operand" "=x")
14586         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14587                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14588                       UNSPEC_ROUND))]
14589   "TARGET_ROUND"
14590   "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14591   [(set_attr "type" "ssecvt")
14592    (set_attr "prefix_extra" "1")
14593    (set_attr "prefix" "maybe_vex")
14594    (set_attr "mode" "<MODE>")])
14595
14596 (define_insn "rintxf2"
14597   [(set (match_operand:XF 0 "register_operand" "=f")
14598         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14599                    UNSPEC_FRNDINT))]
14600   "TARGET_USE_FANCY_MATH_387
14601    && flag_unsafe_math_optimizations"
14602   "frndint"
14603   [(set_attr "type" "fpspc")
14604    (set_attr "mode" "XF")])
14605
14606 (define_expand "rint<mode>2"
14607   [(use (match_operand:MODEF 0 "register_operand" ""))
14608    (use (match_operand:MODEF 1 "register_operand" ""))]
14609   "(TARGET_USE_FANCY_MATH_387
14610     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14611         || TARGET_MIX_SSE_I387)
14612     && flag_unsafe_math_optimizations)
14613    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14614        && !flag_trapping_math)"
14615 {
14616   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14617       && !flag_trapping_math)
14618     {
14619       if (TARGET_ROUND)
14620         emit_insn (gen_sse4_1_round<mode>2
14621                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14622       else if (optimize_insn_for_size_p ())
14623         FAIL;
14624       else
14625         ix86_expand_rint (operands[0], operands[1]);
14626     }
14627   else
14628     {
14629       rtx op0 = gen_reg_rtx (XFmode);
14630       rtx op1 = gen_reg_rtx (XFmode);
14631
14632       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14633       emit_insn (gen_rintxf2 (op0, op1));
14634
14635       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14636     }
14637   DONE;
14638 })
14639
14640 (define_expand "round<mode>2"
14641   [(match_operand:X87MODEF 0 "register_operand" "")
14642    (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14643   "(TARGET_USE_FANCY_MATH_387
14644     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14645         || TARGET_MIX_SSE_I387)
14646     && flag_unsafe_math_optimizations)
14647    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14648        && !flag_trapping_math && !flag_rounding_math)"
14649 {
14650   if (optimize_insn_for_size_p ())
14651     FAIL;
14652
14653   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14654       && !flag_trapping_math && !flag_rounding_math)
14655     {
14656       if (TARGET_ROUND)
14657         {
14658           operands[1] = force_reg (<MODE>mode, operands[1]);
14659           ix86_expand_round_sse4 (operands[0], operands[1]);
14660         }
14661       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14662         ix86_expand_round (operands[0], operands[1]);
14663       else
14664         ix86_expand_rounddf_32 (operands[0], operands[1]);
14665     }
14666   else
14667     {
14668       operands[1] = force_reg (<MODE>mode, operands[1]);
14669       ix86_emit_i387_round (operands[0], operands[1]);
14670     }
14671   DONE;
14672 })
14673
14674 (define_insn_and_split "*fistdi2_1"
14675   [(set (match_operand:DI 0 "nonimmediate_operand" "")
14676         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14677                    UNSPEC_FIST))]
14678   "TARGET_USE_FANCY_MATH_387
14679    && can_create_pseudo_p ()"
14680   "#"
14681   "&& 1"
14682   [(const_int 0)]
14683 {
14684   if (memory_operand (operands[0], VOIDmode))
14685     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14686   else
14687     {
14688       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14689       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14690                                          operands[2]));
14691     }
14692   DONE;
14693 }
14694   [(set_attr "type" "fpspc")
14695    (set_attr "mode" "DI")])
14696
14697 (define_insn "fistdi2"
14698   [(set (match_operand:DI 0 "memory_operand" "=m")
14699         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14700                    UNSPEC_FIST))
14701    (clobber (match_scratch:XF 2 "=&1f"))]
14702   "TARGET_USE_FANCY_MATH_387"
14703   "* return output_fix_trunc (insn, operands, false);"
14704   [(set_attr "type" "fpspc")
14705    (set_attr "mode" "DI")])
14706
14707 (define_insn "fistdi2_with_temp"
14708   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14709         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14710                    UNSPEC_FIST))
14711    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14712    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14713   "TARGET_USE_FANCY_MATH_387"
14714   "#"
14715   [(set_attr "type" "fpspc")
14716    (set_attr "mode" "DI")])
14717
14718 (define_split
14719   [(set (match_operand:DI 0 "register_operand" "")
14720         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14721                    UNSPEC_FIST))
14722    (clobber (match_operand:DI 2 "memory_operand" ""))
14723    (clobber (match_scratch 3 ""))]
14724   "reload_completed"
14725   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14726               (clobber (match_dup 3))])
14727    (set (match_dup 0) (match_dup 2))])
14728
14729 (define_split
14730   [(set (match_operand:DI 0 "memory_operand" "")
14731         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14732                    UNSPEC_FIST))
14733    (clobber (match_operand:DI 2 "memory_operand" ""))
14734    (clobber (match_scratch 3 ""))]
14735   "reload_completed"
14736   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14737               (clobber (match_dup 3))])])
14738
14739 (define_insn_and_split "*fist<mode>2_1"
14740   [(set (match_operand:SWI24 0 "register_operand" "")
14741         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14742                       UNSPEC_FIST))]
14743   "TARGET_USE_FANCY_MATH_387
14744    && can_create_pseudo_p ()"
14745   "#"
14746   "&& 1"
14747   [(const_int 0)]
14748 {
14749   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14750   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14751                                         operands[2]));
14752   DONE;
14753 }
14754   [(set_attr "type" "fpspc")
14755    (set_attr "mode" "<MODE>")])
14756
14757 (define_insn "fist<mode>2"
14758   [(set (match_operand:SWI24 0 "memory_operand" "=m")
14759         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14760                       UNSPEC_FIST))]
14761   "TARGET_USE_FANCY_MATH_387"
14762   "* return output_fix_trunc (insn, operands, false);"
14763   [(set_attr "type" "fpspc")
14764    (set_attr "mode" "<MODE>")])
14765
14766 (define_insn "fist<mode>2_with_temp"
14767   [(set (match_operand:SWI24 0 "register_operand" "=r")
14768         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14769                       UNSPEC_FIST))
14770    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14771   "TARGET_USE_FANCY_MATH_387"
14772   "#"
14773   [(set_attr "type" "fpspc")
14774    (set_attr "mode" "<MODE>")])
14775
14776 (define_split
14777   [(set (match_operand:SWI24 0 "register_operand" "")
14778         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14779                       UNSPEC_FIST))
14780    (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14781   "reload_completed"
14782   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14783    (set (match_dup 0) (match_dup 2))])
14784
14785 (define_split
14786   [(set (match_operand:SWI24 0 "memory_operand" "")
14787         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14788                       UNSPEC_FIST))
14789    (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14790   "reload_completed"
14791   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14792
14793 (define_expand "lrintxf<mode>2"
14794   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14795      (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14796                      UNSPEC_FIST))]
14797   "TARGET_USE_FANCY_MATH_387")
14798
14799 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14800   [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14801      (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14802                         UNSPEC_FIX_NOTRUNC))]
14803   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14804    && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14805
14806 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14807   [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14808    (match_operand:X87MODEF 1 "register_operand" "")]
14809   "(TARGET_USE_FANCY_MATH_387
14810     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14811         || TARGET_MIX_SSE_I387)
14812     && flag_unsafe_math_optimizations)
14813    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14814        && <SWI248x:MODE>mode != HImode 
14815        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14816        && !flag_trapping_math && !flag_rounding_math)"
14817 {
14818   if (optimize_insn_for_size_p ())
14819     FAIL;
14820
14821   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14822       && <SWI248x:MODE>mode != HImode
14823       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14824       && !flag_trapping_math && !flag_rounding_math)
14825     ix86_expand_lround (operands[0], operands[1]);
14826   else
14827     ix86_emit_i387_round (operands[0], operands[1]);
14828   DONE;
14829 })
14830
14831 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14832 (define_insn_and_split "frndintxf2_floor"
14833   [(set (match_operand:XF 0 "register_operand" "")
14834         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14835          UNSPEC_FRNDINT_FLOOR))
14836    (clobber (reg:CC FLAGS_REG))]
14837   "TARGET_USE_FANCY_MATH_387
14838    && flag_unsafe_math_optimizations
14839    && can_create_pseudo_p ()"
14840   "#"
14841   "&& 1"
14842   [(const_int 0)]
14843 {
14844   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14845
14846   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14847   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14848
14849   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14850                                         operands[2], operands[3]));
14851   DONE;
14852 }
14853   [(set_attr "type" "frndint")
14854    (set_attr "i387_cw" "floor")
14855    (set_attr "mode" "XF")])
14856
14857 (define_insn "frndintxf2_floor_i387"
14858   [(set (match_operand:XF 0 "register_operand" "=f")
14859         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14860          UNSPEC_FRNDINT_FLOOR))
14861    (use (match_operand:HI 2 "memory_operand" "m"))
14862    (use (match_operand:HI 3 "memory_operand" "m"))]
14863   "TARGET_USE_FANCY_MATH_387
14864    && flag_unsafe_math_optimizations"
14865   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14866   [(set_attr "type" "frndint")
14867    (set_attr "i387_cw" "floor")
14868    (set_attr "mode" "XF")])
14869
14870 (define_expand "floorxf2"
14871   [(use (match_operand:XF 0 "register_operand" ""))
14872    (use (match_operand:XF 1 "register_operand" ""))]
14873   "TARGET_USE_FANCY_MATH_387
14874    && flag_unsafe_math_optimizations"
14875 {
14876   if (optimize_insn_for_size_p ())
14877     FAIL;
14878   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14879   DONE;
14880 })
14881
14882 (define_expand "floor<mode>2"
14883   [(use (match_operand:MODEF 0 "register_operand" ""))
14884    (use (match_operand:MODEF 1 "register_operand" ""))]
14885   "(TARGET_USE_FANCY_MATH_387
14886     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14887         || TARGET_MIX_SSE_I387)
14888     && flag_unsafe_math_optimizations)
14889    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14890        && !flag_trapping_math)"
14891 {
14892   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14893       && !flag_trapping_math)
14894     {
14895       if (TARGET_ROUND)
14896         emit_insn (gen_sse4_1_round<mode>2
14897                    (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14898       else if (optimize_insn_for_size_p ())
14899         FAIL;
14900       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14901         ix86_expand_floorceil (operands[0], operands[1], true);
14902       else
14903         ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14904     }
14905   else
14906     {
14907       rtx op0, op1;
14908
14909       if (optimize_insn_for_size_p ())
14910         FAIL;
14911
14912       op0 = gen_reg_rtx (XFmode);
14913       op1 = gen_reg_rtx (XFmode);
14914       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14915       emit_insn (gen_frndintxf2_floor (op0, op1));
14916
14917       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14918     }
14919   DONE;
14920 })
14921
14922 (define_insn_and_split "*fist<mode>2_floor_1"
14923   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14924         (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14925                         UNSPEC_FIST_FLOOR))
14926    (clobber (reg:CC FLAGS_REG))]
14927   "TARGET_USE_FANCY_MATH_387
14928    && flag_unsafe_math_optimizations
14929    && can_create_pseudo_p ()"
14930   "#"
14931   "&& 1"
14932   [(const_int 0)]
14933 {
14934   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14935
14936   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14937   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14938   if (memory_operand (operands[0], VOIDmode))
14939     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14940                                       operands[2], operands[3]));
14941   else
14942     {
14943       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14944       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14945                                                   operands[2], operands[3],
14946                                                   operands[4]));
14947     }
14948   DONE;
14949 }
14950   [(set_attr "type" "fistp")
14951    (set_attr "i387_cw" "floor")
14952    (set_attr "mode" "<MODE>")])
14953
14954 (define_insn "fistdi2_floor"
14955   [(set (match_operand:DI 0 "memory_operand" "=m")
14956         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14957                    UNSPEC_FIST_FLOOR))
14958    (use (match_operand:HI 2 "memory_operand" "m"))
14959    (use (match_operand:HI 3 "memory_operand" "m"))
14960    (clobber (match_scratch:XF 4 "=&1f"))]
14961   "TARGET_USE_FANCY_MATH_387
14962    && flag_unsafe_math_optimizations"
14963   "* return output_fix_trunc (insn, operands, false);"
14964   [(set_attr "type" "fistp")
14965    (set_attr "i387_cw" "floor")
14966    (set_attr "mode" "DI")])
14967
14968 (define_insn "fistdi2_floor_with_temp"
14969   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14970         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14971                    UNSPEC_FIST_FLOOR))
14972    (use (match_operand:HI 2 "memory_operand" "m,m"))
14973    (use (match_operand:HI 3 "memory_operand" "m,m"))
14974    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14975    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14976   "TARGET_USE_FANCY_MATH_387
14977    && flag_unsafe_math_optimizations"
14978   "#"
14979   [(set_attr "type" "fistp")
14980    (set_attr "i387_cw" "floor")
14981    (set_attr "mode" "DI")])
14982
14983 (define_split
14984   [(set (match_operand:DI 0 "register_operand" "")
14985         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14986                    UNSPEC_FIST_FLOOR))
14987    (use (match_operand:HI 2 "memory_operand" ""))
14988    (use (match_operand:HI 3 "memory_operand" ""))
14989    (clobber (match_operand:DI 4 "memory_operand" ""))
14990    (clobber (match_scratch 5 ""))]
14991   "reload_completed"
14992   [(parallel [(set (match_dup 4)
14993                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14994               (use (match_dup 2))
14995               (use (match_dup 3))
14996               (clobber (match_dup 5))])
14997    (set (match_dup 0) (match_dup 4))])
14998
14999 (define_split
15000   [(set (match_operand:DI 0 "memory_operand" "")
15001         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15002                    UNSPEC_FIST_FLOOR))
15003    (use (match_operand:HI 2 "memory_operand" ""))
15004    (use (match_operand:HI 3 "memory_operand" ""))
15005    (clobber (match_operand:DI 4 "memory_operand" ""))
15006    (clobber (match_scratch 5 ""))]
15007   "reload_completed"
15008   [(parallel [(set (match_dup 0)
15009                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15010               (use (match_dup 2))
15011               (use (match_dup 3))
15012               (clobber (match_dup 5))])])
15013
15014 (define_insn "fist<mode>2_floor"
15015   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15016         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15017                       UNSPEC_FIST_FLOOR))
15018    (use (match_operand:HI 2 "memory_operand" "m"))
15019    (use (match_operand:HI 3 "memory_operand" "m"))]
15020   "TARGET_USE_FANCY_MATH_387
15021    && flag_unsafe_math_optimizations"
15022   "* return output_fix_trunc (insn, operands, false);"
15023   [(set_attr "type" "fistp")
15024    (set_attr "i387_cw" "floor")
15025    (set_attr "mode" "<MODE>")])
15026
15027 (define_insn "fist<mode>2_floor_with_temp"
15028   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15029         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15030                       UNSPEC_FIST_FLOOR))
15031    (use (match_operand:HI 2 "memory_operand" "m,m"))
15032    (use (match_operand:HI 3 "memory_operand" "m,m"))
15033    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15034   "TARGET_USE_FANCY_MATH_387
15035    && flag_unsafe_math_optimizations"
15036   "#"
15037   [(set_attr "type" "fistp")
15038    (set_attr "i387_cw" "floor")
15039    (set_attr "mode" "<MODE>")])
15040
15041 (define_split
15042   [(set (match_operand:SWI24 0 "register_operand" "")
15043         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15044                       UNSPEC_FIST_FLOOR))
15045    (use (match_operand:HI 2 "memory_operand" ""))
15046    (use (match_operand:HI 3 "memory_operand" ""))
15047    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15048   "reload_completed"
15049   [(parallel [(set (match_dup 4)
15050                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15051               (use (match_dup 2))
15052               (use (match_dup 3))])
15053    (set (match_dup 0) (match_dup 4))])
15054
15055 (define_split
15056   [(set (match_operand:SWI24 0 "memory_operand" "")
15057         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15058                       UNSPEC_FIST_FLOOR))
15059    (use (match_operand:HI 2 "memory_operand" ""))
15060    (use (match_operand:HI 3 "memory_operand" ""))
15061    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15062   "reload_completed"
15063   [(parallel [(set (match_dup 0)
15064                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15065               (use (match_dup 2))
15066               (use (match_dup 3))])])
15067
15068 (define_expand "lfloorxf<mode>2"
15069   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15070                    (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15071                                    UNSPEC_FIST_FLOOR))
15072               (clobber (reg:CC FLAGS_REG))])]
15073   "TARGET_USE_FANCY_MATH_387
15074    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15075    && flag_unsafe_math_optimizations")
15076
15077 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15078   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15079    (match_operand:MODEF 1 "register_operand" "")]
15080   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15081    && !flag_trapping_math"
15082 {
15083   if (TARGET_64BIT && optimize_insn_for_size_p ())
15084     FAIL;
15085   ix86_expand_lfloorceil (operands[0], operands[1], true);
15086   DONE;
15087 })
15088
15089 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15090 (define_insn_and_split "frndintxf2_ceil"
15091   [(set (match_operand:XF 0 "register_operand" "")
15092         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15093          UNSPEC_FRNDINT_CEIL))
15094    (clobber (reg:CC FLAGS_REG))]
15095   "TARGET_USE_FANCY_MATH_387
15096    && flag_unsafe_math_optimizations
15097    && can_create_pseudo_p ()"
15098   "#"
15099   "&& 1"
15100   [(const_int 0)]
15101 {
15102   ix86_optimize_mode_switching[I387_CEIL] = 1;
15103
15104   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15105   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15106
15107   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15108                                        operands[2], operands[3]));
15109   DONE;
15110 }
15111   [(set_attr "type" "frndint")
15112    (set_attr "i387_cw" "ceil")
15113    (set_attr "mode" "XF")])
15114
15115 (define_insn "frndintxf2_ceil_i387"
15116   [(set (match_operand:XF 0 "register_operand" "=f")
15117         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15118          UNSPEC_FRNDINT_CEIL))
15119    (use (match_operand:HI 2 "memory_operand" "m"))
15120    (use (match_operand:HI 3 "memory_operand" "m"))]
15121   "TARGET_USE_FANCY_MATH_387
15122    && flag_unsafe_math_optimizations"
15123   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15124   [(set_attr "type" "frndint")
15125    (set_attr "i387_cw" "ceil")
15126    (set_attr "mode" "XF")])
15127
15128 (define_expand "ceilxf2"
15129   [(use (match_operand:XF 0 "register_operand" ""))
15130    (use (match_operand:XF 1 "register_operand" ""))]
15131   "TARGET_USE_FANCY_MATH_387
15132    && flag_unsafe_math_optimizations"
15133 {
15134   if (optimize_insn_for_size_p ())
15135     FAIL;
15136   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15137   DONE;
15138 })
15139
15140 (define_expand "ceil<mode>2"
15141   [(use (match_operand:MODEF 0 "register_operand" ""))
15142    (use (match_operand:MODEF 1 "register_operand" ""))]
15143   "(TARGET_USE_FANCY_MATH_387
15144     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15145         || TARGET_MIX_SSE_I387)
15146     && flag_unsafe_math_optimizations)
15147    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15148        && !flag_trapping_math)"
15149 {
15150   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15151       && !flag_trapping_math)
15152     {
15153       if (TARGET_ROUND)
15154         emit_insn (gen_sse4_1_round<mode>2
15155                    (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15156       else if (optimize_insn_for_size_p ())
15157         FAIL;
15158       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15159         ix86_expand_floorceil (operands[0], operands[1], false);
15160       else
15161         ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15162     }
15163   else
15164     {
15165       rtx op0, op1;
15166
15167       if (optimize_insn_for_size_p ())
15168         FAIL;
15169
15170       op0 = gen_reg_rtx (XFmode);
15171       op1 = gen_reg_rtx (XFmode);
15172       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15173       emit_insn (gen_frndintxf2_ceil (op0, op1));
15174
15175       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15176     }
15177   DONE;
15178 })
15179
15180 (define_insn_and_split "*fist<mode>2_ceil_1"
15181   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15182         (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15183                         UNSPEC_FIST_CEIL))
15184    (clobber (reg:CC FLAGS_REG))]
15185   "TARGET_USE_FANCY_MATH_387
15186    && flag_unsafe_math_optimizations
15187    && can_create_pseudo_p ()"
15188   "#"
15189   "&& 1"
15190   [(const_int 0)]
15191 {
15192   ix86_optimize_mode_switching[I387_CEIL] = 1;
15193
15194   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15195   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15196   if (memory_operand (operands[0], VOIDmode))
15197     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15198                                      operands[2], operands[3]));
15199   else
15200     {
15201       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15202       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15203                                                  operands[2], operands[3],
15204                                                  operands[4]));
15205     }
15206   DONE;
15207 }
15208   [(set_attr "type" "fistp")
15209    (set_attr "i387_cw" "ceil")
15210    (set_attr "mode" "<MODE>")])
15211
15212 (define_insn "fistdi2_ceil"
15213   [(set (match_operand:DI 0 "memory_operand" "=m")
15214         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15215                    UNSPEC_FIST_CEIL))
15216    (use (match_operand:HI 2 "memory_operand" "m"))
15217    (use (match_operand:HI 3 "memory_operand" "m"))
15218    (clobber (match_scratch:XF 4 "=&1f"))]
15219   "TARGET_USE_FANCY_MATH_387
15220    && flag_unsafe_math_optimizations"
15221   "* return output_fix_trunc (insn, operands, false);"
15222   [(set_attr "type" "fistp")
15223    (set_attr "i387_cw" "ceil")
15224    (set_attr "mode" "DI")])
15225
15226 (define_insn "fistdi2_ceil_with_temp"
15227   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15228         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15229                    UNSPEC_FIST_CEIL))
15230    (use (match_operand:HI 2 "memory_operand" "m,m"))
15231    (use (match_operand:HI 3 "memory_operand" "m,m"))
15232    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15233    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15234   "TARGET_USE_FANCY_MATH_387
15235    && flag_unsafe_math_optimizations"
15236   "#"
15237   [(set_attr "type" "fistp")
15238    (set_attr "i387_cw" "ceil")
15239    (set_attr "mode" "DI")])
15240
15241 (define_split
15242   [(set (match_operand:DI 0 "register_operand" "")
15243         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15244                    UNSPEC_FIST_CEIL))
15245    (use (match_operand:HI 2 "memory_operand" ""))
15246    (use (match_operand:HI 3 "memory_operand" ""))
15247    (clobber (match_operand:DI 4 "memory_operand" ""))
15248    (clobber (match_scratch 5 ""))]
15249   "reload_completed"
15250   [(parallel [(set (match_dup 4)
15251                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15252               (use (match_dup 2))
15253               (use (match_dup 3))
15254               (clobber (match_dup 5))])
15255    (set (match_dup 0) (match_dup 4))])
15256
15257 (define_split
15258   [(set (match_operand:DI 0 "memory_operand" "")
15259         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15260                    UNSPEC_FIST_CEIL))
15261    (use (match_operand:HI 2 "memory_operand" ""))
15262    (use (match_operand:HI 3 "memory_operand" ""))
15263    (clobber (match_operand:DI 4 "memory_operand" ""))
15264    (clobber (match_scratch 5 ""))]
15265   "reload_completed"
15266   [(parallel [(set (match_dup 0)
15267                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15268               (use (match_dup 2))
15269               (use (match_dup 3))
15270               (clobber (match_dup 5))])])
15271
15272 (define_insn "fist<mode>2_ceil"
15273   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15274         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15275                       UNSPEC_FIST_CEIL))
15276    (use (match_operand:HI 2 "memory_operand" "m"))
15277    (use (match_operand:HI 3 "memory_operand" "m"))]
15278   "TARGET_USE_FANCY_MATH_387
15279    && flag_unsafe_math_optimizations"
15280   "* return output_fix_trunc (insn, operands, false);"
15281   [(set_attr "type" "fistp")
15282    (set_attr "i387_cw" "ceil")
15283    (set_attr "mode" "<MODE>")])
15284
15285 (define_insn "fist<mode>2_ceil_with_temp"
15286   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15287         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15288                       UNSPEC_FIST_CEIL))
15289    (use (match_operand:HI 2 "memory_operand" "m,m"))
15290    (use (match_operand:HI 3 "memory_operand" "m,m"))
15291    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15292   "TARGET_USE_FANCY_MATH_387
15293    && flag_unsafe_math_optimizations"
15294   "#"
15295   [(set_attr "type" "fistp")
15296    (set_attr "i387_cw" "ceil")
15297    (set_attr "mode" "<MODE>")])
15298
15299 (define_split
15300   [(set (match_operand:SWI24 0 "register_operand" "")
15301         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15302                       UNSPEC_FIST_CEIL))
15303    (use (match_operand:HI 2 "memory_operand" ""))
15304    (use (match_operand:HI 3 "memory_operand" ""))
15305    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15306   "reload_completed"
15307   [(parallel [(set (match_dup 4)
15308                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15309               (use (match_dup 2))
15310               (use (match_dup 3))])
15311    (set (match_dup 0) (match_dup 4))])
15312
15313 (define_split
15314   [(set (match_operand:SWI24 0 "memory_operand" "")
15315         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15316                       UNSPEC_FIST_CEIL))
15317    (use (match_operand:HI 2 "memory_operand" ""))
15318    (use (match_operand:HI 3 "memory_operand" ""))
15319    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15320   "reload_completed"
15321   [(parallel [(set (match_dup 0)
15322                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15323               (use (match_dup 2))
15324               (use (match_dup 3))])])
15325
15326 (define_expand "lceilxf<mode>2"
15327   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15328                    (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15329                                    UNSPEC_FIST_CEIL))
15330               (clobber (reg:CC FLAGS_REG))])]
15331   "TARGET_USE_FANCY_MATH_387
15332    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15333    && flag_unsafe_math_optimizations")
15334
15335 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15336   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15337    (match_operand:MODEF 1 "register_operand" "")]
15338   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15339    && !flag_trapping_math"
15340 {
15341   ix86_expand_lfloorceil (operands[0], operands[1], false);
15342   DONE;
15343 })
15344
15345 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15346 (define_insn_and_split "frndintxf2_trunc"
15347   [(set (match_operand:XF 0 "register_operand" "")
15348         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15349          UNSPEC_FRNDINT_TRUNC))
15350    (clobber (reg:CC FLAGS_REG))]
15351   "TARGET_USE_FANCY_MATH_387
15352    && flag_unsafe_math_optimizations
15353    && can_create_pseudo_p ()"
15354   "#"
15355   "&& 1"
15356   [(const_int 0)]
15357 {
15358   ix86_optimize_mode_switching[I387_TRUNC] = 1;
15359
15360   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15361   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15362
15363   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15364                                         operands[2], operands[3]));
15365   DONE;
15366 }
15367   [(set_attr "type" "frndint")
15368    (set_attr "i387_cw" "trunc")
15369    (set_attr "mode" "XF")])
15370
15371 (define_insn "frndintxf2_trunc_i387"
15372   [(set (match_operand:XF 0 "register_operand" "=f")
15373         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15374          UNSPEC_FRNDINT_TRUNC))
15375    (use (match_operand:HI 2 "memory_operand" "m"))
15376    (use (match_operand:HI 3 "memory_operand" "m"))]
15377   "TARGET_USE_FANCY_MATH_387
15378    && flag_unsafe_math_optimizations"
15379   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15380   [(set_attr "type" "frndint")
15381    (set_attr "i387_cw" "trunc")
15382    (set_attr "mode" "XF")])
15383
15384 (define_expand "btruncxf2"
15385   [(use (match_operand:XF 0 "register_operand" ""))
15386    (use (match_operand:XF 1 "register_operand" ""))]
15387   "TARGET_USE_FANCY_MATH_387
15388    && flag_unsafe_math_optimizations"
15389 {
15390   if (optimize_insn_for_size_p ())
15391     FAIL;
15392   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15393   DONE;
15394 })
15395
15396 (define_expand "btrunc<mode>2"
15397   [(use (match_operand:MODEF 0 "register_operand" ""))
15398    (use (match_operand:MODEF 1 "register_operand" ""))]
15399   "(TARGET_USE_FANCY_MATH_387
15400     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15401         || TARGET_MIX_SSE_I387)
15402     && flag_unsafe_math_optimizations)
15403    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15404        && !flag_trapping_math)"
15405 {
15406   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15407       && !flag_trapping_math)
15408     {
15409       if (TARGET_ROUND)
15410         emit_insn (gen_sse4_1_round<mode>2
15411                    (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15412       else if (optimize_insn_for_size_p ())
15413         FAIL;
15414       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15415         ix86_expand_trunc (operands[0], operands[1]);
15416       else
15417         ix86_expand_truncdf_32 (operands[0], operands[1]);
15418     }
15419   else
15420     {
15421       rtx op0, op1;
15422
15423       if (optimize_insn_for_size_p ())
15424         FAIL;
15425
15426       op0 = gen_reg_rtx (XFmode);
15427       op1 = gen_reg_rtx (XFmode);
15428       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15429       emit_insn (gen_frndintxf2_trunc (op0, op1));
15430
15431       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15432     }
15433   DONE;
15434 })
15435
15436 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15437 (define_insn_and_split "frndintxf2_mask_pm"
15438   [(set (match_operand:XF 0 "register_operand" "")
15439         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15440          UNSPEC_FRNDINT_MASK_PM))
15441    (clobber (reg:CC FLAGS_REG))]
15442   "TARGET_USE_FANCY_MATH_387
15443    && flag_unsafe_math_optimizations
15444    && can_create_pseudo_p ()"
15445   "#"
15446   "&& 1"
15447   [(const_int 0)]
15448 {
15449   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15450
15451   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15452   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15453
15454   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15455                                           operands[2], operands[3]));
15456   DONE;
15457 }
15458   [(set_attr "type" "frndint")
15459    (set_attr "i387_cw" "mask_pm")
15460    (set_attr "mode" "XF")])
15461
15462 (define_insn "frndintxf2_mask_pm_i387"
15463   [(set (match_operand:XF 0 "register_operand" "=f")
15464         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15465          UNSPEC_FRNDINT_MASK_PM))
15466    (use (match_operand:HI 2 "memory_operand" "m"))
15467    (use (match_operand:HI 3 "memory_operand" "m"))]
15468   "TARGET_USE_FANCY_MATH_387
15469    && flag_unsafe_math_optimizations"
15470   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15471   [(set_attr "type" "frndint")
15472    (set_attr "i387_cw" "mask_pm")
15473    (set_attr "mode" "XF")])
15474
15475 (define_expand "nearbyintxf2"
15476   [(use (match_operand:XF 0 "register_operand" ""))
15477    (use (match_operand:XF 1 "register_operand" ""))]
15478   "TARGET_USE_FANCY_MATH_387
15479    && flag_unsafe_math_optimizations"
15480 {
15481   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15482   DONE;
15483 })
15484
15485 (define_expand "nearbyint<mode>2"
15486   [(use (match_operand:MODEF 0 "register_operand" ""))
15487    (use (match_operand:MODEF 1 "register_operand" ""))]
15488   "TARGET_USE_FANCY_MATH_387
15489    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15490        || TARGET_MIX_SSE_I387)
15491    && flag_unsafe_math_optimizations"
15492 {
15493   rtx op0 = gen_reg_rtx (XFmode);
15494   rtx op1 = gen_reg_rtx (XFmode);
15495
15496   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15497   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15498
15499   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15500   DONE;
15501 })
15502
15503 (define_insn "fxam<mode>2_i387"
15504   [(set (match_operand:HI 0 "register_operand" "=a")
15505         (unspec:HI
15506           [(match_operand:X87MODEF 1 "register_operand" "f")]
15507           UNSPEC_FXAM))]
15508   "TARGET_USE_FANCY_MATH_387"
15509   "fxam\n\tfnstsw\t%0"
15510   [(set_attr "type" "multi")
15511    (set_attr "length" "4")
15512    (set_attr "unit" "i387")
15513    (set_attr "mode" "<MODE>")])
15514
15515 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15516   [(set (match_operand:HI 0 "register_operand" "")
15517         (unspec:HI
15518           [(match_operand:MODEF 1 "memory_operand" "")]
15519           UNSPEC_FXAM_MEM))]
15520   "TARGET_USE_FANCY_MATH_387
15521    && can_create_pseudo_p ()"
15522   "#"
15523   "&& 1"
15524   [(set (match_dup 2)(match_dup 1))
15525    (set (match_dup 0)
15526         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15527 {
15528   operands[2] = gen_reg_rtx (<MODE>mode);
15529
15530   MEM_VOLATILE_P (operands[1]) = 1;
15531 }
15532   [(set_attr "type" "multi")
15533    (set_attr "unit" "i387")
15534    (set_attr "mode" "<MODE>")])
15535
15536 (define_expand "isinfxf2"
15537   [(use (match_operand:SI 0 "register_operand" ""))
15538    (use (match_operand:XF 1 "register_operand" ""))]
15539   "TARGET_USE_FANCY_MATH_387
15540    && TARGET_C99_FUNCTIONS"
15541 {
15542   rtx mask = GEN_INT (0x45);
15543   rtx val = GEN_INT (0x05);
15544
15545   rtx cond;
15546
15547   rtx scratch = gen_reg_rtx (HImode);
15548   rtx res = gen_reg_rtx (QImode);
15549
15550   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15551
15552   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15553   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15554   cond = gen_rtx_fmt_ee (EQ, QImode,
15555                          gen_rtx_REG (CCmode, FLAGS_REG),
15556                          const0_rtx);
15557   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15558   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15559   DONE;
15560 })
15561
15562 (define_expand "isinf<mode>2"
15563   [(use (match_operand:SI 0 "register_operand" ""))
15564    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15565   "TARGET_USE_FANCY_MATH_387
15566    && TARGET_C99_FUNCTIONS
15567    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15568 {
15569   rtx mask = GEN_INT (0x45);
15570   rtx val = GEN_INT (0x05);
15571
15572   rtx cond;
15573
15574   rtx scratch = gen_reg_rtx (HImode);
15575   rtx res = gen_reg_rtx (QImode);
15576
15577   /* Remove excess precision by forcing value through memory. */
15578   if (memory_operand (operands[1], VOIDmode))
15579     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15580   else
15581     {
15582       enum ix86_stack_slot slot = (virtuals_instantiated
15583                                    ? SLOT_TEMP
15584                                    : SLOT_VIRTUAL);
15585       rtx temp = assign_386_stack_local (<MODE>mode, slot);
15586
15587       emit_move_insn (temp, operands[1]);
15588       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15589     }
15590
15591   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15592   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15593   cond = gen_rtx_fmt_ee (EQ, QImode,
15594                          gen_rtx_REG (CCmode, FLAGS_REG),
15595                          const0_rtx);
15596   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15597   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15598   DONE;
15599 })
15600
15601 (define_expand "signbitxf2"
15602   [(use (match_operand:SI 0 "register_operand" ""))
15603    (use (match_operand:XF 1 "register_operand" ""))]
15604   "TARGET_USE_FANCY_MATH_387"
15605 {
15606   rtx scratch = gen_reg_rtx (HImode);
15607
15608   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15609   emit_insn (gen_andsi3 (operands[0],
15610              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15611   DONE;
15612 })
15613
15614 (define_insn "movmsk_df"
15615   [(set (match_operand:SI 0 "register_operand" "=r")
15616         (unspec:SI
15617           [(match_operand:DF 1 "register_operand" "x")]
15618           UNSPEC_MOVMSK))]
15619   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15620   "%vmovmskpd\t{%1, %0|%0, %1}"
15621   [(set_attr "type" "ssemov")
15622    (set_attr "prefix" "maybe_vex")
15623    (set_attr "mode" "DF")])
15624
15625 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15626 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15627 (define_expand "signbitdf2"
15628   [(use (match_operand:SI 0 "register_operand" ""))
15629    (use (match_operand:DF 1 "register_operand" ""))]
15630   "TARGET_USE_FANCY_MATH_387
15631    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15632 {
15633   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15634     {
15635       emit_insn (gen_movmsk_df (operands[0], operands[1]));
15636       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15637     }
15638   else
15639     {
15640       rtx scratch = gen_reg_rtx (HImode);
15641
15642       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15643       emit_insn (gen_andsi3 (operands[0],
15644                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15645     }
15646   DONE;
15647 })
15648
15649 (define_expand "signbitsf2"
15650   [(use (match_operand:SI 0 "register_operand" ""))
15651    (use (match_operand:SF 1 "register_operand" ""))]
15652   "TARGET_USE_FANCY_MATH_387
15653    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15654 {
15655   rtx scratch = gen_reg_rtx (HImode);
15656
15657   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15658   emit_insn (gen_andsi3 (operands[0],
15659              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15660   DONE;
15661 })
15662 \f
15663 ;; Block operation instructions
15664
15665 (define_insn "cld"
15666   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15667   ""
15668   "cld"
15669   [(set_attr "length" "1")
15670    (set_attr "length_immediate" "0")
15671    (set_attr "modrm" "0")])
15672
15673 (define_expand "movmem<mode>"
15674   [(use (match_operand:BLK 0 "memory_operand" ""))
15675    (use (match_operand:BLK 1 "memory_operand" ""))
15676    (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15677    (use (match_operand:SWI48 3 "const_int_operand" ""))
15678    (use (match_operand:SI 4 "const_int_operand" ""))
15679    (use (match_operand:SI 5 "const_int_operand" ""))]
15680   ""
15681 {
15682  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15683                          operands[4], operands[5]))
15684    DONE;
15685  else
15686    FAIL;
15687 })
15688
15689 ;; Most CPUs don't like single string operations
15690 ;; Handle this case here to simplify previous expander.
15691
15692 (define_expand "strmov"
15693   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15694    (set (match_operand 1 "memory_operand" "") (match_dup 4))
15695    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15696               (clobber (reg:CC FLAGS_REG))])
15697    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15698               (clobber (reg:CC FLAGS_REG))])]
15699   ""
15700 {
15701   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15702
15703   /* If .md ever supports :P for Pmode, these can be directly
15704      in the pattern above.  */
15705   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15706   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15707
15708   /* Can't use this if the user has appropriated esi or edi.  */
15709   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15710       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15711     {
15712       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15713                                       operands[2], operands[3],
15714                                       operands[5], operands[6]));
15715       DONE;
15716     }
15717
15718   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15719 })
15720
15721 (define_expand "strmov_singleop"
15722   [(parallel [(set (match_operand 1 "memory_operand" "")
15723                    (match_operand 3 "memory_operand" ""))
15724               (set (match_operand 0 "register_operand" "")
15725                    (match_operand 4 "" ""))
15726               (set (match_operand 2 "register_operand" "")
15727                    (match_operand 5 "" ""))])]
15728   ""
15729   "ix86_current_function_needs_cld = 1;")
15730
15731 (define_insn "*strmovdi_rex_1"
15732   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15733         (mem:DI (match_operand:DI 3 "register_operand" "1")))
15734    (set (match_operand:DI 0 "register_operand" "=D")
15735         (plus:DI (match_dup 2)
15736                  (const_int 8)))
15737    (set (match_operand:DI 1 "register_operand" "=S")
15738         (plus:DI (match_dup 3)
15739                  (const_int 8)))]
15740   "TARGET_64BIT
15741    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15742   "movsq"
15743   [(set_attr "type" "str")
15744    (set_attr "memory" "both")
15745    (set_attr "mode" "DI")])
15746
15747 (define_insn "*strmovsi_1"
15748   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15749         (mem:SI (match_operand:P 3 "register_operand" "1")))
15750    (set (match_operand:P 0 "register_operand" "=D")
15751         (plus:P (match_dup 2)
15752                 (const_int 4)))
15753    (set (match_operand:P 1 "register_operand" "=S")
15754         (plus:P (match_dup 3)
15755                 (const_int 4)))]
15756   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15757   "movs{l|d}"
15758   [(set_attr "type" "str")
15759    (set_attr "memory" "both")
15760    (set_attr "mode" "SI")])
15761
15762 (define_insn "*strmovhi_1"
15763   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15764         (mem:HI (match_operand:P 3 "register_operand" "1")))
15765    (set (match_operand:P 0 "register_operand" "=D")
15766         (plus:P (match_dup 2)
15767                 (const_int 2)))
15768    (set (match_operand:P 1 "register_operand" "=S")
15769         (plus:P (match_dup 3)
15770                 (const_int 2)))]
15771   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15772   "movsw"
15773   [(set_attr "type" "str")
15774    (set_attr "memory" "both")
15775    (set_attr "mode" "HI")])
15776
15777 (define_insn "*strmovqi_1"
15778   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15779         (mem:QI (match_operand:P 3 "register_operand" "1")))
15780    (set (match_operand:P 0 "register_operand" "=D")
15781         (plus:P (match_dup 2)
15782                 (const_int 1)))
15783    (set (match_operand:P 1 "register_operand" "=S")
15784         (plus:P (match_dup 3)
15785                 (const_int 1)))]
15786   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15787   "movsb"
15788   [(set_attr "type" "str")
15789    (set_attr "memory" "both")
15790    (set (attr "prefix_rex")
15791         (if_then_else
15792           (match_test "<P:MODE>mode == DImode")
15793           (const_string "0")
15794           (const_string "*")))
15795    (set_attr "mode" "QI")])
15796
15797 (define_expand "rep_mov"
15798   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15799               (set (match_operand 0 "register_operand" "")
15800                    (match_operand 5 "" ""))
15801               (set (match_operand 2 "register_operand" "")
15802                    (match_operand 6 "" ""))
15803               (set (match_operand 1 "memory_operand" "")
15804                    (match_operand 3 "memory_operand" ""))
15805               (use (match_dup 4))])]
15806   ""
15807   "ix86_current_function_needs_cld = 1;")
15808
15809 (define_insn "*rep_movdi_rex64"
15810   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15811    (set (match_operand:DI 0 "register_operand" "=D")
15812         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15813                             (const_int 3))
15814                  (match_operand:DI 3 "register_operand" "0")))
15815    (set (match_operand:DI 1 "register_operand" "=S")
15816         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15817                  (match_operand:DI 4 "register_operand" "1")))
15818    (set (mem:BLK (match_dup 3))
15819         (mem:BLK (match_dup 4)))
15820    (use (match_dup 5))]
15821   "TARGET_64BIT
15822    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15823   "rep{%;} movsq"
15824   [(set_attr "type" "str")
15825    (set_attr "prefix_rep" "1")
15826    (set_attr "memory" "both")
15827    (set_attr "mode" "DI")])
15828
15829 (define_insn "*rep_movsi"
15830   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15831    (set (match_operand:P 0 "register_operand" "=D")
15832         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15833                           (const_int 2))
15834                  (match_operand:P 3 "register_operand" "0")))
15835    (set (match_operand:P 1 "register_operand" "=S")
15836         (plus:P (ashift:P (match_dup 5) (const_int 2))
15837                 (match_operand:P 4 "register_operand" "1")))
15838    (set (mem:BLK (match_dup 3))
15839         (mem:BLK (match_dup 4)))
15840    (use (match_dup 5))]
15841   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15842   "rep{%;} movs{l|d}"
15843   [(set_attr "type" "str")
15844    (set_attr "prefix_rep" "1")
15845    (set_attr "memory" "both")
15846    (set_attr "mode" "SI")])
15847
15848 (define_insn "*rep_movqi"
15849   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15850    (set (match_operand:P 0 "register_operand" "=D")
15851         (plus:P (match_operand:P 3 "register_operand" "0")
15852                 (match_operand:P 5 "register_operand" "2")))
15853    (set (match_operand:P 1 "register_operand" "=S")
15854         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15855    (set (mem:BLK (match_dup 3))
15856         (mem:BLK (match_dup 4)))
15857    (use (match_dup 5))]
15858   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15859   "rep{%;} movsb"
15860   [(set_attr "type" "str")
15861    (set_attr "prefix_rep" "1")
15862    (set_attr "memory" "both")
15863    (set_attr "mode" "QI")])
15864
15865 (define_expand "setmem<mode>"
15866    [(use (match_operand:BLK 0 "memory_operand" ""))
15867     (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15868     (use (match_operand:QI 2 "nonmemory_operand" ""))
15869     (use (match_operand 3 "const_int_operand" ""))
15870     (use (match_operand:SI 4 "const_int_operand" ""))
15871     (use (match_operand:SI 5 "const_int_operand" ""))]
15872   ""
15873 {
15874  if (ix86_expand_setmem (operands[0], operands[1],
15875                          operands[2], operands[3],
15876                          operands[4], operands[5]))
15877    DONE;
15878  else
15879    FAIL;
15880 })
15881
15882 ;; Most CPUs don't like single string operations
15883 ;; Handle this case here to simplify previous expander.
15884
15885 (define_expand "strset"
15886   [(set (match_operand 1 "memory_operand" "")
15887         (match_operand 2 "register_operand" ""))
15888    (parallel [(set (match_operand 0 "register_operand" "")
15889                    (match_dup 3))
15890               (clobber (reg:CC FLAGS_REG))])]
15891   ""
15892 {
15893   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15894     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15895
15896   /* If .md ever supports :P for Pmode, this can be directly
15897      in the pattern above.  */
15898   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15899                               GEN_INT (GET_MODE_SIZE (GET_MODE
15900                                                       (operands[2]))));
15901   /* Can't use this if the user has appropriated eax or edi.  */
15902   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15903       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15904     {
15905       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15906                                       operands[3]));
15907       DONE;
15908     }
15909 })
15910
15911 (define_expand "strset_singleop"
15912   [(parallel [(set (match_operand 1 "memory_operand" "")
15913                    (match_operand 2 "register_operand" ""))
15914               (set (match_operand 0 "register_operand" "")
15915                    (match_operand 3 "" ""))])]
15916   ""
15917   "ix86_current_function_needs_cld = 1;")
15918
15919 (define_insn "*strsetdi_rex_1"
15920   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15921         (match_operand:DI 2 "register_operand" "a"))
15922    (set (match_operand:DI 0 "register_operand" "=D")
15923         (plus:DI (match_dup 1)
15924                  (const_int 8)))]
15925   "TARGET_64BIT
15926    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15927   "stosq"
15928   [(set_attr "type" "str")
15929    (set_attr "memory" "store")
15930    (set_attr "mode" "DI")])
15931
15932 (define_insn "*strsetsi_1"
15933   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15934         (match_operand:SI 2 "register_operand" "a"))
15935    (set (match_operand:P 0 "register_operand" "=D")
15936         (plus:P (match_dup 1)
15937                 (const_int 4)))]
15938   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15939   "stos{l|d}"
15940   [(set_attr "type" "str")
15941    (set_attr "memory" "store")
15942    (set_attr "mode" "SI")])
15943
15944 (define_insn "*strsethi_1"
15945   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15946         (match_operand:HI 2 "register_operand" "a"))
15947    (set (match_operand:P 0 "register_operand" "=D")
15948         (plus:P (match_dup 1)
15949                 (const_int 2)))]
15950   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15951   "stosw"
15952   [(set_attr "type" "str")
15953    (set_attr "memory" "store")
15954    (set_attr "mode" "HI")])
15955
15956 (define_insn "*strsetqi_1"
15957   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15958         (match_operand:QI 2 "register_operand" "a"))
15959    (set (match_operand:P 0 "register_operand" "=D")
15960         (plus:P (match_dup 1)
15961                 (const_int 1)))]
15962   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15963   "stosb"
15964   [(set_attr "type" "str")
15965    (set_attr "memory" "store")
15966    (set (attr "prefix_rex")
15967         (if_then_else
15968           (match_test "<P:MODE>mode == DImode")
15969           (const_string "0")
15970           (const_string "*")))
15971    (set_attr "mode" "QI")])
15972
15973 (define_expand "rep_stos"
15974   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15975               (set (match_operand 0 "register_operand" "")
15976                    (match_operand 4 "" ""))
15977               (set (match_operand 2 "memory_operand" "") (const_int 0))
15978               (use (match_operand 3 "register_operand" ""))
15979               (use (match_dup 1))])]
15980   ""
15981   "ix86_current_function_needs_cld = 1;")
15982
15983 (define_insn "*rep_stosdi_rex64"
15984   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15985    (set (match_operand:DI 0 "register_operand" "=D")
15986         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15987                             (const_int 3))
15988                  (match_operand:DI 3 "register_operand" "0")))
15989    (set (mem:BLK (match_dup 3))
15990         (const_int 0))
15991    (use (match_operand:DI 2 "register_operand" "a"))
15992    (use (match_dup 4))]
15993   "TARGET_64BIT
15994    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15995   "rep{%;} stosq"
15996   [(set_attr "type" "str")
15997    (set_attr "prefix_rep" "1")
15998    (set_attr "memory" "store")
15999    (set_attr "mode" "DI")])
16000
16001 (define_insn "*rep_stossi"
16002   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16003    (set (match_operand:P 0 "register_operand" "=D")
16004         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16005                           (const_int 2))
16006                  (match_operand:P 3 "register_operand" "0")))
16007    (set (mem:BLK (match_dup 3))
16008         (const_int 0))
16009    (use (match_operand:SI 2 "register_operand" "a"))
16010    (use (match_dup 4))]
16011   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16012   "rep{%;} stos{l|d}"
16013   [(set_attr "type" "str")
16014    (set_attr "prefix_rep" "1")
16015    (set_attr "memory" "store")
16016    (set_attr "mode" "SI")])
16017
16018 (define_insn "*rep_stosqi"
16019   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16020    (set (match_operand:P 0 "register_operand" "=D")
16021         (plus:P (match_operand:P 3 "register_operand" "0")
16022                 (match_operand:P 4 "register_operand" "1")))
16023    (set (mem:BLK (match_dup 3))
16024         (const_int 0))
16025    (use (match_operand:QI 2 "register_operand" "a"))
16026    (use (match_dup 4))]
16027   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16028   "rep{%;} stosb"
16029   [(set_attr "type" "str")
16030    (set_attr "prefix_rep" "1")
16031    (set_attr "memory" "store")
16032    (set (attr "prefix_rex")
16033         (if_then_else
16034           (match_test "<P:MODE>mode == DImode")
16035           (const_string "0")
16036           (const_string "*")))
16037    (set_attr "mode" "QI")])
16038
16039 (define_expand "cmpstrnsi"
16040   [(set (match_operand:SI 0 "register_operand" "")
16041         (compare:SI (match_operand:BLK 1 "general_operand" "")
16042                     (match_operand:BLK 2 "general_operand" "")))
16043    (use (match_operand 3 "general_operand" ""))
16044    (use (match_operand 4 "immediate_operand" ""))]
16045   ""
16046 {
16047   rtx addr1, addr2, out, outlow, count, countreg, align;
16048
16049   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16050     FAIL;
16051
16052   /* Can't use this if the user has appropriated ecx, esi or edi.  */
16053   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16054     FAIL;
16055
16056   out = operands[0];
16057   if (!REG_P (out))
16058     out = gen_reg_rtx (SImode);
16059
16060   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16061   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16062   if (addr1 != XEXP (operands[1], 0))
16063     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16064   if (addr2 != XEXP (operands[2], 0))
16065     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16066
16067   count = operands[3];
16068   countreg = ix86_zero_extend_to_Pmode (count);
16069
16070   /* %%% Iff we are testing strict equality, we can use known alignment
16071      to good advantage.  This may be possible with combine, particularly
16072      once cc0 is dead.  */
16073   align = operands[4];
16074
16075   if (CONST_INT_P (count))
16076     {
16077       if (INTVAL (count) == 0)
16078         {
16079           emit_move_insn (operands[0], const0_rtx);
16080           DONE;
16081         }
16082       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16083                                      operands[1], operands[2]));
16084     }
16085   else
16086     {
16087       rtx (*gen_cmp) (rtx, rtx);
16088
16089       gen_cmp = (TARGET_64BIT
16090                  ? gen_cmpdi_1 : gen_cmpsi_1);
16091
16092       emit_insn (gen_cmp (countreg, countreg));
16093       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16094                                   operands[1], operands[2]));
16095     }
16096
16097   outlow = gen_lowpart (QImode, out);
16098   emit_insn (gen_cmpintqi (outlow));
16099   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16100
16101   if (operands[0] != out)
16102     emit_move_insn (operands[0], out);
16103
16104   DONE;
16105 })
16106
16107 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16108
16109 (define_expand "cmpintqi"
16110   [(set (match_dup 1)
16111         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16112    (set (match_dup 2)
16113         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16114    (parallel [(set (match_operand:QI 0 "register_operand" "")
16115                    (minus:QI (match_dup 1)
16116                              (match_dup 2)))
16117               (clobber (reg:CC FLAGS_REG))])]
16118   ""
16119 {
16120   operands[1] = gen_reg_rtx (QImode);
16121   operands[2] = gen_reg_rtx (QImode);
16122 })
16123
16124 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16125 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16126
16127 (define_expand "cmpstrnqi_nz_1"
16128   [(parallel [(set (reg:CC FLAGS_REG)
16129                    (compare:CC (match_operand 4 "memory_operand" "")
16130                                (match_operand 5 "memory_operand" "")))
16131               (use (match_operand 2 "register_operand" ""))
16132               (use (match_operand:SI 3 "immediate_operand" ""))
16133               (clobber (match_operand 0 "register_operand" ""))
16134               (clobber (match_operand 1 "register_operand" ""))
16135               (clobber (match_dup 2))])]
16136   ""
16137   "ix86_current_function_needs_cld = 1;")
16138
16139 (define_insn "*cmpstrnqi_nz_1"
16140   [(set (reg:CC FLAGS_REG)
16141         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16142                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16143    (use (match_operand:P 6 "register_operand" "2"))
16144    (use (match_operand:SI 3 "immediate_operand" "i"))
16145    (clobber (match_operand:P 0 "register_operand" "=S"))
16146    (clobber (match_operand:P 1 "register_operand" "=D"))
16147    (clobber (match_operand:P 2 "register_operand" "=c"))]
16148   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16149   "repz{%;} cmpsb"
16150   [(set_attr "type" "str")
16151    (set_attr "mode" "QI")
16152    (set (attr "prefix_rex")
16153         (if_then_else
16154           (match_test "<P:MODE>mode == DImode")
16155           (const_string "0")
16156           (const_string "*")))
16157    (set_attr "prefix_rep" "1")])
16158
16159 ;; The same, but the count is not known to not be zero.
16160
16161 (define_expand "cmpstrnqi_1"
16162   [(parallel [(set (reg:CC FLAGS_REG)
16163                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16164                                      (const_int 0))
16165                   (compare:CC (match_operand 4 "memory_operand" "")
16166                               (match_operand 5 "memory_operand" ""))
16167                   (const_int 0)))
16168               (use (match_operand:SI 3 "immediate_operand" ""))
16169               (use (reg:CC FLAGS_REG))
16170               (clobber (match_operand 0 "register_operand" ""))
16171               (clobber (match_operand 1 "register_operand" ""))
16172               (clobber (match_dup 2))])]
16173   ""
16174   "ix86_current_function_needs_cld = 1;")
16175
16176 (define_insn "*cmpstrnqi_1"
16177   [(set (reg:CC FLAGS_REG)
16178         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16179                              (const_int 0))
16180           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16181                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
16182           (const_int 0)))
16183    (use (match_operand:SI 3 "immediate_operand" "i"))
16184    (use (reg:CC FLAGS_REG))
16185    (clobber (match_operand:P 0 "register_operand" "=S"))
16186    (clobber (match_operand:P 1 "register_operand" "=D"))
16187    (clobber (match_operand:P 2 "register_operand" "=c"))]
16188   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16189   "repz{%;} cmpsb"
16190   [(set_attr "type" "str")
16191    (set_attr "mode" "QI")
16192    (set (attr "prefix_rex")
16193         (if_then_else
16194           (match_test "<P:MODE>mode == DImode")
16195           (const_string "0")
16196           (const_string "*")))
16197    (set_attr "prefix_rep" "1")])
16198
16199 (define_expand "strlen<mode>"
16200   [(set (match_operand:P 0 "register_operand" "")
16201         (unspec:P [(match_operand:BLK 1 "general_operand" "")
16202                    (match_operand:QI 2 "immediate_operand" "")
16203                    (match_operand 3 "immediate_operand" "")]
16204                   UNSPEC_SCAS))]
16205   ""
16206 {
16207  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16208    DONE;
16209  else
16210    FAIL;
16211 })
16212
16213 (define_expand "strlenqi_1"
16214   [(parallel [(set (match_operand 0 "register_operand" "")
16215                    (match_operand 2 "" ""))
16216               (clobber (match_operand 1 "register_operand" ""))
16217               (clobber (reg:CC FLAGS_REG))])]
16218   ""
16219   "ix86_current_function_needs_cld = 1;")
16220
16221 (define_insn "*strlenqi_1"
16222   [(set (match_operand:P 0 "register_operand" "=&c")
16223         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16224                    (match_operand:QI 2 "register_operand" "a")
16225                    (match_operand:P 3 "immediate_operand" "i")
16226                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16227    (clobber (match_operand:P 1 "register_operand" "=D"))
16228    (clobber (reg:CC FLAGS_REG))]
16229   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16230   "repnz{%;} scasb"
16231   [(set_attr "type" "str")
16232    (set_attr "mode" "QI")
16233    (set (attr "prefix_rex")
16234         (if_then_else
16235           (match_test "<P:MODE>mode == DImode")
16236           (const_string "0")
16237           (const_string "*")))
16238    (set_attr "prefix_rep" "1")])
16239
16240 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
16241 ;; handled in combine, but it is not currently up to the task.
16242 ;; When used for their truth value, the cmpstrn* expanders generate
16243 ;; code like this:
16244 ;;
16245 ;;   repz cmpsb
16246 ;;   seta       %al
16247 ;;   setb       %dl
16248 ;;   cmpb       %al, %dl
16249 ;;   jcc        label
16250 ;;
16251 ;; The intermediate three instructions are unnecessary.
16252
16253 ;; This one handles cmpstrn*_nz_1...
16254 (define_peephole2
16255   [(parallel[
16256      (set (reg:CC FLAGS_REG)
16257           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16258                       (mem:BLK (match_operand 5 "register_operand" ""))))
16259      (use (match_operand 6 "register_operand" ""))
16260      (use (match_operand:SI 3 "immediate_operand" ""))
16261      (clobber (match_operand 0 "register_operand" ""))
16262      (clobber (match_operand 1 "register_operand" ""))
16263      (clobber (match_operand 2 "register_operand" ""))])
16264    (set (match_operand:QI 7 "register_operand" "")
16265         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16266    (set (match_operand:QI 8 "register_operand" "")
16267         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16268    (set (reg FLAGS_REG)
16269         (compare (match_dup 7) (match_dup 8)))
16270   ]
16271   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16272   [(parallel[
16273      (set (reg:CC FLAGS_REG)
16274           (compare:CC (mem:BLK (match_dup 4))
16275                       (mem:BLK (match_dup 5))))
16276      (use (match_dup 6))
16277      (use (match_dup 3))
16278      (clobber (match_dup 0))
16279      (clobber (match_dup 1))
16280      (clobber (match_dup 2))])])
16281
16282 ;; ...and this one handles cmpstrn*_1.
16283 (define_peephole2
16284   [(parallel[
16285      (set (reg:CC FLAGS_REG)
16286           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16287                                (const_int 0))
16288             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16289                         (mem:BLK (match_operand 5 "register_operand" "")))
16290             (const_int 0)))
16291      (use (match_operand:SI 3 "immediate_operand" ""))
16292      (use (reg:CC FLAGS_REG))
16293      (clobber (match_operand 0 "register_operand" ""))
16294      (clobber (match_operand 1 "register_operand" ""))
16295      (clobber (match_operand 2 "register_operand" ""))])
16296    (set (match_operand:QI 7 "register_operand" "")
16297         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16298    (set (match_operand:QI 8 "register_operand" "")
16299         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16300    (set (reg FLAGS_REG)
16301         (compare (match_dup 7) (match_dup 8)))
16302   ]
16303   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16304   [(parallel[
16305      (set (reg:CC FLAGS_REG)
16306           (if_then_else:CC (ne (match_dup 6)
16307                                (const_int 0))
16308             (compare:CC (mem:BLK (match_dup 4))
16309                         (mem:BLK (match_dup 5)))
16310             (const_int 0)))
16311      (use (match_dup 3))
16312      (use (reg:CC FLAGS_REG))
16313      (clobber (match_dup 0))
16314      (clobber (match_dup 1))
16315      (clobber (match_dup 2))])])
16316 \f
16317 ;; Conditional move instructions.
16318
16319 (define_expand "mov<mode>cc"
16320   [(set (match_operand:SWIM 0 "register_operand" "")
16321         (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16322                            (match_operand:SWIM 2 "<general_operand>" "")
16323                            (match_operand:SWIM 3 "<general_operand>" "")))]
16324   ""
16325   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16326
16327 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16328 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16329 ;; So just document what we're doing explicitly.
16330
16331 (define_expand "x86_mov<mode>cc_0_m1"
16332   [(parallel
16333     [(set (match_operand:SWI48 0 "register_operand" "")
16334           (if_then_else:SWI48
16335             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16336              [(match_operand 1 "flags_reg_operand" "")
16337               (const_int 0)])
16338             (const_int -1)
16339             (const_int 0)))
16340      (clobber (reg:CC FLAGS_REG))])])
16341
16342 (define_insn "*x86_mov<mode>cc_0_m1"
16343   [(set (match_operand:SWI48 0 "register_operand" "=r")
16344         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16345                              [(reg FLAGS_REG) (const_int 0)])
16346           (const_int -1)
16347           (const_int 0)))
16348    (clobber (reg:CC FLAGS_REG))]
16349   ""
16350   "sbb{<imodesuffix>}\t%0, %0"
16351   ; Since we don't have the proper number of operands for an alu insn,
16352   ; fill in all the blanks.
16353   [(set_attr "type" "alu")
16354    (set_attr "use_carry" "1")
16355    (set_attr "pent_pair" "pu")
16356    (set_attr "memory" "none")
16357    (set_attr "imm_disp" "false")
16358    (set_attr "mode" "<MODE>")
16359    (set_attr "length_immediate" "0")])
16360
16361 (define_insn "*x86_mov<mode>cc_0_m1_se"
16362   [(set (match_operand:SWI48 0 "register_operand" "=r")
16363         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16364                              [(reg FLAGS_REG) (const_int 0)])
16365                             (const_int 1)
16366                             (const_int 0)))
16367    (clobber (reg:CC FLAGS_REG))]
16368   ""
16369   "sbb{<imodesuffix>}\t%0, %0"
16370   [(set_attr "type" "alu")
16371    (set_attr "use_carry" "1")
16372    (set_attr "pent_pair" "pu")
16373    (set_attr "memory" "none")
16374    (set_attr "imm_disp" "false")
16375    (set_attr "mode" "<MODE>")
16376    (set_attr "length_immediate" "0")])
16377
16378 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16379   [(set (match_operand:SWI48 0 "register_operand" "=r")
16380         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16381                     [(reg FLAGS_REG) (const_int 0)])))
16382    (clobber (reg:CC FLAGS_REG))]
16383   ""
16384   "sbb{<imodesuffix>}\t%0, %0"
16385   [(set_attr "type" "alu")
16386    (set_attr "use_carry" "1")
16387    (set_attr "pent_pair" "pu")
16388    (set_attr "memory" "none")
16389    (set_attr "imm_disp" "false")
16390    (set_attr "mode" "<MODE>")
16391    (set_attr "length_immediate" "0")])
16392
16393 (define_insn "*mov<mode>cc_noc"
16394   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16395         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16396                                [(reg FLAGS_REG) (const_int 0)])
16397           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16398           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16399   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16400   "@
16401    cmov%O2%C1\t{%2, %0|%0, %2}
16402    cmov%O2%c1\t{%3, %0|%0, %3}"
16403   [(set_attr "type" "icmov")
16404    (set_attr "mode" "<MODE>")])
16405
16406 (define_insn "*movqicc_noc"
16407   [(set (match_operand:QI 0 "register_operand" "=r,r")
16408         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16409                            [(reg FLAGS_REG) (const_int 0)])
16410                       (match_operand:QI 2 "register_operand" "r,0")
16411                       (match_operand:QI 3 "register_operand" "0,r")))]
16412   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16413   "#"
16414   [(set_attr "type" "icmov")
16415    (set_attr "mode" "QI")])
16416
16417 (define_split
16418   [(set (match_operand 0 "register_operand")
16419         (if_then_else (match_operator 1 "ix86_comparison_operator"
16420                         [(reg FLAGS_REG) (const_int 0)])
16421                       (match_operand 2 "register_operand")
16422                       (match_operand 3 "register_operand")))]
16423   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16424    && (GET_MODE (operands[0]) == QImode
16425        || GET_MODE (operands[0]) == HImode)
16426    && reload_completed"
16427   [(set (match_dup 0)
16428         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16429 {
16430   operands[0] = gen_lowpart (SImode, operands[0]);
16431   operands[2] = gen_lowpart (SImode, operands[2]);
16432   operands[3] = gen_lowpart (SImode, operands[3]);
16433 })
16434
16435 (define_expand "mov<mode>cc"
16436   [(set (match_operand:X87MODEF 0 "register_operand" "")
16437         (if_then_else:X87MODEF
16438           (match_operand 1 "ix86_fp_comparison_operator" "")
16439           (match_operand:X87MODEF 2 "register_operand" "")
16440           (match_operand:X87MODEF 3 "register_operand" "")))]
16441   "(TARGET_80387 && TARGET_CMOVE)
16442    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16443   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16444
16445 (define_insn "*movxfcc_1"
16446   [(set (match_operand:XF 0 "register_operand" "=f,f")
16447         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16448                                 [(reg FLAGS_REG) (const_int 0)])
16449                       (match_operand:XF 2 "register_operand" "f,0")
16450                       (match_operand:XF 3 "register_operand" "0,f")))]
16451   "TARGET_80387 && TARGET_CMOVE"
16452   "@
16453    fcmov%F1\t{%2, %0|%0, %2}
16454    fcmov%f1\t{%3, %0|%0, %3}"
16455   [(set_attr "type" "fcmov")
16456    (set_attr "mode" "XF")])
16457
16458 (define_insn "*movdfcc_1_rex64"
16459   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16460         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16461                                 [(reg FLAGS_REG) (const_int 0)])
16462                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16463                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16464   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16465    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16466   "@
16467    fcmov%F1\t{%2, %0|%0, %2}
16468    fcmov%f1\t{%3, %0|%0, %3}
16469    cmov%O2%C1\t{%2, %0|%0, %2}
16470    cmov%O2%c1\t{%3, %0|%0, %3}"
16471   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16472    (set_attr "mode" "DF,DF,DI,DI")])
16473
16474 (define_insn "*movdfcc_1"
16475   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16476         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16477                                 [(reg FLAGS_REG) (const_int 0)])
16478                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16479                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16480   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16481    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16482   "@
16483    fcmov%F1\t{%2, %0|%0, %2}
16484    fcmov%f1\t{%3, %0|%0, %3}
16485    #
16486    #"
16487   [(set_attr "type" "fcmov,fcmov,multi,multi")
16488    (set_attr "mode" "DF,DF,DI,DI")])
16489
16490 (define_split
16491   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16492         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16493                                 [(reg FLAGS_REG) (const_int 0)])
16494                       (match_operand:DF 2 "nonimmediate_operand")
16495                       (match_operand:DF 3 "nonimmediate_operand")))]
16496   "!TARGET_64BIT && reload_completed"
16497   [(set (match_dup 2)
16498         (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16499    (set (match_dup 3)
16500         (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16501 {
16502   split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16503   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16504 })
16505
16506 (define_insn "*movsfcc_1_387"
16507   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16508         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16509                                 [(reg FLAGS_REG) (const_int 0)])
16510                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16511                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16512   "TARGET_80387 && TARGET_CMOVE
16513    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16514   "@
16515    fcmov%F1\t{%2, %0|%0, %2}
16516    fcmov%f1\t{%3, %0|%0, %3}
16517    cmov%O2%C1\t{%2, %0|%0, %2}
16518    cmov%O2%c1\t{%3, %0|%0, %3}"
16519   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16520    (set_attr "mode" "SF,SF,SI,SI")])
16521
16522 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16523 ;; the scalar versions to have only XMM registers as operands.
16524
16525 ;; XOP conditional move
16526 (define_insn "*xop_pcmov_<mode>"
16527   [(set (match_operand:MODEF 0 "register_operand" "=x")
16528         (if_then_else:MODEF
16529           (match_operand:MODEF 1 "register_operand" "x")
16530           (match_operand:MODEF 2 "register_operand" "x")
16531           (match_operand:MODEF 3 "register_operand" "x")))]
16532   "TARGET_XOP"
16533   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16534   [(set_attr "type" "sse4arg")])
16535
16536 ;; These versions of the min/max patterns are intentionally ignorant of
16537 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16538 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16539 ;; are undefined in this condition, we're certain this is correct.
16540
16541 (define_insn "<code><mode>3"
16542   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16543         (smaxmin:MODEF
16544           (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16545           (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16546   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16547   "@
16548    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16549    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16550   [(set_attr "isa" "noavx,avx")
16551    (set_attr "prefix" "orig,vex")
16552    (set_attr "type" "sseadd")
16553    (set_attr "mode" "<MODE>")])
16554
16555 ;; These versions of the min/max patterns implement exactly the operations
16556 ;;   min = (op1 < op2 ? op1 : op2)
16557 ;;   max = (!(op1 < op2) ? op1 : op2)
16558 ;; Their operands are not commutative, and thus they may be used in the
16559 ;; presence of -0.0 and NaN.
16560
16561 (define_insn "*ieee_smin<mode>3"
16562   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16563         (unspec:MODEF
16564           [(match_operand:MODEF 1 "register_operand" "0,x")
16565            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16566          UNSPEC_IEEE_MIN))]
16567   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16568   "@
16569    min<ssemodesuffix>\t{%2, %0|%0, %2}
16570    vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16571   [(set_attr "isa" "noavx,avx")
16572    (set_attr "prefix" "orig,vex")
16573    (set_attr "type" "sseadd")
16574    (set_attr "mode" "<MODE>")])
16575
16576 (define_insn "*ieee_smax<mode>3"
16577   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16578         (unspec:MODEF
16579           [(match_operand:MODEF 1 "register_operand" "0,x")
16580            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16581          UNSPEC_IEEE_MAX))]
16582   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16583   "@
16584    max<ssemodesuffix>\t{%2, %0|%0, %2}
16585    vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16586   [(set_attr "isa" "noavx,avx")
16587    (set_attr "prefix" "orig,vex")
16588    (set_attr "type" "sseadd")
16589    (set_attr "mode" "<MODE>")])
16590
16591 ;; Make two stack loads independent:
16592 ;;   fld aa              fld aa
16593 ;;   fld %st(0)     ->   fld bb
16594 ;;   fmul bb             fmul %st(1), %st
16595 ;;
16596 ;; Actually we only match the last two instructions for simplicity.
16597 (define_peephole2
16598   [(set (match_operand 0 "fp_register_operand" "")
16599         (match_operand 1 "fp_register_operand" ""))
16600    (set (match_dup 0)
16601         (match_operator 2 "binary_fp_operator"
16602            [(match_dup 0)
16603             (match_operand 3 "memory_operand" "")]))]
16604   "REGNO (operands[0]) != REGNO (operands[1])"
16605   [(set (match_dup 0) (match_dup 3))
16606    (set (match_dup 0) (match_dup 4))]
16607
16608   ;; The % modifier is not operational anymore in peephole2's, so we have to
16609   ;; swap the operands manually in the case of addition and multiplication.
16610 {
16611   rtx op0, op1;
16612
16613   if (COMMUTATIVE_ARITH_P (operands[2]))
16614     op0 = operands[0], op1 = operands[1];
16615   else
16616     op0 = operands[1], op1 = operands[0];
16617
16618   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16619                                 GET_MODE (operands[2]),
16620                                 op0, op1);
16621 })
16622
16623 ;; Conditional addition patterns
16624 (define_expand "add<mode>cc"
16625   [(match_operand:SWI 0 "register_operand" "")
16626    (match_operand 1 "ordered_comparison_operator" "")
16627    (match_operand:SWI 2 "register_operand" "")
16628    (match_operand:SWI 3 "const_int_operand" "")]
16629   ""
16630   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16631 \f
16632 ;; Misc patterns (?)
16633
16634 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16635 ;; Otherwise there will be nothing to keep
16636 ;;
16637 ;; [(set (reg ebp) (reg esp))]
16638 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16639 ;;  (clobber (eflags)]
16640 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16641 ;;
16642 ;; in proper program order.
16643
16644 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16645   [(set (match_operand:P 0 "register_operand" "=r,r")
16646         (plus:P (match_operand:P 1 "register_operand" "0,r")
16647                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16648    (clobber (reg:CC FLAGS_REG))
16649    (clobber (mem:BLK (scratch)))]
16650   ""
16651 {
16652   switch (get_attr_type (insn))
16653     {
16654     case TYPE_IMOV:
16655       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16656
16657     case TYPE_ALU:
16658       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16659       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16660         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16661
16662       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16663
16664     default:
16665       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16666       return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16667     }
16668 }
16669   [(set (attr "type")
16670         (cond [(and (eq_attr "alternative" "0")
16671                     (not (match_test "TARGET_OPT_AGU")))
16672                  (const_string "alu")
16673                (match_operand:<MODE> 2 "const0_operand" "")
16674                  (const_string "imov")
16675               ]
16676               (const_string "lea")))
16677    (set (attr "length_immediate")
16678         (cond [(eq_attr "type" "imov")
16679                  (const_string "0")
16680                (and (eq_attr "type" "alu")
16681                     (match_operand 2 "const128_operand" ""))
16682                  (const_string "1")
16683               ]
16684               (const_string "*")))
16685    (set_attr "mode" "<MODE>")])
16686
16687 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16688   [(set (match_operand:P 0 "register_operand" "=r")
16689         (minus:P (match_operand:P 1 "register_operand" "0")
16690                  (match_operand:P 2 "register_operand" "r")))
16691    (clobber (reg:CC FLAGS_REG))
16692    (clobber (mem:BLK (scratch)))]
16693   ""
16694   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16695   [(set_attr "type" "alu")
16696    (set_attr "mode" "<MODE>")])
16697
16698 (define_insn "allocate_stack_worker_probe_<mode>"
16699   [(set (match_operand:P 0 "register_operand" "=a")
16700         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16701                             UNSPECV_STACK_PROBE))
16702    (clobber (reg:CC FLAGS_REG))]
16703   "ix86_target_stack_probe ()"
16704   "call\t___chkstk_ms"
16705   [(set_attr "type" "multi")
16706    (set_attr "length" "5")])
16707
16708 (define_expand "allocate_stack"
16709   [(match_operand 0 "register_operand" "")
16710    (match_operand 1 "general_operand" "")]
16711   "ix86_target_stack_probe ()"
16712 {
16713   rtx x;
16714
16715 #ifndef CHECK_STACK_LIMIT
16716 #define CHECK_STACK_LIMIT 0
16717 #endif
16718
16719   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16720       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16721     {
16722       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16723                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16724       if (x != stack_pointer_rtx)
16725         emit_move_insn (stack_pointer_rtx, x);
16726     }
16727   else
16728     {
16729       x = copy_to_mode_reg (Pmode, operands[1]);
16730       if (TARGET_64BIT)
16731         emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16732       else
16733         emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16734       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16735                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16736       if (x != stack_pointer_rtx)
16737         emit_move_insn (stack_pointer_rtx, x);
16738     }
16739
16740   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16741   DONE;
16742 })
16743
16744 ;; Use IOR for stack probes, this is shorter.
16745 (define_expand "probe_stack"
16746   [(match_operand 0 "memory_operand" "")]
16747   ""
16748 {
16749   rtx (*gen_ior3) (rtx, rtx, rtx);
16750
16751   gen_ior3 = (GET_MODE (operands[0]) == DImode
16752               ? gen_iordi3 : gen_iorsi3);
16753
16754   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16755   DONE;
16756 })
16757
16758 (define_insn "adjust_stack_and_probe<mode>"
16759   [(set (match_operand:P 0 "register_operand" "=r")
16760         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16761                             UNSPECV_PROBE_STACK_RANGE))
16762    (set (reg:P SP_REG)
16763         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16764    (clobber (reg:CC FLAGS_REG))
16765    (clobber (mem:BLK (scratch)))]
16766   ""
16767   "* return output_adjust_stack_and_probe (operands[0]);"
16768   [(set_attr "type" "multi")])
16769
16770 (define_insn "probe_stack_range<mode>"
16771   [(set (match_operand:P 0 "register_operand" "=r")
16772         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16773                             (match_operand:P 2 "const_int_operand" "n")]
16774                             UNSPECV_PROBE_STACK_RANGE))
16775    (clobber (reg:CC FLAGS_REG))]
16776   ""
16777   "* return output_probe_stack_range (operands[0], operands[2]);"
16778   [(set_attr "type" "multi")])
16779
16780 (define_expand "builtin_setjmp_receiver"
16781   [(label_ref (match_operand 0 "" ""))]
16782   "!TARGET_64BIT && flag_pic"
16783 {
16784 #if TARGET_MACHO
16785   if (TARGET_MACHO)
16786     {
16787       rtx xops[3];
16788       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16789       rtx label_rtx = gen_label_rtx ();
16790       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16791       xops[0] = xops[1] = picreg;
16792       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16793       ix86_expand_binary_operator (MINUS, SImode, xops);
16794     }
16795   else
16796 #endif
16797     emit_insn (gen_set_got (pic_offset_table_rtx));
16798   DONE;
16799 })
16800 \f
16801 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16802
16803 (define_split
16804   [(set (match_operand 0 "register_operand" "")
16805         (match_operator 3 "promotable_binary_operator"
16806            [(match_operand 1 "register_operand" "")
16807             (match_operand 2 "aligned_operand" "")]))
16808    (clobber (reg:CC FLAGS_REG))]
16809   "! TARGET_PARTIAL_REG_STALL && reload_completed
16810    && ((GET_MODE (operands[0]) == HImode
16811         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16812             /* ??? next two lines just !satisfies_constraint_K (...) */
16813             || !CONST_INT_P (operands[2])
16814             || satisfies_constraint_K (operands[2])))
16815        || (GET_MODE (operands[0]) == QImode
16816            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16817   [(parallel [(set (match_dup 0)
16818                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16819               (clobber (reg:CC FLAGS_REG))])]
16820 {
16821   operands[0] = gen_lowpart (SImode, operands[0]);
16822   operands[1] = gen_lowpart (SImode, operands[1]);
16823   if (GET_CODE (operands[3]) != ASHIFT)
16824     operands[2] = gen_lowpart (SImode, operands[2]);
16825   PUT_MODE (operands[3], SImode);
16826 })
16827
16828 ; Promote the QImode tests, as i386 has encoding of the AND
16829 ; instruction with 32-bit sign-extended immediate and thus the
16830 ; instruction size is unchanged, except in the %eax case for
16831 ; which it is increased by one byte, hence the ! optimize_size.
16832 (define_split
16833   [(set (match_operand 0 "flags_reg_operand" "")
16834         (match_operator 2 "compare_operator"
16835           [(and (match_operand 3 "aligned_operand" "")
16836                 (match_operand 4 "const_int_operand" ""))
16837            (const_int 0)]))
16838    (set (match_operand 1 "register_operand" "")
16839         (and (match_dup 3) (match_dup 4)))]
16840   "! TARGET_PARTIAL_REG_STALL && reload_completed
16841    && optimize_insn_for_speed_p ()
16842    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16843        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16844    /* Ensure that the operand will remain sign-extended immediate.  */
16845    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16846   [(parallel [(set (match_dup 0)
16847                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16848                                     (const_int 0)]))
16849               (set (match_dup 1)
16850                    (and:SI (match_dup 3) (match_dup 4)))])]
16851 {
16852   operands[4]
16853     = gen_int_mode (INTVAL (operands[4])
16854                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16855   operands[1] = gen_lowpart (SImode, operands[1]);
16856   operands[3] = gen_lowpart (SImode, operands[3]);
16857 })
16858
16859 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16860 ; the TEST instruction with 32-bit sign-extended immediate and thus
16861 ; the instruction size would at least double, which is not what we
16862 ; want even with ! optimize_size.
16863 (define_split
16864   [(set (match_operand 0 "flags_reg_operand" "")
16865         (match_operator 1 "compare_operator"
16866           [(and (match_operand:HI 2 "aligned_operand" "")
16867                 (match_operand:HI 3 "const_int_operand" ""))
16868            (const_int 0)]))]
16869   "! TARGET_PARTIAL_REG_STALL && reload_completed
16870    && ! TARGET_FAST_PREFIX
16871    && optimize_insn_for_speed_p ()
16872    /* Ensure that the operand will remain sign-extended immediate.  */
16873    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16874   [(set (match_dup 0)
16875         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16876                          (const_int 0)]))]
16877 {
16878   operands[3]
16879     = gen_int_mode (INTVAL (operands[3])
16880                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16881   operands[2] = gen_lowpart (SImode, operands[2]);
16882 })
16883
16884 (define_split
16885   [(set (match_operand 0 "register_operand" "")
16886         (neg (match_operand 1 "register_operand" "")))
16887    (clobber (reg:CC FLAGS_REG))]
16888   "! TARGET_PARTIAL_REG_STALL && reload_completed
16889    && (GET_MODE (operands[0]) == HImode
16890        || (GET_MODE (operands[0]) == QImode
16891            && (TARGET_PROMOTE_QImode
16892                || optimize_insn_for_size_p ())))"
16893   [(parallel [(set (match_dup 0)
16894                    (neg:SI (match_dup 1)))
16895               (clobber (reg:CC FLAGS_REG))])]
16896 {
16897   operands[0] = gen_lowpart (SImode, operands[0]);
16898   operands[1] = gen_lowpart (SImode, operands[1]);
16899 })
16900
16901 (define_split
16902   [(set (match_operand 0 "register_operand" "")
16903         (not (match_operand 1 "register_operand" "")))]
16904   "! TARGET_PARTIAL_REG_STALL && reload_completed
16905    && (GET_MODE (operands[0]) == HImode
16906        || (GET_MODE (operands[0]) == QImode
16907            && (TARGET_PROMOTE_QImode
16908                || optimize_insn_for_size_p ())))"
16909   [(set (match_dup 0)
16910         (not:SI (match_dup 1)))]
16911 {
16912   operands[0] = gen_lowpart (SImode, operands[0]);
16913   operands[1] = gen_lowpart (SImode, operands[1]);
16914 })
16915 \f
16916 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
16917 ;; transform a complex memory operation into two memory to register operations.
16918
16919 ;; Don't push memory operands
16920 (define_peephole2
16921   [(set (match_operand:SWI 0 "push_operand" "")
16922         (match_operand:SWI 1 "memory_operand" ""))
16923    (match_scratch:SWI 2 "<r>")]
16924   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16925    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16926   [(set (match_dup 2) (match_dup 1))
16927    (set (match_dup 0) (match_dup 2))])
16928
16929 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16930 ;; SImode pushes.
16931 (define_peephole2
16932   [(set (match_operand:SF 0 "push_operand" "")
16933         (match_operand:SF 1 "memory_operand" ""))
16934    (match_scratch:SF 2 "r")]
16935   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16936    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16937   [(set (match_dup 2) (match_dup 1))
16938    (set (match_dup 0) (match_dup 2))])
16939
16940 ;; Don't move an immediate directly to memory when the instruction
16941 ;; gets too big.
16942 (define_peephole2
16943   [(match_scratch:SWI124 1 "<r>")
16944    (set (match_operand:SWI124 0 "memory_operand" "")
16945         (const_int 0))]
16946   "optimize_insn_for_speed_p ()
16947    && !TARGET_USE_MOV0
16948    && TARGET_SPLIT_LONG_MOVES
16949    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16950    && peep2_regno_dead_p (0, FLAGS_REG)"
16951   [(parallel [(set (match_dup 2) (const_int 0))
16952               (clobber (reg:CC FLAGS_REG))])
16953    (set (match_dup 0) (match_dup 1))]
16954   "operands[2] = gen_lowpart (SImode, operands[1]);")
16955
16956 (define_peephole2
16957   [(match_scratch:SWI124 2 "<r>")
16958    (set (match_operand:SWI124 0 "memory_operand" "")
16959         (match_operand:SWI124 1 "immediate_operand" ""))]
16960   "optimize_insn_for_speed_p ()
16961    && TARGET_SPLIT_LONG_MOVES
16962    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16963   [(set (match_dup 2) (match_dup 1))
16964    (set (match_dup 0) (match_dup 2))])
16965
16966 ;; Don't compare memory with zero, load and use a test instead.
16967 (define_peephole2
16968   [(set (match_operand 0 "flags_reg_operand" "")
16969         (match_operator 1 "compare_operator"
16970           [(match_operand:SI 2 "memory_operand" "")
16971            (const_int 0)]))
16972    (match_scratch:SI 3 "r")]
16973   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16974   [(set (match_dup 3) (match_dup 2))
16975    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16976
16977 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16978 ;; Don't split NOTs with a displacement operand, because resulting XOR
16979 ;; will not be pairable anyway.
16980 ;;
16981 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16982 ;; represented using a modRM byte.  The XOR replacement is long decoded,
16983 ;; so this split helps here as well.
16984 ;;
16985 ;; Note: Can't do this as a regular split because we can't get proper
16986 ;; lifetime information then.
16987
16988 (define_peephole2
16989   [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16990         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16991   "optimize_insn_for_speed_p ()
16992    && ((TARGET_NOT_UNPAIRABLE
16993         && (!MEM_P (operands[0])
16994             || !memory_displacement_operand (operands[0], <MODE>mode)))
16995        || (TARGET_NOT_VECTORMODE
16996            && long_memory_operand (operands[0], <MODE>mode)))
16997    && peep2_regno_dead_p (0, FLAGS_REG)"
16998   [(parallel [(set (match_dup 0)
16999                    (xor:SWI124 (match_dup 1) (const_int -1)))
17000               (clobber (reg:CC FLAGS_REG))])])
17001
17002 ;; Non pairable "test imm, reg" instructions can be translated to
17003 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17004 ;; byte opcode instead of two, have a short form for byte operands),
17005 ;; so do it for other CPUs as well.  Given that the value was dead,
17006 ;; this should not create any new dependencies.  Pass on the sub-word
17007 ;; versions if we're concerned about partial register stalls.
17008
17009 (define_peephole2
17010   [(set (match_operand 0 "flags_reg_operand" "")
17011         (match_operator 1 "compare_operator"
17012           [(and:SI (match_operand:SI 2 "register_operand" "")
17013                    (match_operand:SI 3 "immediate_operand" ""))
17014            (const_int 0)]))]
17015   "ix86_match_ccmode (insn, CCNOmode)
17016    && (true_regnum (operands[2]) != AX_REG
17017        || satisfies_constraint_K (operands[3]))
17018    && peep2_reg_dead_p (1, operands[2])"
17019   [(parallel
17020      [(set (match_dup 0)
17021            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17022                             (const_int 0)]))
17023       (set (match_dup 2)
17024            (and:SI (match_dup 2) (match_dup 3)))])])
17025
17026 ;; We don't need to handle HImode case, because it will be promoted to SImode
17027 ;; on ! TARGET_PARTIAL_REG_STALL
17028
17029 (define_peephole2
17030   [(set (match_operand 0 "flags_reg_operand" "")
17031         (match_operator 1 "compare_operator"
17032           [(and:QI (match_operand:QI 2 "register_operand" "")
17033                    (match_operand:QI 3 "immediate_operand" ""))
17034            (const_int 0)]))]
17035   "! TARGET_PARTIAL_REG_STALL
17036    && ix86_match_ccmode (insn, CCNOmode)
17037    && true_regnum (operands[2]) != AX_REG
17038    && peep2_reg_dead_p (1, operands[2])"
17039   [(parallel
17040      [(set (match_dup 0)
17041            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17042                             (const_int 0)]))
17043       (set (match_dup 2)
17044            (and:QI (match_dup 2) (match_dup 3)))])])
17045
17046 (define_peephole2
17047   [(set (match_operand 0 "flags_reg_operand" "")
17048         (match_operator 1 "compare_operator"
17049           [(and:SI
17050              (zero_extract:SI
17051                (match_operand 2 "ext_register_operand" "")
17052                (const_int 8)
17053                (const_int 8))
17054              (match_operand 3 "const_int_operand" ""))
17055            (const_int 0)]))]
17056   "! TARGET_PARTIAL_REG_STALL
17057    && ix86_match_ccmode (insn, CCNOmode)
17058    && true_regnum (operands[2]) != AX_REG
17059    && peep2_reg_dead_p (1, operands[2])"
17060   [(parallel [(set (match_dup 0)
17061                    (match_op_dup 1
17062                      [(and:SI
17063                         (zero_extract:SI
17064                           (match_dup 2)
17065                           (const_int 8)
17066                           (const_int 8))
17067                         (match_dup 3))
17068                       (const_int 0)]))
17069               (set (zero_extract:SI (match_dup 2)
17070                                     (const_int 8)
17071                                     (const_int 8))
17072                    (and:SI
17073                      (zero_extract:SI
17074                        (match_dup 2)
17075                        (const_int 8)
17076                        (const_int 8))
17077                      (match_dup 3)))])])
17078
17079 ;; Don't do logical operations with memory inputs.
17080 (define_peephole2
17081   [(match_scratch:SI 2 "r")
17082    (parallel [(set (match_operand:SI 0 "register_operand" "")
17083                    (match_operator:SI 3 "arith_or_logical_operator"
17084                      [(match_dup 0)
17085                       (match_operand:SI 1 "memory_operand" "")]))
17086               (clobber (reg:CC FLAGS_REG))])]
17087   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17088   [(set (match_dup 2) (match_dup 1))
17089    (parallel [(set (match_dup 0)
17090                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17091               (clobber (reg:CC FLAGS_REG))])])
17092
17093 (define_peephole2
17094   [(match_scratch:SI 2 "r")
17095    (parallel [(set (match_operand:SI 0 "register_operand" "")
17096                    (match_operator:SI 3 "arith_or_logical_operator"
17097                      [(match_operand:SI 1 "memory_operand" "")
17098                       (match_dup 0)]))
17099               (clobber (reg:CC FLAGS_REG))])]
17100   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17101   [(set (match_dup 2) (match_dup 1))
17102    (parallel [(set (match_dup 0)
17103                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17104               (clobber (reg:CC FLAGS_REG))])])
17105
17106 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17107 ;; refers to the destination of the load!
17108
17109 (define_peephole2
17110   [(set (match_operand:SI 0 "register_operand" "")
17111         (match_operand:SI 1 "register_operand" ""))
17112    (parallel [(set (match_dup 0)
17113                    (match_operator:SI 3 "commutative_operator"
17114                      [(match_dup 0)
17115                       (match_operand:SI 2 "memory_operand" "")]))
17116               (clobber (reg:CC FLAGS_REG))])]
17117   "REGNO (operands[0]) != REGNO (operands[1])
17118    && GENERAL_REGNO_P (REGNO (operands[0]))
17119    && GENERAL_REGNO_P (REGNO (operands[1]))"
17120   [(set (match_dup 0) (match_dup 4))
17121    (parallel [(set (match_dup 0)
17122                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17123               (clobber (reg:CC FLAGS_REG))])]
17124   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17125
17126 (define_peephole2
17127   [(set (match_operand 0 "register_operand" "")
17128         (match_operand 1 "register_operand" ""))
17129    (set (match_dup 0)
17130                    (match_operator 3 "commutative_operator"
17131                      [(match_dup 0)
17132                       (match_operand 2 "memory_operand" "")]))]
17133   "REGNO (operands[0]) != REGNO (operands[1])
17134    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
17135        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17136   [(set (match_dup 0) (match_dup 2))
17137    (set (match_dup 0)
17138         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17139
17140 ; Don't do logical operations with memory outputs
17141 ;
17142 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17143 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17144 ; the same decoder scheduling characteristics as the original.
17145
17146 (define_peephole2
17147   [(match_scratch:SI 2 "r")
17148    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17149                    (match_operator:SI 3 "arith_or_logical_operator"
17150                      [(match_dup 0)
17151                       (match_operand:SI 1 "nonmemory_operand" "")]))
17152               (clobber (reg:CC FLAGS_REG))])]
17153   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17154    /* Do not split stack checking probes.  */
17155    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17156   [(set (match_dup 2) (match_dup 0))
17157    (parallel [(set (match_dup 2)
17158                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17159               (clobber (reg:CC FLAGS_REG))])
17160    (set (match_dup 0) (match_dup 2))])
17161
17162 (define_peephole2
17163   [(match_scratch:SI 2 "r")
17164    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17165                    (match_operator:SI 3 "arith_or_logical_operator"
17166                      [(match_operand:SI 1 "nonmemory_operand" "")
17167                       (match_dup 0)]))
17168               (clobber (reg:CC FLAGS_REG))])]
17169   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17170    /* Do not split stack checking probes.  */
17171    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17172   [(set (match_dup 2) (match_dup 0))
17173    (parallel [(set (match_dup 2)
17174                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17175               (clobber (reg:CC FLAGS_REG))])
17176    (set (match_dup 0) (match_dup 2))])
17177
17178 ;; Attempt to use arith or logical operations with memory outputs with
17179 ;; setting of flags.
17180 (define_peephole2
17181   [(set (match_operand:SWI 0 "register_operand" "")
17182         (match_operand:SWI 1 "memory_operand" ""))
17183    (parallel [(set (match_dup 0)
17184                    (match_operator:SWI 3 "plusminuslogic_operator"
17185                      [(match_dup 0)
17186                       (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17187               (clobber (reg:CC FLAGS_REG))])
17188    (set (match_dup 1) (match_dup 0))
17189    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17190   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17191    && peep2_reg_dead_p (4, operands[0])
17192    && !reg_overlap_mentioned_p (operands[0], operands[1])
17193    && (<MODE>mode != QImode
17194        || immediate_operand (operands[2], QImode)
17195        || q_regs_operand (operands[2], QImode))
17196    && ix86_match_ccmode (peep2_next_insn (3),
17197                          (GET_CODE (operands[3]) == PLUS
17198                           || GET_CODE (operands[3]) == MINUS)
17199                          ? CCGOCmode : CCNOmode)"
17200   [(parallel [(set (match_dup 4) (match_dup 5))
17201               (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17202                                                   (match_dup 2)]))])]
17203 {
17204   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17205   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17206                                 copy_rtx (operands[1]),
17207                                 copy_rtx (operands[2]));
17208   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17209                                  operands[5], const0_rtx);
17210 })
17211
17212 (define_peephole2
17213   [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17214                    (match_operator:SWI 2 "plusminuslogic_operator"
17215                      [(match_dup 0)
17216                       (match_operand:SWI 1 "memory_operand" "")]))
17217               (clobber (reg:CC FLAGS_REG))])
17218    (set (match_dup 1) (match_dup 0))
17219    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17220   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17221    && GET_CODE (operands[2]) != MINUS
17222    && peep2_reg_dead_p (3, operands[0])
17223    && !reg_overlap_mentioned_p (operands[0], operands[1])
17224    && ix86_match_ccmode (peep2_next_insn (2),
17225                          GET_CODE (operands[2]) == PLUS
17226                          ? CCGOCmode : CCNOmode)"
17227   [(parallel [(set (match_dup 3) (match_dup 4))
17228               (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17229                                                   (match_dup 0)]))])]
17230 {
17231   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17232   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17233                                 copy_rtx (operands[1]),
17234                                 copy_rtx (operands[0]));
17235   operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17236                                  operands[4], const0_rtx);
17237 })
17238
17239 (define_peephole2
17240   [(set (match_operand:SWI12 0 "register_operand" "")
17241         (match_operand:SWI12 1 "memory_operand" ""))
17242    (parallel [(set (match_operand:SI 4 "register_operand" "")
17243                    (match_operator:SI 3 "plusminuslogic_operator"
17244                      [(match_dup 4)
17245                       (match_operand:SI 2 "nonmemory_operand" "")]))
17246               (clobber (reg:CC FLAGS_REG))])
17247    (set (match_dup 1) (match_dup 0))
17248    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17249   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17250    && REG_P (operands[0]) && REG_P (operands[4])
17251    && REGNO (operands[0]) == REGNO (operands[4])
17252    && peep2_reg_dead_p (4, operands[0])
17253    && (<MODE>mode != QImode
17254        || immediate_operand (operands[2], SImode)
17255        || q_regs_operand (operands[2], SImode))
17256    && !reg_overlap_mentioned_p (operands[0], operands[1])
17257    && ix86_match_ccmode (peep2_next_insn (3),
17258                          (GET_CODE (operands[3]) == PLUS
17259                           || GET_CODE (operands[3]) == MINUS)
17260                          ? CCGOCmode : CCNOmode)"
17261   [(parallel [(set (match_dup 4) (match_dup 5))
17262               (set (match_dup 1) (match_dup 6))])]
17263 {
17264   operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17265   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17266   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17267                                 copy_rtx (operands[1]), operands[2]);
17268   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17269                                  operands[5], const0_rtx);
17270   operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17271                                 copy_rtx (operands[1]),
17272                                 copy_rtx (operands[2]));
17273 })
17274
17275 ;; Attempt to always use XOR for zeroing registers.
17276 (define_peephole2
17277   [(set (match_operand 0 "register_operand" "")
17278         (match_operand 1 "const0_operand" ""))]
17279   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17280    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17281    && GENERAL_REG_P (operands[0])
17282    && peep2_regno_dead_p (0, FLAGS_REG)"
17283   [(parallel [(set (match_dup 0) (const_int 0))
17284               (clobber (reg:CC FLAGS_REG))])]
17285   "operands[0] = gen_lowpart (word_mode, operands[0]);")
17286
17287 (define_peephole2
17288   [(set (strict_low_part (match_operand 0 "register_operand" ""))
17289         (const_int 0))]
17290   "(GET_MODE (operands[0]) == QImode
17291     || GET_MODE (operands[0]) == HImode)
17292    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17293    && peep2_regno_dead_p (0, FLAGS_REG)"
17294   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17295               (clobber (reg:CC FLAGS_REG))])])
17296
17297 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17298 (define_peephole2
17299   [(set (match_operand:SWI248 0 "register_operand" "")
17300         (const_int -1))]
17301   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17302    && peep2_regno_dead_p (0, FLAGS_REG)"
17303   [(parallel [(set (match_dup 0) (const_int -1))
17304               (clobber (reg:CC FLAGS_REG))])]
17305 {
17306   if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17307     operands[0] = gen_lowpart (SImode, operands[0]);
17308 })
17309
17310 ;; Attempt to convert simple lea to add/shift.
17311 ;; These can be created by move expanders.
17312
17313 (define_peephole2
17314   [(set (match_operand:SWI48 0 "register_operand" "")
17315         (plus:SWI48 (match_dup 0)
17316                     (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17317   "peep2_regno_dead_p (0, FLAGS_REG)"
17318   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17319               (clobber (reg:CC FLAGS_REG))])])
17320
17321 (define_peephole2
17322   [(set (match_operand:SI 0 "register_operand" "")
17323         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17324                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17325   "TARGET_64BIT
17326    && peep2_regno_dead_p (0, FLAGS_REG)
17327    && REGNO (operands[0]) == REGNO (operands[1])"
17328   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17329               (clobber (reg:CC FLAGS_REG))])]
17330   "operands[2] = gen_lowpart (SImode, operands[2]);")
17331
17332 (define_peephole2
17333   [(set (match_operand:SWI48 0 "register_operand" "")
17334         (mult:SWI48 (match_dup 0)
17335                     (match_operand:SWI48 1 "const_int_operand" "")))]
17336   "exact_log2 (INTVAL (operands[1])) >= 0
17337    && peep2_regno_dead_p (0, FLAGS_REG)"
17338   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17339               (clobber (reg:CC FLAGS_REG))])]
17340   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17341
17342 (define_peephole2
17343   [(set (match_operand:SI 0 "register_operand" "")
17344         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17345                    (match_operand:DI 2 "const_int_operand" "")) 0))]
17346   "TARGET_64BIT
17347    && exact_log2 (INTVAL (operands[2])) >= 0
17348    && REGNO (operands[0]) == REGNO (operands[1])
17349    && peep2_regno_dead_p (0, FLAGS_REG)"
17350   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17351               (clobber (reg:CC FLAGS_REG))])]
17352   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17353
17354 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17355 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17356 ;; On many CPUs it is also faster, since special hardware to avoid esp
17357 ;; dependencies is present.
17358
17359 ;; While some of these conversions may be done using splitters, we use
17360 ;; peepholes in order to allow combine_stack_adjustments pass to see
17361 ;; nonobfuscated RTL.
17362
17363 ;; Convert prologue esp subtractions to push.
17364 ;; We need register to push.  In order to keep verify_flow_info happy we have
17365 ;; two choices
17366 ;; - use scratch and clobber it in order to avoid dependencies
17367 ;; - use already live register
17368 ;; We can't use the second way right now, since there is no reliable way how to
17369 ;; verify that given register is live.  First choice will also most likely in
17370 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17371 ;; call clobbered registers are dead.  We may want to use base pointer as an
17372 ;; alternative when no register is available later.
17373
17374 (define_peephole2
17375   [(match_scratch:P 1 "r")
17376    (parallel [(set (reg:P SP_REG)
17377                    (plus:P (reg:P SP_REG)
17378                            (match_operand:P 0 "const_int_operand" "")))
17379               (clobber (reg:CC FLAGS_REG))
17380               (clobber (mem:BLK (scratch)))])]
17381   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17382    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17383   [(clobber (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 (define_peephole2
17388   [(match_scratch:P 1 "r")
17389    (parallel [(set (reg:P SP_REG)
17390                    (plus:P (reg:P SP_REG)
17391                            (match_operand:P 0 "const_int_operand" "")))
17392               (clobber (reg:CC FLAGS_REG))
17393               (clobber (mem:BLK (scratch)))])]
17394   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17395    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17396   [(clobber (match_dup 1))
17397    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17398    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17399               (clobber (mem:BLK (scratch)))])])
17400
17401 ;; Convert esp subtractions to push.
17402 (define_peephole2
17403   [(match_scratch:P 1 "r")
17404    (parallel [(set (reg:P SP_REG)
17405                    (plus:P (reg:P SP_REG)
17406                            (match_operand:P 0 "const_int_operand" "")))
17407               (clobber (reg:CC FLAGS_REG))])]
17408   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17409    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17410   [(clobber (match_dup 1))
17411    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17412
17413 (define_peephole2
17414   [(match_scratch:P 1 "r")
17415    (parallel [(set (reg:P SP_REG)
17416                    (plus:P (reg:P SP_REG)
17417                            (match_operand:P 0 "const_int_operand" "")))
17418               (clobber (reg:CC FLAGS_REG))])]
17419   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17420    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17421   [(clobber (match_dup 1))
17422    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17423    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17424
17425 ;; Convert epilogue deallocator to pop.
17426 (define_peephole2
17427   [(match_scratch:P 1 "r")
17428    (parallel [(set (reg:P SP_REG)
17429                    (plus:P (reg:P SP_REG)
17430                            (match_operand:P 0 "const_int_operand" "")))
17431               (clobber (reg:CC FLAGS_REG))
17432               (clobber (mem:BLK (scratch)))])]
17433   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17434    && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17435   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17436               (clobber (mem:BLK (scratch)))])])
17437
17438 ;; Two pops case is tricky, since pop causes dependency
17439 ;; on destination register.  We use two registers if available.
17440 (define_peephole2
17441   [(match_scratch:P 1 "r")
17442    (match_scratch:P 2 "r")
17443    (parallel [(set (reg:P SP_REG)
17444                    (plus:P (reg:P SP_REG)
17445                            (match_operand:P 0 "const_int_operand" "")))
17446               (clobber (reg:CC FLAGS_REG))
17447               (clobber (mem:BLK (scratch)))])]
17448   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17449    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17450   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17451               (clobber (mem:BLK (scratch)))])
17452    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17453
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               (clobber (mem:BLK (scratch)))])]
17461   "optimize_insn_for_size_p ()
17462    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17463   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17464               (clobber (mem:BLK (scratch)))])
17465    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17466
17467 ;; Convert esp additions to pop.
17468 (define_peephole2
17469   [(match_scratch:P 1 "r")
17470    (parallel [(set (reg:P SP_REG)
17471                    (plus:P (reg:P SP_REG)
17472                            (match_operand:P 0 "const_int_operand" "")))
17473               (clobber (reg:CC FLAGS_REG))])]
17474   "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17475   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17476
17477 ;; Two pops case is tricky, since pop causes dependency
17478 ;; on destination register.  We use two registers if available.
17479 (define_peephole2
17480   [(match_scratch:P 1 "r")
17481    (match_scratch:P 2 "r")
17482    (parallel [(set (reg:P SP_REG)
17483                    (plus:P (reg:P SP_REG)
17484                            (match_operand:P 0 "const_int_operand" "")))
17485               (clobber (reg:CC FLAGS_REG))])]
17486   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17487   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17488    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17489
17490 (define_peephole2
17491   [(match_scratch:P 1 "r")
17492    (parallel [(set (reg:P SP_REG)
17493                    (plus:P (reg:P SP_REG)
17494                            (match_operand:P 0 "const_int_operand" "")))
17495               (clobber (reg:CC FLAGS_REG))])]
17496   "optimize_insn_for_size_p ()
17497    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17498   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17499    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17500 \f
17501 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17502 ;; required and register dies.  Similarly for 128 to -128.
17503 (define_peephole2
17504   [(set (match_operand 0 "flags_reg_operand" "")
17505         (match_operator 1 "compare_operator"
17506           [(match_operand 2 "register_operand" "")
17507            (match_operand 3 "const_int_operand" "")]))]
17508   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17509      && incdec_operand (operands[3], GET_MODE (operands[3])))
17510     || (!TARGET_FUSE_CMP_AND_BRANCH
17511         && INTVAL (operands[3]) == 128))
17512    && ix86_match_ccmode (insn, CCGCmode)
17513    && peep2_reg_dead_p (1, operands[2])"
17514   [(parallel [(set (match_dup 0)
17515                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17516               (clobber (match_dup 2))])])
17517 \f
17518 ;; Convert imul by three, five and nine into lea
17519 (define_peephole2
17520   [(parallel
17521     [(set (match_operand:SWI48 0 "register_operand" "")
17522           (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17523                       (match_operand:SWI48 2 "const359_operand" "")))
17524      (clobber (reg:CC FLAGS_REG))])]
17525   "!TARGET_PARTIAL_REG_STALL
17526    || <MODE>mode == SImode
17527    || optimize_function_for_size_p (cfun)"
17528   [(set (match_dup 0)
17529         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17530                     (match_dup 1)))]
17531   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17532
17533 (define_peephole2
17534   [(parallel
17535     [(set (match_operand:SWI48 0 "register_operand" "")
17536           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17537                       (match_operand:SWI48 2 "const359_operand" "")))
17538      (clobber (reg:CC FLAGS_REG))])]
17539   "optimize_insn_for_speed_p ()
17540    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17541   [(set (match_dup 0) (match_dup 1))
17542    (set (match_dup 0)
17543         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17544                     (match_dup 0)))]
17545   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17546
17547 ;; imul $32bit_imm, mem, reg is vector decoded, while
17548 ;; imul $32bit_imm, reg, reg is direct decoded.
17549 (define_peephole2
17550   [(match_scratch:SWI48 3 "r")
17551    (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17552                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17553                                (match_operand:SWI48 2 "immediate_operand" "")))
17554               (clobber (reg:CC FLAGS_REG))])]
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) (mult:SWI48 (match_dup 3) (match_dup 2)))
17559               (clobber (reg:CC FLAGS_REG))])])
17560
17561 (define_peephole2
17562   [(match_scratch:SI 3 "r")
17563    (parallel [(set (match_operand:DI 0 "register_operand" "")
17564                    (zero_extend:DI
17565                      (mult:SI (match_operand:SI 1 "memory_operand" "")
17566                               (match_operand:SI 2 "immediate_operand" ""))))
17567               (clobber (reg:CC FLAGS_REG))])]
17568   "TARGET_64BIT
17569    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17570    && !satisfies_constraint_K (operands[2])"
17571   [(set (match_dup 3) (match_dup 1))
17572    (parallel [(set (match_dup 0)
17573                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17574               (clobber (reg:CC FLAGS_REG))])])
17575
17576 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17577 ;; Convert it into imul reg, reg
17578 ;; It would be better to force assembler to encode instruction using long
17579 ;; immediate, but there is apparently no way to do so.
17580 (define_peephole2
17581   [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17582                    (mult:SWI248
17583                     (match_operand:SWI248 1 "nonimmediate_operand" "")
17584                     (match_operand:SWI248 2 "const_int_operand" "")))
17585               (clobber (reg:CC FLAGS_REG))])
17586    (match_scratch:SWI248 3 "r")]
17587   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17588    && satisfies_constraint_K (operands[2])"
17589   [(set (match_dup 3) (match_dup 2))
17590    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17591               (clobber (reg:CC FLAGS_REG))])]
17592 {
17593   if (!rtx_equal_p (operands[0], operands[1]))
17594     emit_move_insn (operands[0], operands[1]);
17595 })
17596
17597 ;; After splitting up read-modify operations, array accesses with memory
17598 ;; operands might end up in form:
17599 ;;  sall    $2, %eax
17600 ;;  movl    4(%esp), %edx
17601 ;;  addl    %edx, %eax
17602 ;; instead of pre-splitting:
17603 ;;  sall    $2, %eax
17604 ;;  addl    4(%esp), %eax
17605 ;; Turn it into:
17606 ;;  movl    4(%esp), %edx
17607 ;;  leal    (%edx,%eax,4), %eax
17608
17609 (define_peephole2
17610   [(match_scratch:P 5 "r")
17611    (parallel [(set (match_operand 0 "register_operand" "")
17612                    (ashift (match_operand 1 "register_operand" "")
17613                            (match_operand 2 "const_int_operand" "")))
17614                (clobber (reg:CC FLAGS_REG))])
17615    (parallel [(set (match_operand 3 "register_operand" "")
17616                    (plus (match_dup 0)
17617                          (match_operand 4 "x86_64_general_operand" "")))
17618                    (clobber (reg:CC FLAGS_REG))])]
17619   "IN_RANGE (INTVAL (operands[2]), 1, 3)
17620    /* Validate MODE for lea.  */
17621    && ((!TARGET_PARTIAL_REG_STALL
17622         && (GET_MODE (operands[0]) == QImode
17623             || GET_MODE (operands[0]) == HImode))
17624        || GET_MODE (operands[0]) == SImode
17625        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17626    && (rtx_equal_p (operands[0], operands[3])
17627        || peep2_reg_dead_p (2, operands[0]))
17628    /* We reorder load and the shift.  */
17629    && !reg_overlap_mentioned_p (operands[0], operands[4])"
17630   [(set (match_dup 5) (match_dup 4))
17631    (set (match_dup 0) (match_dup 1))]
17632 {
17633   enum machine_mode op1mode = GET_MODE (operands[1]);
17634   enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17635   int scale = 1 << INTVAL (operands[2]);
17636   rtx index = gen_lowpart (Pmode, operands[1]);
17637   rtx base = gen_lowpart (Pmode, operands[5]);
17638   rtx dest = gen_lowpart (mode, operands[3]);
17639
17640   operands[1] = gen_rtx_PLUS (Pmode, base,
17641                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17642   operands[5] = base;
17643   if (mode != Pmode)
17644     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17645   if (op1mode != Pmode)
17646     operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17647   operands[0] = dest;
17648 })
17649 \f
17650 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17651 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17652 ;; caught for use by garbage collectors and the like.  Using an insn that
17653 ;; maps to SIGILL makes it more likely the program will rightfully die.
17654 ;; Keeping with tradition, "6" is in honor of #UD.
17655 (define_insn "trap"
17656   [(trap_if (const_int 1) (const_int 6))]
17657   ""
17658   { return ASM_SHORT "0x0b0f"; }
17659   [(set_attr "length" "2")])
17660
17661 (define_expand "prefetch"
17662   [(prefetch (match_operand 0 "address_operand" "")
17663              (match_operand:SI 1 "const_int_operand" "")
17664              (match_operand:SI 2 "const_int_operand" ""))]
17665   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17666 {
17667   int rw = INTVAL (operands[1]);
17668   int locality = INTVAL (operands[2]);
17669
17670   gcc_assert (rw == 0 || rw == 1);
17671   gcc_assert (IN_RANGE (locality, 0, 3));
17672
17673   if (TARGET_PREFETCHW && rw)
17674     operands[2] = GEN_INT (3);
17675   /* Use 3dNOW prefetch in case we are asking for write prefetch not
17676      supported by SSE counterpart or the SSE prefetch is not available
17677      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17678      of locality.  */
17679   else if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17680     operands[2] = GEN_INT (3);
17681   else
17682     operands[1] = const0_rtx;
17683 })
17684
17685 (define_insn "*prefetch_sse"
17686   [(prefetch (match_operand 0 "address_operand" "p")
17687              (const_int 0)
17688              (match_operand:SI 1 "const_int_operand" ""))]
17689   "TARGET_PREFETCH_SSE"
17690 {
17691   static const char * const patterns[4] = {
17692    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17693   };
17694
17695   int locality = INTVAL (operands[1]);
17696   gcc_assert (IN_RANGE (locality, 0, 3));
17697
17698   return patterns[locality];
17699 }
17700   [(set_attr "type" "sse")
17701    (set_attr "atom_sse_attr" "prefetch")
17702    (set (attr "length_address")
17703         (symbol_ref "memory_address_length (operands[0])"))
17704    (set_attr "memory" "none")])
17705
17706 (define_insn "*prefetch_3dnow"
17707   [(prefetch (match_operand 0 "address_operand" "p")
17708              (match_operand:SI 1 "const_int_operand" "n")
17709              (const_int 3))]
17710   "TARGET_3DNOW || TARGET_PREFETCHW"
17711 {
17712   if (INTVAL (operands[1]) == 0)
17713     return "prefetch\t%a0";
17714   else
17715     return "prefetchw\t%a0";
17716 }
17717   [(set_attr "type" "mmx")
17718    (set (attr "length_address")
17719         (symbol_ref "memory_address_length (operands[0])"))
17720    (set_attr "memory" "none")])
17721
17722 (define_expand "stack_protect_set"
17723   [(match_operand 0 "memory_operand" "")
17724    (match_operand 1 "memory_operand" "")]
17725   "!TARGET_HAS_BIONIC"
17726 {
17727   rtx (*insn)(rtx, rtx);
17728
17729 #ifdef TARGET_THREAD_SSP_OFFSET
17730   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17731   insn = (TARGET_LP64
17732           ? gen_stack_tls_protect_set_di
17733           : gen_stack_tls_protect_set_si);
17734 #else
17735   insn = (TARGET_LP64
17736           ? gen_stack_protect_set_di
17737           : gen_stack_protect_set_si);
17738 #endif
17739
17740   emit_insn (insn (operands[0], operands[1]));
17741   DONE;
17742 })
17743
17744 (define_insn "stack_protect_set_<mode>"
17745   [(set (match_operand:PTR 0 "memory_operand" "=m")
17746         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17747                     UNSPEC_SP_SET))
17748    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17749    (clobber (reg:CC FLAGS_REG))]
17750   "!TARGET_HAS_BIONIC"
17751   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17752   [(set_attr "type" "multi")])
17753
17754 (define_insn "stack_tls_protect_set_<mode>"
17755   [(set (match_operand:PTR 0 "memory_operand" "=m")
17756         (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17757                     UNSPEC_SP_TLS_SET))
17758    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17759    (clobber (reg:CC FLAGS_REG))]
17760   ""
17761   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17762   [(set_attr "type" "multi")])
17763
17764 (define_expand "stack_protect_test"
17765   [(match_operand 0 "memory_operand" "")
17766    (match_operand 1 "memory_operand" "")
17767    (match_operand 2 "" "")]
17768   "!TARGET_HAS_BIONIC"
17769 {
17770   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17771
17772   rtx (*insn)(rtx, rtx, rtx);
17773
17774 #ifdef TARGET_THREAD_SSP_OFFSET
17775   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17776   insn = (TARGET_LP64
17777           ? gen_stack_tls_protect_test_di
17778           : gen_stack_tls_protect_test_si);
17779 #else
17780   insn = (TARGET_LP64
17781           ? gen_stack_protect_test_di
17782           : gen_stack_protect_test_si);
17783 #endif
17784
17785   emit_insn (insn (flags, operands[0], operands[1]));
17786
17787   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17788                                   flags, const0_rtx, operands[2]));
17789   DONE;
17790 })
17791
17792 (define_insn "stack_protect_test_<mode>"
17793   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17794         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17795                      (match_operand:PTR 2 "memory_operand" "m")]
17796                     UNSPEC_SP_TEST))
17797    (clobber (match_scratch:PTR 3 "=&r"))]
17798   "!TARGET_HAS_BIONIC"
17799   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17800   [(set_attr "type" "multi")])
17801
17802 (define_insn "stack_tls_protect_test_<mode>"
17803   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17804         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17805                      (match_operand:PTR 2 "const_int_operand" "i")]
17806                     UNSPEC_SP_TLS_TEST))
17807    (clobber (match_scratch:PTR 3 "=r"))]
17808   ""
17809   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17810   [(set_attr "type" "multi")])
17811
17812 (define_insn "sse4_2_crc32<mode>"
17813   [(set (match_operand:SI 0 "register_operand" "=r")
17814         (unspec:SI
17815           [(match_operand:SI 1 "register_operand" "0")
17816            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17817           UNSPEC_CRC32))]
17818   "TARGET_SSE4_2 || TARGET_CRC32"
17819   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17820   [(set_attr "type" "sselog1")
17821    (set_attr "prefix_rep" "1")
17822    (set_attr "prefix_extra" "1")
17823    (set (attr "prefix_data16")
17824      (if_then_else (match_operand:HI 2 "" "")
17825        (const_string "1")
17826        (const_string "*")))
17827    (set (attr "prefix_rex")
17828      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17829        (const_string "1")
17830        (const_string "*")))
17831    (set_attr "mode" "SI")])
17832
17833 (define_insn "sse4_2_crc32di"
17834   [(set (match_operand:DI 0 "register_operand" "=r")
17835         (unspec:DI
17836           [(match_operand:DI 1 "register_operand" "0")
17837            (match_operand:DI 2 "nonimmediate_operand" "rm")]
17838           UNSPEC_CRC32))]
17839   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17840   "crc32{q}\t{%2, %0|%0, %2}"
17841   [(set_attr "type" "sselog1")
17842    (set_attr "prefix_rep" "1")
17843    (set_attr "prefix_extra" "1")
17844    (set_attr "mode" "DI")])
17845
17846 (define_expand "rdpmc"
17847   [(match_operand:DI 0 "register_operand" "")
17848    (match_operand:SI 1 "register_operand" "")]
17849   ""
17850 {
17851   rtx reg = gen_reg_rtx (DImode);
17852   rtx si;
17853
17854   /* Force operand 1 into ECX.  */
17855   rtx ecx = gen_rtx_REG (SImode, CX_REG);
17856   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17857   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17858                                 UNSPECV_RDPMC);
17859
17860   if (TARGET_64BIT)
17861     {
17862       rtvec vec = rtvec_alloc (2);
17863       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17864       rtx upper = gen_reg_rtx (DImode);
17865       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17866                                         gen_rtvec (1, const0_rtx),
17867                                         UNSPECV_RDPMC);
17868       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17869       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17870       emit_insn (load);
17871       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17872                                    NULL, 1, OPTAB_DIRECT);
17873       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17874                                  OPTAB_DIRECT);
17875     }
17876   else
17877     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17878   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17879   DONE;
17880 })
17881
17882 (define_insn "*rdpmc"
17883   [(set (match_operand:DI 0 "register_operand" "=A")
17884         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17885                             UNSPECV_RDPMC))]
17886   "!TARGET_64BIT"
17887   "rdpmc"
17888   [(set_attr "type" "other")
17889    (set_attr "length" "2")])
17890
17891 (define_insn "*rdpmc_rex64"
17892   [(set (match_operand:DI 0 "register_operand" "=a")
17893         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17894                             UNSPECV_RDPMC))
17895   (set (match_operand:DI 1 "register_operand" "=d")
17896        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17897   "TARGET_64BIT"
17898   "rdpmc"
17899   [(set_attr "type" "other")
17900    (set_attr "length" "2")])
17901
17902 (define_expand "rdtsc"
17903   [(set (match_operand:DI 0 "register_operand" "")
17904         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17905   ""
17906 {
17907   if (TARGET_64BIT)
17908     {
17909       rtvec vec = rtvec_alloc (2);
17910       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17911       rtx upper = gen_reg_rtx (DImode);
17912       rtx lower = gen_reg_rtx (DImode);
17913       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17914                                          gen_rtvec (1, const0_rtx),
17915                                          UNSPECV_RDTSC);
17916       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17917       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17918       emit_insn (load);
17919       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17920                                    NULL, 1, OPTAB_DIRECT);
17921       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17922                                    OPTAB_DIRECT);
17923       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17924       DONE;
17925     }
17926 })
17927
17928 (define_insn "*rdtsc"
17929   [(set (match_operand:DI 0 "register_operand" "=A")
17930         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17931   "!TARGET_64BIT"
17932   "rdtsc"
17933   [(set_attr "type" "other")
17934    (set_attr "length" "2")])
17935
17936 (define_insn "*rdtsc_rex64"
17937   [(set (match_operand:DI 0 "register_operand" "=a")
17938         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17939    (set (match_operand:DI 1 "register_operand" "=d")
17940         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17941   "TARGET_64BIT"
17942   "rdtsc"
17943   [(set_attr "type" "other")
17944    (set_attr "length" "2")])
17945
17946 (define_expand "rdtscp"
17947   [(match_operand:DI 0 "register_operand" "")
17948    (match_operand:SI 1 "memory_operand" "")]
17949   ""
17950 {
17951   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17952                                     gen_rtvec (1, const0_rtx),
17953                                     UNSPECV_RDTSCP);
17954   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17955                                     gen_rtvec (1, const0_rtx),
17956                                     UNSPECV_RDTSCP);
17957   rtx reg = gen_reg_rtx (DImode);
17958   rtx tmp = gen_reg_rtx (SImode);
17959
17960   if (TARGET_64BIT)
17961     {
17962       rtvec vec = rtvec_alloc (3);
17963       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17964       rtx upper = gen_reg_rtx (DImode);
17965       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17966       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17967       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17968       emit_insn (load);
17969       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17970                                    NULL, 1, OPTAB_DIRECT);
17971       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17972                                  OPTAB_DIRECT);
17973     }
17974   else
17975     {
17976       rtvec vec = rtvec_alloc (2);
17977       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17978       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17979       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17980       emit_insn (load);
17981     }
17982   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17983   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17984   DONE;
17985 })
17986
17987 (define_insn "*rdtscp"
17988   [(set (match_operand:DI 0 "register_operand" "=A")
17989         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17990    (set (match_operand:SI 1 "register_operand" "=c")
17991         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17992   "!TARGET_64BIT"
17993   "rdtscp"
17994   [(set_attr "type" "other")
17995    (set_attr "length" "3")])
17996
17997 (define_insn "*rdtscp_rex64"
17998   [(set (match_operand:DI 0 "register_operand" "=a")
17999         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18000    (set (match_operand:DI 1 "register_operand" "=d")
18001         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18002    (set (match_operand:SI 2 "register_operand" "=c")
18003         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18004   "TARGET_64BIT"
18005   "rdtscp"
18006   [(set_attr "type" "other")
18007    (set_attr "length" "3")])
18008
18009 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18010 ;;
18011 ;; LWP instructions
18012 ;;
18013 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18014
18015 (define_expand "lwp_llwpcb"
18016   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18017                     UNSPECV_LLWP_INTRINSIC)]
18018   "TARGET_LWP")
18019
18020 (define_insn "*lwp_llwpcb<mode>1"
18021   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18022                     UNSPECV_LLWP_INTRINSIC)]
18023   "TARGET_LWP"
18024   "llwpcb\t%0"
18025   [(set_attr "type" "lwp")
18026    (set_attr "mode" "<MODE>")
18027    (set_attr "length" "5")])
18028
18029 (define_expand "lwp_slwpcb"
18030   [(set (match_operand 0 "register_operand" "=r")
18031         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18032   "TARGET_LWP"
18033 {
18034   rtx (*insn)(rtx);
18035
18036   insn = (TARGET_64BIT
18037           ? gen_lwp_slwpcbdi
18038           : gen_lwp_slwpcbsi);
18039
18040   emit_insn (insn (operands[0]));
18041   DONE;
18042 })
18043
18044 (define_insn "lwp_slwpcb<mode>"
18045   [(set (match_operand:P 0 "register_operand" "=r")
18046         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18047   "TARGET_LWP"
18048   "slwpcb\t%0"
18049   [(set_attr "type" "lwp")
18050    (set_attr "mode" "<MODE>")
18051    (set_attr "length" "5")])
18052
18053 (define_expand "lwp_lwpval<mode>3"
18054   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18055                      (match_operand:SI 2 "nonimmediate_operand" "rm")
18056                      (match_operand:SI 3 "const_int_operand" "i")]
18057                     UNSPECV_LWPVAL_INTRINSIC)]
18058   "TARGET_LWP"
18059   ;; Avoid unused variable warning.
18060   "(void) operands[0];")
18061
18062 (define_insn "*lwp_lwpval<mode>3_1"
18063   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18064                      (match_operand:SI 1 "nonimmediate_operand" "rm")
18065                      (match_operand:SI 2 "const_int_operand" "i")]
18066                     UNSPECV_LWPVAL_INTRINSIC)]
18067   "TARGET_LWP"
18068   "lwpval\t{%2, %1, %0|%0, %1, %2}"
18069   [(set_attr "type" "lwp")
18070    (set_attr "mode" "<MODE>")
18071    (set (attr "length")
18072         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18073
18074 (define_expand "lwp_lwpins<mode>3"
18075   [(set (reg:CCC FLAGS_REG)
18076         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18077                               (match_operand:SI 2 "nonimmediate_operand" "rm")
18078                               (match_operand:SI 3 "const_int_operand" "i")]
18079                              UNSPECV_LWPINS_INTRINSIC))
18080    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18081         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18082   "TARGET_LWP")
18083
18084 (define_insn "*lwp_lwpins<mode>3_1"
18085   [(set (reg:CCC FLAGS_REG)
18086         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18087                               (match_operand:SI 1 "nonimmediate_operand" "rm")
18088                               (match_operand:SI 2 "const_int_operand" "i")]
18089                              UNSPECV_LWPINS_INTRINSIC))]
18090   "TARGET_LWP"
18091   "lwpins\t{%2, %1, %0|%0, %1, %2}"
18092   [(set_attr "type" "lwp")
18093    (set_attr "mode" "<MODE>")
18094    (set (attr "length")
18095         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18096
18097 (define_insn "rdfsbase<mode>"
18098   [(set (match_operand:SWI48 0 "register_operand" "=r")
18099         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18100   "TARGET_64BIT && TARGET_FSGSBASE"
18101   "rdfsbase %0"
18102   [(set_attr "type" "other")
18103    (set_attr "prefix_extra" "2")])
18104
18105 (define_insn "rdgsbase<mode>"
18106   [(set (match_operand:SWI48 0 "register_operand" "=r")
18107         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18108   "TARGET_64BIT && TARGET_FSGSBASE"
18109   "rdgsbase %0"
18110   [(set_attr "type" "other")
18111    (set_attr "prefix_extra" "2")])
18112
18113 (define_insn "wrfsbase<mode>"
18114   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18115                     UNSPECV_WRFSBASE)]
18116   "TARGET_64BIT && TARGET_FSGSBASE"
18117   "wrfsbase %0"
18118   [(set_attr "type" "other")
18119    (set_attr "prefix_extra" "2")])
18120
18121 (define_insn "wrgsbase<mode>"
18122   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18123                     UNSPECV_WRGSBASE)]
18124   "TARGET_64BIT && TARGET_FSGSBASE"
18125   "wrgsbase %0"
18126   [(set_attr "type" "other")
18127    (set_attr "prefix_extra" "2")])
18128
18129 (define_insn "rdrand<mode>_1"
18130   [(set (match_operand:SWI248 0 "register_operand" "=r")
18131         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18132    (set (reg:CCC FLAGS_REG)
18133         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18134   "TARGET_RDRND"
18135   "rdrand\t%0"
18136   [(set_attr "type" "other")
18137    (set_attr "prefix_extra" "1")])
18138
18139 (define_expand "pause"
18140   [(set (match_dup 0)
18141         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18142   ""
18143 {
18144   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18145   MEM_VOLATILE_P (operands[0]) = 1;
18146 })
18147
18148 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18149 ;; They have the same encoding.
18150 (define_insn "*pause"
18151   [(set (match_operand:BLK 0 "" "")
18152         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18153   ""
18154   "rep; nop"
18155   [(set_attr "length" "2")
18156    (set_attr "memory" "unknown")])
18157
18158 (include "mmx.md")
18159 (include "sse.md")
18160 (include "sync.md")