Merge branch 'vendor/GDB'
[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,fma4,fma"
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" "fma4") (symbol_ref "TARGET_FMA4")
647          (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
648         ]
649         (const_int 1)))
650
651 ;; Describe a user's asm statement.
652 (define_asm_attributes
653   [(set_attr "length" "128")
654    (set_attr "type" "multi")])
655
656 (define_code_iterator plusminus [plus minus])
657
658 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
659
660 ;; Base name for define_insn
661 (define_code_attr plusminus_insn
662   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
663    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
664
665 ;; Base name for insn mnemonic.
666 (define_code_attr plusminus_mnemonic
667   [(plus "add") (ss_plus "adds") (us_plus "addus")
668    (minus "sub") (ss_minus "subs") (us_minus "subus")])
669 (define_code_attr plusminus_carry_mnemonic
670   [(plus "adc") (minus "sbb")])
671
672 ;; Mark commutative operators as such in constraints.
673 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
674                         (minus "") (ss_minus "") (us_minus "")])
675
676 ;; Mapping of max and min
677 (define_code_iterator maxmin [smax smin umax umin])
678
679 ;; Mapping of signed max and min
680 (define_code_iterator smaxmin [smax smin])
681
682 ;; Mapping of unsigned max and min
683 (define_code_iterator umaxmin [umax umin])
684
685 ;; Base name for integer and FP insn mnemonic
686 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
687                               (umax "maxu") (umin "minu")])
688 (define_code_attr maxmin_float [(smax "max") (smin "min")])
689
690 ;; Mapping of logic operators
691 (define_code_iterator any_logic [and ior xor])
692 (define_code_iterator any_or [ior xor])
693
694 ;; Base name for insn mnemonic.
695 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
696
697 ;; Mapping of logic-shift operators
698 (define_code_iterator any_lshift [ashift lshiftrt])
699
700 ;; Mapping of shift-right operators
701 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
702
703 ;; Base name for define_insn
704 (define_code_attr shift_insn
705   [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
706
707 ;; Base name for insn mnemonic.
708 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
709 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
710
711 ;; Mapping of rotate operators
712 (define_code_iterator any_rotate [rotate rotatert])
713
714 ;; Base name for define_insn
715 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
716
717 ;; Base name for insn mnemonic.
718 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
719
720 ;; Mapping of abs neg operators
721 (define_code_iterator absneg [abs neg])
722
723 ;; Base name for x87 insn mnemonic.
724 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
725
726 ;; Used in signed and unsigned widening multiplications.
727 (define_code_iterator any_extend [sign_extend zero_extend])
728
729 ;; Prefix for insn menmonic.
730 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
731
732 ;; Prefix for define_insn
733 (define_code_attr u [(sign_extend "") (zero_extend "u")])
734 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
735
736 ;; All integer modes.
737 (define_mode_iterator SWI1248x [QI HI SI DI])
738
739 ;; All integer modes without QImode.
740 (define_mode_iterator SWI248x [HI SI DI])
741
742 ;; All integer modes without QImode and HImode.
743 (define_mode_iterator SWI48x [SI DI])
744
745 ;; All integer modes without SImode and DImode.
746 (define_mode_iterator SWI12 [QI HI])
747
748 ;; All integer modes without DImode.
749 (define_mode_iterator SWI124 [QI HI SI])
750
751 ;; All integer modes without QImode and DImode.
752 (define_mode_iterator SWI24 [HI SI])
753
754 ;; Single word integer modes.
755 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
756
757 ;; Single word integer modes without QImode.
758 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
759
760 ;; Single word integer modes without QImode and HImode.
761 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
762
763 ;; All math-dependant single and double word integer modes.
764 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
765                              (HI "TARGET_HIMODE_MATH")
766                              SI DI (TI "TARGET_64BIT")])
767
768 ;; Math-dependant single word integer modes.
769 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
770                             (HI "TARGET_HIMODE_MATH")
771                             SI (DI "TARGET_64BIT")])
772
773 ;; Math-dependant integer modes without DImode.
774 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
775                                (HI "TARGET_HIMODE_MATH")
776                                SI])
777
778 ;; Math-dependant single word integer modes without QImode.
779 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
780                                SI (DI "TARGET_64BIT")])
781
782 ;; Double word integer modes.
783 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
784                            (TI "TARGET_64BIT")])
785
786 ;; Double word integer modes as mode attribute.
787 (define_mode_attr DWI [(SI "DI") (DI "TI")])
788 (define_mode_attr dwi [(SI "di") (DI "ti")])
789
790 ;; Half mode for double word integer modes.
791 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
792                             (DI "TARGET_64BIT")])
793
794 ;; Instruction suffix for integer modes.
795 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
796
797 ;; Pointer size prefix for integer modes (Intel asm dialect)
798 (define_mode_attr iptrsize [(QI "BYTE")
799                             (HI "WORD")
800                             (SI "DWORD")
801                             (DI "QWORD")])
802
803 ;; Register class for integer modes.
804 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
805
806 ;; Immediate operand constraint for integer modes.
807 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
808
809 ;; General operand constraint for word modes.
810 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
811
812 ;; Immediate operand constraint for double integer modes.
813 (define_mode_attr di [(SI "nF") (DI "e")])
814
815 ;; Immediate operand constraint for shifts.
816 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
817
818 ;; General operand predicate for integer modes.
819 (define_mode_attr general_operand
820         [(QI "general_operand")
821          (HI "general_operand")
822          (SI "x86_64_general_operand")
823          (DI "x86_64_general_operand")
824          (TI "x86_64_general_operand")])
825
826 ;; General sign/zero extend operand predicate for integer modes.
827 (define_mode_attr general_szext_operand
828         [(QI "general_operand")
829          (HI "general_operand")
830          (SI "x86_64_szext_general_operand")
831          (DI "x86_64_szext_general_operand")])
832
833 ;; Immediate operand predicate for integer modes.
834 (define_mode_attr immediate_operand
835         [(QI "immediate_operand")
836          (HI "immediate_operand")
837          (SI "x86_64_immediate_operand")
838          (DI "x86_64_immediate_operand")])
839
840 ;; Nonmemory operand predicate for integer modes.
841 (define_mode_attr nonmemory_operand
842         [(QI "nonmemory_operand")
843          (HI "nonmemory_operand")
844          (SI "x86_64_nonmemory_operand")
845          (DI "x86_64_nonmemory_operand")])
846
847 ;; Operand predicate for shifts.
848 (define_mode_attr shift_operand
849         [(QI "nonimmediate_operand")
850          (HI "nonimmediate_operand")
851          (SI "nonimmediate_operand")
852          (DI "shiftdi_operand")
853          (TI "register_operand")])
854
855 ;; Operand predicate for shift argument.
856 (define_mode_attr shift_immediate_operand
857         [(QI "const_1_to_31_operand")
858          (HI "const_1_to_31_operand")
859          (SI "const_1_to_31_operand")
860          (DI "const_1_to_63_operand")])
861
862 ;; Input operand predicate for arithmetic left shifts.
863 (define_mode_attr ashl_input_operand
864         [(QI "nonimmediate_operand")
865          (HI "nonimmediate_operand")
866          (SI "nonimmediate_operand")
867          (DI "ashldi_input_operand")
868          (TI "reg_or_pm1_operand")])
869
870 ;; SSE and x87 SFmode and DFmode floating point modes
871 (define_mode_iterator MODEF [SF DF])
872
873 ;; All x87 floating point modes
874 (define_mode_iterator X87MODEF [SF DF XF])
875
876 ;; SSE instruction suffix for various modes
877 (define_mode_attr ssemodesuffix
878   [(SF "ss") (DF "sd")
879    (V8SF "ps") (V4DF "pd")
880    (V4SF "ps") (V2DF "pd")
881    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
882    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
883
884 ;; SSE vector suffix for floating point modes
885 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
886
887 ;; SSE vector mode corresponding to a scalar mode
888 (define_mode_attr ssevecmode
889   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
890
891 ;; Instruction suffix for REX 64bit operators.
892 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
893
894 ;; This mode iterator allows :P to be used for patterns that operate on
895 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
896 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
897
898 ;; This mode iterator allows :PTR to be used for patterns that operate on
899 ;; ptr_mode sized quantities.
900 (define_mode_iterator PTR
901   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
902 \f
903 ;; Scheduling descriptions
904
905 (include "pentium.md")
906 (include "ppro.md")
907 (include "k6.md")
908 (include "athlon.md")
909 (include "bdver1.md")
910 (include "geode.md")
911 (include "atom.md")
912 (include "core2.md")
913
914 \f
915 ;; Operand and operator predicates and constraints
916
917 (include "predicates.md")
918 (include "constraints.md")
919
920 \f
921 ;; Compare and branch/compare and store instructions.
922
923 (define_expand "cbranch<mode>4"
924   [(set (reg:CC FLAGS_REG)
925         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
926                     (match_operand:SDWIM 2 "<general_operand>" "")))
927    (set (pc) (if_then_else
928                (match_operator 0 "ordered_comparison_operator"
929                 [(reg:CC FLAGS_REG) (const_int 0)])
930                (label_ref (match_operand 3 "" ""))
931                (pc)))]
932   ""
933 {
934   if (MEM_P (operands[1]) && MEM_P (operands[2]))
935     operands[1] = force_reg (<MODE>mode, operands[1]);
936   ix86_expand_branch (GET_CODE (operands[0]),
937                       operands[1], operands[2], operands[3]);
938   DONE;
939 })
940
941 (define_expand "cstore<mode>4"
942   [(set (reg:CC FLAGS_REG)
943         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
944                     (match_operand:SWIM 3 "<general_operand>" "")))
945    (set (match_operand:QI 0 "register_operand" "")
946         (match_operator 1 "ordered_comparison_operator"
947           [(reg:CC FLAGS_REG) (const_int 0)]))]
948   ""
949 {
950   if (MEM_P (operands[2]) && MEM_P (operands[3]))
951     operands[2] = force_reg (<MODE>mode, operands[2]);
952   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
953                      operands[2], operands[3]);
954   DONE;
955 })
956
957 (define_expand "cmp<mode>_1"
958   [(set (reg:CC FLAGS_REG)
959         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
960                     (match_operand:SWI48 1 "<general_operand>" "")))])
961
962 (define_insn "*cmp<mode>_ccno_1"
963   [(set (reg FLAGS_REG)
964         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
965                  (match_operand:SWI 1 "const0_operand" "")))]
966   "ix86_match_ccmode (insn, CCNOmode)"
967   "@
968    test{<imodesuffix>}\t%0, %0
969    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
970   [(set_attr "type" "test,icmp")
971    (set_attr "length_immediate" "0,1")
972    (set_attr "mode" "<MODE>")])
973
974 (define_insn "*cmp<mode>_1"
975   [(set (reg FLAGS_REG)
976         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
977                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
978   "ix86_match_ccmode (insn, CCmode)"
979   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
980   [(set_attr "type" "icmp")
981    (set_attr "mode" "<MODE>")])
982
983 (define_insn "*cmp<mode>_minus_1"
984   [(set (reg FLAGS_REG)
985         (compare
986           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
987                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
988           (const_int 0)))]
989   "ix86_match_ccmode (insn, CCGOCmode)"
990   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
991   [(set_attr "type" "icmp")
992    (set_attr "mode" "<MODE>")])
993
994 (define_insn "*cmpqi_ext_1"
995   [(set (reg FLAGS_REG)
996         (compare
997           (match_operand:QI 0 "general_operand" "Qm")
998           (subreg:QI
999             (zero_extract:SI
1000               (match_operand 1 "ext_register_operand" "Q")
1001               (const_int 8)
1002               (const_int 8)) 0)))]
1003   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1004   "cmp{b}\t{%h1, %0|%0, %h1}"
1005   [(set_attr "type" "icmp")
1006    (set_attr "mode" "QI")])
1007
1008 (define_insn "*cmpqi_ext_1_rex64"
1009   [(set (reg FLAGS_REG)
1010         (compare
1011           (match_operand:QI 0 "register_operand" "Q")
1012           (subreg:QI
1013             (zero_extract:SI
1014               (match_operand 1 "ext_register_operand" "Q")
1015               (const_int 8)
1016               (const_int 8)) 0)))]
1017   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1018   "cmp{b}\t{%h1, %0|%0, %h1}"
1019   [(set_attr "type" "icmp")
1020    (set_attr "mode" "QI")])
1021
1022 (define_insn "*cmpqi_ext_2"
1023   [(set (reg FLAGS_REG)
1024         (compare
1025           (subreg:QI
1026             (zero_extract:SI
1027               (match_operand 0 "ext_register_operand" "Q")
1028               (const_int 8)
1029               (const_int 8)) 0)
1030           (match_operand:QI 1 "const0_operand" "")))]
1031   "ix86_match_ccmode (insn, CCNOmode)"
1032   "test{b}\t%h0, %h0"
1033   [(set_attr "type" "test")
1034    (set_attr "length_immediate" "0")
1035    (set_attr "mode" "QI")])
1036
1037 (define_expand "cmpqi_ext_3"
1038   [(set (reg:CC FLAGS_REG)
1039         (compare:CC
1040           (subreg:QI
1041             (zero_extract:SI
1042               (match_operand 0 "ext_register_operand" "")
1043               (const_int 8)
1044               (const_int 8)) 0)
1045           (match_operand:QI 1 "immediate_operand" "")))])
1046
1047 (define_insn "*cmpqi_ext_3_insn"
1048   [(set (reg FLAGS_REG)
1049         (compare
1050           (subreg:QI
1051             (zero_extract:SI
1052               (match_operand 0 "ext_register_operand" "Q")
1053               (const_int 8)
1054               (const_int 8)) 0)
1055           (match_operand:QI 1 "general_operand" "Qmn")))]
1056   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1057   "cmp{b}\t{%1, %h0|%h0, %1}"
1058   [(set_attr "type" "icmp")
1059    (set_attr "modrm" "1")
1060    (set_attr "mode" "QI")])
1061
1062 (define_insn "*cmpqi_ext_3_insn_rex64"
1063   [(set (reg FLAGS_REG)
1064         (compare
1065           (subreg:QI
1066             (zero_extract:SI
1067               (match_operand 0 "ext_register_operand" "Q")
1068               (const_int 8)
1069               (const_int 8)) 0)
1070           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1071   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1072   "cmp{b}\t{%1, %h0|%h0, %1}"
1073   [(set_attr "type" "icmp")
1074    (set_attr "modrm" "1")
1075    (set_attr "mode" "QI")])
1076
1077 (define_insn "*cmpqi_ext_4"
1078   [(set (reg FLAGS_REG)
1079         (compare
1080           (subreg:QI
1081             (zero_extract:SI
1082               (match_operand 0 "ext_register_operand" "Q")
1083               (const_int 8)
1084               (const_int 8)) 0)
1085           (subreg:QI
1086             (zero_extract:SI
1087               (match_operand 1 "ext_register_operand" "Q")
1088               (const_int 8)
1089               (const_int 8)) 0)))]
1090   "ix86_match_ccmode (insn, CCmode)"
1091   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1092   [(set_attr "type" "icmp")
1093    (set_attr "mode" "QI")])
1094
1095 ;; These implement float point compares.
1096 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1097 ;; which would allow mix and match FP modes on the compares.  Which is what
1098 ;; the old patterns did, but with many more of them.
1099
1100 (define_expand "cbranchxf4"
1101   [(set (reg:CC FLAGS_REG)
1102         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1103                     (match_operand:XF 2 "nonmemory_operand" "")))
1104    (set (pc) (if_then_else
1105               (match_operator 0 "ix86_fp_comparison_operator"
1106                [(reg:CC FLAGS_REG)
1107                 (const_int 0)])
1108               (label_ref (match_operand 3 "" ""))
1109               (pc)))]
1110   "TARGET_80387"
1111 {
1112   ix86_expand_branch (GET_CODE (operands[0]),
1113                       operands[1], operands[2], operands[3]);
1114   DONE;
1115 })
1116
1117 (define_expand "cstorexf4"
1118   [(set (reg:CC FLAGS_REG)
1119         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1120                     (match_operand:XF 3 "nonmemory_operand" "")))
1121    (set (match_operand:QI 0 "register_operand" "")
1122               (match_operator 1 "ix86_fp_comparison_operator"
1123                [(reg:CC FLAGS_REG)
1124                 (const_int 0)]))]
1125   "TARGET_80387"
1126 {
1127   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1128                      operands[2], operands[3]);
1129   DONE;
1130 })
1131
1132 (define_expand "cbranch<mode>4"
1133   [(set (reg:CC FLAGS_REG)
1134         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1135                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1136    (set (pc) (if_then_else
1137               (match_operator 0 "ix86_fp_comparison_operator"
1138                [(reg:CC FLAGS_REG)
1139                 (const_int 0)])
1140               (label_ref (match_operand 3 "" ""))
1141               (pc)))]
1142   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1143 {
1144   ix86_expand_branch (GET_CODE (operands[0]),
1145                       operands[1], operands[2], operands[3]);
1146   DONE;
1147 })
1148
1149 (define_expand "cstore<mode>4"
1150   [(set (reg:CC FLAGS_REG)
1151         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1152                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1153    (set (match_operand:QI 0 "register_operand" "")
1154               (match_operator 1 "ix86_fp_comparison_operator"
1155                [(reg:CC FLAGS_REG)
1156                 (const_int 0)]))]
1157   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1158 {
1159   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1160                      operands[2], operands[3]);
1161   DONE;
1162 })
1163
1164 (define_expand "cbranchcc4"
1165   [(set (pc) (if_then_else
1166               (match_operator 0 "comparison_operator"
1167                [(match_operand 1 "flags_reg_operand" "")
1168                 (match_operand 2 "const0_operand" "")])
1169               (label_ref (match_operand 3 "" ""))
1170               (pc)))]
1171   ""
1172 {
1173   ix86_expand_branch (GET_CODE (operands[0]),
1174                       operands[1], operands[2], operands[3]);
1175   DONE;
1176 })
1177
1178 (define_expand "cstorecc4"
1179   [(set (match_operand:QI 0 "register_operand" "")
1180               (match_operator 1 "comparison_operator"
1181                [(match_operand 2 "flags_reg_operand" "")
1182                 (match_operand 3 "const0_operand" "")]))]
1183   ""
1184 {
1185   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1186                      operands[2], operands[3]);
1187   DONE;
1188 })
1189
1190
1191 ;; FP compares, step 1:
1192 ;; Set the FP condition codes.
1193 ;;
1194 ;; CCFPmode     compare with exceptions
1195 ;; CCFPUmode    compare with no exceptions
1196
1197 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1198 ;; used to manage the reg stack popping would not be preserved.
1199
1200 (define_insn "*cmpfp_0"
1201   [(set (match_operand:HI 0 "register_operand" "=a")
1202         (unspec:HI
1203           [(compare:CCFP
1204              (match_operand 1 "register_operand" "f")
1205              (match_operand 2 "const0_operand" ""))]
1206         UNSPEC_FNSTSW))]
1207   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1208    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1209   "* return output_fp_compare (insn, operands, false, false);"
1210   [(set_attr "type" "multi")
1211    (set_attr "unit" "i387")
1212    (set (attr "mode")
1213      (cond [(match_operand:SF 1 "" "")
1214               (const_string "SF")
1215             (match_operand:DF 1 "" "")
1216               (const_string "DF")
1217            ]
1218            (const_string "XF")))])
1219
1220 (define_insn_and_split "*cmpfp_0_cc"
1221   [(set (reg:CCFP FLAGS_REG)
1222         (compare:CCFP
1223           (match_operand 1 "register_operand" "f")
1224           (match_operand 2 "const0_operand" "")))
1225    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1226   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1227    && TARGET_SAHF && !TARGET_CMOVE
1228    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1229   "#"
1230   "&& reload_completed"
1231   [(set (match_dup 0)
1232         (unspec:HI
1233           [(compare:CCFP (match_dup 1)(match_dup 2))]
1234         UNSPEC_FNSTSW))
1235    (set (reg:CC FLAGS_REG)
1236         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1237   ""
1238   [(set_attr "type" "multi")
1239    (set_attr "unit" "i387")
1240    (set (attr "mode")
1241      (cond [(match_operand:SF 1 "" "")
1242               (const_string "SF")
1243             (match_operand:DF 1 "" "")
1244               (const_string "DF")
1245            ]
1246            (const_string "XF")))])
1247
1248 (define_insn "*cmpfp_xf"
1249   [(set (match_operand:HI 0 "register_operand" "=a")
1250         (unspec:HI
1251           [(compare:CCFP
1252              (match_operand:XF 1 "register_operand" "f")
1253              (match_operand:XF 2 "register_operand" "f"))]
1254           UNSPEC_FNSTSW))]
1255   "TARGET_80387"
1256   "* return output_fp_compare (insn, operands, false, false);"
1257   [(set_attr "type" "multi")
1258    (set_attr "unit" "i387")
1259    (set_attr "mode" "XF")])
1260
1261 (define_insn_and_split "*cmpfp_xf_cc"
1262   [(set (reg:CCFP FLAGS_REG)
1263         (compare:CCFP
1264           (match_operand:XF 1 "register_operand" "f")
1265           (match_operand:XF 2 "register_operand" "f")))
1266    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1267   "TARGET_80387
1268    && TARGET_SAHF && !TARGET_CMOVE"
1269   "#"
1270   "&& reload_completed"
1271   [(set (match_dup 0)
1272         (unspec:HI
1273           [(compare:CCFP (match_dup 1)(match_dup 2))]
1274         UNSPEC_FNSTSW))
1275    (set (reg:CC FLAGS_REG)
1276         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1277   ""
1278   [(set_attr "type" "multi")
1279    (set_attr "unit" "i387")
1280    (set_attr "mode" "XF")])
1281
1282 (define_insn "*cmpfp_<mode>"
1283   [(set (match_operand:HI 0 "register_operand" "=a")
1284         (unspec:HI
1285           [(compare:CCFP
1286              (match_operand:MODEF 1 "register_operand" "f")
1287              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1288           UNSPEC_FNSTSW))]
1289   "TARGET_80387"
1290   "* return output_fp_compare (insn, operands, false, false);"
1291   [(set_attr "type" "multi")
1292    (set_attr "unit" "i387")
1293    (set_attr "mode" "<MODE>")])
1294
1295 (define_insn_and_split "*cmpfp_<mode>_cc"
1296   [(set (reg:CCFP FLAGS_REG)
1297         (compare:CCFP
1298           (match_operand:MODEF 1 "register_operand" "f")
1299           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1300    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1301   "TARGET_80387
1302    && TARGET_SAHF && !TARGET_CMOVE"
1303   "#"
1304   "&& reload_completed"
1305   [(set (match_dup 0)
1306         (unspec:HI
1307           [(compare:CCFP (match_dup 1)(match_dup 2))]
1308         UNSPEC_FNSTSW))
1309    (set (reg:CC FLAGS_REG)
1310         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1311   ""
1312   [(set_attr "type" "multi")
1313    (set_attr "unit" "i387")
1314    (set_attr "mode" "<MODE>")])
1315
1316 (define_insn "*cmpfp_u"
1317   [(set (match_operand:HI 0 "register_operand" "=a")
1318         (unspec:HI
1319           [(compare:CCFPU
1320              (match_operand 1 "register_operand" "f")
1321              (match_operand 2 "register_operand" "f"))]
1322           UNSPEC_FNSTSW))]
1323   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1324    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1325   "* return output_fp_compare (insn, operands, false, true);"
1326   [(set_attr "type" "multi")
1327    (set_attr "unit" "i387")
1328    (set (attr "mode")
1329      (cond [(match_operand:SF 1 "" "")
1330               (const_string "SF")
1331             (match_operand:DF 1 "" "")
1332               (const_string "DF")
1333            ]
1334            (const_string "XF")))])
1335
1336 (define_insn_and_split "*cmpfp_u_cc"
1337   [(set (reg:CCFPU FLAGS_REG)
1338         (compare:CCFPU
1339           (match_operand 1 "register_operand" "f")
1340           (match_operand 2 "register_operand" "f")))
1341    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1342   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1343    && TARGET_SAHF && !TARGET_CMOVE
1344    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1345   "#"
1346   "&& reload_completed"
1347   [(set (match_dup 0)
1348         (unspec:HI
1349           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1350         UNSPEC_FNSTSW))
1351    (set (reg:CC FLAGS_REG)
1352         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1353   ""
1354   [(set_attr "type" "multi")
1355    (set_attr "unit" "i387")
1356    (set (attr "mode")
1357      (cond [(match_operand:SF 1 "" "")
1358               (const_string "SF")
1359             (match_operand:DF 1 "" "")
1360               (const_string "DF")
1361            ]
1362            (const_string "XF")))])
1363
1364 (define_insn "*cmpfp_<mode>"
1365   [(set (match_operand:HI 0 "register_operand" "=a")
1366         (unspec:HI
1367           [(compare:CCFP
1368              (match_operand 1 "register_operand" "f")
1369              (match_operator 3 "float_operator"
1370                [(match_operand:SWI24 2 "memory_operand" "m")]))]
1371           UNSPEC_FNSTSW))]
1372   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1373    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1374    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1375   "* return output_fp_compare (insn, operands, false, false);"
1376   [(set_attr "type" "multi")
1377    (set_attr "unit" "i387")
1378    (set_attr "fp_int_src" "true")
1379    (set_attr "mode" "<MODE>")])
1380
1381 (define_insn_and_split "*cmpfp_<mode>_cc"
1382   [(set (reg:CCFP FLAGS_REG)
1383         (compare:CCFP
1384           (match_operand 1 "register_operand" "f")
1385           (match_operator 3 "float_operator"
1386             [(match_operand:SWI24 2 "memory_operand" "m")])))
1387    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1388   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1389    && TARGET_SAHF && !TARGET_CMOVE
1390    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1391    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1392   "#"
1393   "&& reload_completed"
1394   [(set (match_dup 0)
1395         (unspec:HI
1396           [(compare:CCFP
1397              (match_dup 1)
1398              (match_op_dup 3 [(match_dup 2)]))]
1399         UNSPEC_FNSTSW))
1400    (set (reg:CC FLAGS_REG)
1401         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1402   ""
1403   [(set_attr "type" "multi")
1404    (set_attr "unit" "i387")
1405    (set_attr "fp_int_src" "true")
1406    (set_attr "mode" "<MODE>")])
1407
1408 ;; FP compares, step 2
1409 ;; Move the fpsw to ax.
1410
1411 (define_insn "x86_fnstsw_1"
1412   [(set (match_operand:HI 0 "register_operand" "=a")
1413         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1414   "TARGET_80387"
1415   "fnstsw\t%0"
1416   [(set (attr "length")
1417         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1418    (set_attr "mode" "SI")
1419    (set_attr "unit" "i387")])
1420
1421 ;; FP compares, step 3
1422 ;; Get ax into flags, general case.
1423
1424 (define_insn "x86_sahf_1"
1425   [(set (reg:CC FLAGS_REG)
1426         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1427                    UNSPEC_SAHF))]
1428   "TARGET_SAHF"
1429 {
1430 #ifndef HAVE_AS_IX86_SAHF
1431   if (TARGET_64BIT)
1432     return ASM_BYTE "0x9e";
1433   else
1434 #endif
1435   return "sahf";
1436 }
1437   [(set_attr "length" "1")
1438    (set_attr "athlon_decode" "vector")
1439    (set_attr "amdfam10_decode" "direct")
1440    (set_attr "bdver1_decode" "direct")
1441    (set_attr "mode" "SI")])
1442
1443 ;; Pentium Pro can do steps 1 through 3 in one go.
1444 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1445 ;; (these i387 instructions set flags directly)
1446 (define_insn "*cmpfp_i_mixed"
1447   [(set (reg:CCFP FLAGS_REG)
1448         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1449                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1450   "TARGET_MIX_SSE_I387
1451    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1452    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1453   "* return output_fp_compare (insn, operands, true, false);"
1454   [(set_attr "type" "fcmp,ssecomi")
1455    (set_attr "prefix" "orig,maybe_vex")
1456    (set (attr "mode")
1457      (if_then_else (match_operand:SF 1 "" "")
1458         (const_string "SF")
1459         (const_string "DF")))
1460    (set (attr "prefix_rep")
1461         (if_then_else (eq_attr "type" "ssecomi")
1462                       (const_string "0")
1463                       (const_string "*")))
1464    (set (attr "prefix_data16")
1465         (cond [(eq_attr "type" "fcmp")
1466                  (const_string "*")
1467                (eq_attr "mode" "DF")
1468                  (const_string "1")
1469               ]
1470               (const_string "0")))
1471    (set_attr "athlon_decode" "vector")
1472    (set_attr "amdfam10_decode" "direct")
1473    (set_attr "bdver1_decode" "double")])
1474
1475 (define_insn "*cmpfp_i_sse"
1476   [(set (reg:CCFP FLAGS_REG)
1477         (compare:CCFP (match_operand 0 "register_operand" "x")
1478                       (match_operand 1 "nonimmediate_operand" "xm")))]
1479   "TARGET_SSE_MATH
1480    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1481    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1482   "* return output_fp_compare (insn, operands, true, false);"
1483   [(set_attr "type" "ssecomi")
1484    (set_attr "prefix" "maybe_vex")
1485    (set (attr "mode")
1486      (if_then_else (match_operand:SF 1 "" "")
1487         (const_string "SF")
1488         (const_string "DF")))
1489    (set_attr "prefix_rep" "0")
1490    (set (attr "prefix_data16")
1491         (if_then_else (eq_attr "mode" "DF")
1492                       (const_string "1")
1493                       (const_string "0")))
1494    (set_attr "athlon_decode" "vector")
1495    (set_attr "amdfam10_decode" "direct")
1496    (set_attr "bdver1_decode" "double")])
1497
1498 (define_insn "*cmpfp_i_i387"
1499   [(set (reg:CCFP FLAGS_REG)
1500         (compare:CCFP (match_operand 0 "register_operand" "f")
1501                       (match_operand 1 "register_operand" "f")))]
1502   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1503    && TARGET_CMOVE
1504    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1505    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1506   "* return output_fp_compare (insn, operands, true, false);"
1507   [(set_attr "type" "fcmp")
1508    (set (attr "mode")
1509      (cond [(match_operand:SF 1 "" "")
1510               (const_string "SF")
1511             (match_operand:DF 1 "" "")
1512               (const_string "DF")
1513            ]
1514            (const_string "XF")))
1515    (set_attr "athlon_decode" "vector")
1516    (set_attr "amdfam10_decode" "direct")
1517    (set_attr "bdver1_decode" "double")])
1518
1519 (define_insn "*cmpfp_iu_mixed"
1520   [(set (reg:CCFPU FLAGS_REG)
1521         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1522                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1523   "TARGET_MIX_SSE_I387
1524    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1525    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1526   "* return output_fp_compare (insn, operands, true, true);"
1527   [(set_attr "type" "fcmp,ssecomi")
1528    (set_attr "prefix" "orig,maybe_vex")
1529    (set (attr "mode")
1530      (if_then_else (match_operand:SF 1 "" "")
1531         (const_string "SF")
1532         (const_string "DF")))
1533    (set (attr "prefix_rep")
1534         (if_then_else (eq_attr "type" "ssecomi")
1535                       (const_string "0")
1536                       (const_string "*")))
1537    (set (attr "prefix_data16")
1538         (cond [(eq_attr "type" "fcmp")
1539                  (const_string "*")
1540                (eq_attr "mode" "DF")
1541                  (const_string "1")
1542               ]
1543               (const_string "0")))
1544    (set_attr "athlon_decode" "vector")
1545    (set_attr "amdfam10_decode" "direct")
1546    (set_attr "bdver1_decode" "double")])
1547
1548 (define_insn "*cmpfp_iu_sse"
1549   [(set (reg:CCFPU FLAGS_REG)
1550         (compare:CCFPU (match_operand 0 "register_operand" "x")
1551                        (match_operand 1 "nonimmediate_operand" "xm")))]
1552   "TARGET_SSE_MATH
1553    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1554    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1555   "* return output_fp_compare (insn, operands, true, true);"
1556   [(set_attr "type" "ssecomi")
1557    (set_attr "prefix" "maybe_vex")
1558    (set (attr "mode")
1559      (if_then_else (match_operand:SF 1 "" "")
1560         (const_string "SF")
1561         (const_string "DF")))
1562    (set_attr "prefix_rep" "0")
1563    (set (attr "prefix_data16")
1564         (if_then_else (eq_attr "mode" "DF")
1565                       (const_string "1")
1566                       (const_string "0")))
1567    (set_attr "athlon_decode" "vector")
1568    (set_attr "amdfam10_decode" "direct")
1569    (set_attr "bdver1_decode" "double")])
1570
1571 (define_insn "*cmpfp_iu_387"
1572   [(set (reg:CCFPU FLAGS_REG)
1573         (compare:CCFPU (match_operand 0 "register_operand" "f")
1574                        (match_operand 1 "register_operand" "f")))]
1575   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1576    && TARGET_CMOVE
1577    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1578    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1579   "* return output_fp_compare (insn, operands, true, true);"
1580   [(set_attr "type" "fcmp")
1581    (set (attr "mode")
1582      (cond [(match_operand:SF 1 "" "")
1583               (const_string "SF")
1584             (match_operand:DF 1 "" "")
1585               (const_string "DF")
1586            ]
1587            (const_string "XF")))
1588    (set_attr "athlon_decode" "vector")
1589    (set_attr "amdfam10_decode" "direct")
1590    (set_attr "bdver1_decode" "direct")])
1591 \f
1592 ;; Push/pop instructions.
1593
1594 (define_insn "*push<mode>2"
1595   [(set (match_operand:DWI 0 "push_operand" "=<")
1596         (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1597   ""
1598   "#"
1599   [(set_attr "type" "multi")
1600    (set_attr "mode" "<MODE>")])
1601
1602 (define_split
1603   [(set (match_operand:TI 0 "push_operand" "")
1604         (match_operand:TI 1 "general_operand" ""))]
1605   "TARGET_64BIT && reload_completed
1606    && !SSE_REG_P (operands[1])"
1607   [(const_int 0)]
1608   "ix86_split_long_move (operands); DONE;")
1609
1610 (define_insn "*pushdi2_rex64"
1611   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1612         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1613   "TARGET_64BIT"
1614   "@
1615    push{q}\t%1
1616    #"
1617   [(set_attr "type" "push,multi")
1618    (set_attr "mode" "DI")])
1619
1620 ;; Convert impossible pushes of immediate to existing instructions.
1621 ;; First try to get scratch register and go through it.  In case this
1622 ;; fails, push sign extended lower part first and then overwrite
1623 ;; upper part by 32bit move.
1624 (define_peephole2
1625   [(match_scratch:DI 2 "r")
1626    (set (match_operand:DI 0 "push_operand" "")
1627         (match_operand:DI 1 "immediate_operand" ""))]
1628   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1629    && !x86_64_immediate_operand (operands[1], DImode)"
1630   [(set (match_dup 2) (match_dup 1))
1631    (set (match_dup 0) (match_dup 2))])
1632
1633 ;; We need to define this as both peepholer and splitter for case
1634 ;; peephole2 pass is not run.
1635 ;; "&& 1" is needed to keep it from matching the previous pattern.
1636 (define_peephole2
1637   [(set (match_operand:DI 0 "push_operand" "")
1638         (match_operand:DI 1 "immediate_operand" ""))]
1639   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1640    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1641   [(set (match_dup 0) (match_dup 1))
1642    (set (match_dup 2) (match_dup 3))]
1643 {
1644   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1645
1646   operands[1] = gen_lowpart (DImode, operands[2]);
1647   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1648                                                    GEN_INT (4)));
1649 })
1650
1651 (define_split
1652   [(set (match_operand:DI 0 "push_operand" "")
1653         (match_operand:DI 1 "immediate_operand" ""))]
1654   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1655                     ? epilogue_completed : reload_completed)
1656    && !symbolic_operand (operands[1], DImode)
1657    && !x86_64_immediate_operand (operands[1], DImode)"
1658   [(set (match_dup 0) (match_dup 1))
1659    (set (match_dup 2) (match_dup 3))]
1660 {
1661   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1662
1663   operands[1] = gen_lowpart (DImode, operands[2]);
1664   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1665                                                    GEN_INT (4)));
1666 })
1667
1668 (define_split
1669   [(set (match_operand:DI 0 "push_operand" "")
1670         (match_operand:DI 1 "general_operand" ""))]
1671   "!TARGET_64BIT && reload_completed
1672    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1673   [(const_int 0)]
1674   "ix86_split_long_move (operands); DONE;")
1675
1676 (define_insn "*pushsi2"
1677   [(set (match_operand:SI 0 "push_operand" "=<")
1678         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1679   "!TARGET_64BIT"
1680   "push{l}\t%1"
1681   [(set_attr "type" "push")
1682    (set_attr "mode" "SI")])
1683
1684 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1685 ;; "push a byte/word".  But actually we use pushl, which has the effect
1686 ;; of rounding the amount pushed up to a word.
1687
1688 ;; For TARGET_64BIT we always round up to 8 bytes.
1689 (define_insn "*push<mode>2_rex64"
1690   [(set (match_operand:SWI124 0 "push_operand" "=X")
1691         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1692   "TARGET_64BIT"
1693   "push{q}\t%q1"
1694   [(set_attr "type" "push")
1695    (set_attr "mode" "DI")])
1696
1697 (define_insn "*push<mode>2"
1698   [(set (match_operand:SWI12 0 "push_operand" "=X")
1699         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1700   "!TARGET_64BIT"
1701   "push{l}\t%k1"
1702   [(set_attr "type" "push")
1703    (set_attr "mode" "SI")])
1704
1705 (define_insn "*push<mode>2_prologue"
1706   [(set (match_operand:P 0 "push_operand" "=<")
1707         (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1708    (clobber (mem:BLK (scratch)))]
1709   ""
1710   "push{<imodesuffix>}\t%1"
1711   [(set_attr "type" "push")
1712    (set_attr "mode" "<MODE>")])
1713
1714 (define_insn "*pop<mode>1"
1715   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1716         (match_operand:P 1 "pop_operand" ">"))]
1717   ""
1718   "pop{<imodesuffix>}\t%0"
1719   [(set_attr "type" "pop")
1720    (set_attr "mode" "<MODE>")])
1721
1722 (define_insn "*pop<mode>1_epilogue"
1723   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1724         (match_operand:P 1 "pop_operand" ">"))
1725    (clobber (mem:BLK (scratch)))]
1726   ""
1727   "pop{<imodesuffix>}\t%0"
1728   [(set_attr "type" "pop")
1729    (set_attr "mode" "<MODE>")])
1730 \f
1731 ;; Move instructions.
1732
1733 (define_expand "movoi"
1734   [(set (match_operand:OI 0 "nonimmediate_operand" "")
1735         (match_operand:OI 1 "general_operand" ""))]
1736   "TARGET_AVX"
1737   "ix86_expand_move (OImode, operands); DONE;")
1738
1739 (define_expand "movti"
1740   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1741         (match_operand:TI 1 "nonimmediate_operand" ""))]
1742   "TARGET_64BIT || TARGET_SSE"
1743 {
1744   if (TARGET_64BIT)
1745     ix86_expand_move (TImode, operands);
1746   else if (push_operand (operands[0], TImode))
1747     ix86_expand_push (TImode, operands[1]);
1748   else
1749     ix86_expand_vector_move (TImode, operands);
1750   DONE;
1751 })
1752
1753 ;; This expands to what emit_move_complex would generate if we didn't
1754 ;; have a movti pattern.  Having this avoids problems with reload on
1755 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1756 ;; to have around all the time.
1757 (define_expand "movcdi"
1758   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1759         (match_operand:CDI 1 "general_operand" ""))]
1760   ""
1761 {
1762   if (push_operand (operands[0], CDImode))
1763     emit_move_complex_push (CDImode, operands[0], operands[1]);
1764   else
1765     emit_move_complex_parts (operands[0], operands[1]);
1766   DONE;
1767 })
1768
1769 (define_expand "mov<mode>"
1770   [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1771         (match_operand:SWI1248x 1 "general_operand" ""))]
1772   ""
1773   "ix86_expand_move (<MODE>mode, operands); DONE;")
1774
1775 (define_insn "*mov<mode>_xor"
1776   [(set (match_operand:SWI48 0 "register_operand" "=r")
1777         (match_operand:SWI48 1 "const0_operand" ""))
1778    (clobber (reg:CC FLAGS_REG))]
1779   "reload_completed"
1780   "xor{l}\t%k0, %k0"
1781   [(set_attr "type" "alu1")
1782    (set_attr "mode" "SI")
1783    (set_attr "length_immediate" "0")])
1784
1785 (define_insn "*mov<mode>_or"
1786   [(set (match_operand:SWI48 0 "register_operand" "=r")
1787         (match_operand:SWI48 1 "const_int_operand" ""))
1788    (clobber (reg:CC FLAGS_REG))]
1789   "reload_completed
1790    && operands[1] == constm1_rtx"
1791   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1792   [(set_attr "type" "alu1")
1793    (set_attr "mode" "<MODE>")
1794    (set_attr "length_immediate" "1")])
1795
1796 (define_insn "*movoi_internal_avx"
1797   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1798         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1799   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1800 {
1801   switch (which_alternative)
1802     {
1803     case 0:
1804       return standard_sse_constant_opcode (insn, operands[1]);
1805     case 1:
1806     case 2:
1807       if (misaligned_operand (operands[0], OImode)
1808           || misaligned_operand (operands[1], OImode))
1809         return "vmovdqu\t{%1, %0|%0, %1}";
1810       else
1811         return "vmovdqa\t{%1, %0|%0, %1}";
1812     default:
1813       gcc_unreachable ();
1814     }
1815 }
1816   [(set_attr "type" "sselog1,ssemov,ssemov")
1817    (set_attr "prefix" "vex")
1818    (set_attr "mode" "OI")])
1819
1820 (define_insn "*movti_internal_rex64"
1821   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,m")
1822         (match_operand:TI 1 "general_operand" "riFo,re,C,xm,x"))]
1823   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1824 {
1825   switch (which_alternative)
1826     {
1827     case 0:
1828     case 1:
1829       return "#";
1830     case 2:
1831       return standard_sse_constant_opcode (insn, operands[1]);
1832     case 3:
1833     case 4:
1834       /* TDmode values are passed as TImode on the stack.  Moving them
1835          to stack may result in unaligned memory access.  */
1836       if (misaligned_operand (operands[0], TImode)
1837           || misaligned_operand (operands[1], TImode))
1838         {
1839           if (get_attr_mode (insn) == MODE_V4SF)
1840             return "%vmovups\t{%1, %0|%0, %1}";
1841           else
1842             return "%vmovdqu\t{%1, %0|%0, %1}";
1843         }
1844       else
1845         {
1846           if (get_attr_mode (insn) == MODE_V4SF)
1847             return "%vmovaps\t{%1, %0|%0, %1}";
1848           else
1849             return "%vmovdqa\t{%1, %0|%0, %1}";
1850         }
1851     default:
1852       gcc_unreachable ();
1853     }
1854 }
1855   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1856    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1857    (set (attr "mode")
1858         (cond [(eq_attr "alternative" "2,3")
1859                  (if_then_else
1860                    (match_test "optimize_function_for_size_p (cfun)")
1861                    (const_string "V4SF")
1862                    (const_string "TI"))
1863                (eq_attr "alternative" "4")
1864                  (if_then_else
1865                    (ior (match_test "TARGET_SSE_TYPELESS_STORES")
1866                         (match_test "optimize_function_for_size_p (cfun)"))
1867                    (const_string "V4SF")
1868                    (const_string "TI"))]
1869                (const_string "DI")))])
1870
1871 (define_split
1872   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1873         (match_operand:TI 1 "general_operand" ""))]
1874   "reload_completed
1875    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1876   [(const_int 0)]
1877   "ix86_split_long_move (operands); DONE;")
1878
1879 (define_insn "*movti_internal_sse"
1880   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1881         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1882   "TARGET_SSE && !TARGET_64BIT
1883    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1884 {
1885   switch (which_alternative)
1886     {
1887     case 0:
1888       return standard_sse_constant_opcode (insn, operands[1]);
1889     case 1:
1890     case 2:
1891       /* TDmode values are passed as TImode on the stack.  Moving them
1892          to stack may result in unaligned memory access.  */
1893       if (misaligned_operand (operands[0], TImode)
1894           || misaligned_operand (operands[1], TImode))
1895         {
1896           if (get_attr_mode (insn) == MODE_V4SF)
1897             return "%vmovups\t{%1, %0|%0, %1}";
1898           else
1899             return "%vmovdqu\t{%1, %0|%0, %1}";
1900         }
1901       else
1902         {
1903           if (get_attr_mode (insn) == MODE_V4SF)
1904             return "%vmovaps\t{%1, %0|%0, %1}";
1905           else
1906             return "%vmovdqa\t{%1, %0|%0, %1}";
1907         }
1908     default:
1909       gcc_unreachable ();
1910     }
1911 }
1912   [(set_attr "type" "sselog1,ssemov,ssemov")
1913    (set_attr "prefix" "maybe_vex")
1914    (set (attr "mode")
1915         (cond [(ior (not (match_test "TARGET_SSE2"))
1916                     (match_test "optimize_function_for_size_p (cfun)"))
1917                  (const_string "V4SF")
1918                (and (eq_attr "alternative" "2")
1919                     (match_test "TARGET_SSE_TYPELESS_STORES"))
1920                  (const_string "V4SF")]
1921               (const_string "TI")))])
1922
1923 (define_insn "*movdi_internal_rex64"
1924   [(set (match_operand:DI 0 "nonimmediate_operand"
1925           "=r,r  ,r,m ,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1926         (match_operand:DI 1 "general_operand"
1927           "Z ,rem,i,re,C ,*y ,m  ,*Ym,r   ,C ,*x,*x,m ,*Yi,r   ,*Ym,*x"))]
1928   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1929 {
1930   switch (get_attr_type (insn))
1931     {
1932     case TYPE_SSECVT:
1933       if (SSE_REG_P (operands[0]))
1934         return "movq2dq\t{%1, %0|%0, %1}";
1935       else
1936         return "movdq2q\t{%1, %0|%0, %1}";
1937
1938     case TYPE_SSEMOV:
1939       if (get_attr_mode (insn) == MODE_TI)
1940         return "%vmovdqa\t{%1, %0|%0, %1}";
1941       /* Handle broken assemblers that require movd instead of movq.  */
1942       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1943         return "%vmovd\t{%1, %0|%0, %1}";
1944       else
1945         return "%vmovq\t{%1, %0|%0, %1}";
1946
1947     case TYPE_MMXMOV:
1948       /* Handle broken assemblers that require movd instead of movq.  */
1949       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1950         return "movd\t{%1, %0|%0, %1}";
1951       else
1952         return "movq\t{%1, %0|%0, %1}";
1953
1954     case TYPE_SSELOG1:
1955       return standard_sse_constant_opcode (insn, operands[1]);
1956
1957     case TYPE_MMX:
1958       return "pxor\t%0, %0";
1959
1960     case TYPE_LEA:
1961       return "lea{q}\t{%E1, %0|%0, %E1}";
1962
1963     default:
1964       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1965       if (get_attr_mode (insn) == MODE_SI)
1966         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1967       else if (which_alternative == 2)
1968         return "movabs{q}\t{%1, %0|%0, %1}";
1969       else if (ix86_use_lea_for_mov (insn, operands))
1970         return "lea{q}\t{%E1, %0|%0, %E1}";
1971       else
1972         return "mov{q}\t{%1, %0|%0, %1}";
1973     }
1974 }
1975   [(set (attr "type")
1976      (cond [(eq_attr "alternative" "4")
1977               (const_string "mmx")
1978             (eq_attr "alternative" "5,6,7,8")
1979               (const_string "mmxmov")
1980             (eq_attr "alternative" "9")
1981               (const_string "sselog1")
1982             (eq_attr "alternative" "10,11,12,13,14")
1983               (const_string "ssemov")
1984             (eq_attr "alternative" "15,16")
1985               (const_string "ssecvt")
1986             (match_operand 1 "pic_32bit_operand" "")
1987               (const_string "lea")
1988            ]
1989            (const_string "imov")))
1990    (set (attr "modrm")
1991      (if_then_else
1992        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
1993          (const_string "0")
1994          (const_string "*")))
1995    (set (attr "length_immediate")
1996      (if_then_else
1997        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
1998          (const_string "8")
1999          (const_string "*")))
2000    (set (attr "prefix_rex")
2001      (if_then_else (eq_attr "alternative" "7,8")
2002        (const_string "1")
2003        (const_string "*")))
2004    (set (attr "prefix_data16")
2005      (if_then_else (eq_attr "alternative" "10")
2006        (const_string "1")
2007        (const_string "*")))
2008    (set (attr "prefix")
2009      (if_then_else (eq_attr "alternative" "11,12,13,14,15")
2010        (const_string "maybe_vex")
2011        (const_string "orig")))
2012    (set_attr "mode" "SI,DI,DI,DI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2013
2014 ;; Reload patterns to support multi-word load/store
2015 ;; with non-offsetable address.
2016 (define_expand "reload_noff_store"
2017   [(parallel [(match_operand 0 "memory_operand" "=m")
2018               (match_operand 1 "register_operand" "r")
2019               (match_operand:DI 2 "register_operand" "=&r")])]
2020   "TARGET_64BIT"
2021 {
2022   rtx mem = operands[0];
2023   rtx addr = XEXP (mem, 0);
2024
2025   emit_move_insn (operands[2], addr);
2026   mem = replace_equiv_address_nv (mem, operands[2]);
2027
2028   emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2029   DONE;
2030 })
2031
2032 (define_expand "reload_noff_load"
2033   [(parallel [(match_operand 0 "register_operand" "=r")
2034               (match_operand 1 "memory_operand" "m")
2035               (match_operand:DI 2 "register_operand" "=r")])]
2036   "TARGET_64BIT"
2037 {
2038   rtx mem = operands[1];
2039   rtx addr = XEXP (mem, 0);
2040
2041   emit_move_insn (operands[2], addr);
2042   mem = replace_equiv_address_nv (mem, operands[2]);
2043
2044   emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2045   DONE;
2046 })
2047
2048 (define_insn "*movdi_internal"
2049   [(set (match_operand:DI 0 "nonimmediate_operand"
2050           "=r  ,o  ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2051         (match_operand:DI 1 "general_operand"
2052           "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2053   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2054 {
2055   switch (get_attr_type (insn))
2056     {
2057     case TYPE_SSECVT:
2058       if (SSE_REG_P (operands[0]))
2059         return "movq2dq\t{%1, %0|%0, %1}";
2060       else
2061         return "movdq2q\t{%1, %0|%0, %1}";
2062
2063     case TYPE_SSEMOV:
2064       switch (get_attr_mode (insn))
2065         {
2066         case MODE_TI:
2067           return "%vmovdqa\t{%1, %0|%0, %1}";
2068         case MODE_DI:
2069            return "%vmovq\t{%1, %0|%0, %1}";
2070         case MODE_V4SF:
2071           return "movaps\t{%1, %0|%0, %1}";
2072         case MODE_V2SF:
2073           return "movlps\t{%1, %0|%0, %1}";
2074         default:
2075           gcc_unreachable ();
2076         }
2077
2078     case TYPE_MMXMOV:
2079       return "movq\t{%1, %0|%0, %1}";
2080
2081     case TYPE_SSELOG1:
2082       return standard_sse_constant_opcode (insn, operands[1]);
2083
2084     case TYPE_MMX:
2085       return "pxor\t%0, %0";
2086
2087     case TYPE_MULTI:
2088       return "#";
2089
2090     default:
2091       gcc_unreachable ();
2092     }
2093 }
2094   [(set (attr "isa")
2095      (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2096               (const_string "sse2")
2097             (eq_attr "alternative" "9,10,11,12")
2098               (const_string "noavx")
2099            ]
2100            (const_string "*")))
2101    (set (attr "type")
2102      (cond [(eq_attr "alternative" "0,1")
2103               (const_string "multi")
2104             (eq_attr "alternative" "2")
2105               (const_string "mmx")
2106             (eq_attr "alternative" "3,4")
2107               (const_string "mmxmov")
2108             (eq_attr "alternative" "5,9")
2109               (const_string "sselog1")
2110             (eq_attr "alternative" "13,14")
2111               (const_string "ssecvt")
2112            ]
2113            (const_string "ssemov")))
2114    (set (attr "prefix")
2115      (if_then_else (eq_attr "alternative" "5,6,7,8")
2116        (const_string "maybe_vex")
2117        (const_string "orig")))
2118    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2119
2120 (define_split
2121   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2122         (match_operand:DI 1 "general_operand" ""))]
2123   "!TARGET_64BIT && reload_completed
2124    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2125    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2126   [(const_int 0)]
2127   "ix86_split_long_move (operands); DONE;")
2128
2129 (define_insn "*movsi_internal"
2130   [(set (match_operand:SI 0 "nonimmediate_operand"
2131                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2132         (match_operand:SI 1 "general_operand"
2133                         "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
2134   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2135 {
2136   switch (get_attr_type (insn))
2137     {
2138     case TYPE_SSELOG1:
2139       return standard_sse_constant_opcode (insn, operands[1]);
2140
2141     case TYPE_SSEMOV:
2142       switch (get_attr_mode (insn))
2143         {
2144         case MODE_TI:
2145           return "%vmovdqa\t{%1, %0|%0, %1}";
2146         case MODE_V4SF:
2147           return "%vmovaps\t{%1, %0|%0, %1}";
2148         case MODE_SI:
2149           return "%vmovd\t{%1, %0|%0, %1}";
2150         case MODE_SF:
2151           return "%vmovss\t{%1, %0|%0, %1}";
2152         default:
2153           gcc_unreachable ();
2154         }
2155
2156     case TYPE_MMX:
2157       return "pxor\t%0, %0";
2158
2159     case TYPE_MMXMOV:
2160       if (get_attr_mode (insn) == MODE_DI)
2161         return "movq\t{%1, %0|%0, %1}";
2162       return "movd\t{%1, %0|%0, %1}";
2163
2164     case TYPE_LEA:
2165       return "lea{l}\t{%E1, %0|%0, %E1}";
2166
2167     default:
2168       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2169       if (ix86_use_lea_for_mov (insn, operands))
2170         return "lea{l}\t{%E1, %0|%0, %E1}";
2171       else
2172         return "mov{l}\t{%1, %0|%0, %1}";
2173     }
2174 }
2175   [(set (attr "type")
2176      (cond [(eq_attr "alternative" "2")
2177               (const_string "mmx")
2178             (eq_attr "alternative" "3,4,5")
2179               (const_string "mmxmov")
2180             (eq_attr "alternative" "6")
2181               (const_string "sselog1")
2182             (eq_attr "alternative" "7,8,9,10,11")
2183               (const_string "ssemov")
2184             (match_operand 1 "pic_32bit_operand" "")
2185               (const_string "lea")
2186            ]
2187            (const_string "imov")))
2188    (set (attr "prefix")
2189      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2190        (const_string "orig")
2191        (const_string "maybe_vex")))
2192    (set (attr "prefix_data16")
2193      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2194        (const_string "1")
2195        (const_string "*")))
2196    (set (attr "mode")
2197      (cond [(eq_attr "alternative" "2,3")
2198               (const_string "DI")
2199             (eq_attr "alternative" "6,7")
2200               (if_then_else
2201                 (not (match_test "TARGET_SSE2"))
2202                 (const_string "V4SF")
2203                 (const_string "TI"))
2204             (and (eq_attr "alternative" "8,9,10,11")
2205                  (not (match_test "TARGET_SSE2")))
2206               (const_string "SF")
2207            ]
2208            (const_string "SI")))])
2209
2210 (define_insn "*movhi_internal"
2211   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2212         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2213   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2214 {
2215   switch (get_attr_type (insn))
2216     {
2217     case TYPE_IMOVX:
2218       /* movzwl is faster than movw on p2 due to partial word stalls,
2219          though not as fast as an aligned movl.  */
2220       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2221     default:
2222       if (get_attr_mode (insn) == MODE_SI)
2223         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2224       else
2225         return "mov{w}\t{%1, %0|%0, %1}";
2226     }
2227 }
2228   [(set (attr "type")
2229      (cond [(match_test "optimize_function_for_size_p (cfun)")
2230               (const_string "imov")
2231             (and (eq_attr "alternative" "0")
2232                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2233                       (not (match_test "TARGET_HIMODE_MATH"))))
2234               (const_string "imov")
2235             (and (eq_attr "alternative" "1,2")
2236                  (match_operand:HI 1 "aligned_operand" ""))
2237               (const_string "imov")
2238             (and (match_test "TARGET_MOVX")
2239                  (eq_attr "alternative" "0,2"))
2240               (const_string "imovx")
2241            ]
2242            (const_string "imov")))
2243     (set (attr "mode")
2244       (cond [(eq_attr "type" "imovx")
2245                (const_string "SI")
2246              (and (eq_attr "alternative" "1,2")
2247                   (match_operand:HI 1 "aligned_operand" ""))
2248                (const_string "SI")
2249              (and (eq_attr "alternative" "0")
2250                   (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2251                        (not (match_test "TARGET_HIMODE_MATH"))))
2252                (const_string "SI")
2253             ]
2254             (const_string "HI")))])
2255
2256 ;; Situation is quite tricky about when to choose full sized (SImode) move
2257 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2258 ;; partial register dependency machines (such as AMD Athlon), where QImode
2259 ;; moves issue extra dependency and for partial register stalls machines
2260 ;; that don't use QImode patterns (and QImode move cause stall on the next
2261 ;; instruction).
2262 ;;
2263 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2264 ;; register stall machines with, where we use QImode instructions, since
2265 ;; partial register stall can be caused there.  Then we use movzx.
2266 (define_insn "*movqi_internal"
2267   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2268         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2269   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2270 {
2271   switch (get_attr_type (insn))
2272     {
2273     case TYPE_IMOVX:
2274       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2275       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2276     default:
2277       if (get_attr_mode (insn) == MODE_SI)
2278         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2279       else
2280         return "mov{b}\t{%1, %0|%0, %1}";
2281     }
2282 }
2283   [(set (attr "type")
2284      (cond [(and (eq_attr "alternative" "5")
2285                  (not (match_operand:QI 1 "aligned_operand" "")))
2286               (const_string "imovx")
2287             (match_test "optimize_function_for_size_p (cfun)")
2288               (const_string "imov")
2289             (and (eq_attr "alternative" "3")
2290                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2291                       (not (match_test "TARGET_QIMODE_MATH"))))
2292               (const_string "imov")
2293             (eq_attr "alternative" "3,5")
2294               (const_string "imovx")
2295             (and (match_test "TARGET_MOVX")
2296                  (eq_attr "alternative" "2"))
2297               (const_string "imovx")
2298            ]
2299            (const_string "imov")))
2300    (set (attr "mode")
2301       (cond [(eq_attr "alternative" "3,4,5")
2302                (const_string "SI")
2303              (eq_attr "alternative" "6")
2304                (const_string "QI")
2305              (eq_attr "type" "imovx")
2306                (const_string "SI")
2307              (and (eq_attr "type" "imov")
2308                   (and (eq_attr "alternative" "0,1")
2309                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2310                             (and (not (match_test "optimize_function_for_size_p (cfun)"))
2311                                  (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2312                (const_string "SI")
2313              ;; Avoid partial register stalls when not using QImode arithmetic
2314              (and (eq_attr "type" "imov")
2315                   (and (eq_attr "alternative" "0,1")
2316                        (and (match_test "TARGET_PARTIAL_REG_STALL")
2317                             (not (match_test "TARGET_QIMODE_MATH")))))
2318                (const_string "SI")
2319            ]
2320            (const_string "QI")))])
2321
2322 ;; Stores and loads of ax to arbitrary constant address.
2323 ;; We fake an second form of instruction to force reload to load address
2324 ;; into register when rax is not available
2325 (define_insn "*movabs<mode>_1"
2326   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2327         (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2328   "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2329   "@
2330    movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2331    mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2332   [(set_attr "type" "imov")
2333    (set_attr "modrm" "0,*")
2334    (set_attr "length_address" "8,0")
2335    (set_attr "length_immediate" "0,*")
2336    (set_attr "memory" "store")
2337    (set_attr "mode" "<MODE>")])
2338
2339 (define_insn "*movabs<mode>_2"
2340   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2341         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2342   "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2343   "@
2344    movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2345    mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2346   [(set_attr "type" "imov")
2347    (set_attr "modrm" "0,*")
2348    (set_attr "length_address" "8,0")
2349    (set_attr "length_immediate" "0")
2350    (set_attr "memory" "load")
2351    (set_attr "mode" "<MODE>")])
2352
2353 (define_insn "*swap<mode>"
2354   [(set (match_operand:SWI48 0 "register_operand" "+r")
2355         (match_operand:SWI48 1 "register_operand" "+r"))
2356    (set (match_dup 1)
2357         (match_dup 0))]
2358   ""
2359   "xchg{<imodesuffix>}\t%1, %0"
2360   [(set_attr "type" "imov")
2361    (set_attr "mode" "<MODE>")
2362    (set_attr "pent_pair" "np")
2363    (set_attr "athlon_decode" "vector")
2364    (set_attr "amdfam10_decode" "double")
2365    (set_attr "bdver1_decode" "double")])
2366
2367 (define_insn "*swap<mode>_1"
2368   [(set (match_operand:SWI12 0 "register_operand" "+r")
2369         (match_operand:SWI12 1 "register_operand" "+r"))
2370    (set (match_dup 1)
2371         (match_dup 0))]
2372   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2373   "xchg{l}\t%k1, %k0"
2374   [(set_attr "type" "imov")
2375    (set_attr "mode" "SI")
2376    (set_attr "pent_pair" "np")
2377    (set_attr "athlon_decode" "vector")
2378    (set_attr "amdfam10_decode" "double")
2379    (set_attr "bdver1_decode" "double")])
2380
2381 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2382 ;; is disabled for AMDFAM10
2383 (define_insn "*swap<mode>_2"
2384   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2385         (match_operand:SWI12 1 "register_operand" "+<r>"))
2386    (set (match_dup 1)
2387         (match_dup 0))]
2388   "TARGET_PARTIAL_REG_STALL"
2389   "xchg{<imodesuffix>}\t%1, %0"
2390   [(set_attr "type" "imov")
2391    (set_attr "mode" "<MODE>")
2392    (set_attr "pent_pair" "np")
2393    (set_attr "athlon_decode" "vector")])
2394
2395 (define_expand "movstrict<mode>"
2396   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2397         (match_operand:SWI12 1 "general_operand" ""))]
2398   ""
2399 {
2400   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2401     FAIL;
2402   if (GET_CODE (operands[0]) == SUBREG
2403       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2404     FAIL;
2405   /* Don't generate memory->memory moves, go through a register */
2406   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2407     operands[1] = force_reg (<MODE>mode, operands[1]);
2408 })
2409
2410 (define_insn "*movstrict<mode>_1"
2411   [(set (strict_low_part
2412           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2413         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2414   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2415    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2416   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2417   [(set_attr "type" "imov")
2418    (set_attr "mode" "<MODE>")])
2419
2420 (define_insn "*movstrict<mode>_xor"
2421   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2422         (match_operand:SWI12 1 "const0_operand" ""))
2423    (clobber (reg:CC FLAGS_REG))]
2424   "reload_completed"
2425   "xor{<imodesuffix>}\t%0, %0"
2426   [(set_attr "type" "alu1")
2427    (set_attr "mode" "<MODE>")
2428    (set_attr "length_immediate" "0")])
2429
2430 (define_insn "*mov<mode>_extv_1"
2431   [(set (match_operand:SWI24 0 "register_operand" "=R")
2432         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2433                             (const_int 8)
2434                             (const_int 8)))]
2435   ""
2436   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2437   [(set_attr "type" "imovx")
2438    (set_attr "mode" "SI")])
2439
2440 (define_insn "*movqi_extv_1_rex64"
2441   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2442         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2443                          (const_int 8)
2444                          (const_int 8)))]
2445   "TARGET_64BIT"
2446 {
2447   switch (get_attr_type (insn))
2448     {
2449     case TYPE_IMOVX:
2450       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2451     default:
2452       return "mov{b}\t{%h1, %0|%0, %h1}";
2453     }
2454 }
2455   [(set (attr "type")
2456      (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2457                         (match_test "TARGET_MOVX"))
2458         (const_string "imovx")
2459         (const_string "imov")))
2460    (set (attr "mode")
2461      (if_then_else (eq_attr "type" "imovx")
2462         (const_string "SI")
2463         (const_string "QI")))])
2464
2465 (define_insn "*movqi_extv_1"
2466   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2467         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2468                          (const_int 8)
2469                          (const_int 8)))]
2470   "!TARGET_64BIT"
2471 {
2472   switch (get_attr_type (insn))
2473     {
2474     case TYPE_IMOVX:
2475       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2476     default:
2477       return "mov{b}\t{%h1, %0|%0, %h1}";
2478     }
2479 }
2480   [(set (attr "type")
2481      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2482                         (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2483                              (match_test "TARGET_MOVX")))
2484         (const_string "imovx")
2485         (const_string "imov")))
2486    (set (attr "mode")
2487      (if_then_else (eq_attr "type" "imovx")
2488         (const_string "SI")
2489         (const_string "QI")))])
2490
2491 (define_insn "*mov<mode>_extzv_1"
2492   [(set (match_operand:SWI48 0 "register_operand" "=R")
2493         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2494                             (const_int 8)
2495                             (const_int 8)))]
2496   ""
2497   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2498   [(set_attr "type" "imovx")
2499    (set_attr "mode" "SI")])
2500
2501 (define_insn "*movqi_extzv_2_rex64"
2502   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2503         (subreg:QI
2504           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2505                            (const_int 8)
2506                            (const_int 8)) 0))]
2507   "TARGET_64BIT"
2508 {
2509   switch (get_attr_type (insn))
2510     {
2511     case TYPE_IMOVX:
2512       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2513     default:
2514       return "mov{b}\t{%h1, %0|%0, %h1}";
2515     }
2516 }
2517   [(set (attr "type")
2518      (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2519                         (match_test "TARGET_MOVX"))
2520         (const_string "imovx")
2521         (const_string "imov")))
2522    (set (attr "mode")
2523      (if_then_else (eq_attr "type" "imovx")
2524         (const_string "SI")
2525         (const_string "QI")))])
2526
2527 (define_insn "*movqi_extzv_2"
2528   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2529         (subreg:QI
2530           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2531                            (const_int 8)
2532                            (const_int 8)) 0))]
2533   "!TARGET_64BIT"
2534 {
2535   switch (get_attr_type (insn))
2536     {
2537     case TYPE_IMOVX:
2538       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2539     default:
2540       return "mov{b}\t{%h1, %0|%0, %h1}";
2541     }
2542 }
2543   [(set (attr "type")
2544      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2545                         (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2546                              (match_test "TARGET_MOVX")))
2547         (const_string "imovx")
2548         (const_string "imov")))
2549    (set (attr "mode")
2550      (if_then_else (eq_attr "type" "imovx")
2551         (const_string "SI")
2552         (const_string "QI")))])
2553
2554 (define_expand "mov<mode>_insv_1"
2555   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2556                             (const_int 8)
2557                             (const_int 8))
2558         (match_operand:SWI48 1 "nonmemory_operand" ""))])
2559
2560 (define_insn "*mov<mode>_insv_1_rex64"
2561   [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2562                              (const_int 8)
2563                              (const_int 8))
2564         (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2565   "TARGET_64BIT"
2566 {
2567   if (CONST_INT_P (operands[1]))
2568     operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2569   return "mov{b}\t{%b1, %h0|%h0, %b1}";
2570 }
2571   [(set_attr "type" "imov")
2572    (set_attr "mode" "QI")])
2573
2574 (define_insn "*movsi_insv_1"
2575   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2576                          (const_int 8)
2577                          (const_int 8))
2578         (match_operand:SI 1 "general_operand" "Qmn"))]
2579   "!TARGET_64BIT"
2580 {
2581   if (CONST_INT_P (operands[1]))
2582     operands[1] = simplify_gen_subreg (QImode, operands[1], SImode, 0);
2583   return "mov{b}\t{%b1, %h0|%h0, %b1}";
2584 }
2585   [(set_attr "type" "imov")
2586    (set_attr "mode" "QI")])
2587
2588 (define_insn "*movqi_insv_2"
2589   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2590                          (const_int 8)
2591                          (const_int 8))
2592         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2593                      (const_int 8)))]
2594   ""
2595   "mov{b}\t{%h1, %h0|%h0, %h1}"
2596   [(set_attr "type" "imov")
2597    (set_attr "mode" "QI")])
2598 \f
2599 ;; Floating point push instructions.
2600
2601 (define_insn "*pushtf"
2602   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2603         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2604   "TARGET_SSE2"
2605 {
2606   /* This insn should be already split before reg-stack.  */
2607   gcc_unreachable ();
2608 }
2609   [(set_attr "type" "multi")
2610    (set_attr "unit" "sse,*,*")
2611    (set_attr "mode" "TF,SI,SI")])
2612
2613 ;; %%% Kill this when call knows how to work this out.
2614 (define_split
2615   [(set (match_operand:TF 0 "push_operand" "")
2616         (match_operand:TF 1 "sse_reg_operand" ""))]
2617   "TARGET_SSE2 && reload_completed"
2618   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2619    (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2620
2621 (define_insn "*pushxf"
2622   [(set (match_operand:XF 0 "push_operand" "=<,<")
2623         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2624   "optimize_function_for_speed_p (cfun)"
2625 {
2626   /* This insn should be already split before reg-stack.  */
2627   gcc_unreachable ();
2628 }
2629   [(set_attr "type" "multi")
2630    (set_attr "unit" "i387,*")
2631    (set_attr "mode" "XF,SI")])
2632
2633 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2634 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2635 ;; Pushing using integer instructions is longer except for constants
2636 ;; and direct memory references (assuming that any given constant is pushed
2637 ;; only once, but this ought to be handled elsewhere).
2638
2639 (define_insn "*pushxf_nointeger"
2640   [(set (match_operand:XF 0 "push_operand" "=<,<")
2641         (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2642   "optimize_function_for_size_p (cfun)"
2643 {
2644   /* This insn should be already split before reg-stack.  */
2645   gcc_unreachable ();
2646 }
2647   [(set_attr "type" "multi")
2648    (set_attr "unit" "i387,*")
2649    (set_attr "mode" "XF,SI")])
2650
2651 ;; %%% Kill this when call knows how to work this out.
2652 (define_split
2653   [(set (match_operand:XF 0 "push_operand" "")
2654         (match_operand:XF 1 "fp_register_operand" ""))]
2655   "reload_completed"
2656   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2657    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2658   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2659
2660 (define_insn "*pushdf_rex64"
2661   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2662         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2663   "TARGET_64BIT"
2664 {
2665   /* This insn should be already split before reg-stack.  */
2666   gcc_unreachable ();
2667 }
2668   [(set_attr "type" "multi")
2669    (set_attr "unit" "i387,*,*")
2670    (set_attr "mode" "DF,DI,DF")])
2671
2672 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2673 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2674 ;; On the average, pushdf using integers can be still shorter.
2675
2676 (define_insn "*pushdf"
2677   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2678         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2679   "!TARGET_64BIT"
2680 {
2681   /* This insn should be already split before reg-stack.  */
2682   gcc_unreachable ();
2683 }
2684   [(set_attr "isa" "*,*,sse2")
2685    (set_attr "type" "multi")
2686    (set_attr "unit" "i387,*,*")
2687    (set_attr "mode" "DF,DI,DF")])
2688
2689 ;; %%% Kill this when call knows how to work this out.
2690 (define_split
2691   [(set (match_operand:DF 0 "push_operand" "")
2692         (match_operand:DF 1 "any_fp_register_operand" ""))]
2693   "reload_completed"
2694   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2695    (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2696
2697 (define_insn "*pushsf_rex64"
2698   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2699         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2700   "TARGET_64BIT"
2701 {
2702   /* Anything else should be already split before reg-stack.  */
2703   gcc_assert (which_alternative == 1);
2704   return "push{q}\t%q1";
2705 }
2706   [(set_attr "type" "multi,push,multi")
2707    (set_attr "unit" "i387,*,*")
2708    (set_attr "mode" "SF,DI,SF")])
2709
2710 (define_insn "*pushsf"
2711   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2712         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2713   "!TARGET_64BIT"
2714 {
2715   /* Anything else should be already split before reg-stack.  */
2716   gcc_assert (which_alternative == 1);
2717   return "push{l}\t%1";
2718 }
2719   [(set_attr "type" "multi,push,multi")
2720    (set_attr "unit" "i387,*,*")
2721    (set_attr "mode" "SF,SI,SF")])
2722
2723 ;; %%% Kill this when call knows how to work this out.
2724 (define_split
2725   [(set (match_operand:SF 0 "push_operand" "")
2726         (match_operand:SF 1 "any_fp_register_operand" ""))]
2727   "reload_completed"
2728   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2729    (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2730   "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2731
2732 (define_split
2733   [(set (match_operand:SF 0 "push_operand" "")
2734         (match_operand:SF 1 "memory_operand" ""))]
2735   "reload_completed
2736    && (operands[2] = find_constant_src (insn))"
2737   [(set (match_dup 0) (match_dup 2))])
2738
2739 (define_split
2740   [(set (match_operand 0 "push_operand" "")
2741         (match_operand 1 "general_operand" ""))]
2742   "reload_completed
2743    && (GET_MODE (operands[0]) == TFmode
2744        || GET_MODE (operands[0]) == XFmode
2745        || GET_MODE (operands[0]) == DFmode)
2746    && !ANY_FP_REG_P (operands[1])"
2747   [(const_int 0)]
2748   "ix86_split_long_move (operands); DONE;")
2749 \f
2750 ;; Floating point move instructions.
2751
2752 (define_expand "movtf"
2753   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2754         (match_operand:TF 1 "nonimmediate_operand" ""))]
2755   "TARGET_64BIT || TARGET_SSE2"
2756 {
2757   ix86_expand_move (TFmode, operands);
2758   DONE;
2759 })
2760
2761 (define_expand "mov<mode>"
2762   [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2763         (match_operand:X87MODEF 1 "general_operand" ""))]
2764   ""
2765   "ix86_expand_move (<MODE>mode, operands); DONE;")
2766
2767 (define_insn "*movtf_internal_rex64"
2768   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2769         (match_operand:TF 1 "general_operand"      "xm,x,C,*roF,*r"))]
2770   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2771    && (!can_create_pseudo_p ()
2772        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2773        || GET_CODE (operands[1]) != CONST_DOUBLE
2774        || (optimize_function_for_size_p (cfun)
2775            && standard_sse_constant_p (operands[1])
2776            && !memory_operand (operands[0], TFmode))
2777        || (!TARGET_MEMORY_MISMATCH_STALL
2778            && memory_operand (operands[0], TFmode)))"
2779 {
2780   switch (which_alternative)
2781     {
2782     case 0:
2783     case 1:
2784       /* Handle misaligned load/store since we
2785          don't have movmisaligntf pattern. */
2786       if (misaligned_operand (operands[0], TFmode)
2787           || misaligned_operand (operands[1], TFmode))
2788         {
2789           if (get_attr_mode (insn) == MODE_V4SF)
2790             return "%vmovups\t{%1, %0|%0, %1}";
2791           else
2792             return "%vmovdqu\t{%1, %0|%0, %1}";
2793         }
2794       else
2795         {
2796           if (get_attr_mode (insn) == MODE_V4SF)
2797             return "%vmovaps\t{%1, %0|%0, %1}";
2798           else
2799             return "%vmovdqa\t{%1, %0|%0, %1}";
2800         }
2801
2802     case 2:
2803       return standard_sse_constant_opcode (insn, operands[1]);
2804
2805     case 3:
2806     case 4:
2807         return "#";
2808
2809     default:
2810       gcc_unreachable ();
2811     }
2812 }
2813   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2814    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2815    (set (attr "mode")
2816         (cond [(eq_attr "alternative" "0,2")
2817                  (if_then_else
2818                    (match_test "optimize_function_for_size_p (cfun)")
2819                    (const_string "V4SF")
2820                    (const_string "TI"))
2821                (eq_attr "alternative" "1")
2822                  (if_then_else
2823                    (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2824                         (match_test "optimize_function_for_size_p (cfun)"))
2825                    (const_string "V4SF")
2826                    (const_string "TI"))]
2827                (const_string "DI")))])
2828
2829 (define_insn "*movtf_internal_sse2"
2830   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x")
2831         (match_operand:TF 1 "general_operand"      "xm,x,C"))]
2832   "TARGET_SSE2 && !TARGET_64BIT
2833    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2834    && (!can_create_pseudo_p ()
2835        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2836        || GET_CODE (operands[1]) != CONST_DOUBLE
2837        || (optimize_function_for_size_p (cfun)
2838            && standard_sse_constant_p (operands[1])
2839            && !memory_operand (operands[0], TFmode))
2840        || (!TARGET_MEMORY_MISMATCH_STALL
2841            && memory_operand (operands[0], TFmode)))"
2842 {
2843   switch (which_alternative)
2844     {
2845     case 0:
2846     case 1:
2847       /* Handle misaligned load/store since we
2848          don't have movmisaligntf pattern. */
2849       if (misaligned_operand (operands[0], TFmode)
2850           || misaligned_operand (operands[1], TFmode))
2851         {
2852           if (get_attr_mode (insn) == MODE_V4SF)
2853             return "%vmovups\t{%1, %0|%0, %1}";
2854           else
2855             return "%vmovdqu\t{%1, %0|%0, %1}";
2856         }
2857       else
2858         {
2859           if (get_attr_mode (insn) == MODE_V4SF)
2860             return "%vmovaps\t{%1, %0|%0, %1}";
2861           else
2862             return "%vmovdqa\t{%1, %0|%0, %1}";
2863         }
2864
2865     case 2:
2866       return standard_sse_constant_opcode (insn, operands[1]);
2867
2868     default:
2869       gcc_unreachable ();
2870     }
2871 }
2872   [(set_attr "type" "ssemov,ssemov,sselog1")
2873    (set_attr "prefix" "maybe_vex")
2874    (set (attr "mode")
2875         (cond [(eq_attr "alternative" "0,2")
2876                  (if_then_else
2877                    (match_test "optimize_function_for_size_p (cfun)")
2878                    (const_string "V4SF")
2879                    (const_string "TI"))
2880                (eq_attr "alternative" "1")
2881                  (if_then_else
2882                    (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2883                         (match_test "optimize_function_for_size_p (cfun)"))
2884                    (const_string "V4SF")
2885                    (const_string "TI"))]
2886                (const_string "DI")))])
2887
2888 (define_insn "*movxf_internal_rex64"
2889   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2890         (match_operand:XF 1 "general_operand"      "fm,f,G,Yx*roF,Yx*rC"))]
2891   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2892    && (!can_create_pseudo_p ()
2893        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2894        || GET_CODE (operands[1]) != CONST_DOUBLE
2895        || (optimize_function_for_size_p (cfun)
2896            && standard_80387_constant_p (operands[1]) > 0
2897            && !memory_operand (operands[0], XFmode))
2898        || (!TARGET_MEMORY_MISMATCH_STALL
2899            && memory_operand (operands[0], XFmode)))"
2900 {
2901   switch (which_alternative)
2902     {
2903     case 0:
2904     case 1:
2905       return output_387_reg_move (insn, operands);
2906
2907     case 2:
2908       return standard_80387_constant_opcode (operands[1]);
2909
2910     case 3:
2911     case 4:
2912       return "#";
2913
2914     default:
2915       gcc_unreachable ();
2916     }
2917 }
2918   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2919    (set_attr "mode" "XF,XF,XF,SI,SI")])
2920
2921 ;; Possible store forwarding (partial memory) stall in alternative 4.
2922 (define_insn "*movxf_internal"
2923   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2924         (match_operand:XF 1 "general_operand"      "fm,f,G,Yx*roF,Yx*rF"))]
2925   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2926    && (!can_create_pseudo_p ()
2927        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2928        || GET_CODE (operands[1]) != CONST_DOUBLE
2929        || (optimize_function_for_size_p (cfun)
2930            && standard_80387_constant_p (operands[1]) > 0
2931            && !memory_operand (operands[0], XFmode))
2932        || (!TARGET_MEMORY_MISMATCH_STALL
2933            && memory_operand (operands[0], XFmode)))"
2934 {
2935   switch (which_alternative)
2936     {
2937     case 0:
2938     case 1:
2939       return output_387_reg_move (insn, operands);
2940
2941     case 2:
2942       return standard_80387_constant_opcode (operands[1]);
2943
2944     case 3:
2945     case 4:
2946       return "#";
2947
2948     default:
2949       gcc_unreachable ();
2950     }
2951 }
2952   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2953    (set_attr "mode" "XF,XF,XF,SI,SI")])
2954
2955 (define_insn "*movdf_internal_rex64"
2956   [(set (match_operand:DF 0 "nonimmediate_operand"
2957                 "=?Yf*f,?m   ,?Yf*f,?r,?m,?r,?r,x,x,x,m,Yi,r ")
2958         (match_operand:DF 1 "general_operand"
2959                 "Yf*fm ,Yf*f ,G    ,rm,rC,C ,F ,C,x,m,x,r ,Yi"))]
2960   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2961    && (!can_create_pseudo_p ()
2962        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2963        || GET_CODE (operands[1]) != CONST_DOUBLE
2964        || (optimize_function_for_size_p (cfun)
2965            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2966                 && standard_80387_constant_p (operands[1]) > 0)
2967                || (TARGET_SSE2 && TARGET_SSE_MATH
2968                    && standard_sse_constant_p (operands[1]))))
2969        || memory_operand (operands[0], DFmode))"
2970 {
2971   switch (which_alternative)
2972     {
2973     case 0:
2974     case 1:
2975       return output_387_reg_move (insn, operands);
2976
2977     case 2:
2978       return standard_80387_constant_opcode (operands[1]);
2979
2980     case 3:
2981     case 4:
2982       return "mov{q}\t{%1, %0|%0, %1}";
2983
2984     case 5:
2985       return "mov{l}\t{%1, %k0|%k0, %1}";
2986
2987     case 6:
2988       return "movabs{q}\t{%1, %0|%0, %1}";
2989
2990     case 7:
2991       return standard_sse_constant_opcode (insn, operands[1]);
2992
2993     case 8:
2994     case 9:
2995     case 10:
2996       switch (get_attr_mode (insn))
2997         {
2998         case MODE_V2DF:
2999           if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3000             return "%vmovapd\t{%1, %0|%0, %1}";
3001         case MODE_V4SF:
3002           return "%vmovaps\t{%1, %0|%0, %1}";
3003
3004         case MODE_DI:
3005           return "%vmovq\t{%1, %0|%0, %1}";
3006         case MODE_DF:
3007           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3008             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3009           return "%vmovsd\t{%1, %0|%0, %1}";
3010         case MODE_V1DF:
3011           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3012         case MODE_V2SF:
3013           return "%vmovlps\t{%1, %d0|%d0, %1}";
3014         default:
3015           gcc_unreachable ();
3016         }
3017
3018     case 11:
3019     case 12:
3020       /* Handle broken assemblers that require movd instead of movq.  */
3021       return "%vmovd\t{%1, %0|%0, %1}";
3022
3023     default:
3024       gcc_unreachable();
3025     }
3026 }
3027   [(set (attr "type")
3028         (cond [(eq_attr "alternative" "0,1,2")
3029                  (const_string "fmov")
3030                (eq_attr "alternative" "3,4,5,6")
3031                  (const_string "imov")
3032                (eq_attr "alternative" "7")
3033                  (const_string "sselog1")
3034               ]
3035               (const_string "ssemov")))
3036    (set (attr "modrm")
3037      (if_then_else
3038        (and (eq_attr "alternative" "6") (eq_attr "type" "imov"))
3039          (const_string "0")
3040          (const_string "*")))
3041    (set (attr "length_immediate")
3042      (if_then_else
3043        (and (eq_attr "alternative" "6") (eq_attr "type" "imov"))
3044          (const_string "8")
3045          (const_string "*")))
3046    (set (attr "prefix")
3047      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3048        (const_string "orig")
3049        (const_string "maybe_vex")))
3050    (set (attr "prefix_data16")
3051      (if_then_else (eq_attr "mode" "V1DF")
3052        (const_string "1")
3053        (const_string "*")))
3054    (set (attr "mode")
3055         (cond [(eq_attr "alternative" "0,1,2")
3056                  (const_string "DF")
3057                (eq_attr "alternative" "3,4,6,11,12")
3058                  (const_string "DI")
3059                (eq_attr "alternative" "5")
3060                  (const_string "SI")
3061
3062                /* xorps is one byte shorter.  */
3063                (eq_attr "alternative" "7")
3064                  (cond [(match_test "optimize_function_for_size_p (cfun)")
3065                           (const_string "V4SF")
3066                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3067                           (const_string "TI")
3068                        ]
3069                        (const_string "V2DF"))
3070
3071                /* For architectures resolving dependencies on
3072                   whole SSE registers use APD move to break dependency
3073                   chains, otherwise use short move to avoid extra work.
3074
3075                   movaps encodes one byte shorter.  */
3076                (eq_attr "alternative" "8")
3077                  (cond
3078                    [(match_test "optimize_function_for_size_p (cfun)")
3079                       (const_string "V4SF")
3080                     (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3081                       (const_string "V2DF")
3082                    ]
3083                    (const_string "DF"))
3084                /* For architectures resolving dependencies on register
3085                   parts we may avoid extra work to zero out upper part
3086                   of register.  */
3087                (eq_attr "alternative" "9")
3088                  (if_then_else
3089                    (match_test "TARGET_SSE_SPLIT_REGS")
3090                    (const_string "V1DF")
3091                    (const_string "DF"))
3092               ]
3093               (const_string "DF")))])
3094
3095 ;; Possible store forwarding (partial memory) stall in alternative 4.
3096 (define_insn "*movdf_internal"
3097   [(set (match_operand:DF 0 "nonimmediate_operand"
3098                 "=Yf*f,m   ,Yf*f,?Yd*r ,!o   ,x,x,x,m,*x,*x,*x,m")
3099         (match_operand:DF 1 "general_operand"
3100                 "Yf*fm,Yf*f,G   ,Yd*roF,Yd*rF,C,x,m,x,C ,*x,m ,*x"))]
3101   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3102    && (!can_create_pseudo_p ()
3103        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3104        || GET_CODE (operands[1]) != CONST_DOUBLE
3105        || (optimize_function_for_size_p (cfun)
3106            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3107                 && standard_80387_constant_p (operands[1]) > 0)
3108                || (TARGET_SSE2 && TARGET_SSE_MATH
3109                    && standard_sse_constant_p (operands[1])))
3110            && !memory_operand (operands[0], DFmode))
3111        || (!TARGET_MEMORY_MISMATCH_STALL
3112            && memory_operand (operands[0], DFmode)))"
3113 {
3114   switch (which_alternative)
3115     {
3116     case 0:
3117     case 1:
3118       return output_387_reg_move (insn, operands);
3119
3120     case 2:
3121       return standard_80387_constant_opcode (operands[1]);
3122
3123     case 3:
3124     case 4:
3125       return "#";
3126
3127     case 5:
3128     case 9:
3129       return standard_sse_constant_opcode (insn, operands[1]);
3130
3131     case 6:
3132     case 7:
3133     case 8:
3134     case 10:
3135     case 11:
3136     case 12:
3137       switch (get_attr_mode (insn))
3138         {
3139         case MODE_V2DF:
3140           if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3141             return "%vmovapd\t{%1, %0|%0, %1}";
3142         case MODE_V4SF:
3143           return "%vmovaps\t{%1, %0|%0, %1}";
3144
3145         case MODE_DI:
3146           return "%vmovq\t{%1, %0|%0, %1}";
3147         case MODE_DF:
3148           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3149             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3150           return "%vmovsd\t{%1, %0|%0, %1}";
3151         case MODE_V1DF:
3152           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3153         case MODE_V2SF:
3154           return "%vmovlps\t{%1, %d0|%d0, %1}";
3155         default:
3156           gcc_unreachable ();
3157         }
3158
3159     default:
3160       gcc_unreachable ();
3161     }
3162 }
3163   [(set (attr "isa")
3164      (if_then_else (eq_attr "alternative" "5,6,7,8")
3165        (const_string "sse2")
3166        (const_string "*")))
3167    (set (attr "type")
3168         (cond [(eq_attr "alternative" "0,1,2")
3169                  (const_string "fmov")
3170                (eq_attr "alternative" "3,4")
3171                  (const_string "multi")
3172                (eq_attr "alternative" "5,9")
3173                  (const_string "sselog1")
3174               ]
3175               (const_string "ssemov")))
3176    (set (attr "prefix")
3177      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3178        (const_string "orig")
3179        (const_string "maybe_vex")))
3180    (set (attr "prefix_data16")
3181      (if_then_else (eq_attr "mode" "V1DF")
3182        (const_string "1")
3183        (const_string "*")))
3184    (set (attr "mode")
3185         (cond [(eq_attr "alternative" "0,1,2")
3186                  (const_string "DF")
3187                (eq_attr "alternative" "3,4")
3188                  (const_string "SI")
3189
3190                /* For SSE1, we have many fewer alternatives.  */
3191                (not (match_test "TARGET_SSE2"))
3192                  (if_then_else
3193                    (eq_attr "alternative" "5,6,9,10")
3194                    (const_string "V4SF")
3195                    (const_string "V2SF"))
3196
3197                /* xorps is one byte shorter.  */
3198                (eq_attr "alternative" "5,9")
3199                  (cond [(match_test "optimize_function_for_size_p (cfun)")
3200                           (const_string "V4SF")
3201                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3202                           (const_string "TI")
3203                        ]
3204                        (const_string "V2DF"))
3205
3206                /* For architectures resolving dependencies on
3207                   whole SSE registers use APD move to break dependency
3208                   chains, otherwise use short move to avoid extra work.
3209
3210                   movaps encodes one byte shorter.  */
3211                (eq_attr "alternative" "6,10")
3212                  (cond
3213                    [(match_test "optimize_function_for_size_p (cfun)")
3214                       (const_string "V4SF")
3215                     (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3216                       (const_string "V2DF")
3217                    ]
3218                    (const_string "DF"))
3219                /* For architectures resolving dependencies on register
3220                   parts we may avoid extra work to zero out upper part
3221                   of register.  */
3222                (eq_attr "alternative" "7,11")
3223                  (if_then_else
3224                    (match_test "TARGET_SSE_SPLIT_REGS")
3225                    (const_string "V1DF")
3226                    (const_string "DF"))
3227               ]
3228               (const_string "DF")))])
3229
3230 (define_insn "*movsf_internal"
3231   [(set (match_operand:SF 0 "nonimmediate_operand"
3232           "=Yf*f,m   ,Yf*f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3233         (match_operand:SF 1 "general_operand"
3234           "Yf*fm,Yf*f,G   ,rmF,rF,C,x,m,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
3235   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3236    && (!can_create_pseudo_p ()
3237        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3238        || GET_CODE (operands[1]) != CONST_DOUBLE
3239        || (optimize_function_for_size_p (cfun)
3240            && ((!TARGET_SSE_MATH
3241                 && standard_80387_constant_p (operands[1]) > 0)
3242                || (TARGET_SSE_MATH
3243                    && standard_sse_constant_p (operands[1]))))
3244        || memory_operand (operands[0], SFmode))"
3245 {
3246   switch (which_alternative)
3247     {
3248     case 0:
3249     case 1:
3250       return output_387_reg_move (insn, operands);
3251
3252     case 2:
3253       return standard_80387_constant_opcode (operands[1]);
3254
3255     case 3:
3256     case 4:
3257       return "mov{l}\t{%1, %0|%0, %1}";
3258
3259     case 5:
3260       return standard_sse_constant_opcode (insn, operands[1]);
3261
3262     case 6:
3263       if (get_attr_mode (insn) == MODE_V4SF)
3264         return "%vmovaps\t{%1, %0|%0, %1}";
3265       if (TARGET_AVX)
3266         return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3267
3268     case 7:
3269     case 8:
3270       return "%vmovss\t{%1, %0|%0, %1}";
3271
3272     case 9:
3273     case 10:
3274     case 14:
3275     case 15:
3276       return "movd\t{%1, %0|%0, %1}";
3277
3278     case 11:
3279       return "movq\t{%1, %0|%0, %1}";
3280
3281     case 12:
3282     case 13:
3283       return "%vmovd\t{%1, %0|%0, %1}";
3284
3285     default:
3286       gcc_unreachable ();
3287     }
3288 }
3289   [(set (attr "type")
3290         (cond [(eq_attr "alternative" "0,1,2")
3291                  (const_string "fmov")
3292                (eq_attr "alternative" "3,4")
3293                  (const_string "imov")
3294                (eq_attr "alternative" "5")
3295                  (const_string "sselog1")
3296                (eq_attr "alternative" "9,10,11,14,15")
3297                  (const_string "mmxmov")
3298               ]
3299               (const_string "ssemov")))
3300    (set (attr "prefix")
3301      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3302        (const_string "maybe_vex")
3303        (const_string "orig")))
3304    (set (attr "mode")
3305         (cond [(eq_attr "alternative" "3,4,9,10")
3306                  (const_string "SI")
3307                (eq_attr "alternative" "5")
3308                  (if_then_else
3309                    (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3310                              (match_test "TARGET_SSE2"))
3311                         (not (match_test "optimize_function_for_size_p (cfun)")))
3312                    (const_string "TI")
3313                    (const_string "V4SF"))
3314                /* For architectures resolving dependencies on
3315                   whole SSE registers use APS move to break dependency
3316                   chains, otherwise use short move to avoid extra work.
3317
3318                   Do the same for architectures resolving dependencies on
3319                   the parts.  While in DF mode it is better to always handle
3320                   just register parts, the SF mode is different due to lack
3321                   of instructions to load just part of the register.  It is
3322                   better to maintain the whole registers in single format
3323                   to avoid problems on using packed logical operations.  */
3324                (eq_attr "alternative" "6")
3325                  (if_then_else
3326                    (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3327                         (match_test "TARGET_SSE_SPLIT_REGS"))
3328                    (const_string "V4SF")
3329                    (const_string "SF"))
3330                (eq_attr "alternative" "11")
3331                  (const_string "DI")]
3332                (const_string "SF")))])
3333
3334 (define_split
3335   [(set (match_operand 0 "any_fp_register_operand" "")
3336         (match_operand 1 "memory_operand" ""))]
3337   "reload_completed
3338    && (GET_MODE (operands[0]) == TFmode
3339        || GET_MODE (operands[0]) == XFmode
3340        || GET_MODE (operands[0]) == DFmode
3341        || GET_MODE (operands[0]) == SFmode)
3342    && (operands[2] = find_constant_src (insn))"
3343   [(set (match_dup 0) (match_dup 2))]
3344 {
3345   rtx c = operands[2];
3346   int r = REGNO (operands[0]);
3347
3348   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3349       || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3350     FAIL;
3351 })
3352
3353 (define_split
3354   [(set (match_operand 0 "any_fp_register_operand" "")
3355         (float_extend (match_operand 1 "memory_operand" "")))]
3356   "reload_completed
3357    && (GET_MODE (operands[0]) == TFmode
3358        || GET_MODE (operands[0]) == XFmode
3359        || GET_MODE (operands[0]) == DFmode)
3360    && (operands[2] = find_constant_src (insn))"
3361   [(set (match_dup 0) (match_dup 2))]
3362 {
3363   rtx c = operands[2];
3364   int r = REGNO (operands[0]);
3365
3366   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3367       || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3368     FAIL;
3369 })
3370
3371 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3372 (define_split
3373   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3374         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3375   "reload_completed
3376    && (standard_80387_constant_p (operands[1]) == 8
3377        || standard_80387_constant_p (operands[1]) == 9)"
3378   [(set (match_dup 0)(match_dup 1))
3379    (set (match_dup 0)
3380         (neg:X87MODEF (match_dup 0)))]
3381 {
3382   REAL_VALUE_TYPE r;
3383
3384   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3385   if (real_isnegzero (&r))
3386     operands[1] = CONST0_RTX (<MODE>mode);
3387   else
3388     operands[1] = CONST1_RTX (<MODE>mode);
3389 })
3390
3391 (define_split
3392   [(set (match_operand 0 "nonimmediate_operand" "")
3393         (match_operand 1 "general_operand" ""))]
3394   "reload_completed
3395    && (GET_MODE (operands[0]) == TFmode
3396        || GET_MODE (operands[0]) == XFmode
3397        || GET_MODE (operands[0]) == DFmode)
3398    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3399   [(const_int 0)]
3400   "ix86_split_long_move (operands); DONE;")
3401
3402 (define_insn "swapxf"
3403   [(set (match_operand:XF 0 "register_operand" "+f")
3404         (match_operand:XF 1 "register_operand" "+f"))
3405    (set (match_dup 1)
3406         (match_dup 0))]
3407   "TARGET_80387"
3408 {
3409   if (STACK_TOP_P (operands[0]))
3410     return "fxch\t%1";
3411   else
3412     return "fxch\t%0";
3413 }
3414   [(set_attr "type" "fxch")
3415    (set_attr "mode" "XF")])
3416
3417 (define_insn "*swap<mode>"
3418   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3419         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3420    (set (match_dup 1)
3421         (match_dup 0))]
3422   "TARGET_80387 || reload_completed"
3423 {
3424   if (STACK_TOP_P (operands[0]))
3425     return "fxch\t%1";
3426   else
3427     return "fxch\t%0";
3428 }
3429   [(set_attr "type" "fxch")
3430    (set_attr "mode" "<MODE>")])
3431 \f
3432 ;; Zero extension instructions
3433
3434 (define_expand "zero_extendsidi2"
3435   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3436         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3437   ""
3438 {
3439   if (!TARGET_64BIT)
3440     {
3441       emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3442       DONE;
3443     }
3444 })
3445
3446 (define_insn "*zero_extendsidi2_rex64"
3447   [(set (match_operand:DI 0 "nonimmediate_operand"  "=r,o,?*Ym,?*y,?*Yi,*x")
3448         (zero_extend:DI
3449          (match_operand:SI 1 "nonimmediate_operand" "rm,0,r   ,m  ,r   ,m")))]
3450   "TARGET_64BIT"
3451   "@
3452    mov{l}\t{%1, %k0|%k0, %1}
3453    #
3454    movd\t{%1, %0|%0, %1}
3455    movd\t{%1, %0|%0, %1}
3456    %vmovd\t{%1, %0|%0, %1}
3457    %vmovd\t{%1, %0|%0, %1}"
3458   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3459    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3460    (set_attr "prefix_0f" "0,*,*,*,*,*")
3461    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3462
3463 (define_split
3464   [(set (match_operand:DI 0 "memory_operand" "")
3465         (zero_extend:DI (match_dup 0)))]
3466   "TARGET_64BIT"
3467   [(set (match_dup 4) (const_int 0))]
3468   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3469
3470 ;; %%% Kill me once multi-word ops are sane.
3471 (define_insn "zero_extendsidi2_1"
3472   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*x")
3473         (zero_extend:DI
3474          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3475    (clobber (reg:CC FLAGS_REG))]
3476   "!TARGET_64BIT"
3477   "@
3478    #
3479    #
3480    #
3481    movd\t{%1, %0|%0, %1}
3482    movd\t{%1, %0|%0, %1}
3483    %vmovd\t{%1, %0|%0, %1}
3484    %vmovd\t{%1, %0|%0, %1}"
3485   [(set_attr "isa" "*,*,*,*,*,*,sse2")
3486    (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3487    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3488    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3489
3490 (define_split
3491   [(set (match_operand:DI 0 "register_operand" "")
3492         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3493    (clobber (reg:CC FLAGS_REG))]
3494   "!TARGET_64BIT && reload_completed
3495    && true_regnum (operands[0]) == true_regnum (operands[1])"
3496   [(set (match_dup 4) (const_int 0))]
3497   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3498
3499 (define_split
3500   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3501         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3502    (clobber (reg:CC FLAGS_REG))]
3503   "!TARGET_64BIT && reload_completed
3504    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3505   [(set (match_dup 3) (match_dup 1))
3506    (set (match_dup 4) (const_int 0))]
3507   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3508
3509 (define_insn "zero_extend<mode>di2"
3510   [(set (match_operand:DI 0 "register_operand" "=r")
3511         (zero_extend:DI
3512          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3513   "TARGET_64BIT"
3514   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3515   [(set_attr "type" "imovx")
3516    (set_attr "mode" "SI")])
3517
3518 (define_expand "zero_extendhisi2"
3519   [(set (match_operand:SI 0 "register_operand" "")
3520         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3521   ""
3522 {
3523   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3524     {
3525       operands[1] = force_reg (HImode, operands[1]);
3526       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3527       DONE;
3528     }
3529 })
3530
3531 (define_insn_and_split "zero_extendhisi2_and"
3532   [(set (match_operand:SI 0 "register_operand" "=r")
3533         (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3534    (clobber (reg:CC FLAGS_REG))]
3535   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3536   "#"
3537   "&& reload_completed"
3538   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3539               (clobber (reg:CC FLAGS_REG))])]
3540   ""
3541   [(set_attr "type" "alu1")
3542    (set_attr "mode" "SI")])
3543
3544 (define_insn "*zero_extendhisi2_movzwl"
3545   [(set (match_operand:SI 0 "register_operand" "=r")
3546         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3547   "!TARGET_ZERO_EXTEND_WITH_AND
3548    || optimize_function_for_size_p (cfun)"
3549   "movz{wl|x}\t{%1, %0|%0, %1}"
3550   [(set_attr "type" "imovx")
3551    (set_attr "mode" "SI")])
3552
3553 (define_expand "zero_extendqi<mode>2"
3554   [(parallel
3555     [(set (match_operand:SWI24 0 "register_operand" "")
3556           (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3557      (clobber (reg:CC FLAGS_REG))])])
3558
3559 (define_insn "*zero_extendqi<mode>2_and"
3560   [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3561         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3562    (clobber (reg:CC FLAGS_REG))]
3563   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3564   "#"
3565   [(set_attr "type" "alu1")
3566    (set_attr "mode" "<MODE>")])
3567
3568 ;; When source and destination does not overlap, clear destination
3569 ;; first and then do the movb
3570 (define_split
3571   [(set (match_operand:SWI24 0 "register_operand" "")
3572         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3573    (clobber (reg:CC FLAGS_REG))]
3574   "reload_completed
3575    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3576    && ANY_QI_REG_P (operands[0])
3577    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3578    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3579   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3580 {
3581   operands[2] = gen_lowpart (QImode, operands[0]);
3582   ix86_expand_clear (operands[0]);
3583 })
3584
3585 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3586   [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3587         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3588    (clobber (reg:CC FLAGS_REG))]
3589   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3590   "#"
3591   [(set_attr "type" "imovx,alu1")
3592    (set_attr "mode" "<MODE>")])
3593
3594 ;; For the movzbl case strip only the clobber
3595 (define_split
3596   [(set (match_operand:SWI24 0 "register_operand" "")
3597         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3598    (clobber (reg:CC FLAGS_REG))]
3599   "reload_completed
3600    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3601    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3602   [(set (match_dup 0)
3603         (zero_extend:SWI24 (match_dup 1)))])
3604
3605 ; zero extend to SImode to avoid partial register stalls
3606 (define_insn "*zero_extendqi<mode>2_movzbl"
3607   [(set (match_operand:SWI24 0 "register_operand" "=r")
3608         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3609   "reload_completed
3610    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3611   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3612   [(set_attr "type" "imovx")
3613    (set_attr "mode" "SI")])
3614
3615 ;; Rest is handled by single and.
3616 (define_split
3617   [(set (match_operand:SWI24 0 "register_operand" "")
3618         (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3619    (clobber (reg:CC FLAGS_REG))]
3620   "reload_completed
3621    && true_regnum (operands[0]) == true_regnum (operands[1])"
3622   [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3623               (clobber (reg:CC FLAGS_REG))])])
3624 \f
3625 ;; Sign extension instructions
3626
3627 (define_expand "extendsidi2"
3628   [(set (match_operand:DI 0 "register_operand" "")
3629         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3630   ""
3631 {
3632   if (!TARGET_64BIT)
3633     {
3634       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3635       DONE;
3636     }
3637 })
3638
3639 (define_insn "*extendsidi2_rex64"
3640   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3641         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3642   "TARGET_64BIT"
3643   "@
3644    {cltq|cdqe}
3645    movs{lq|x}\t{%1, %0|%0, %1}"
3646   [(set_attr "type" "imovx")
3647    (set_attr "mode" "DI")
3648    (set_attr "prefix_0f" "0")
3649    (set_attr "modrm" "0,1")])
3650
3651 (define_insn "extendsidi2_1"
3652   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3653         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3654    (clobber (reg:CC FLAGS_REG))
3655    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3656   "!TARGET_64BIT"
3657   "#")
3658
3659 ;; Extend to memory case when source register does die.
3660 (define_split
3661   [(set (match_operand:DI 0 "memory_operand" "")
3662         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3663    (clobber (reg:CC FLAGS_REG))
3664    (clobber (match_operand:SI 2 "register_operand" ""))]
3665   "(reload_completed
3666     && dead_or_set_p (insn, operands[1])
3667     && !reg_mentioned_p (operands[1], operands[0]))"
3668   [(set (match_dup 3) (match_dup 1))
3669    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3670               (clobber (reg:CC FLAGS_REG))])
3671    (set (match_dup 4) (match_dup 1))]
3672   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3673
3674 ;; Extend to memory case when source register does not die.
3675 (define_split
3676   [(set (match_operand:DI 0 "memory_operand" "")
3677         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3678    (clobber (reg:CC FLAGS_REG))
3679    (clobber (match_operand:SI 2 "register_operand" ""))]
3680   "reload_completed"
3681   [(const_int 0)]
3682 {
3683   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3684
3685   emit_move_insn (operands[3], operands[1]);
3686
3687   /* Generate a cltd if possible and doing so it profitable.  */
3688   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3689       && true_regnum (operands[1]) == AX_REG
3690       && true_regnum (operands[2]) == DX_REG)
3691     {
3692       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3693     }
3694   else
3695     {
3696       emit_move_insn (operands[2], operands[1]);
3697       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3698     }
3699   emit_move_insn (operands[4], operands[2]);
3700   DONE;
3701 })
3702
3703 ;; Extend to register case.  Optimize case where source and destination
3704 ;; registers match and cases where we can use cltd.
3705 (define_split
3706   [(set (match_operand:DI 0 "register_operand" "")
3707         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3708    (clobber (reg:CC FLAGS_REG))
3709    (clobber (match_scratch:SI 2 ""))]
3710   "reload_completed"
3711   [(const_int 0)]
3712 {
3713   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3714
3715   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3716     emit_move_insn (operands[3], operands[1]);
3717
3718   /* Generate a cltd if possible and doing so it profitable.  */
3719   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3720       && true_regnum (operands[3]) == AX_REG
3721       && true_regnum (operands[4]) == DX_REG)
3722     {
3723       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3724       DONE;
3725     }
3726
3727   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3728     emit_move_insn (operands[4], operands[1]);
3729
3730   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3731   DONE;
3732 })
3733
3734 (define_insn "extend<mode>di2"
3735   [(set (match_operand:DI 0 "register_operand" "=r")
3736         (sign_extend:DI
3737          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3738   "TARGET_64BIT"
3739   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3740   [(set_attr "type" "imovx")
3741    (set_attr "mode" "DI")])
3742
3743 (define_insn "extendhisi2"
3744   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3745         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3746   ""
3747 {
3748   switch (get_attr_prefix_0f (insn))
3749     {
3750     case 0:
3751       return "{cwtl|cwde}";
3752     default:
3753       return "movs{wl|x}\t{%1, %0|%0, %1}";
3754     }
3755 }
3756   [(set_attr "type" "imovx")
3757    (set_attr "mode" "SI")
3758    (set (attr "prefix_0f")
3759      ;; movsx is short decodable while cwtl is vector decoded.
3760      (if_then_else (and (eq_attr "cpu" "!k6")
3761                         (eq_attr "alternative" "0"))
3762         (const_string "0")
3763         (const_string "1")))
3764    (set (attr "modrm")
3765      (if_then_else (eq_attr "prefix_0f" "0")
3766         (const_string "0")
3767         (const_string "1")))])
3768
3769 (define_insn "*extendhisi2_zext"
3770   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3771         (zero_extend:DI
3772          (sign_extend:SI
3773           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3774   "TARGET_64BIT"
3775 {
3776   switch (get_attr_prefix_0f (insn))
3777     {
3778     case 0:
3779       return "{cwtl|cwde}";
3780     default:
3781       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3782     }
3783 }
3784   [(set_attr "type" "imovx")
3785    (set_attr "mode" "SI")
3786    (set (attr "prefix_0f")
3787      ;; movsx is short decodable while cwtl is vector decoded.
3788      (if_then_else (and (eq_attr "cpu" "!k6")
3789                         (eq_attr "alternative" "0"))
3790         (const_string "0")
3791         (const_string "1")))
3792    (set (attr "modrm")
3793      (if_then_else (eq_attr "prefix_0f" "0")
3794         (const_string "0")
3795         (const_string "1")))])
3796
3797 (define_insn "extendqisi2"
3798   [(set (match_operand:SI 0 "register_operand" "=r")
3799         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3800   ""
3801   "movs{bl|x}\t{%1, %0|%0, %1}"
3802    [(set_attr "type" "imovx")
3803     (set_attr "mode" "SI")])
3804
3805 (define_insn "*extendqisi2_zext"
3806   [(set (match_operand:DI 0 "register_operand" "=r")
3807         (zero_extend:DI
3808           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3809   "TARGET_64BIT"
3810   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3811    [(set_attr "type" "imovx")
3812     (set_attr "mode" "SI")])
3813
3814 (define_insn "extendqihi2"
3815   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3816         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3817   ""
3818 {
3819   switch (get_attr_prefix_0f (insn))
3820     {
3821     case 0:
3822       return "{cbtw|cbw}";
3823     default:
3824       return "movs{bw|x}\t{%1, %0|%0, %1}";
3825     }
3826 }
3827   [(set_attr "type" "imovx")
3828    (set_attr "mode" "HI")
3829    (set (attr "prefix_0f")
3830      ;; movsx is short decodable while cwtl is vector decoded.
3831      (if_then_else (and (eq_attr "cpu" "!k6")
3832                         (eq_attr "alternative" "0"))
3833         (const_string "0")
3834         (const_string "1")))
3835    (set (attr "modrm")
3836      (if_then_else (eq_attr "prefix_0f" "0")
3837         (const_string "0")
3838         (const_string "1")))])
3839 \f
3840 ;; Conversions between float and double.
3841
3842 ;; These are all no-ops in the model used for the 80387.
3843 ;; So just emit moves.
3844
3845 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3846 (define_split
3847   [(set (match_operand:DF 0 "push_operand" "")
3848         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3849   "reload_completed"
3850   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3851    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3852
3853 (define_split
3854   [(set (match_operand:XF 0 "push_operand" "")
3855         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3856   "reload_completed"
3857   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3858    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3859   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3860
3861 (define_expand "extendsfdf2"
3862   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3863         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3864   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3865 {
3866   /* ??? Needed for compress_float_constant since all fp constants
3867      are TARGET_LEGITIMATE_CONSTANT_P.  */
3868   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3869     {
3870       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3871           && standard_80387_constant_p (operands[1]) > 0)
3872         {
3873           operands[1] = simplify_const_unary_operation
3874             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3875           emit_move_insn_1 (operands[0], operands[1]);
3876           DONE;
3877         }
3878       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3879     }
3880 })
3881
3882 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3883    cvtss2sd:
3884       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3885       cvtps2pd xmm2,xmm1
3886    We do the conversion post reload to avoid producing of 128bit spills
3887    that might lead to ICE on 32bit target.  The sequence unlikely combine
3888    anyway.  */
3889 (define_split
3890   [(set (match_operand:DF 0 "register_operand" "")
3891         (float_extend:DF
3892           (match_operand:SF 1 "nonimmediate_operand" "")))]
3893   "TARGET_USE_VECTOR_FP_CONVERTS
3894    && optimize_insn_for_speed_p ()
3895    && reload_completed && SSE_REG_P (operands[0])"
3896    [(set (match_dup 2)
3897          (float_extend:V2DF
3898            (vec_select:V2SF
3899              (match_dup 3)
3900              (parallel [(const_int 0) (const_int 1)]))))]
3901 {
3902   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3903   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3904   /* Use movss for loading from memory, unpcklps reg, reg for registers.
3905      Try to avoid move when unpacking can be done in source.  */
3906   if (REG_P (operands[1]))
3907     {
3908       /* If it is unsafe to overwrite upper half of source, we need
3909          to move to destination and unpack there.  */
3910       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3911            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3912           && true_regnum (operands[0]) != true_regnum (operands[1]))
3913         {
3914           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3915           emit_move_insn (tmp, operands[1]);
3916         }
3917       else
3918         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3919       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3920                                              operands[3]));
3921     }
3922   else
3923     emit_insn (gen_vec_setv4sf_0 (operands[3],
3924                                   CONST0_RTX (V4SFmode), operands[1]));
3925 })
3926
3927 (define_insn "*extendsfdf2_mixed"
3928   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3929         (float_extend:DF
3930           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3931   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3932 {
3933   switch (which_alternative)
3934     {
3935     case 0:
3936     case 1:
3937       return output_387_reg_move (insn, operands);
3938
3939     case 2:
3940       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3941
3942     default:
3943       gcc_unreachable ();
3944     }
3945 }
3946   [(set_attr "type" "fmov,fmov,ssecvt")
3947    (set_attr "prefix" "orig,orig,maybe_vex")
3948    (set_attr "mode" "SF,XF,DF")])
3949
3950 (define_insn "*extendsfdf2_sse"
3951   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3952         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3953   "TARGET_SSE2 && TARGET_SSE_MATH"
3954   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3955   [(set_attr "type" "ssecvt")
3956    (set_attr "prefix" "maybe_vex")
3957    (set_attr "mode" "DF")])
3958
3959 (define_insn "*extendsfdf2_i387"
3960   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3961         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3962   "TARGET_80387"
3963   "* return output_387_reg_move (insn, operands);"
3964   [(set_attr "type" "fmov")
3965    (set_attr "mode" "SF,XF")])
3966
3967 (define_expand "extend<mode>xf2"
3968   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3969         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3970   "TARGET_80387"
3971 {
3972   /* ??? Needed for compress_float_constant since all fp constants
3973      are TARGET_LEGITIMATE_CONSTANT_P.  */
3974   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3975     {
3976       if (standard_80387_constant_p (operands[1]) > 0)
3977         {
3978           operands[1] = simplify_const_unary_operation
3979             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3980           emit_move_insn_1 (operands[0], operands[1]);
3981           DONE;
3982         }
3983       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3984     }
3985 })
3986
3987 (define_insn "*extend<mode>xf2_i387"
3988   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3989         (float_extend:XF
3990           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3991   "TARGET_80387"
3992   "* return output_387_reg_move (insn, operands);"
3993   [(set_attr "type" "fmov")
3994    (set_attr "mode" "<MODE>,XF")])
3995
3996 ;; %%% This seems bad bad news.
3997 ;; This cannot output into an f-reg because there is no way to be sure
3998 ;; of truncating in that case.  Otherwise this is just like a simple move
3999 ;; insn.  So we pretend we can output to a reg in order to get better
4000 ;; register preferencing, but we really use a stack slot.
4001
4002 ;; Conversion from DFmode to SFmode.
4003
4004 (define_expand "truncdfsf2"
4005   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4006         (float_truncate:SF
4007           (match_operand:DF 1 "nonimmediate_operand" "")))]
4008   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4009 {
4010   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4011     ;
4012   else if (flag_unsafe_math_optimizations)
4013     ;
4014   else
4015     {
4016       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4017       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4018       DONE;
4019     }
4020 })
4021
4022 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4023    cvtsd2ss:
4024       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4025       cvtpd2ps xmm2,xmm1
4026    We do the conversion post reload to avoid producing of 128bit spills
4027    that might lead to ICE on 32bit target.  The sequence unlikely combine
4028    anyway.  */
4029 (define_split
4030   [(set (match_operand:SF 0 "register_operand" "")
4031         (float_truncate:SF
4032           (match_operand:DF 1 "nonimmediate_operand" "")))]
4033   "TARGET_USE_VECTOR_FP_CONVERTS
4034    && optimize_insn_for_speed_p ()
4035    && reload_completed && SSE_REG_P (operands[0])"
4036    [(set (match_dup 2)
4037          (vec_concat:V4SF
4038            (float_truncate:V2SF
4039              (match_dup 4))
4040            (match_dup 3)))]
4041 {
4042   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4043   operands[3] = CONST0_RTX (V2SFmode);
4044   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4045   /* Use movsd for loading from memory, unpcklpd for registers.
4046      Try to avoid move when unpacking can be done in source, or SSE3
4047      movddup is available.  */
4048   if (REG_P (operands[1]))
4049     {
4050       if (!TARGET_SSE3
4051           && true_regnum (operands[0]) != true_regnum (operands[1])
4052           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4053               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4054         {
4055           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4056           emit_move_insn (tmp, operands[1]);
4057           operands[1] = tmp;
4058         }
4059       else if (!TARGET_SSE3)
4060         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4061       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4062     }
4063   else
4064     emit_insn (gen_sse2_loadlpd (operands[4],
4065                                  CONST0_RTX (V2DFmode), operands[1]));
4066 })
4067
4068 (define_expand "truncdfsf2_with_temp"
4069   [(parallel [(set (match_operand:SF 0 "" "")
4070                    (float_truncate:SF (match_operand:DF 1 "" "")))
4071               (clobber (match_operand:SF 2 "" ""))])])
4072
4073 (define_insn "*truncdfsf_fast_mixed"
4074   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4075         (float_truncate:SF
4076           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4077   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
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     default:
4086       gcc_unreachable ();
4087     }
4088 }
4089   [(set_attr "type" "fmov,ssecvt")
4090    (set_attr "prefix" "orig,maybe_vex")
4091    (set_attr "mode" "SF")])
4092
4093 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4094 ;; because nothing we do here is unsafe.
4095 (define_insn "*truncdfsf_fast_sse"
4096   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4097         (float_truncate:SF
4098           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4099   "TARGET_SSE2 && TARGET_SSE_MATH"
4100   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4101   [(set_attr "type" "ssecvt")
4102    (set_attr "prefix" "maybe_vex")
4103    (set_attr "mode" "SF")])
4104
4105 (define_insn "*truncdfsf_fast_i387"
4106   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4107         (float_truncate:SF
4108           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4109   "TARGET_80387 && flag_unsafe_math_optimizations"
4110   "* return output_387_reg_move (insn, operands);"
4111   [(set_attr "type" "fmov")
4112    (set_attr "mode" "SF")])
4113
4114 (define_insn "*truncdfsf_mixed"
4115   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,x ,?f,?x,?*r")
4116         (float_truncate:SF
4117           (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4118    (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
4119   "TARGET_MIX_SSE_I387"
4120 {
4121   switch (which_alternative)
4122     {
4123     case 0:
4124       return output_387_reg_move (insn, operands);
4125     case 1:
4126       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4127
4128     default:
4129       return "#";
4130     }
4131 }
4132   [(set_attr "isa" "*,sse2,*,*,*")
4133    (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4134    (set_attr "unit" "*,*,i387,i387,i387")
4135    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4136    (set_attr "mode" "SF")])
4137
4138 (define_insn "*truncdfsf_i387"
4139   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4140         (float_truncate:SF
4141           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4142    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4143   "TARGET_80387"
4144 {
4145   switch (which_alternative)
4146     {
4147     case 0:
4148       return output_387_reg_move (insn, operands);
4149
4150     default:
4151       return "#";
4152     }
4153 }
4154   [(set_attr "type" "fmov,multi,multi,multi")
4155    (set_attr "unit" "*,i387,i387,i387")
4156    (set_attr "mode" "SF")])
4157
4158 (define_insn "*truncdfsf2_i387_1"
4159   [(set (match_operand:SF 0 "memory_operand" "=m")
4160         (float_truncate:SF
4161           (match_operand:DF 1 "register_operand" "f")))]
4162   "TARGET_80387
4163    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4164    && !TARGET_MIX_SSE_I387"
4165   "* return output_387_reg_move (insn, operands);"
4166   [(set_attr "type" "fmov")
4167    (set_attr "mode" "SF")])
4168
4169 (define_split
4170   [(set (match_operand:SF 0 "register_operand" "")
4171         (float_truncate:SF
4172          (match_operand:DF 1 "fp_register_operand" "")))
4173    (clobber (match_operand 2 "" ""))]
4174   "reload_completed"
4175   [(set (match_dup 2) (match_dup 1))
4176    (set (match_dup 0) (match_dup 2))]
4177   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4178
4179 ;; Conversion from XFmode to {SF,DF}mode
4180
4181 (define_expand "truncxf<mode>2"
4182   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4183                    (float_truncate:MODEF
4184                      (match_operand:XF 1 "register_operand" "")))
4185               (clobber (match_dup 2))])]
4186   "TARGET_80387"
4187 {
4188   if (flag_unsafe_math_optimizations)
4189     {
4190       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4191       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4192       if (reg != operands[0])
4193         emit_move_insn (operands[0], reg);
4194       DONE;
4195     }
4196   else
4197     operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4198 })
4199
4200 (define_insn "*truncxfsf2_mixed"
4201   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4202         (float_truncate:SF
4203           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4204    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4205   "TARGET_80387"
4206 {
4207   gcc_assert (!which_alternative);
4208   return output_387_reg_move (insn, operands);
4209 }
4210   [(set_attr "type" "fmov,multi,multi,multi")
4211    (set_attr "unit" "*,i387,i387,i387")
4212    (set_attr "mode" "SF")])
4213
4214 (define_insn "*truncxfdf2_mixed"
4215   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4216         (float_truncate:DF
4217           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4218    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4219   "TARGET_80387"
4220 {
4221   gcc_assert (!which_alternative);
4222   return output_387_reg_move (insn, operands);
4223 }
4224   [(set_attr "isa" "*,*,sse2,*")
4225    (set_attr "type" "fmov,multi,multi,multi")
4226    (set_attr "unit" "*,i387,i387,i387")
4227    (set_attr "mode" "DF")])
4228
4229 (define_insn "truncxf<mode>2_i387_noop"
4230   [(set (match_operand:MODEF 0 "register_operand" "=f")
4231         (float_truncate:MODEF
4232           (match_operand:XF 1 "register_operand" "f")))]
4233   "TARGET_80387 && flag_unsafe_math_optimizations"
4234   "* return output_387_reg_move (insn, operands);"
4235   [(set_attr "type" "fmov")
4236    (set_attr "mode" "<MODE>")])
4237
4238 (define_insn "*truncxf<mode>2_i387"
4239   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4240         (float_truncate:MODEF
4241           (match_operand:XF 1 "register_operand" "f")))]
4242   "TARGET_80387"
4243   "* return output_387_reg_move (insn, operands);"
4244   [(set_attr "type" "fmov")
4245    (set_attr "mode" "<MODE>")])
4246
4247 (define_split
4248   [(set (match_operand:MODEF 0 "register_operand" "")
4249         (float_truncate:MODEF
4250           (match_operand:XF 1 "register_operand" "")))
4251    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4252   "TARGET_80387 && reload_completed"
4253   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4254    (set (match_dup 0) (match_dup 2))])
4255
4256 (define_split
4257   [(set (match_operand:MODEF 0 "memory_operand" "")
4258         (float_truncate:MODEF
4259           (match_operand:XF 1 "register_operand" "")))
4260    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4261   "TARGET_80387"
4262   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4263 \f
4264 ;; Signed conversion to DImode.
4265
4266 (define_expand "fix_truncxfdi2"
4267   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4268                    (fix:DI (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_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4275      DONE;
4276    }
4277 })
4278
4279 (define_expand "fix_trunc<mode>di2"
4280   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4281                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4282               (clobber (reg:CC FLAGS_REG))])]
4283   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4284 {
4285   if (TARGET_FISTTP
4286       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4287    {
4288      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4289      DONE;
4290    }
4291   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4292    {
4293      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4294      emit_insn (gen_fix_trunc<mode>di_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 SImode.
4302
4303 (define_expand "fix_truncxfsi2"
4304   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4305                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4306               (clobber (reg:CC FLAGS_REG))])]
4307   "TARGET_80387"
4308 {
4309   if (TARGET_FISTTP)
4310    {
4311      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4312      DONE;
4313    }
4314 })
4315
4316 (define_expand "fix_trunc<mode>si2"
4317   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4318                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4319               (clobber (reg:CC FLAGS_REG))])]
4320   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4321 {
4322   if (TARGET_FISTTP
4323       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4324    {
4325      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4326      DONE;
4327    }
4328   if (SSE_FLOAT_MODE_P (<MODE>mode))
4329    {
4330      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4331      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4332      if (out != operands[0])
4333         emit_move_insn (operands[0], out);
4334      DONE;
4335    }
4336 })
4337
4338 ;; Signed conversion to HImode.
4339
4340 (define_expand "fix_trunc<mode>hi2"
4341   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4342                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4343               (clobber (reg:CC FLAGS_REG))])]
4344   "TARGET_80387
4345    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4346 {
4347   if (TARGET_FISTTP)
4348    {
4349      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4350      DONE;
4351    }
4352 })
4353
4354 ;; Unsigned conversion to SImode.
4355
4356 (define_expand "fixuns_trunc<mode>si2"
4357   [(parallel
4358     [(set (match_operand:SI 0 "register_operand" "")
4359           (unsigned_fix:SI
4360             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4361      (use (match_dup 2))
4362      (clobber (match_scratch:<ssevecmode> 3 ""))
4363      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4364   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4365 {
4366   enum machine_mode mode = <MODE>mode;
4367   enum machine_mode vecmode = <ssevecmode>mode;
4368   REAL_VALUE_TYPE TWO31r;
4369   rtx two31;
4370
4371   if (optimize_insn_for_size_p ())
4372     FAIL;
4373
4374   real_ldexp (&TWO31r, &dconst1, 31);
4375   two31 = const_double_from_real_value (TWO31r, mode);
4376   two31 = ix86_build_const_vector (vecmode, true, two31);
4377   operands[2] = force_reg (vecmode, two31);
4378 })
4379
4380 (define_insn_and_split "*fixuns_trunc<mode>_1"
4381   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4382         (unsigned_fix:SI
4383           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4384    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4385    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4386    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4387   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4388    && optimize_function_for_speed_p (cfun)"
4389   "#"
4390   "&& reload_completed"
4391   [(const_int 0)]
4392 {
4393   ix86_split_convert_uns_si_sse (operands);
4394   DONE;
4395 })
4396
4397 ;; Unsigned conversion to HImode.
4398 ;; Without these patterns, we'll try the unsigned SI conversion which
4399 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4400
4401 (define_expand "fixuns_trunc<mode>hi2"
4402   [(set (match_dup 2)
4403         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4404    (set (match_operand:HI 0 "nonimmediate_operand" "")
4405         (subreg:HI (match_dup 2) 0))]
4406   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4407   "operands[2] = gen_reg_rtx (SImode);")
4408
4409 ;; When SSE is available, it is always faster to use it!
4410 (define_insn "fix_trunc<mode>di_sse"
4411   [(set (match_operand:DI 0 "register_operand" "=r,r")
4412         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4413   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4414    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4415   "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4416   [(set_attr "type" "sseicvt")
4417    (set_attr "prefix" "maybe_vex")
4418    (set_attr "prefix_rex" "1")
4419    (set_attr "mode" "<MODE>")
4420    (set_attr "athlon_decode" "double,vector")
4421    (set_attr "amdfam10_decode" "double,double")
4422    (set_attr "bdver1_decode" "double,double")])
4423
4424 (define_insn "fix_trunc<mode>si_sse"
4425   [(set (match_operand:SI 0 "register_operand" "=r,r")
4426         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4427   "SSE_FLOAT_MODE_P (<MODE>mode)
4428    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4429   "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4430   [(set_attr "type" "sseicvt")
4431    (set_attr "prefix" "maybe_vex")
4432    (set_attr "mode" "<MODE>")
4433    (set_attr "athlon_decode" "double,vector")
4434    (set_attr "amdfam10_decode" "double,double")
4435    (set_attr "bdver1_decode" "double,double")])
4436
4437 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4438 (define_peephole2
4439   [(set (match_operand:MODEF 0 "register_operand" "")
4440         (match_operand:MODEF 1 "memory_operand" ""))
4441    (set (match_operand:SWI48x 2 "register_operand" "")
4442         (fix:SWI48x (match_dup 0)))]
4443   "TARGET_SHORTEN_X87_SSE
4444    && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4445    && peep2_reg_dead_p (2, operands[0])"
4446   [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4447
4448 ;; Avoid vector decoded forms of the instruction.
4449 (define_peephole2
4450   [(match_scratch:DF 2 "x")
4451    (set (match_operand:SWI48x 0 "register_operand" "")
4452         (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4453   "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4454   [(set (match_dup 2) (match_dup 1))
4455    (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4456
4457 (define_peephole2
4458   [(match_scratch:SF 2 "x")
4459    (set (match_operand:SWI48x 0 "register_operand" "")
4460         (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4461   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4462   [(set (match_dup 2) (match_dup 1))
4463    (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4464
4465 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4466   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4467         (fix:SWI248x (match_operand 1 "register_operand" "")))]
4468   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4469    && TARGET_FISTTP
4470    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4471          && (TARGET_64BIT || <MODE>mode != DImode))
4472         && TARGET_SSE_MATH)
4473    && can_create_pseudo_p ()"
4474   "#"
4475   "&& 1"
4476   [(const_int 0)]
4477 {
4478   if (memory_operand (operands[0], VOIDmode))
4479     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4480   else
4481     {
4482       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4483       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4484                                                             operands[1],
4485                                                             operands[2]));
4486     }
4487   DONE;
4488 }
4489   [(set_attr "type" "fisttp")
4490    (set_attr "mode" "<MODE>")])
4491
4492 (define_insn "fix_trunc<mode>_i387_fisttp"
4493   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4494         (fix:SWI248x (match_operand 1 "register_operand" "f")))
4495    (clobber (match_scratch:XF 2 "=&1f"))]
4496   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4497    && TARGET_FISTTP
4498    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4499          && (TARGET_64BIT || <MODE>mode != DImode))
4500         && TARGET_SSE_MATH)"
4501   "* return output_fix_trunc (insn, operands, true);"
4502   [(set_attr "type" "fisttp")
4503    (set_attr "mode" "<MODE>")])
4504
4505 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4506   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4507         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4508    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4509    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
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         && TARGET_SSE_MATH)"
4515   "#"
4516   [(set_attr "type" "fisttp")
4517    (set_attr "mode" "<MODE>")])
4518
4519 (define_split
4520   [(set (match_operand:SWI248x 0 "register_operand" "")
4521         (fix:SWI248x (match_operand 1 "register_operand" "")))
4522    (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4523    (clobber (match_scratch 3 ""))]
4524   "reload_completed"
4525   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4526               (clobber (match_dup 3))])
4527    (set (match_dup 0) (match_dup 2))])
4528
4529 (define_split
4530   [(set (match_operand:SWI248x 0 "memory_operand" "")
4531         (fix:SWI248x (match_operand 1 "register_operand" "")))
4532    (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4533    (clobber (match_scratch 3 ""))]
4534   "reload_completed"
4535   [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4536               (clobber (match_dup 3))])])
4537
4538 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4539 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4540 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4541 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4542 ;; function in i386.c.
4543 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4544   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4545         (fix:SWI248x (match_operand 1 "register_operand" "")))
4546    (clobber (reg:CC FLAGS_REG))]
4547   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4548    && !TARGET_FISTTP
4549    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4550          && (TARGET_64BIT || <MODE>mode != DImode))
4551    && can_create_pseudo_p ()"
4552   "#"
4553   "&& 1"
4554   [(const_int 0)]
4555 {
4556   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4557
4558   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4559   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4560   if (memory_operand (operands[0], VOIDmode))
4561     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4562                                          operands[2], operands[3]));
4563   else
4564     {
4565       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4566       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4567                                                      operands[2], operands[3],
4568                                                      operands[4]));
4569     }
4570   DONE;
4571 }
4572   [(set_attr "type" "fistp")
4573    (set_attr "i387_cw" "trunc")
4574    (set_attr "mode" "<MODE>")])
4575
4576 (define_insn "fix_truncdi_i387"
4577   [(set (match_operand:DI 0 "memory_operand" "=m")
4578         (fix:DI (match_operand 1 "register_operand" "f")))
4579    (use (match_operand:HI 2 "memory_operand" "m"))
4580    (use (match_operand:HI 3 "memory_operand" "m"))
4581    (clobber (match_scratch:XF 4 "=&1f"))]
4582   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4583    && !TARGET_FISTTP
4584    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4585   "* return output_fix_trunc (insn, operands, false);"
4586   [(set_attr "type" "fistp")
4587    (set_attr "i387_cw" "trunc")
4588    (set_attr "mode" "DI")])
4589
4590 (define_insn "fix_truncdi_i387_with_temp"
4591   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4592         (fix:DI (match_operand 1 "register_operand" "f,f")))
4593    (use (match_operand:HI 2 "memory_operand" "m,m"))
4594    (use (match_operand:HI 3 "memory_operand" "m,m"))
4595    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4596    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4597   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4598    && !TARGET_FISTTP
4599    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4600   "#"
4601   [(set_attr "type" "fistp")
4602    (set_attr "i387_cw" "trunc")
4603    (set_attr "mode" "DI")])
4604
4605 (define_split
4606   [(set (match_operand:DI 0 "register_operand" "")
4607         (fix:DI (match_operand 1 "register_operand" "")))
4608    (use (match_operand:HI 2 "memory_operand" ""))
4609    (use (match_operand:HI 3 "memory_operand" ""))
4610    (clobber (match_operand:DI 4 "memory_operand" ""))
4611    (clobber (match_scratch 5 ""))]
4612   "reload_completed"
4613   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4614               (use (match_dup 2))
4615               (use (match_dup 3))
4616               (clobber (match_dup 5))])
4617    (set (match_dup 0) (match_dup 4))])
4618
4619 (define_split
4620   [(set (match_operand:DI 0 "memory_operand" "")
4621         (fix:DI (match_operand 1 "register_operand" "")))
4622    (use (match_operand:HI 2 "memory_operand" ""))
4623    (use (match_operand:HI 3 "memory_operand" ""))
4624    (clobber (match_operand:DI 4 "memory_operand" ""))
4625    (clobber (match_scratch 5 ""))]
4626   "reload_completed"
4627   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4628               (use (match_dup 2))
4629               (use (match_dup 3))
4630               (clobber (match_dup 5))])])
4631
4632 (define_insn "fix_trunc<mode>_i387"
4633   [(set (match_operand:SWI24 0 "memory_operand" "=m")
4634         (fix:SWI24 (match_operand 1 "register_operand" "f")))
4635    (use (match_operand:HI 2 "memory_operand" "m"))
4636    (use (match_operand:HI 3 "memory_operand" "m"))]
4637   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4638    && !TARGET_FISTTP
4639    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4640   "* return output_fix_trunc (insn, operands, false);"
4641   [(set_attr "type" "fistp")
4642    (set_attr "i387_cw" "trunc")
4643    (set_attr "mode" "<MODE>")])
4644
4645 (define_insn "fix_trunc<mode>_i387_with_temp"
4646   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4647         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4648    (use (match_operand:HI 2 "memory_operand" "m,m"))
4649    (use (match_operand:HI 3 "memory_operand" "m,m"))
4650    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4651   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4652    && !TARGET_FISTTP
4653    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4654   "#"
4655   [(set_attr "type" "fistp")
4656    (set_attr "i387_cw" "trunc")
4657    (set_attr "mode" "<MODE>")])
4658
4659 (define_split
4660   [(set (match_operand:SWI24 0 "register_operand" "")
4661         (fix:SWI24 (match_operand 1 "register_operand" "")))
4662    (use (match_operand:HI 2 "memory_operand" ""))
4663    (use (match_operand:HI 3 "memory_operand" ""))
4664    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4665   "reload_completed"
4666   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4667               (use (match_dup 2))
4668               (use (match_dup 3))])
4669    (set (match_dup 0) (match_dup 4))])
4670
4671 (define_split
4672   [(set (match_operand:SWI24 0 "memory_operand" "")
4673         (fix:SWI24 (match_operand 1 "register_operand" "")))
4674    (use (match_operand:HI 2 "memory_operand" ""))
4675    (use (match_operand:HI 3 "memory_operand" ""))
4676    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4677   "reload_completed"
4678   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4679               (use (match_dup 2))
4680               (use (match_dup 3))])])
4681
4682 (define_insn "x86_fnstcw_1"
4683   [(set (match_operand:HI 0 "memory_operand" "=m")
4684         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4685   "TARGET_80387"
4686   "fnstcw\t%0"
4687   [(set (attr "length")
4688         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4689    (set_attr "mode" "HI")
4690    (set_attr "unit" "i387")
4691    (set_attr "bdver1_decode" "vector")])
4692
4693 (define_insn "x86_fldcw_1"
4694   [(set (reg:HI FPCR_REG)
4695         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4696   "TARGET_80387"
4697   "fldcw\t%0"
4698   [(set (attr "length")
4699         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4700    (set_attr "mode" "HI")
4701    (set_attr "unit" "i387")
4702    (set_attr "athlon_decode" "vector")
4703    (set_attr "amdfam10_decode" "vector")
4704    (set_attr "bdver1_decode" "vector")])
4705 \f
4706 ;; Conversion between fixed point and floating point.
4707
4708 ;; Even though we only accept memory inputs, the backend _really_
4709 ;; wants to be able to do this between registers.
4710
4711 (define_expand "floathi<mode>2"
4712   [(set (match_operand:X87MODEF 0 "register_operand" "")
4713         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4714   "TARGET_80387
4715    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4716        || TARGET_MIX_SSE_I387)")
4717
4718 ;; Pre-reload splitter to add memory clobber to the pattern.
4719 (define_insn_and_split "*floathi<mode>2_1"
4720   [(set (match_operand:X87MODEF 0 "register_operand" "")
4721         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4722   "TARGET_80387
4723    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4724        || TARGET_MIX_SSE_I387)
4725    && can_create_pseudo_p ()"
4726   "#"
4727   "&& 1"
4728   [(parallel [(set (match_dup 0)
4729               (float:X87MODEF (match_dup 1)))
4730    (clobber (match_dup 2))])]
4731   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4732
4733 (define_insn "*floathi<mode>2_i387_with_temp"
4734   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4735         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4736   (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4737   "TARGET_80387
4738    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4739        || TARGET_MIX_SSE_I387)"
4740   "#"
4741   [(set_attr "type" "fmov,multi")
4742    (set_attr "mode" "<MODE>")
4743    (set_attr "unit" "*,i387")
4744    (set_attr "fp_int_src" "true")])
4745
4746 (define_insn "*floathi<mode>2_i387"
4747   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4748         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4749   "TARGET_80387
4750    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4751        || TARGET_MIX_SSE_I387)"
4752   "fild%Z1\t%1"
4753   [(set_attr "type" "fmov")
4754    (set_attr "mode" "<MODE>")
4755    (set_attr "fp_int_src" "true")])
4756
4757 (define_split
4758   [(set (match_operand:X87MODEF 0 "register_operand" "")
4759         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4760    (clobber (match_operand:HI 2 "memory_operand" ""))]
4761   "TARGET_80387
4762    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4763        || TARGET_MIX_SSE_I387)
4764    && reload_completed"
4765   [(set (match_dup 2) (match_dup 1))
4766    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4767
4768 (define_split
4769   [(set (match_operand:X87MODEF 0 "register_operand" "")
4770         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4771    (clobber (match_operand:HI 2 "memory_operand" ""))]
4772    "TARGET_80387
4773     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4774         || TARGET_MIX_SSE_I387)
4775     && reload_completed"
4776   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4777
4778 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4779   [(set (match_operand:X87MODEF 0 "register_operand" "")
4780         (float:X87MODEF
4781           (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4782   "TARGET_80387
4783    || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4784        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4785 {
4786   if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4787         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4788       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4789     {
4790       rtx reg = gen_reg_rtx (XFmode);
4791       rtx (*insn)(rtx, rtx);
4792
4793       emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4794
4795       if (<X87MODEF:MODE>mode == SFmode)
4796         insn = gen_truncxfsf2;
4797       else if (<X87MODEF:MODE>mode == DFmode)
4798         insn = gen_truncxfdf2;
4799       else
4800         gcc_unreachable ();
4801
4802       emit_insn (insn (operands[0], reg));
4803       DONE;
4804     }
4805 })
4806
4807 ;; Pre-reload splitter to add memory clobber to the pattern.
4808 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4809   [(set (match_operand:X87MODEF 0 "register_operand" "")
4810         (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4811   "((TARGET_80387
4812      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4813      && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4814            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4815          || TARGET_MIX_SSE_I387))
4816     || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4817         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4818         && ((<SWI48x:MODE>mode == SImode
4819              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4820              && optimize_function_for_speed_p (cfun)
4821              && flag_trapping_math)
4822             || !(TARGET_INTER_UNIT_CONVERSIONS
4823                  || optimize_function_for_size_p (cfun)))))
4824    && can_create_pseudo_p ()"
4825   "#"
4826   "&& 1"
4827   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4828               (clobber (match_dup 2))])]
4829 {
4830   operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4831
4832   /* Avoid store forwarding (partial memory) stall penalty
4833      by passing DImode value through XMM registers.  */
4834   if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4835       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4836       && optimize_function_for_speed_p (cfun))
4837     {
4838       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4839                                                             operands[1],
4840                                                             operands[2]));
4841       DONE;
4842     }
4843 })
4844
4845 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4846   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4847         (float:MODEF
4848           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4849    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4850   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4851    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4852   "#"
4853   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4854    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4855    (set_attr "unit" "*,i387,*,*,*")
4856    (set_attr "athlon_decode" "*,*,double,direct,double")
4857    (set_attr "amdfam10_decode" "*,*,vector,double,double")
4858    (set_attr "bdver1_decode" "*,*,double,direct,double")
4859    (set_attr "fp_int_src" "true")])
4860
4861 (define_insn "*floatsi<mode>2_vector_mixed"
4862   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4863         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4864   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4865    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4866   "@
4867    fild%Z1\t%1
4868    #"
4869   [(set_attr "type" "fmov,sseicvt")
4870    (set_attr "mode" "<MODE>,<ssevecmode>")
4871    (set_attr "unit" "i387,*")
4872    (set_attr "athlon_decode" "*,direct")
4873    (set_attr "amdfam10_decode" "*,double")
4874    (set_attr "bdver1_decode" "*,direct")
4875    (set_attr "fp_int_src" "true")])
4876
4877 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4878   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4879         (float:MODEF
4880           (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4881    (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4882   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4883    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4884   "#"
4885   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4886    (set_attr "mode" "<MODEF:MODE>")
4887    (set_attr "unit" "*,i387,*,*")
4888    (set_attr "athlon_decode" "*,*,double,direct")
4889    (set_attr "amdfam10_decode" "*,*,vector,double")
4890    (set_attr "bdver1_decode" "*,*,double,direct")
4891    (set_attr "fp_int_src" "true")])
4892
4893 (define_split
4894   [(set (match_operand:MODEF 0 "register_operand" "")
4895         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4896    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4897   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4898    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4899    && TARGET_INTER_UNIT_CONVERSIONS
4900    && reload_completed
4901    && (SSE_REG_P (operands[0])
4902        || (GET_CODE (operands[0]) == SUBREG
4903            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4904   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4905
4906 (define_split
4907   [(set (match_operand:MODEF 0 "register_operand" "")
4908         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4909    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4910   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4911    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4912    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4913    && reload_completed
4914    && (SSE_REG_P (operands[0])
4915        || (GET_CODE (operands[0]) == SUBREG
4916            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4917   [(set (match_dup 2) (match_dup 1))
4918    (set (match_dup 0) (float:MODEF (match_dup 2)))])
4919
4920 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4921   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4922         (float:MODEF
4923           (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4924   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4925    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4926    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4927   "@
4928    fild%Z1\t%1
4929    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4930    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4931   [(set_attr "type" "fmov,sseicvt,sseicvt")
4932    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4933    (set_attr "mode" "<MODEF:MODE>")
4934    (set (attr "prefix_rex")
4935      (if_then_else
4936        (and (eq_attr "prefix" "maybe_vex")
4937             (match_test "<SWI48x:MODE>mode == DImode"))
4938        (const_string "1")
4939        (const_string "*")))
4940    (set_attr "unit" "i387,*,*")
4941    (set_attr "athlon_decode" "*,double,direct")
4942    (set_attr "amdfam10_decode" "*,vector,double")
4943    (set_attr "bdver1_decode" "*,double,direct")
4944    (set_attr "fp_int_src" "true")])
4945
4946 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4947   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4948         (float:MODEF
4949           (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4950   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4951    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4952    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4953   "@
4954    fild%Z1\t%1
4955    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4956   [(set_attr "type" "fmov,sseicvt")
4957    (set_attr "prefix" "orig,maybe_vex")
4958    (set_attr "mode" "<MODEF:MODE>")
4959    (set (attr "prefix_rex")
4960      (if_then_else
4961        (and (eq_attr "prefix" "maybe_vex")
4962             (match_test "<SWI48x:MODE>mode == DImode"))
4963        (const_string "1")
4964        (const_string "*")))
4965    (set_attr "athlon_decode" "*,direct")
4966    (set_attr "amdfam10_decode" "*,double")
4967    (set_attr "bdver1_decode" "*,direct")
4968    (set_attr "fp_int_src" "true")])
4969
4970 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4971   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4972         (float:MODEF
4973           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4974    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4975   "TARGET_SSE2 && TARGET_SSE_MATH
4976    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4977   "#"
4978   [(set_attr "type" "sseicvt")
4979    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4980    (set_attr "athlon_decode" "double,direct,double")
4981    (set_attr "amdfam10_decode" "vector,double,double")
4982    (set_attr "bdver1_decode" "double,direct,double")
4983    (set_attr "fp_int_src" "true")])
4984
4985 (define_insn "*floatsi<mode>2_vector_sse"
4986   [(set (match_operand:MODEF 0 "register_operand" "=x")
4987         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4988   "TARGET_SSE2 && TARGET_SSE_MATH
4989    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4990   "#"
4991   [(set_attr "type" "sseicvt")
4992    (set_attr "mode" "<MODE>")
4993    (set_attr "athlon_decode" "direct")
4994    (set_attr "amdfam10_decode" "double")
4995    (set_attr "bdver1_decode" "direct")
4996    (set_attr "fp_int_src" "true")])
4997
4998 (define_split
4999   [(set (match_operand:MODEF 0 "register_operand" "")
5000         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5001    (clobber (match_operand:SI 2 "memory_operand" ""))]
5002   "TARGET_SSE2 && TARGET_SSE_MATH
5003    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5004    && reload_completed
5005    && (SSE_REG_P (operands[0])
5006        || (GET_CODE (operands[0]) == SUBREG
5007            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5008   [(const_int 0)]
5009 {
5010   rtx op1 = operands[1];
5011
5012   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5013                                      <MODE>mode, 0);
5014   if (GET_CODE (op1) == SUBREG)
5015     op1 = SUBREG_REG (op1);
5016
5017   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5018     {
5019       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5020       emit_insn (gen_sse2_loadld (operands[4],
5021                                   CONST0_RTX (V4SImode), operands[1]));
5022     }
5023   /* We can ignore possible trapping value in the
5024      high part of SSE register for non-trapping math. */
5025   else if (SSE_REG_P (op1) && !flag_trapping_math)
5026     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5027   else
5028     {
5029       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5030       emit_move_insn (operands[2], operands[1]);
5031       emit_insn (gen_sse2_loadld (operands[4],
5032                                   CONST0_RTX (V4SImode), operands[2]));
5033     }
5034   if (<ssevecmode>mode == V4SFmode)
5035     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5036   else
5037     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5038   DONE;
5039 })
5040
5041 (define_split
5042   [(set (match_operand:MODEF 0 "register_operand" "")
5043         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5044    (clobber (match_operand:SI 2 "memory_operand" ""))]
5045   "TARGET_SSE2 && TARGET_SSE_MATH
5046    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5047    && reload_completed
5048    && (SSE_REG_P (operands[0])
5049        || (GET_CODE (operands[0]) == SUBREG
5050            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5051   [(const_int 0)]
5052 {
5053   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5054                                      <MODE>mode, 0);
5055   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5056
5057   emit_insn (gen_sse2_loadld (operands[4],
5058                               CONST0_RTX (V4SImode), operands[1]));
5059   if (<ssevecmode>mode == V4SFmode)
5060     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5061   else
5062     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5063   DONE;
5064 })
5065
5066 (define_split
5067   [(set (match_operand:MODEF 0 "register_operand" "")
5068         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5069   "TARGET_SSE2 && TARGET_SSE_MATH
5070    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5071    && reload_completed
5072    && (SSE_REG_P (operands[0])
5073        || (GET_CODE (operands[0]) == SUBREG
5074            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5075   [(const_int 0)]
5076 {
5077   rtx op1 = operands[1];
5078
5079   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5080                                      <MODE>mode, 0);
5081   if (GET_CODE (op1) == SUBREG)
5082     op1 = SUBREG_REG (op1);
5083
5084   if (GENERAL_REG_P (op1))
5085     {
5086       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5087       if (TARGET_INTER_UNIT_MOVES)
5088         emit_insn (gen_sse2_loadld (operands[4],
5089                                     CONST0_RTX (V4SImode), operands[1]));
5090       else
5091         {
5092           operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5093                                               operands[1]);
5094           emit_insn (gen_sse2_loadld (operands[4],
5095                                       CONST0_RTX (V4SImode), operands[5]));
5096           ix86_free_from_memory (GET_MODE (operands[1]));
5097         }
5098     }
5099   /* We can ignore possible trapping value in the
5100      high part of SSE register for non-trapping math. */
5101   else if (SSE_REG_P (op1) && !flag_trapping_math)
5102     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5103   else
5104     gcc_unreachable ();
5105   if (<ssevecmode>mode == V4SFmode)
5106     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5107   else
5108     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5109   DONE;
5110 })
5111
5112 (define_split
5113   [(set (match_operand:MODEF 0 "register_operand" "")
5114         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5115   "TARGET_SSE2 && TARGET_SSE_MATH
5116    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5117    && reload_completed
5118    && (SSE_REG_P (operands[0])
5119        || (GET_CODE (operands[0]) == SUBREG
5120            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5121   [(const_int 0)]
5122 {
5123   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5124                                      <MODE>mode, 0);
5125   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5126
5127   emit_insn (gen_sse2_loadld (operands[4],
5128                               CONST0_RTX (V4SImode), operands[1]));
5129   if (<ssevecmode>mode == V4SFmode)
5130     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5131   else
5132     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5133   DONE;
5134 })
5135
5136 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5137   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5138         (float:MODEF
5139           (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5140   (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5141   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5142    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5143   "#"
5144   [(set_attr "type" "sseicvt")
5145    (set_attr "mode" "<MODEF:MODE>")
5146    (set_attr "athlon_decode" "double,direct")
5147    (set_attr "amdfam10_decode" "vector,double")
5148    (set_attr "bdver1_decode" "double,direct")
5149    (set_attr "fp_int_src" "true")])
5150
5151 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5152   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5153         (float:MODEF
5154           (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5155   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5156    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5157    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5158   "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5159   [(set_attr "type" "sseicvt")
5160    (set_attr "prefix" "maybe_vex")
5161    (set_attr "mode" "<MODEF:MODE>")
5162    (set (attr "prefix_rex")
5163      (if_then_else
5164        (and (eq_attr "prefix" "maybe_vex")
5165             (match_test "<SWI48x:MODE>mode == DImode"))
5166        (const_string "1")
5167        (const_string "*")))
5168    (set_attr "athlon_decode" "double,direct")
5169    (set_attr "amdfam10_decode" "vector,double")
5170    (set_attr "bdver1_decode" "double,direct")
5171    (set_attr "fp_int_src" "true")])
5172
5173 (define_split
5174   [(set (match_operand:MODEF 0 "register_operand" "")
5175         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5176    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5177   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5178    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5179    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5180    && reload_completed
5181    && (SSE_REG_P (operands[0])
5182        || (GET_CODE (operands[0]) == SUBREG
5183            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5184   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5185
5186 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5187   [(set (match_operand:MODEF 0 "register_operand" "=x")
5188         (float:MODEF
5189           (match_operand:SWI48x 1 "memory_operand" "m")))]
5190   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5191    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5192    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5193   "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5194   [(set_attr "type" "sseicvt")
5195    (set_attr "prefix" "maybe_vex")
5196    (set_attr "mode" "<MODEF:MODE>")
5197    (set (attr "prefix_rex")
5198      (if_then_else
5199        (and (eq_attr "prefix" "maybe_vex")
5200             (match_test "<SWI48x:MODE>mode == DImode"))
5201        (const_string "1")
5202        (const_string "*")))
5203    (set_attr "athlon_decode" "direct")
5204    (set_attr "amdfam10_decode" "double")
5205    (set_attr "bdver1_decode" "direct")
5206    (set_attr "fp_int_src" "true")])
5207
5208 (define_split
5209   [(set (match_operand:MODEF 0 "register_operand" "")
5210         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5211    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5212   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5213    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5214    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5215    && reload_completed
5216    && (SSE_REG_P (operands[0])
5217        || (GET_CODE (operands[0]) == SUBREG
5218            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5219   [(set (match_dup 2) (match_dup 1))
5220    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5221
5222 (define_split
5223   [(set (match_operand:MODEF 0 "register_operand" "")
5224         (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5225    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5226   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5227    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5228    && reload_completed
5229    && (SSE_REG_P (operands[0])
5230        || (GET_CODE (operands[0]) == SUBREG
5231            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5232   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5233
5234 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5235   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5236         (float:X87MODEF
5237           (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5238   (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5239   "TARGET_80387
5240    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5241   "@
5242    fild%Z1\t%1
5243    #"
5244   [(set_attr "type" "fmov,multi")
5245    (set_attr "mode" "<X87MODEF:MODE>")
5246    (set_attr "unit" "*,i387")
5247    (set_attr "fp_int_src" "true")])
5248
5249 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5250   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5251         (float:X87MODEF
5252           (match_operand:SWI48x 1 "memory_operand" "m")))]
5253   "TARGET_80387
5254    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5255   "fild%Z1\t%1"
5256   [(set_attr "type" "fmov")
5257    (set_attr "mode" "<X87MODEF:MODE>")
5258    (set_attr "fp_int_src" "true")])
5259
5260 (define_split
5261   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5262         (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5263    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5264   "TARGET_80387
5265    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5266    && reload_completed"
5267   [(set (match_dup 2) (match_dup 1))
5268    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5269
5270 (define_split
5271   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5272         (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5273    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5274   "TARGET_80387
5275    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5276    && reload_completed"
5277   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5278
5279 ;; Avoid store forwarding (partial memory) stall penalty
5280 ;; by passing DImode value through XMM registers.  */
5281
5282 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5283   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5284         (float:X87MODEF
5285           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5286    (clobber (match_scratch:V4SI 3 "=X,x"))
5287    (clobber (match_scratch:V4SI 4 "=X,x"))
5288    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5289   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5290    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5291    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5292   "#"
5293   [(set_attr "type" "multi")
5294    (set_attr "mode" "<X87MODEF:MODE>")
5295    (set_attr "unit" "i387")
5296    (set_attr "fp_int_src" "true")])
5297
5298 (define_split
5299   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5300         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5301    (clobber (match_scratch:V4SI 3 ""))
5302    (clobber (match_scratch:V4SI 4 ""))
5303    (clobber (match_operand:DI 2 "memory_operand" ""))]
5304   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5305    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5306    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5307    && reload_completed"
5308   [(set (match_dup 2) (match_dup 3))
5309    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5310 {
5311   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5312      Assemble the 64-bit DImode value in an xmm register.  */
5313   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5314                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5315   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5316                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5317   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5318                                          operands[4]));
5319
5320   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5321 })
5322
5323 (define_split
5324   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5325         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5326    (clobber (match_scratch:V4SI 3 ""))
5327    (clobber (match_scratch:V4SI 4 ""))
5328    (clobber (match_operand:DI 2 "memory_operand" ""))]
5329   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5330    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5331    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5332    && reload_completed"
5333   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5334
5335 ;; Avoid store forwarding (partial memory) stall penalty by extending
5336 ;; SImode value to DImode through XMM register instead of pushing two
5337 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5338 ;; targets benefit from this optimization. Also note that fild
5339 ;; loads from memory only.
5340
5341 (define_insn "*floatunssi<mode>2_1"
5342   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5343         (unsigned_float:X87MODEF
5344           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5345    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5346    (clobber (match_scratch:SI 3 "=X,x"))]
5347   "!TARGET_64BIT
5348    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5349    && TARGET_SSE"
5350   "#"
5351   [(set_attr "type" "multi")
5352    (set_attr "mode" "<MODE>")])
5353
5354 (define_split
5355   [(set (match_operand:X87MODEF 0 "register_operand" "")
5356         (unsigned_float:X87MODEF
5357           (match_operand:SI 1 "register_operand" "")))
5358    (clobber (match_operand:DI 2 "memory_operand" ""))
5359    (clobber (match_scratch:SI 3 ""))]
5360   "!TARGET_64BIT
5361    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5362    && TARGET_SSE
5363    && reload_completed"
5364   [(set (match_dup 2) (match_dup 1))
5365    (set (match_dup 0)
5366         (float:X87MODEF (match_dup 2)))]
5367   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5368
5369 (define_split
5370   [(set (match_operand:X87MODEF 0 "register_operand" "")
5371         (unsigned_float:X87MODEF
5372           (match_operand:SI 1 "memory_operand" "")))
5373    (clobber (match_operand:DI 2 "memory_operand" ""))
5374    (clobber (match_scratch:SI 3 ""))]
5375   "!TARGET_64BIT
5376    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5377    && TARGET_SSE
5378    && reload_completed"
5379   [(set (match_dup 2) (match_dup 3))
5380    (set (match_dup 0)
5381         (float:X87MODEF (match_dup 2)))]
5382 {
5383   emit_move_insn (operands[3], operands[1]);
5384   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5385 })
5386
5387 (define_expand "floatunssi<mode>2"
5388   [(parallel
5389      [(set (match_operand:X87MODEF 0 "register_operand" "")
5390            (unsigned_float:X87MODEF
5391              (match_operand:SI 1 "nonimmediate_operand" "")))
5392       (clobber (match_dup 2))
5393       (clobber (match_scratch:SI 3 ""))])]
5394   "!TARGET_64BIT
5395    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5396         && TARGET_SSE)
5397        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5398 {
5399   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5400     {
5401       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5402       DONE;
5403     }
5404   else
5405     operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5406 })
5407
5408 (define_expand "floatunsdisf2"
5409   [(use (match_operand:SF 0 "register_operand" ""))
5410    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5411   "TARGET_64BIT && TARGET_SSE_MATH"
5412   "x86_emit_floatuns (operands); DONE;")
5413
5414 (define_expand "floatunsdidf2"
5415   [(use (match_operand:DF 0 "register_operand" ""))
5416    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5417   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5418    && TARGET_SSE2 && TARGET_SSE_MATH"
5419 {
5420   if (TARGET_64BIT)
5421     x86_emit_floatuns (operands);
5422   else
5423     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5424   DONE;
5425 })
5426 \f
5427 ;; Load effective address instructions
5428
5429 (define_insn_and_split "*lea<mode>"
5430   [(set (match_operand:SWI48 0 "register_operand" "=r")
5431         (match_operand:SWI48 1 "lea_address_operand" "p"))]
5432   ""
5433 {
5434   rtx addr = operands[1];
5435
5436   if (SImode_address_operand (addr, VOIDmode))
5437     {
5438       gcc_assert (TARGET_64BIT);
5439       return "lea{l}\t{%E1, %k0|%k0, %E1}";
5440     }
5441   else 
5442     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5443 }
5444   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5445   [(const_int 0)]
5446 {
5447   ix86_split_lea_for_addr (operands, <MODE>mode);
5448   DONE;
5449 }
5450   [(set_attr "type" "lea")
5451    (set (attr "mode")
5452      (if_then_else
5453        (match_operand 1 "SImode_address_operand")
5454        (const_string "SI")
5455        (const_string "<MODE>")))])
5456 \f
5457 ;; Add instructions
5458
5459 (define_expand "add<mode>3"
5460   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5461         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5462                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5463   ""
5464   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5465
5466 (define_insn_and_split "*add<dwi>3_doubleword"
5467   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5468         (plus:<DWI>
5469           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5470           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5471    (clobber (reg:CC FLAGS_REG))]
5472   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5473   "#"
5474   "reload_completed"
5475   [(parallel [(set (reg:CC FLAGS_REG)
5476                    (unspec:CC [(match_dup 1) (match_dup 2)]
5477                               UNSPEC_ADD_CARRY))
5478               (set (match_dup 0)
5479                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5480    (parallel [(set (match_dup 3)
5481                    (plus:DWIH
5482                      (match_dup 4)
5483                      (plus:DWIH
5484                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5485                        (match_dup 5))))
5486               (clobber (reg:CC FLAGS_REG))])]
5487   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5488
5489 (define_insn "*add<mode>3_cc"
5490   [(set (reg:CC FLAGS_REG)
5491         (unspec:CC
5492           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5493            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5494           UNSPEC_ADD_CARRY))
5495    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5496         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5497   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5498   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5499   [(set_attr "type" "alu")
5500    (set_attr "mode" "<MODE>")])
5501
5502 (define_insn "addqi3_cc"
5503   [(set (reg:CC FLAGS_REG)
5504         (unspec:CC
5505           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5506            (match_operand:QI 2 "general_operand" "qn,qm")]
5507           UNSPEC_ADD_CARRY))
5508    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5509         (plus:QI (match_dup 1) (match_dup 2)))]
5510   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5511   "add{b}\t{%2, %0|%0, %2}"
5512   [(set_attr "type" "alu")
5513    (set_attr "mode" "QI")])
5514
5515 (define_insn "*add<mode>_1"
5516   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5517         (plus:SWI48
5518           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5519           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5520    (clobber (reg:CC FLAGS_REG))]
5521   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5522 {
5523   switch (get_attr_type (insn))
5524     {
5525     case TYPE_LEA:
5526       return "#";
5527
5528     case TYPE_INCDEC:
5529       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5530       if (operands[2] == const1_rtx)
5531         return "inc{<imodesuffix>}\t%0";
5532       else
5533         {
5534           gcc_assert (operands[2] == constm1_rtx);
5535           return "dec{<imodesuffix>}\t%0";
5536         }
5537
5538     default:
5539       /* For most processors, ADD is faster than LEA.  This alternative
5540          was added to use ADD as much as possible.  */
5541       if (which_alternative == 2)
5542         {
5543           rtx tmp;
5544           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5545         }
5546         
5547       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5548       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5549         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5550
5551       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5552     }
5553 }
5554   [(set (attr "type")
5555      (cond [(eq_attr "alternative" "3")
5556               (const_string "lea")
5557             (match_operand:SWI48 2 "incdec_operand" "")
5558               (const_string "incdec")
5559            ]
5560            (const_string "alu")))
5561    (set (attr "length_immediate")
5562       (if_then_else
5563         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5564         (const_string "1")
5565         (const_string "*")))
5566    (set_attr "mode" "<MODE>")])
5567
5568 ;; It may seem that nonimmediate operand is proper one for operand 1.
5569 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5570 ;; we take care in ix86_binary_operator_ok to not allow two memory
5571 ;; operands so proper swapping will be done in reload.  This allow
5572 ;; patterns constructed from addsi_1 to match.
5573
5574 (define_insn "addsi_1_zext"
5575   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5576         (zero_extend:DI
5577           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5578                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5579    (clobber (reg:CC FLAGS_REG))]
5580   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5581 {
5582   switch (get_attr_type (insn))
5583     {
5584     case TYPE_LEA:
5585       return "#";
5586
5587     case TYPE_INCDEC:
5588       if (operands[2] == const1_rtx)
5589         return "inc{l}\t%k0";
5590       else
5591         {
5592           gcc_assert (operands[2] == constm1_rtx);
5593           return "dec{l}\t%k0";
5594         }
5595
5596     default:
5597       /* For most processors, ADD is faster than LEA.  This alternative
5598          was added to use ADD as much as possible.  */
5599       if (which_alternative == 1)
5600         {
5601           rtx tmp;
5602           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5603         }
5604
5605       if (x86_maybe_negate_const_int (&operands[2], SImode))
5606         return "sub{l}\t{%2, %k0|%k0, %2}";
5607
5608       return "add{l}\t{%2, %k0|%k0, %2}";
5609     }
5610 }
5611   [(set (attr "type")
5612      (cond [(eq_attr "alternative" "2")
5613               (const_string "lea")
5614             (match_operand:SI 2 "incdec_operand" "")
5615               (const_string "incdec")
5616            ]
5617            (const_string "alu")))
5618    (set (attr "length_immediate")
5619       (if_then_else
5620         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5621         (const_string "1")
5622         (const_string "*")))
5623    (set_attr "mode" "SI")])
5624
5625 (define_insn "*addhi_1"
5626   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5627         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5628                  (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5629    (clobber (reg:CC FLAGS_REG))]
5630   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5631 {
5632   switch (get_attr_type (insn))
5633     {
5634     case TYPE_LEA:
5635       return "#";
5636
5637     case TYPE_INCDEC:
5638       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5639       if (operands[2] == const1_rtx)
5640         return "inc{w}\t%0";
5641       else
5642         {
5643           gcc_assert (operands[2] == constm1_rtx);
5644           return "dec{w}\t%0";
5645         }
5646
5647     default:
5648       /* For most processors, ADD is faster than LEA.  This alternative
5649          was added to use ADD as much as possible.  */
5650       if (which_alternative == 2)
5651         {
5652           rtx tmp;
5653           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5654         }
5655
5656       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5657       if (x86_maybe_negate_const_int (&operands[2], HImode))
5658         return "sub{w}\t{%2, %0|%0, %2}";
5659
5660       return "add{w}\t{%2, %0|%0, %2}";
5661     }
5662 }
5663   [(set (attr "type")
5664      (cond [(eq_attr "alternative" "3")
5665               (const_string "lea")
5666             (match_operand:HI 2 "incdec_operand" "")
5667               (const_string "incdec")
5668            ]
5669            (const_string "alu")))
5670    (set (attr "length_immediate")
5671       (if_then_else
5672         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5673         (const_string "1")
5674         (const_string "*")))
5675    (set_attr "mode" "HI,HI,HI,SI")])
5676
5677 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5678 (define_insn "*addqi_1"
5679   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5680         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5681                  (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5682    (clobber (reg:CC FLAGS_REG))]
5683   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5684 {
5685   bool widen = (which_alternative == 3 || which_alternative == 4);
5686
5687   switch (get_attr_type (insn))
5688     {
5689     case TYPE_LEA:
5690       return "#";
5691
5692     case TYPE_INCDEC:
5693       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5694       if (operands[2] == const1_rtx)
5695         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5696       else
5697         {
5698           gcc_assert (operands[2] == constm1_rtx);
5699           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5700         }
5701
5702     default:
5703       /* For most processors, ADD is faster than LEA.  These alternatives
5704          were added to use ADD as much as possible.  */
5705       if (which_alternative == 2 || which_alternative == 4)
5706         {
5707           rtx tmp;
5708           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5709         }
5710
5711       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5712       if (x86_maybe_negate_const_int (&operands[2], QImode))
5713         {
5714           if (widen)
5715             return "sub{l}\t{%2, %k0|%k0, %2}";
5716           else
5717             return "sub{b}\t{%2, %0|%0, %2}";
5718         }
5719       if (widen)
5720         return "add{l}\t{%k2, %k0|%k0, %k2}";
5721       else
5722         return "add{b}\t{%2, %0|%0, %2}";
5723     }
5724 }
5725   [(set (attr "type")
5726      (cond [(eq_attr "alternative" "5")
5727               (const_string "lea")
5728             (match_operand:QI 2 "incdec_operand" "")
5729               (const_string "incdec")
5730            ]
5731            (const_string "alu")))
5732    (set (attr "length_immediate")
5733       (if_then_else
5734         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5735         (const_string "1")
5736         (const_string "*")))
5737    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5738
5739 (define_insn "*addqi_1_slp"
5740   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5741         (plus:QI (match_dup 0)
5742                  (match_operand:QI 1 "general_operand" "qn,qm")))
5743    (clobber (reg:CC FLAGS_REG))]
5744   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5745    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5746 {
5747   switch (get_attr_type (insn))
5748     {
5749     case TYPE_INCDEC:
5750       if (operands[1] == const1_rtx)
5751         return "inc{b}\t%0";
5752       else
5753         {
5754           gcc_assert (operands[1] == constm1_rtx);
5755           return "dec{b}\t%0";
5756         }
5757
5758     default:
5759       if (x86_maybe_negate_const_int (&operands[1], QImode))
5760         return "sub{b}\t{%1, %0|%0, %1}";
5761
5762       return "add{b}\t{%1, %0|%0, %1}";
5763     }
5764 }
5765   [(set (attr "type")
5766      (if_then_else (match_operand:QI 1 "incdec_operand" "")
5767         (const_string "incdec")
5768         (const_string "alu1")))
5769    (set (attr "memory")
5770      (if_then_else (match_operand 1 "memory_operand" "")
5771         (const_string "load")
5772         (const_string "none")))
5773    (set_attr "mode" "QI")])
5774
5775 ;; Split non destructive adds if we cannot use lea.
5776 (define_split
5777   [(set (match_operand:SWI48 0 "register_operand" "")
5778         (plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5779               (match_operand:SWI48 2 "nonmemory_operand" "")))
5780    (clobber (reg:CC FLAGS_REG))]
5781   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5782   [(set (match_dup 0) (match_dup 1))
5783    (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5784               (clobber (reg:CC FLAGS_REG))])])
5785
5786 ;; Convert add to the lea pattern to avoid flags dependency.
5787 (define_split
5788   [(set (match_operand:SWI 0 "register_operand" "")
5789         (plus:SWI (match_operand:SWI 1 "register_operand" "")
5790                   (match_operand:SWI 2 "<nonmemory_operand>" "")))
5791    (clobber (reg:CC FLAGS_REG))]
5792   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5793   [(const_int 0)]
5794 {
5795   enum machine_mode mode = <MODE>mode;
5796   rtx pat;
5797
5798   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5799     { 
5800       mode = SImode; 
5801       operands[0] = gen_lowpart (mode, operands[0]);
5802       operands[1] = gen_lowpart (mode, operands[1]);
5803       operands[2] = gen_lowpart (mode, operands[2]);
5804     }
5805
5806   pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5807
5808   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5809   DONE;
5810 })
5811
5812 ;; Convert add to the lea pattern to avoid flags dependency.
5813 (define_split
5814   [(set (match_operand:DI 0 "register_operand" "")
5815         (zero_extend:DI
5816           (plus:SI (match_operand:SI 1 "register_operand" "")
5817                    (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5818    (clobber (reg:CC FLAGS_REG))]
5819   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5820   [(set (match_dup 0)
5821         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5822
5823 (define_insn "*add<mode>_2"
5824   [(set (reg FLAGS_REG)
5825         (compare
5826           (plus:SWI
5827             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5828             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5829           (const_int 0)))
5830    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5831         (plus:SWI (match_dup 1) (match_dup 2)))]
5832   "ix86_match_ccmode (insn, CCGOCmode)
5833    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5834 {
5835   switch (get_attr_type (insn))
5836     {
5837     case TYPE_INCDEC:
5838       if (operands[2] == const1_rtx)
5839         return "inc{<imodesuffix>}\t%0";
5840       else
5841         {
5842           gcc_assert (operands[2] == constm1_rtx);
5843           return "dec{<imodesuffix>}\t%0";
5844         }
5845
5846     default:
5847       if (which_alternative == 2)
5848         {
5849           rtx tmp;
5850           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5851         }
5852         
5853       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5854       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5855         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5856
5857       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5858     }
5859 }
5860   [(set (attr "type")
5861      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5862         (const_string "incdec")
5863         (const_string "alu")))
5864    (set (attr "length_immediate")
5865       (if_then_else
5866         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5867         (const_string "1")
5868         (const_string "*")))
5869    (set_attr "mode" "<MODE>")])
5870
5871 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5872 (define_insn "*addsi_2_zext"
5873   [(set (reg FLAGS_REG)
5874         (compare
5875           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5876                    (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5877           (const_int 0)))
5878    (set (match_operand:DI 0 "register_operand" "=r,r")
5879         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5880   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5881    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5882 {
5883   switch (get_attr_type (insn))
5884     {
5885     case TYPE_INCDEC:
5886       if (operands[2] == const1_rtx)
5887         return "inc{l}\t%k0";
5888       else
5889         {
5890           gcc_assert (operands[2] == constm1_rtx);
5891           return "dec{l}\t%k0";
5892         }
5893
5894     default:
5895       if (which_alternative == 1)
5896         {
5897           rtx tmp;
5898           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5899         }
5900
5901       if (x86_maybe_negate_const_int (&operands[2], SImode))
5902         return "sub{l}\t{%2, %k0|%k0, %2}";
5903
5904       return "add{l}\t{%2, %k0|%k0, %2}";
5905     }
5906 }
5907   [(set (attr "type")
5908      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5909         (const_string "incdec")
5910         (const_string "alu")))
5911    (set (attr "length_immediate")
5912       (if_then_else
5913         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5914         (const_string "1")
5915         (const_string "*")))
5916    (set_attr "mode" "SI")])
5917
5918 (define_insn "*add<mode>_3"
5919   [(set (reg FLAGS_REG)
5920         (compare
5921           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5922           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5923    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5924   "ix86_match_ccmode (insn, CCZmode)
5925    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5926 {
5927   switch (get_attr_type (insn))
5928     {
5929     case TYPE_INCDEC:
5930       if (operands[2] == const1_rtx)
5931         return "inc{<imodesuffix>}\t%0";
5932       else
5933         {
5934           gcc_assert (operands[2] == constm1_rtx);
5935           return "dec{<imodesuffix>}\t%0";
5936         }
5937
5938     default:
5939       if (which_alternative == 1)
5940         {
5941           rtx tmp;
5942           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5943         }
5944
5945       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5946       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5947         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5948
5949       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5950     }
5951 }
5952   [(set (attr "type")
5953      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5954         (const_string "incdec")
5955         (const_string "alu")))
5956    (set (attr "length_immediate")
5957       (if_then_else
5958         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5959         (const_string "1")
5960         (const_string "*")))
5961    (set_attr "mode" "<MODE>")])
5962
5963 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5964 (define_insn "*addsi_3_zext"
5965   [(set (reg FLAGS_REG)
5966         (compare
5967           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5968           (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5969    (set (match_operand:DI 0 "register_operand" "=r,r")
5970         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5971   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5972    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5973 {
5974   switch (get_attr_type (insn))
5975     {
5976     case TYPE_INCDEC:
5977       if (operands[2] == const1_rtx)
5978         return "inc{l}\t%k0";
5979       else
5980         {
5981           gcc_assert (operands[2] == constm1_rtx);
5982           return "dec{l}\t%k0";
5983         }
5984
5985     default:
5986       if (which_alternative == 1)
5987         {
5988           rtx tmp;
5989           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5990         }
5991
5992       if (x86_maybe_negate_const_int (&operands[2], SImode))
5993         return "sub{l}\t{%2, %k0|%k0, %2}";
5994
5995       return "add{l}\t{%2, %k0|%k0, %2}";
5996     }
5997 }
5998   [(set (attr "type")
5999      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6000         (const_string "incdec")
6001         (const_string "alu")))
6002    (set (attr "length_immediate")
6003       (if_then_else
6004         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6005         (const_string "1")
6006         (const_string "*")))
6007    (set_attr "mode" "SI")])
6008
6009 ; For comparisons against 1, -1 and 128, we may generate better code
6010 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6011 ; is matched then.  We can't accept general immediate, because for
6012 ; case of overflows,  the result is messed up.
6013 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6014 ; only for comparisons not depending on it.
6015
6016 (define_insn "*adddi_4"
6017   [(set (reg FLAGS_REG)
6018         (compare
6019           (match_operand:DI 1 "nonimmediate_operand" "0")
6020           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6021    (clobber (match_scratch:DI 0 "=rm"))]
6022   "TARGET_64BIT
6023    && ix86_match_ccmode (insn, CCGCmode)"
6024 {
6025   switch (get_attr_type (insn))
6026     {
6027     case TYPE_INCDEC:
6028       if (operands[2] == constm1_rtx)
6029         return "inc{q}\t%0";
6030       else
6031         {
6032           gcc_assert (operands[2] == const1_rtx);
6033           return "dec{q}\t%0";
6034         }
6035
6036     default:
6037       if (x86_maybe_negate_const_int (&operands[2], DImode))
6038         return "add{q}\t{%2, %0|%0, %2}";
6039
6040       return "sub{q}\t{%2, %0|%0, %2}";
6041     }
6042 }
6043   [(set (attr "type")
6044      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6045         (const_string "incdec")
6046         (const_string "alu")))
6047    (set (attr "length_immediate")
6048       (if_then_else
6049         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6050         (const_string "1")
6051         (const_string "*")))
6052    (set_attr "mode" "DI")])
6053
6054 ; For comparisons against 1, -1 and 128, we may generate better code
6055 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6056 ; is matched then.  We can't accept general immediate, because for
6057 ; case of overflows,  the result is messed up.
6058 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6059 ; only for comparisons not depending on it.
6060
6061 (define_insn "*add<mode>_4"
6062   [(set (reg FLAGS_REG)
6063         (compare
6064           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6065           (match_operand:SWI124 2 "const_int_operand" "n")))
6066    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6067   "ix86_match_ccmode (insn, CCGCmode)"
6068 {
6069   switch (get_attr_type (insn))
6070     {
6071     case TYPE_INCDEC:
6072       if (operands[2] == constm1_rtx)
6073         return "inc{<imodesuffix>}\t%0";
6074       else
6075         {
6076           gcc_assert (operands[2] == const1_rtx);
6077           return "dec{<imodesuffix>}\t%0";
6078         }
6079
6080     default:
6081       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6082         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6083
6084       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6085     }
6086 }
6087   [(set (attr "type")
6088      (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6089         (const_string "incdec")
6090         (const_string "alu")))
6091    (set (attr "length_immediate")
6092       (if_then_else
6093         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6094         (const_string "1")
6095         (const_string "*")))
6096    (set_attr "mode" "<MODE>")])
6097
6098 (define_insn "*add<mode>_5"
6099   [(set (reg FLAGS_REG)
6100         (compare
6101           (plus:SWI
6102             (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6103             (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6104           (const_int 0)))
6105    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6106   "ix86_match_ccmode (insn, CCGOCmode)
6107    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6108 {
6109   switch (get_attr_type (insn))
6110     {
6111     case TYPE_INCDEC:
6112       if (operands[2] == const1_rtx)
6113         return "inc{<imodesuffix>}\t%0";
6114       else
6115         {
6116           gcc_assert (operands[2] == constm1_rtx);
6117           return "dec{<imodesuffix>}\t%0";
6118         }
6119
6120     default:
6121       if (which_alternative == 1)
6122         {
6123           rtx tmp;
6124           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6125         }
6126
6127       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6128       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6129         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6130
6131       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6132     }
6133 }
6134   [(set (attr "type")
6135      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6136         (const_string "incdec")
6137         (const_string "alu")))
6138    (set (attr "length_immediate")
6139       (if_then_else
6140         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6141         (const_string "1")
6142         (const_string "*")))
6143    (set_attr "mode" "<MODE>")])
6144
6145 (define_insn "*addqi_ext_1_rex64"
6146   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6147                          (const_int 8)
6148                          (const_int 8))
6149         (plus:SI
6150           (zero_extract:SI
6151             (match_operand 1 "ext_register_operand" "0")
6152             (const_int 8)
6153             (const_int 8))
6154           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6155    (clobber (reg:CC FLAGS_REG))]
6156   "TARGET_64BIT"
6157 {
6158   switch (get_attr_type (insn))
6159     {
6160     case TYPE_INCDEC:
6161       if (operands[2] == const1_rtx)
6162         return "inc{b}\t%h0";
6163       else
6164         {
6165           gcc_assert (operands[2] == constm1_rtx);
6166           return "dec{b}\t%h0";
6167         }
6168
6169     default:
6170       return "add{b}\t{%2, %h0|%h0, %2}";
6171     }
6172 }
6173   [(set (attr "type")
6174      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6175         (const_string "incdec")
6176         (const_string "alu")))
6177    (set_attr "modrm" "1")
6178    (set_attr "mode" "QI")])
6179
6180 (define_insn "addqi_ext_1"
6181   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6182                          (const_int 8)
6183                          (const_int 8))
6184         (plus:SI
6185           (zero_extract:SI
6186             (match_operand 1 "ext_register_operand" "0")
6187             (const_int 8)
6188             (const_int 8))
6189           (match_operand:QI 2 "general_operand" "Qmn")))
6190    (clobber (reg:CC FLAGS_REG))]
6191   "!TARGET_64BIT"
6192 {
6193   switch (get_attr_type (insn))
6194     {
6195     case TYPE_INCDEC:
6196       if (operands[2] == const1_rtx)
6197         return "inc{b}\t%h0";
6198       else
6199         {
6200           gcc_assert (operands[2] == constm1_rtx);
6201           return "dec{b}\t%h0";
6202         }
6203
6204     default:
6205       return "add{b}\t{%2, %h0|%h0, %2}";
6206     }
6207 }
6208   [(set (attr "type")
6209      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6210         (const_string "incdec")
6211         (const_string "alu")))
6212    (set_attr "modrm" "1")
6213    (set_attr "mode" "QI")])
6214
6215 (define_insn "*addqi_ext_2"
6216   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6217                          (const_int 8)
6218                          (const_int 8))
6219         (plus:SI
6220           (zero_extract:SI
6221             (match_operand 1 "ext_register_operand" "%0")
6222             (const_int 8)
6223             (const_int 8))
6224           (zero_extract:SI
6225             (match_operand 2 "ext_register_operand" "Q")
6226             (const_int 8)
6227             (const_int 8))))
6228    (clobber (reg:CC FLAGS_REG))]
6229   ""
6230   "add{b}\t{%h2, %h0|%h0, %h2}"
6231   [(set_attr "type" "alu")
6232    (set_attr "mode" "QI")])
6233
6234 ;; The lea patterns for modes less than 32 bits need to be matched by
6235 ;; several insns converted to real lea by splitters.
6236
6237 (define_insn_and_split "*lea_general_1"
6238   [(set (match_operand 0 "register_operand" "=r")
6239         (plus (plus (match_operand 1 "index_register_operand" "l")
6240                     (match_operand 2 "register_operand" "r"))
6241               (match_operand 3 "immediate_operand" "i")))]
6242   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6243    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6244    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6245    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6246    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6247        || GET_MODE (operands[3]) == VOIDmode)"
6248   "#"
6249   "&& reload_completed"
6250   [(const_int 0)]
6251 {
6252   enum machine_mode mode = SImode;
6253   rtx pat;
6254
6255   operands[0] = gen_lowpart (mode, operands[0]);
6256   operands[1] = gen_lowpart (mode, operands[1]);
6257   operands[2] = gen_lowpart (mode, operands[2]);
6258   operands[3] = gen_lowpart (mode, operands[3]);
6259
6260   pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6261                       operands[3]);
6262
6263   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6264   DONE;
6265 }
6266   [(set_attr "type" "lea")
6267    (set_attr "mode" "SI")])
6268
6269 (define_insn_and_split "*lea_general_2"
6270   [(set (match_operand 0 "register_operand" "=r")
6271         (plus (mult (match_operand 1 "index_register_operand" "l")
6272                     (match_operand 2 "const248_operand" "n"))
6273               (match_operand 3 "nonmemory_operand" "ri")))]
6274   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6275    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6276    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6277    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6278        || GET_MODE (operands[3]) == VOIDmode)"
6279   "#"
6280   "&& reload_completed"
6281   [(const_int 0)]
6282 {
6283   enum machine_mode mode = SImode;
6284   rtx pat;
6285
6286   operands[0] = gen_lowpart (mode, operands[0]);
6287   operands[1] = gen_lowpart (mode, operands[1]);
6288   operands[3] = gen_lowpart (mode, operands[3]);
6289
6290   pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6291                       operands[3]);
6292
6293   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6294   DONE;
6295 }
6296   [(set_attr "type" "lea")
6297    (set_attr "mode" "SI")])
6298
6299 (define_insn_and_split "*lea_general_3"
6300   [(set (match_operand 0 "register_operand" "=r")
6301         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6302                           (match_operand 2 "const248_operand" "n"))
6303                     (match_operand 3 "register_operand" "r"))
6304               (match_operand 4 "immediate_operand" "i")))]
6305   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6306    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6307    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6308    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6309   "#"
6310   "&& reload_completed"
6311   [(const_int 0)]
6312 {
6313   enum machine_mode mode = SImode;
6314   rtx pat;
6315
6316   operands[0] = gen_lowpart (mode, operands[0]);
6317   operands[1] = gen_lowpart (mode, operands[1]);
6318   operands[3] = gen_lowpart (mode, operands[3]);
6319   operands[4] = gen_lowpart (mode, operands[4]);
6320
6321   pat = gen_rtx_PLUS (mode,
6322                       gen_rtx_PLUS (mode,
6323                                     gen_rtx_MULT (mode, operands[1],
6324                                                         operands[2]),
6325                                     operands[3]),
6326                       operands[4]);
6327
6328   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6329   DONE;
6330 }
6331   [(set_attr "type" "lea")
6332    (set_attr "mode" "SI")])
6333
6334 (define_insn_and_split "*lea_general_4"
6335   [(set (match_operand 0 "register_operand" "=r")
6336         (any_or (ashift
6337                   (match_operand 1 "index_register_operand" "l")
6338                   (match_operand 2 "const_int_operand" "n"))
6339                 (match_operand 3 "const_int_operand" "n")))]
6340   "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6341       && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6342     || GET_MODE (operands[0]) == SImode
6343     || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6344    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6345    && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6346    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6347        < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6348   "#"
6349   "&& reload_completed"
6350   [(const_int 0)]
6351 {
6352   enum machine_mode mode = GET_MODE (operands[0]);
6353   rtx pat;
6354
6355   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6356     { 
6357       mode = SImode; 
6358       operands[0] = gen_lowpart (mode, operands[0]);
6359       operands[1] = gen_lowpart (mode, operands[1]);
6360     }
6361
6362   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6363
6364   pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6365                        INTVAL (operands[3]));
6366
6367   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6368   DONE;
6369 }
6370   [(set_attr "type" "lea")
6371    (set (attr "mode")
6372       (if_then_else (match_operand:DI 0 "" "")
6373         (const_string "DI")
6374         (const_string "SI")))])
6375 \f
6376 ;; Subtract instructions
6377
6378 (define_expand "sub<mode>3"
6379   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6380         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6381                      (match_operand:SDWIM 2 "<general_operand>" "")))]
6382   ""
6383   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6384
6385 (define_insn_and_split "*sub<dwi>3_doubleword"
6386   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6387         (minus:<DWI>
6388           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6389           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6390    (clobber (reg:CC FLAGS_REG))]
6391   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6392   "#"
6393   "reload_completed"
6394   [(parallel [(set (reg:CC FLAGS_REG)
6395                    (compare:CC (match_dup 1) (match_dup 2)))
6396               (set (match_dup 0)
6397                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6398    (parallel [(set (match_dup 3)
6399                    (minus:DWIH
6400                      (match_dup 4)
6401                      (plus:DWIH
6402                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6403                        (match_dup 5))))
6404               (clobber (reg:CC FLAGS_REG))])]
6405   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6406
6407 (define_insn "*sub<mode>_1"
6408   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6409         (minus:SWI
6410           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6411           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6412    (clobber (reg:CC FLAGS_REG))]
6413   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6414   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6415   [(set_attr "type" "alu")
6416    (set_attr "mode" "<MODE>")])
6417
6418 (define_insn "*subsi_1_zext"
6419   [(set (match_operand:DI 0 "register_operand" "=r")
6420         (zero_extend:DI
6421           (minus:SI (match_operand:SI 1 "register_operand" "0")
6422                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6423    (clobber (reg:CC FLAGS_REG))]
6424   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6425   "sub{l}\t{%2, %k0|%k0, %2}"
6426   [(set_attr "type" "alu")
6427    (set_attr "mode" "SI")])
6428
6429 (define_insn "*subqi_1_slp"
6430   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6431         (minus:QI (match_dup 0)
6432                   (match_operand:QI 1 "general_operand" "qn,qm")))
6433    (clobber (reg:CC FLAGS_REG))]
6434   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6435    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6436   "sub{b}\t{%1, %0|%0, %1}"
6437   [(set_attr "type" "alu1")
6438    (set_attr "mode" "QI")])
6439
6440 (define_insn "*sub<mode>_2"
6441   [(set (reg FLAGS_REG)
6442         (compare
6443           (minus:SWI
6444             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6445             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6446           (const_int 0)))
6447    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6448         (minus:SWI (match_dup 1) (match_dup 2)))]
6449   "ix86_match_ccmode (insn, CCGOCmode)
6450    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6451   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6452   [(set_attr "type" "alu")
6453    (set_attr "mode" "<MODE>")])
6454
6455 (define_insn "*subsi_2_zext"
6456   [(set (reg FLAGS_REG)
6457         (compare
6458           (minus:SI (match_operand:SI 1 "register_operand" "0")
6459                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6460           (const_int 0)))
6461    (set (match_operand:DI 0 "register_operand" "=r")
6462         (zero_extend:DI
6463           (minus:SI (match_dup 1)
6464                     (match_dup 2))))]
6465   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6466    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6467   "sub{l}\t{%2, %k0|%k0, %2}"
6468   [(set_attr "type" "alu")
6469    (set_attr "mode" "SI")])
6470
6471 (define_insn "*sub<mode>_3"
6472   [(set (reg FLAGS_REG)
6473         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6474                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6475    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6476         (minus:SWI (match_dup 1) (match_dup 2)))]
6477   "ix86_match_ccmode (insn, CCmode)
6478    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6479   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6480   [(set_attr "type" "alu")
6481    (set_attr "mode" "<MODE>")])
6482
6483 (define_insn "*subsi_3_zext"
6484   [(set (reg FLAGS_REG)
6485         (compare (match_operand:SI 1 "register_operand" "0")
6486                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6487    (set (match_operand:DI 0 "register_operand" "=r")
6488         (zero_extend:DI
6489           (minus:SI (match_dup 1)
6490                     (match_dup 2))))]
6491   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6492    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6493   "sub{l}\t{%2, %1|%1, %2}"
6494   [(set_attr "type" "alu")
6495    (set_attr "mode" "SI")])
6496 \f
6497 ;; Add with carry and subtract with borrow
6498
6499 (define_expand "<plusminus_insn><mode>3_carry"
6500   [(parallel
6501     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6502           (plusminus:SWI
6503             (match_operand:SWI 1 "nonimmediate_operand" "")
6504             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6505                        [(match_operand 3 "flags_reg_operand" "")
6506                         (const_int 0)])
6507                       (match_operand:SWI 2 "<general_operand>" ""))))
6508      (clobber (reg:CC FLAGS_REG))])]
6509   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6510
6511 (define_insn "*<plusminus_insn><mode>3_carry"
6512   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6513         (plusminus:SWI
6514           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6515           (plus:SWI
6516             (match_operator 3 "ix86_carry_flag_operator"
6517              [(reg FLAGS_REG) (const_int 0)])
6518             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6519    (clobber (reg:CC FLAGS_REG))]
6520   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6521   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6522   [(set_attr "type" "alu")
6523    (set_attr "use_carry" "1")
6524    (set_attr "pent_pair" "pu")
6525    (set_attr "mode" "<MODE>")])
6526
6527 (define_insn "*addsi3_carry_zext"
6528   [(set (match_operand:DI 0 "register_operand" "=r")
6529         (zero_extend:DI
6530           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6531                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6532                              [(reg FLAGS_REG) (const_int 0)])
6533                             (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6534    (clobber (reg:CC FLAGS_REG))]
6535   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6536   "adc{l}\t{%2, %k0|%k0, %2}"
6537   [(set_attr "type" "alu")
6538    (set_attr "use_carry" "1")
6539    (set_attr "pent_pair" "pu")
6540    (set_attr "mode" "SI")])
6541
6542 (define_insn "*subsi3_carry_zext"
6543   [(set (match_operand:DI 0 "register_operand" "=r")
6544         (zero_extend:DI
6545           (minus:SI (match_operand:SI 1 "register_operand" "0")
6546                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6547                               [(reg FLAGS_REG) (const_int 0)])
6548                              (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6549    (clobber (reg:CC FLAGS_REG))]
6550   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6551   "sbb{l}\t{%2, %k0|%k0, %2}"
6552   [(set_attr "type" "alu")
6553    (set_attr "pent_pair" "pu")
6554    (set_attr "mode" "SI")])
6555 \f
6556 ;; Overflow setting add and subtract instructions
6557
6558 (define_insn "*add<mode>3_cconly_overflow"
6559   [(set (reg:CCC FLAGS_REG)
6560         (compare:CCC
6561           (plus:SWI
6562             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6563             (match_operand:SWI 2 "<general_operand>" "<g>"))
6564           (match_dup 1)))
6565    (clobber (match_scratch:SWI 0 "=<r>"))]
6566   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6567   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6568   [(set_attr "type" "alu")
6569    (set_attr "mode" "<MODE>")])
6570
6571 (define_insn "*sub<mode>3_cconly_overflow"
6572   [(set (reg:CCC FLAGS_REG)
6573         (compare:CCC
6574           (minus:SWI
6575             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6576             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6577           (match_dup 0)))]
6578   ""
6579   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6580   [(set_attr "type" "icmp")
6581    (set_attr "mode" "<MODE>")])
6582
6583 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6584   [(set (reg:CCC FLAGS_REG)
6585         (compare:CCC
6586             (plusminus:SWI
6587                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6588                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6589             (match_dup 1)))
6590    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6591         (plusminus:SWI (match_dup 1) (match_dup 2)))]
6592   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6593   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6594   [(set_attr "type" "alu")
6595    (set_attr "mode" "<MODE>")])
6596
6597 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6598   [(set (reg:CCC FLAGS_REG)
6599         (compare:CCC
6600           (plusminus:SI
6601             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6602             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6603           (match_dup 1)))
6604    (set (match_operand:DI 0 "register_operand" "=r")
6605         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6606   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6607   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6608   [(set_attr "type" "alu")
6609    (set_attr "mode" "SI")])
6610
6611 ;; The patterns that match these are at the end of this file.
6612
6613 (define_expand "<plusminus_insn>xf3"
6614   [(set (match_operand:XF 0 "register_operand" "")
6615         (plusminus:XF
6616           (match_operand:XF 1 "register_operand" "")
6617           (match_operand:XF 2 "register_operand" "")))]
6618   "TARGET_80387")
6619
6620 (define_expand "<plusminus_insn><mode>3"
6621   [(set (match_operand:MODEF 0 "register_operand" "")
6622         (plusminus:MODEF
6623           (match_operand:MODEF 1 "register_operand" "")
6624           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6625   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6626     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6627 \f
6628 ;; Multiply instructions
6629
6630 (define_expand "mul<mode>3"
6631   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6632                    (mult:SWIM248
6633                      (match_operand:SWIM248 1 "register_operand" "")
6634                      (match_operand:SWIM248 2 "<general_operand>" "")))
6635               (clobber (reg:CC FLAGS_REG))])])
6636
6637 (define_expand "mulqi3"
6638   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6639                    (mult:QI
6640                      (match_operand:QI 1 "register_operand" "")
6641                      (match_operand:QI 2 "nonimmediate_operand" "")))
6642               (clobber (reg:CC FLAGS_REG))])]
6643   "TARGET_QIMODE_MATH")
6644
6645 ;; On AMDFAM10
6646 ;; IMUL reg32/64, reg32/64, imm8        Direct
6647 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6648 ;; IMUL reg32/64, reg32/64, imm32       Direct
6649 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6650 ;; IMUL reg32/64, reg32/64              Direct
6651 ;; IMUL reg32/64, mem32/64              Direct
6652 ;;
6653 ;; On BDVER1, all above IMULs use DirectPath
6654
6655 (define_insn "*mul<mode>3_1"
6656   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6657         (mult:SWI48
6658           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6659           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6660    (clobber (reg:CC FLAGS_REG))]
6661   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6662   "@
6663    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6664    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6665    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6666   [(set_attr "type" "imul")
6667    (set_attr "prefix_0f" "0,0,1")
6668    (set (attr "athlon_decode")
6669         (cond [(eq_attr "cpu" "athlon")
6670                   (const_string "vector")
6671                (eq_attr "alternative" "1")
6672                   (const_string "vector")
6673                (and (eq_attr "alternative" "2")
6674                     (match_operand 1 "memory_operand" ""))
6675                   (const_string "vector")]
6676               (const_string "direct")))
6677    (set (attr "amdfam10_decode")
6678         (cond [(and (eq_attr "alternative" "0,1")
6679                     (match_operand 1 "memory_operand" ""))
6680                   (const_string "vector")]
6681               (const_string "direct")))
6682    (set_attr "bdver1_decode" "direct")
6683    (set_attr "mode" "<MODE>")])
6684
6685 (define_insn "*mulsi3_1_zext"
6686   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6687         (zero_extend:DI
6688           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6689                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6690    (clobber (reg:CC FLAGS_REG))]
6691   "TARGET_64BIT
6692    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6693   "@
6694    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6695    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6696    imul{l}\t{%2, %k0|%k0, %2}"
6697   [(set_attr "type" "imul")
6698    (set_attr "prefix_0f" "0,0,1")
6699    (set (attr "athlon_decode")
6700         (cond [(eq_attr "cpu" "athlon")
6701                   (const_string "vector")
6702                (eq_attr "alternative" "1")
6703                   (const_string "vector")
6704                (and (eq_attr "alternative" "2")
6705                     (match_operand 1 "memory_operand" ""))
6706                   (const_string "vector")]
6707               (const_string "direct")))
6708    (set (attr "amdfam10_decode")
6709         (cond [(and (eq_attr "alternative" "0,1")
6710                     (match_operand 1 "memory_operand" ""))
6711                   (const_string "vector")]
6712               (const_string "direct")))
6713    (set_attr "bdver1_decode" "direct")
6714    (set_attr "mode" "SI")])
6715
6716 ;; On AMDFAM10
6717 ;; IMUL reg16, reg16, imm8      VectorPath
6718 ;; IMUL reg16, mem16, imm8      VectorPath
6719 ;; IMUL reg16, reg16, imm16     VectorPath
6720 ;; IMUL reg16, mem16, imm16     VectorPath
6721 ;; IMUL reg16, reg16            Direct
6722 ;; IMUL reg16, mem16            Direct
6723 ;;
6724 ;; On BDVER1, all HI MULs use DoublePath
6725
6726 (define_insn "*mulhi3_1"
6727   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6728         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6729                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6730    (clobber (reg:CC FLAGS_REG))]
6731   "TARGET_HIMODE_MATH
6732    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6733   "@
6734    imul{w}\t{%2, %1, %0|%0, %1, %2}
6735    imul{w}\t{%2, %1, %0|%0, %1, %2}
6736    imul{w}\t{%2, %0|%0, %2}"
6737   [(set_attr "type" "imul")
6738    (set_attr "prefix_0f" "0,0,1")
6739    (set (attr "athlon_decode")
6740         (cond [(eq_attr "cpu" "athlon")
6741                   (const_string "vector")
6742                (eq_attr "alternative" "1,2")
6743                   (const_string "vector")]
6744               (const_string "direct")))
6745    (set (attr "amdfam10_decode")
6746         (cond [(eq_attr "alternative" "0,1")
6747                   (const_string "vector")]
6748               (const_string "direct")))
6749    (set_attr "bdver1_decode" "double")
6750    (set_attr "mode" "HI")])
6751
6752 ;;On AMDFAM10 and BDVER1
6753 ;; MUL reg8     Direct
6754 ;; MUL mem8     Direct
6755
6756 (define_insn "*mulqi3_1"
6757   [(set (match_operand:QI 0 "register_operand" "=a")
6758         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6759                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6760    (clobber (reg:CC FLAGS_REG))]
6761   "TARGET_QIMODE_MATH
6762    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6763   "mul{b}\t%2"
6764   [(set_attr "type" "imul")
6765    (set_attr "length_immediate" "0")
6766    (set (attr "athlon_decode")
6767      (if_then_else (eq_attr "cpu" "athlon")
6768         (const_string "vector")
6769         (const_string "direct")))
6770    (set_attr "amdfam10_decode" "direct")
6771    (set_attr "bdver1_decode" "direct")
6772    (set_attr "mode" "QI")])
6773
6774 (define_expand "<u>mul<mode><dwi>3"
6775   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6776                    (mult:<DWI>
6777                      (any_extend:<DWI>
6778                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
6779                      (any_extend:<DWI>
6780                        (match_operand:DWIH 2 "register_operand" ""))))
6781               (clobber (reg:CC FLAGS_REG))])])
6782
6783 (define_expand "<u>mulqihi3"
6784   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6785                    (mult:HI
6786                      (any_extend:HI
6787                        (match_operand:QI 1 "nonimmediate_operand" ""))
6788                      (any_extend:HI
6789                        (match_operand:QI 2 "register_operand" ""))))
6790               (clobber (reg:CC FLAGS_REG))])]
6791   "TARGET_QIMODE_MATH")
6792
6793 (define_insn "*bmi2_umulditi3_1"
6794   [(set (match_operand:DI 0 "register_operand" "=r")
6795         (mult:DI
6796           (match_operand:DI 2 "nonimmediate_operand" "%d")
6797           (match_operand:DI 3 "nonimmediate_operand" "rm")))
6798    (set (match_operand:DI 1 "register_operand" "=r")
6799         (truncate:DI
6800           (lshiftrt:TI
6801             (mult:TI (zero_extend:TI (match_dup 2))
6802                      (zero_extend:TI (match_dup 3)))
6803             (const_int 64))))]
6804   "TARGET_64BIT && TARGET_BMI2
6805    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6806   "mulx\t{%3, %0, %1|%1, %0, %3}"
6807   [(set_attr "type" "imulx")
6808    (set_attr "prefix" "vex")
6809    (set_attr "mode" "DI")])
6810
6811 (define_insn "*bmi2_umulsidi3_1"
6812   [(set (match_operand:SI 0 "register_operand" "=r")
6813         (mult:SI
6814           (match_operand:SI 2 "nonimmediate_operand" "%d")
6815           (match_operand:SI 3 "nonimmediate_operand" "rm")))
6816    (set (match_operand:SI 1 "register_operand" "=r")
6817         (truncate:SI
6818           (lshiftrt:DI
6819             (mult:DI (zero_extend:DI (match_dup 2))
6820                      (zero_extend:DI (match_dup 3)))
6821             (const_int 32))))]
6822   "!TARGET_64BIT && TARGET_BMI2
6823    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6824   "mulx\t{%3, %0, %1|%1, %0, %3}"
6825   [(set_attr "type" "imulx")
6826    (set_attr "prefix" "vex")
6827    (set_attr "mode" "SI")])
6828
6829 (define_insn "*umul<mode><dwi>3_1"
6830   [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6831         (mult:<DWI>
6832           (zero_extend:<DWI>
6833             (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6834           (zero_extend:<DWI>
6835             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6836    (clobber (reg:CC FLAGS_REG))]
6837   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6838   "@
6839    mul{<imodesuffix>}\t%2
6840    #"
6841   [(set_attr "isa" "*,bmi2")
6842    (set_attr "type" "imul,imulx")
6843    (set_attr "length_immediate" "0,*")
6844    (set (attr "athlon_decode")
6845         (cond [(eq_attr "alternative" "0")
6846                  (if_then_else (eq_attr "cpu" "athlon")
6847                    (const_string "vector")
6848                    (const_string "double"))]
6849               (const_string "*")))
6850    (set_attr "amdfam10_decode" "double,*")
6851    (set_attr "bdver1_decode" "direct,*")
6852    (set_attr "prefix" "orig,vex")
6853    (set_attr "mode" "<MODE>")])
6854
6855 ;; Convert mul to the mulx pattern to avoid flags dependency.
6856 (define_split
6857  [(set (match_operand:<DWI> 0 "register_operand" "")
6858        (mult:<DWI>
6859          (zero_extend:<DWI>
6860            (match_operand:DWIH 1 "register_operand" ""))
6861          (zero_extend:<DWI>
6862            (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6863   (clobber (reg:CC FLAGS_REG))]
6864  "TARGET_BMI2 && reload_completed
6865   && true_regnum (operands[1]) == DX_REG"
6866   [(parallel [(set (match_dup 3)
6867                    (mult:DWIH (match_dup 1) (match_dup 2)))
6868               (set (match_dup 4)
6869                    (truncate:DWIH
6870                      (lshiftrt:<DWI>
6871                        (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6872                                    (zero_extend:<DWI> (match_dup 2)))
6873                        (match_dup 5))))])]
6874 {
6875   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6876
6877   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6878 })
6879
6880 (define_insn "*mul<mode><dwi>3_1"
6881   [(set (match_operand:<DWI> 0 "register_operand" "=A")
6882         (mult:<DWI>
6883           (sign_extend:<DWI>
6884             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6885           (sign_extend:<DWI>
6886             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6887    (clobber (reg:CC FLAGS_REG))]
6888   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6889   "imul{<imodesuffix>}\t%2"
6890   [(set_attr "type" "imul")
6891    (set_attr "length_immediate" "0")
6892    (set (attr "athlon_decode")
6893      (if_then_else (eq_attr "cpu" "athlon")
6894         (const_string "vector")
6895         (const_string "double")))
6896    (set_attr "amdfam10_decode" "double")
6897    (set_attr "bdver1_decode" "direct")
6898    (set_attr "mode" "<MODE>")])
6899
6900 (define_insn "*<u>mulqihi3_1"
6901   [(set (match_operand:HI 0 "register_operand" "=a")
6902         (mult:HI
6903           (any_extend:HI
6904             (match_operand:QI 1 "nonimmediate_operand" "%0"))
6905           (any_extend:HI
6906             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6907    (clobber (reg:CC FLAGS_REG))]
6908   "TARGET_QIMODE_MATH
6909    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6910   "<sgnprefix>mul{b}\t%2"
6911   [(set_attr "type" "imul")
6912    (set_attr "length_immediate" "0")
6913    (set (attr "athlon_decode")
6914      (if_then_else (eq_attr "cpu" "athlon")
6915         (const_string "vector")
6916         (const_string "direct")))
6917    (set_attr "amdfam10_decode" "direct")
6918    (set_attr "bdver1_decode" "direct")
6919    (set_attr "mode" "QI")])
6920
6921 (define_expand "<s>mul<mode>3_highpart"
6922   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6923                    (truncate:SWI48
6924                      (lshiftrt:<DWI>
6925                        (mult:<DWI>
6926                          (any_extend:<DWI>
6927                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
6928                          (any_extend:<DWI>
6929                            (match_operand:SWI48 2 "register_operand" "")))
6930                        (match_dup 4))))
6931               (clobber (match_scratch:SWI48 3 ""))
6932               (clobber (reg:CC FLAGS_REG))])]
6933   ""
6934   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6935
6936 (define_insn "*<s>muldi3_highpart_1"
6937   [(set (match_operand:DI 0 "register_operand" "=d")
6938         (truncate:DI
6939           (lshiftrt:TI
6940             (mult:TI
6941               (any_extend:TI
6942                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6943               (any_extend:TI
6944                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6945             (const_int 64))))
6946    (clobber (match_scratch:DI 3 "=1"))
6947    (clobber (reg:CC FLAGS_REG))]
6948   "TARGET_64BIT
6949    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6950   "<sgnprefix>mul{q}\t%2"
6951   [(set_attr "type" "imul")
6952    (set_attr "length_immediate" "0")
6953    (set (attr "athlon_decode")
6954      (if_then_else (eq_attr "cpu" "athlon")
6955         (const_string "vector")
6956         (const_string "double")))
6957    (set_attr "amdfam10_decode" "double")
6958    (set_attr "bdver1_decode" "direct")
6959    (set_attr "mode" "DI")])
6960
6961 (define_insn "*<s>mulsi3_highpart_1"
6962   [(set (match_operand:SI 0 "register_operand" "=d")
6963         (truncate:SI
6964           (lshiftrt:DI
6965             (mult:DI
6966               (any_extend:DI
6967                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6968               (any_extend:DI
6969                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6970             (const_int 32))))
6971    (clobber (match_scratch:SI 3 "=1"))
6972    (clobber (reg:CC FLAGS_REG))]
6973   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6974   "<sgnprefix>mul{l}\t%2"
6975   [(set_attr "type" "imul")
6976    (set_attr "length_immediate" "0")
6977    (set (attr "athlon_decode")
6978      (if_then_else (eq_attr "cpu" "athlon")
6979         (const_string "vector")
6980         (const_string "double")))
6981    (set_attr "amdfam10_decode" "double")
6982    (set_attr "bdver1_decode" "direct")
6983    (set_attr "mode" "SI")])
6984
6985 (define_insn "*<s>mulsi3_highpart_zext"
6986   [(set (match_operand:DI 0 "register_operand" "=d")
6987         (zero_extend:DI (truncate:SI
6988           (lshiftrt:DI
6989             (mult:DI (any_extend:DI
6990                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
6991                      (any_extend:DI
6992                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
6993             (const_int 32)))))
6994    (clobber (match_scratch:SI 3 "=1"))
6995    (clobber (reg:CC FLAGS_REG))]
6996   "TARGET_64BIT
6997    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6998   "<sgnprefix>mul{l}\t%2"
6999   [(set_attr "type" "imul")
7000    (set_attr "length_immediate" "0")
7001    (set (attr "athlon_decode")
7002      (if_then_else (eq_attr "cpu" "athlon")
7003         (const_string "vector")
7004         (const_string "double")))
7005    (set_attr "amdfam10_decode" "double")
7006    (set_attr "bdver1_decode" "direct")
7007    (set_attr "mode" "SI")])
7008
7009 ;; The patterns that match these are at the end of this file.
7010
7011 (define_expand "mulxf3"
7012   [(set (match_operand:XF 0 "register_operand" "")
7013         (mult:XF (match_operand:XF 1 "register_operand" "")
7014                  (match_operand:XF 2 "register_operand" "")))]
7015   "TARGET_80387")
7016
7017 (define_expand "mul<mode>3"
7018   [(set (match_operand:MODEF 0 "register_operand" "")
7019         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7020                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7021   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7022     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7023 \f
7024 ;; Divide instructions
7025
7026 ;; The patterns that match these are at the end of this file.
7027
7028 (define_expand "divxf3"
7029   [(set (match_operand:XF 0 "register_operand" "")
7030         (div:XF (match_operand:XF 1 "register_operand" "")
7031                 (match_operand:XF 2 "register_operand" "")))]
7032   "TARGET_80387")
7033
7034 (define_expand "divdf3"
7035   [(set (match_operand:DF 0 "register_operand" "")
7036         (div:DF (match_operand:DF 1 "register_operand" "")
7037                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7038    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7039     || (TARGET_SSE2 && TARGET_SSE_MATH)")
7040
7041 (define_expand "divsf3"
7042   [(set (match_operand:SF 0 "register_operand" "")
7043         (div:SF (match_operand:SF 1 "register_operand" "")
7044                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7045   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7046     || TARGET_SSE_MATH"
7047 {
7048   if (TARGET_SSE_MATH
7049       && TARGET_RECIP_DIV
7050       && optimize_insn_for_speed_p ()
7051       && flag_finite_math_only && !flag_trapping_math
7052       && flag_unsafe_math_optimizations)
7053     {
7054       ix86_emit_swdivsf (operands[0], operands[1],
7055                          operands[2], SFmode);
7056       DONE;
7057     }
7058 })
7059 \f
7060 ;; Divmod instructions.
7061
7062 (define_expand "divmod<mode>4"
7063   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7064                    (div:SWIM248
7065                      (match_operand:SWIM248 1 "register_operand" "")
7066                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7067               (set (match_operand:SWIM248 3 "register_operand" "")
7068                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7069               (clobber (reg:CC FLAGS_REG))])])
7070
7071 ;; Split with 8bit unsigned divide:
7072 ;;      if (dividend an divisor are in [0-255])
7073 ;;         use 8bit unsigned integer divide
7074 ;;       else
7075 ;;         use original integer divide
7076 (define_split
7077   [(set (match_operand:SWI48 0 "register_operand" "")
7078         (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7079                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7080    (set (match_operand:SWI48 1 "register_operand" "")
7081         (mod:SWI48 (match_dup 2) (match_dup 3)))
7082    (clobber (reg:CC FLAGS_REG))]
7083   "TARGET_USE_8BIT_IDIV
7084    && TARGET_QIMODE_MATH
7085    && can_create_pseudo_p ()
7086    && !optimize_insn_for_size_p ()"
7087   [(const_int 0)]
7088   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7089
7090 (define_insn_and_split "divmod<mode>4_1"
7091   [(set (match_operand:SWI48 0 "register_operand" "=a")
7092         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7093                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7094    (set (match_operand:SWI48 1 "register_operand" "=&d")
7095         (mod:SWI48 (match_dup 2) (match_dup 3)))
7096    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7097    (clobber (reg:CC FLAGS_REG))]
7098   ""
7099   "#"
7100   "reload_completed"
7101   [(parallel [(set (match_dup 1)
7102                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7103               (clobber (reg:CC FLAGS_REG))])
7104    (parallel [(set (match_dup 0)
7105                    (div:SWI48 (match_dup 2) (match_dup 3)))
7106               (set (match_dup 1)
7107                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7108               (use (match_dup 1))
7109               (clobber (reg:CC FLAGS_REG))])]
7110 {
7111   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7112
7113   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7114     operands[4] = operands[2];
7115   else
7116     {
7117       /* Avoid use of cltd in favor of a mov+shift.  */
7118       emit_move_insn (operands[1], operands[2]);
7119       operands[4] = operands[1];
7120     }
7121 }
7122   [(set_attr "type" "multi")
7123    (set_attr "mode" "<MODE>")])
7124
7125 (define_insn_and_split "*divmod<mode>4"
7126   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7127         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7128                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7129    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7130         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7131    (clobber (reg:CC FLAGS_REG))]
7132   ""
7133   "#"
7134   "reload_completed"
7135   [(parallel [(set (match_dup 1)
7136                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7137               (clobber (reg:CC FLAGS_REG))])
7138    (parallel [(set (match_dup 0)
7139                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7140               (set (match_dup 1)
7141                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7142               (use (match_dup 1))
7143               (clobber (reg:CC FLAGS_REG))])]
7144 {
7145   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7146
7147   if (<MODE>mode != HImode
7148       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7149     operands[4] = operands[2];
7150   else
7151     {
7152       /* Avoid use of cltd in favor of a mov+shift.  */
7153       emit_move_insn (operands[1], operands[2]);
7154       operands[4] = operands[1];
7155     }
7156 }
7157   [(set_attr "type" "multi")
7158    (set_attr "mode" "<MODE>")])
7159
7160 (define_insn "*divmod<mode>4_noext"
7161   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7162         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7163                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7164    (set (match_operand:SWIM248 1 "register_operand" "=d")
7165         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7166    (use (match_operand:SWIM248 4 "register_operand" "1"))
7167    (clobber (reg:CC FLAGS_REG))]
7168   ""
7169   "idiv{<imodesuffix>}\t%3"
7170   [(set_attr "type" "idiv")
7171    (set_attr "mode" "<MODE>")])
7172
7173 (define_expand "divmodqi4"
7174   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7175                    (div:QI
7176                      (match_operand:QI 1 "register_operand" "")
7177                      (match_operand:QI 2 "nonimmediate_operand" "")))
7178               (set (match_operand:QI 3 "register_operand" "")
7179                    (mod:QI (match_dup 1) (match_dup 2)))
7180               (clobber (reg:CC FLAGS_REG))])]
7181   "TARGET_QIMODE_MATH"
7182 {
7183   rtx div, mod, insn;
7184   rtx tmp0, tmp1;
7185   
7186   tmp0 = gen_reg_rtx (HImode);
7187   tmp1 = gen_reg_rtx (HImode);
7188
7189   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7190      in AX.  */
7191   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7192   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7193
7194   /* Extract remainder from AH.  */
7195   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7196   insn = emit_move_insn (operands[3], tmp1);
7197
7198   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7199   set_unique_reg_note (insn, REG_EQUAL, mod);
7200
7201   /* Extract quotient from AL.  */
7202   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7203
7204   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7205   set_unique_reg_note (insn, REG_EQUAL, div);
7206
7207   DONE;
7208 })
7209
7210 ;; Divide AX by r/m8, with result stored in
7211 ;; AL <- Quotient
7212 ;; AH <- Remainder
7213 ;; Change div/mod to HImode and extend the second argument to HImode
7214 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7215 ;; combine may fail.
7216 (define_insn "divmodhiqi3"
7217   [(set (match_operand:HI 0 "register_operand" "=a")
7218         (ior:HI
7219           (ashift:HI
7220             (zero_extend:HI
7221               (truncate:QI
7222                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7223                         (sign_extend:HI
7224                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7225             (const_int 8))
7226           (zero_extend:HI
7227             (truncate:QI
7228               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7229    (clobber (reg:CC FLAGS_REG))]
7230   "TARGET_QIMODE_MATH"
7231   "idiv{b}\t%2"
7232   [(set_attr "type" "idiv")
7233    (set_attr "mode" "QI")])
7234
7235 (define_expand "udivmod<mode>4"
7236   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7237                    (udiv:SWIM248
7238                      (match_operand:SWIM248 1 "register_operand" "")
7239                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7240               (set (match_operand:SWIM248 3 "register_operand" "")
7241                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7242               (clobber (reg:CC FLAGS_REG))])])
7243
7244 ;; Split with 8bit unsigned divide:
7245 ;;      if (dividend an divisor are in [0-255])
7246 ;;         use 8bit unsigned integer divide
7247 ;;       else
7248 ;;         use original integer divide
7249 (define_split
7250   [(set (match_operand:SWI48 0 "register_operand" "")
7251         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7252                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7253    (set (match_operand:SWI48 1 "register_operand" "")
7254         (umod:SWI48 (match_dup 2) (match_dup 3)))
7255    (clobber (reg:CC FLAGS_REG))]
7256   "TARGET_USE_8BIT_IDIV
7257    && TARGET_QIMODE_MATH
7258    && can_create_pseudo_p ()
7259    && !optimize_insn_for_size_p ()"
7260   [(const_int 0)]
7261   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7262
7263 (define_insn_and_split "udivmod<mode>4_1"
7264   [(set (match_operand:SWI48 0 "register_operand" "=a")
7265         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7266                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7267    (set (match_operand:SWI48 1 "register_operand" "=&d")
7268         (umod:SWI48 (match_dup 2) (match_dup 3)))
7269    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7270    (clobber (reg:CC FLAGS_REG))]
7271   ""
7272   "#"
7273   "reload_completed"
7274   [(set (match_dup 1) (const_int 0))
7275    (parallel [(set (match_dup 0)
7276                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7277               (set (match_dup 1)
7278                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7279               (use (match_dup 1))
7280               (clobber (reg:CC FLAGS_REG))])]
7281   ""
7282   [(set_attr "type" "multi")
7283    (set_attr "mode" "<MODE>")])
7284
7285 (define_insn_and_split "*udivmod<mode>4"
7286   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7287         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7288                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7289    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7290         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7291    (clobber (reg:CC FLAGS_REG))]
7292   ""
7293   "#"
7294   "reload_completed"
7295   [(set (match_dup 1) (const_int 0))
7296    (parallel [(set (match_dup 0)
7297                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7298               (set (match_dup 1)
7299                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7300               (use (match_dup 1))
7301               (clobber (reg:CC FLAGS_REG))])]
7302   ""
7303   [(set_attr "type" "multi")
7304    (set_attr "mode" "<MODE>")])
7305
7306 (define_insn "*udivmod<mode>4_noext"
7307   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7308         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7309                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7310    (set (match_operand:SWIM248 1 "register_operand" "=d")
7311         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7312    (use (match_operand:SWIM248 4 "register_operand" "1"))
7313    (clobber (reg:CC FLAGS_REG))]
7314   ""
7315   "div{<imodesuffix>}\t%3"
7316   [(set_attr "type" "idiv")
7317    (set_attr "mode" "<MODE>")])
7318
7319 (define_expand "udivmodqi4"
7320   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7321                    (udiv:QI
7322                      (match_operand:QI 1 "register_operand" "")
7323                      (match_operand:QI 2 "nonimmediate_operand" "")))
7324               (set (match_operand:QI 3 "register_operand" "")
7325                    (umod:QI (match_dup 1) (match_dup 2)))
7326               (clobber (reg:CC FLAGS_REG))])]
7327   "TARGET_QIMODE_MATH"
7328 {
7329   rtx div, mod, insn;
7330   rtx tmp0, tmp1;
7331   
7332   tmp0 = gen_reg_rtx (HImode);
7333   tmp1 = gen_reg_rtx (HImode);
7334
7335   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7336      in AX.  */
7337   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7338   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7339
7340   /* Extract remainder from AH.  */
7341   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7342   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7343   insn = emit_move_insn (operands[3], tmp1);
7344
7345   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7346   set_unique_reg_note (insn, REG_EQUAL, mod);
7347
7348   /* Extract quotient from AL.  */
7349   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7350
7351   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7352   set_unique_reg_note (insn, REG_EQUAL, div);
7353
7354   DONE;
7355 })
7356
7357 (define_insn "udivmodhiqi3"
7358   [(set (match_operand:HI 0 "register_operand" "=a")
7359         (ior:HI
7360           (ashift:HI
7361             (zero_extend:HI
7362               (truncate:QI
7363                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7364                         (zero_extend:HI
7365                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7366             (const_int 8))
7367           (zero_extend:HI
7368             (truncate:QI
7369               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7370    (clobber (reg:CC FLAGS_REG))]
7371   "TARGET_QIMODE_MATH"
7372   "div{b}\t%2"
7373   [(set_attr "type" "idiv")
7374    (set_attr "mode" "QI")])
7375
7376 ;; We cannot use div/idiv for double division, because it causes
7377 ;; "division by zero" on the overflow and that's not what we expect
7378 ;; from truncate.  Because true (non truncating) double division is
7379 ;; never generated, we can't create this insn anyway.
7380 ;
7381 ;(define_insn ""
7382 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7383 ;       (truncate:SI
7384 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7385 ;                  (zero_extend:DI
7386 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7387 ;   (set (match_operand:SI 3 "register_operand" "=d")
7388 ;       (truncate:SI
7389 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7390 ;   (clobber (reg:CC FLAGS_REG))]
7391 ;  ""
7392 ;  "div{l}\t{%2, %0|%0, %2}"
7393 ;  [(set_attr "type" "idiv")])
7394 \f
7395 ;;- Logical AND instructions
7396
7397 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7398 ;; Note that this excludes ah.
7399
7400 (define_expand "testsi_ccno_1"
7401   [(set (reg:CCNO FLAGS_REG)
7402         (compare:CCNO
7403           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7404                   (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7405           (const_int 0)))])
7406
7407 (define_expand "testqi_ccz_1"
7408   [(set (reg:CCZ FLAGS_REG)
7409         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7410                              (match_operand:QI 1 "nonmemory_operand" ""))
7411                  (const_int 0)))])
7412
7413 (define_expand "testdi_ccno_1"
7414   [(set (reg:CCNO FLAGS_REG)
7415         (compare:CCNO
7416           (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7417                   (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7418           (const_int 0)))]
7419   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7420
7421 (define_insn "*testdi_1"
7422   [(set (reg FLAGS_REG)
7423         (compare
7424          (and:DI
7425           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7426           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7427          (const_int 0)))]
7428   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7429    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7430   "@
7431    test{l}\t{%k1, %k0|%k0, %k1}
7432    test{l}\t{%k1, %k0|%k0, %k1}
7433    test{q}\t{%1, %0|%0, %1}
7434    test{q}\t{%1, %0|%0, %1}
7435    test{q}\t{%1, %0|%0, %1}"
7436   [(set_attr "type" "test")
7437    (set_attr "modrm" "0,1,0,1,1")
7438    (set_attr "mode" "SI,SI,DI,DI,DI")])
7439
7440 (define_insn "*testqi_1_maybe_si"
7441   [(set (reg FLAGS_REG)
7442         (compare
7443           (and:QI
7444             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7445             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7446           (const_int 0)))]
7447    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7448     && ix86_match_ccmode (insn,
7449                          CONST_INT_P (operands[1])
7450                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7451 {
7452   if (which_alternative == 3)
7453     {
7454       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7455         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7456       return "test{l}\t{%1, %k0|%k0, %1}";
7457     }
7458   return "test{b}\t{%1, %0|%0, %1}";
7459 }
7460   [(set_attr "type" "test")
7461    (set_attr "modrm" "0,1,1,1")
7462    (set_attr "mode" "QI,QI,QI,SI")
7463    (set_attr "pent_pair" "uv,np,uv,np")])
7464
7465 (define_insn "*test<mode>_1"
7466   [(set (reg FLAGS_REG)
7467         (compare
7468          (and:SWI124
7469           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7470           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7471          (const_int 0)))]
7472   "ix86_match_ccmode (insn, CCNOmode)
7473    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7474   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7475   [(set_attr "type" "test")
7476    (set_attr "modrm" "0,1,1")
7477    (set_attr "mode" "<MODE>")
7478    (set_attr "pent_pair" "uv,np,uv")])
7479
7480 (define_expand "testqi_ext_ccno_0"
7481   [(set (reg:CCNO FLAGS_REG)
7482         (compare:CCNO
7483           (and:SI
7484             (zero_extract:SI
7485               (match_operand 0 "ext_register_operand" "")
7486               (const_int 8)
7487               (const_int 8))
7488             (match_operand 1 "const_int_operand" ""))
7489           (const_int 0)))])
7490
7491 (define_insn "*testqi_ext_0"
7492   [(set (reg FLAGS_REG)
7493         (compare
7494           (and:SI
7495             (zero_extract:SI
7496               (match_operand 0 "ext_register_operand" "Q")
7497               (const_int 8)
7498               (const_int 8))
7499             (match_operand 1 "const_int_operand" "n"))
7500           (const_int 0)))]
7501   "ix86_match_ccmode (insn, CCNOmode)"
7502   "test{b}\t{%1, %h0|%h0, %1}"
7503   [(set_attr "type" "test")
7504    (set_attr "mode" "QI")
7505    (set_attr "length_immediate" "1")
7506    (set_attr "modrm" "1")
7507    (set_attr "pent_pair" "np")])
7508
7509 (define_insn "*testqi_ext_1_rex64"
7510   [(set (reg FLAGS_REG)
7511         (compare
7512           (and:SI
7513             (zero_extract:SI
7514               (match_operand 0 "ext_register_operand" "Q")
7515               (const_int 8)
7516               (const_int 8))
7517             (zero_extend:SI
7518               (match_operand:QI 1 "register_operand" "Q")))
7519           (const_int 0)))]
7520   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7521   "test{b}\t{%1, %h0|%h0, %1}"
7522   [(set_attr "type" "test")
7523    (set_attr "mode" "QI")])
7524
7525 (define_insn "*testqi_ext_1"
7526   [(set (reg FLAGS_REG)
7527         (compare
7528           (and:SI
7529             (zero_extract:SI
7530               (match_operand 0 "ext_register_operand" "Q")
7531               (const_int 8)
7532               (const_int 8))
7533             (zero_extend:SI
7534               (match_operand:QI 1 "general_operand" "Qm")))
7535           (const_int 0)))]
7536   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7537   "test{b}\t{%1, %h0|%h0, %1}"
7538   [(set_attr "type" "test")
7539    (set_attr "mode" "QI")])
7540
7541 (define_insn "*testqi_ext_2"
7542   [(set (reg FLAGS_REG)
7543         (compare
7544           (and:SI
7545             (zero_extract:SI
7546               (match_operand 0 "ext_register_operand" "Q")
7547               (const_int 8)
7548               (const_int 8))
7549             (zero_extract:SI
7550               (match_operand 1 "ext_register_operand" "Q")
7551               (const_int 8)
7552               (const_int 8)))
7553           (const_int 0)))]
7554   "ix86_match_ccmode (insn, CCNOmode)"
7555   "test{b}\t{%h1, %h0|%h0, %h1}"
7556   [(set_attr "type" "test")
7557    (set_attr "mode" "QI")])
7558
7559 (define_insn "*testqi_ext_3_rex64"
7560   [(set (reg FLAGS_REG)
7561         (compare (zero_extract:DI
7562                    (match_operand 0 "nonimmediate_operand" "rm")
7563                    (match_operand:DI 1 "const_int_operand" "")
7564                    (match_operand:DI 2 "const_int_operand" ""))
7565                  (const_int 0)))]
7566   "TARGET_64BIT
7567    && ix86_match_ccmode (insn, CCNOmode)
7568    && INTVAL (operands[1]) > 0
7569    && INTVAL (operands[2]) >= 0
7570    /* Ensure that resulting mask is zero or sign extended operand.  */
7571    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7572        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7573            && INTVAL (operands[1]) > 32))
7574    && (GET_MODE (operands[0]) == SImode
7575        || GET_MODE (operands[0]) == DImode
7576        || GET_MODE (operands[0]) == HImode
7577        || GET_MODE (operands[0]) == QImode)"
7578   "#")
7579
7580 ;; Combine likes to form bit extractions for some tests.  Humor it.
7581 (define_insn "*testqi_ext_3"
7582   [(set (reg FLAGS_REG)
7583         (compare (zero_extract:SI
7584                    (match_operand 0 "nonimmediate_operand" "rm")
7585                    (match_operand:SI 1 "const_int_operand" "")
7586                    (match_operand:SI 2 "const_int_operand" ""))
7587                  (const_int 0)))]
7588   "ix86_match_ccmode (insn, CCNOmode)
7589    && INTVAL (operands[1]) > 0
7590    && INTVAL (operands[2]) >= 0
7591    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7592    && (GET_MODE (operands[0]) == SImode
7593        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7594        || GET_MODE (operands[0]) == HImode
7595        || GET_MODE (operands[0]) == QImode)"
7596   "#")
7597
7598 (define_split
7599   [(set (match_operand 0 "flags_reg_operand" "")
7600         (match_operator 1 "compare_operator"
7601           [(zero_extract
7602              (match_operand 2 "nonimmediate_operand" "")
7603              (match_operand 3 "const_int_operand" "")
7604              (match_operand 4 "const_int_operand" ""))
7605            (const_int 0)]))]
7606   "ix86_match_ccmode (insn, CCNOmode)"
7607   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7608 {
7609   rtx val = operands[2];
7610   HOST_WIDE_INT len = INTVAL (operands[3]);
7611   HOST_WIDE_INT pos = INTVAL (operands[4]);
7612   HOST_WIDE_INT mask;
7613   enum machine_mode mode, submode;
7614
7615   mode = GET_MODE (val);
7616   if (MEM_P (val))
7617     {
7618       /* ??? Combine likes to put non-volatile mem extractions in QImode
7619          no matter the size of the test.  So find a mode that works.  */
7620       if (! MEM_VOLATILE_P (val))
7621         {
7622           mode = smallest_mode_for_size (pos + len, MODE_INT);
7623           val = adjust_address (val, mode, 0);
7624         }
7625     }
7626   else if (GET_CODE (val) == SUBREG
7627            && (submode = GET_MODE (SUBREG_REG (val)),
7628                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7629            && pos + len <= GET_MODE_BITSIZE (submode)
7630            && GET_MODE_CLASS (submode) == MODE_INT)
7631     {
7632       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7633       mode = submode;
7634       val = SUBREG_REG (val);
7635     }
7636   else if (mode == HImode && pos + len <= 8)
7637     {
7638       /* Small HImode tests can be converted to QImode.  */
7639       mode = QImode;
7640       val = gen_lowpart (QImode, val);
7641     }
7642
7643   if (len == HOST_BITS_PER_WIDE_INT)
7644     mask = -1;
7645   else
7646     mask = ((HOST_WIDE_INT)1 << len) - 1;
7647   mask <<= pos;
7648
7649   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7650 })
7651
7652 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7653 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7654 ;; this is relatively important trick.
7655 ;; Do the conversion only post-reload to avoid limiting of the register class
7656 ;; to QI regs.
7657 (define_split
7658   [(set (match_operand 0 "flags_reg_operand" "")
7659         (match_operator 1 "compare_operator"
7660           [(and (match_operand 2 "register_operand" "")
7661                 (match_operand 3 "const_int_operand" ""))
7662            (const_int 0)]))]
7663    "reload_completed
7664     && QI_REG_P (operands[2])
7665     && GET_MODE (operands[2]) != QImode
7666     && ((ix86_match_ccmode (insn, CCZmode)
7667          && !(INTVAL (operands[3]) & ~(255 << 8)))
7668         || (ix86_match_ccmode (insn, CCNOmode)
7669             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7670   [(set (match_dup 0)
7671         (match_op_dup 1
7672           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7673                    (match_dup 3))
7674            (const_int 0)]))]
7675 {
7676   operands[2] = gen_lowpart (SImode, operands[2]);
7677   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7678 })
7679
7680 (define_split
7681   [(set (match_operand 0 "flags_reg_operand" "")
7682         (match_operator 1 "compare_operator"
7683           [(and (match_operand 2 "nonimmediate_operand" "")
7684                 (match_operand 3 "const_int_operand" ""))
7685            (const_int 0)]))]
7686    "reload_completed
7687     && GET_MODE (operands[2]) != QImode
7688     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7689     && ((ix86_match_ccmode (insn, CCZmode)
7690          && !(INTVAL (operands[3]) & ~255))
7691         || (ix86_match_ccmode (insn, CCNOmode)
7692             && !(INTVAL (operands[3]) & ~127)))"
7693   [(set (match_dup 0)
7694         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7695                          (const_int 0)]))]
7696 {
7697   operands[2] = gen_lowpart (QImode, operands[2]);
7698   operands[3] = gen_lowpart (QImode, operands[3]);
7699 })
7700
7701 ;; %%% This used to optimize known byte-wide and operations to memory,
7702 ;; and sometimes to QImode registers.  If this is considered useful,
7703 ;; it should be done with splitters.
7704
7705 (define_expand "and<mode>3"
7706   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7707         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7708                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7709   ""
7710 {
7711   if (<MODE>mode == DImode
7712       && GET_CODE (operands[2]) == CONST_INT
7713       && INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff
7714       && REG_P (operands[1]))
7715     emit_insn (gen_zero_extendsidi2 (operands[0],
7716                                      gen_lowpart (SImode, operands[1])));
7717   else
7718     ix86_expand_binary_operator (AND, <MODE>mode, operands);
7719   DONE;
7720 })
7721
7722 (define_insn "*anddi_1"
7723   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7724         (and:DI
7725          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7726          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7727    (clobber (reg:CC FLAGS_REG))]
7728   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7729 {
7730   switch (get_attr_type (insn))
7731     {
7732     case TYPE_IMOVX:
7733       {
7734         enum machine_mode mode;
7735
7736         gcc_assert (CONST_INT_P (operands[2]));
7737         if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff)
7738           mode = SImode;
7739         else if (INTVAL (operands[2]) == 0xffff)
7740           mode = HImode;
7741         else
7742           {
7743             gcc_assert (INTVAL (operands[2]) == 0xff);
7744             mode = QImode;
7745           }
7746
7747         operands[1] = gen_lowpart (mode, operands[1]);
7748         if (mode == SImode)
7749           return "mov{l}\t{%1, %k0|%k0, %1}";
7750         else if (mode == HImode)
7751           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7752         else
7753           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7754       }
7755
7756     default:
7757       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7758       if (get_attr_mode (insn) == MODE_SI)
7759         return "and{l}\t{%k2, %k0|%k0, %k2}";
7760       else
7761         return "and{q}\t{%2, %0|%0, %2}";
7762     }
7763 }
7764   [(set_attr "type" "alu,alu,alu,imovx")
7765    (set_attr "length_immediate" "*,*,*,0")
7766    (set (attr "prefix_rex")
7767      (if_then_else
7768        (and (eq_attr "type" "imovx")
7769             (and (match_test "INTVAL (operands[2]) == 0xff")
7770                  (match_operand 1 "ext_QIreg_operand" "")))
7771        (const_string "1")
7772        (const_string "*")))
7773    (set_attr "mode" "SI,DI,DI,SI")])
7774
7775 (define_insn "*andsi_1"
7776   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7777         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7778                 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7779    (clobber (reg:CC FLAGS_REG))]
7780   "ix86_binary_operator_ok (AND, SImode, operands)"
7781 {
7782   switch (get_attr_type (insn))
7783     {
7784     case TYPE_IMOVX:
7785       {
7786         enum machine_mode mode;
7787
7788         gcc_assert (CONST_INT_P (operands[2]));
7789         if (INTVAL (operands[2]) == 0xffff)
7790           mode = HImode;
7791         else
7792           {
7793             gcc_assert (INTVAL (operands[2]) == 0xff);
7794             mode = QImode;
7795           }
7796
7797         operands[1] = gen_lowpart (mode, operands[1]);
7798         if (mode == HImode)
7799           return "movz{wl|x}\t{%1, %0|%0, %1}";
7800         else
7801           return "movz{bl|x}\t{%1, %0|%0, %1}";
7802       }
7803
7804     default:
7805       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7806       return "and{l}\t{%2, %0|%0, %2}";
7807     }
7808 }
7809   [(set_attr "type" "alu,alu,imovx")
7810    (set (attr "prefix_rex")
7811      (if_then_else
7812        (and (eq_attr "type" "imovx")
7813             (and (match_test "INTVAL (operands[2]) == 0xff")
7814                  (match_operand 1 "ext_QIreg_operand" "")))
7815        (const_string "1")
7816        (const_string "*")))
7817    (set_attr "length_immediate" "*,*,0")
7818    (set_attr "mode" "SI")])
7819
7820 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7821 (define_insn "*andsi_1_zext"
7822   [(set (match_operand:DI 0 "register_operand" "=r")
7823         (zero_extend:DI
7824           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7825                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7826    (clobber (reg:CC FLAGS_REG))]
7827   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7828   "and{l}\t{%2, %k0|%k0, %2}"
7829   [(set_attr "type" "alu")
7830    (set_attr "mode" "SI")])
7831
7832 (define_insn "*andhi_1"
7833   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7834         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7835                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7836    (clobber (reg:CC FLAGS_REG))]
7837   "ix86_binary_operator_ok (AND, HImode, operands)"
7838 {
7839   switch (get_attr_type (insn))
7840     {
7841     case TYPE_IMOVX:
7842       gcc_assert (CONST_INT_P (operands[2]));
7843       gcc_assert (INTVAL (operands[2]) == 0xff);
7844       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7845
7846     default:
7847       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7848
7849       return "and{w}\t{%2, %0|%0, %2}";
7850     }
7851 }
7852   [(set_attr "type" "alu,alu,imovx")
7853    (set_attr "length_immediate" "*,*,0")
7854    (set (attr "prefix_rex")
7855      (if_then_else
7856        (and (eq_attr "type" "imovx")
7857             (match_operand 1 "ext_QIreg_operand" ""))
7858        (const_string "1")
7859        (const_string "*")))
7860    (set_attr "mode" "HI,HI,SI")])
7861
7862 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7863 (define_insn "*andqi_1"
7864   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7865         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7866                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7867    (clobber (reg:CC FLAGS_REG))]
7868   "ix86_binary_operator_ok (AND, QImode, operands)"
7869   "@
7870    and{b}\t{%2, %0|%0, %2}
7871    and{b}\t{%2, %0|%0, %2}
7872    and{l}\t{%k2, %k0|%k0, %k2}"
7873   [(set_attr "type" "alu")
7874    (set_attr "mode" "QI,QI,SI")])
7875
7876 (define_insn "*andqi_1_slp"
7877   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7878         (and:QI (match_dup 0)
7879                 (match_operand:QI 1 "general_operand" "qn,qmn")))
7880    (clobber (reg:CC FLAGS_REG))]
7881   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7882    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7883   "and{b}\t{%1, %0|%0, %1}"
7884   [(set_attr "type" "alu1")
7885    (set_attr "mode" "QI")])
7886
7887 (define_split
7888   [(set (match_operand 0 "register_operand" "")
7889         (and (match_dup 0)
7890              (const_int -65536)))
7891    (clobber (reg:CC FLAGS_REG))]
7892   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7893     || optimize_function_for_size_p (cfun)"
7894   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7895   "operands[1] = gen_lowpart (HImode, operands[0]);")
7896
7897 (define_split
7898   [(set (match_operand 0 "ext_register_operand" "")
7899         (and (match_dup 0)
7900              (const_int -256)))
7901    (clobber (reg:CC FLAGS_REG))]
7902   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7903    && reload_completed"
7904   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7905   "operands[1] = gen_lowpart (QImode, operands[0]);")
7906
7907 (define_split
7908   [(set (match_operand 0 "ext_register_operand" "")
7909         (and (match_dup 0)
7910              (const_int -65281)))
7911    (clobber (reg:CC FLAGS_REG))]
7912   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7913    && reload_completed"
7914   [(parallel [(set (zero_extract:SI (match_dup 0)
7915                                     (const_int 8)
7916                                     (const_int 8))
7917                    (xor:SI
7918                      (zero_extract:SI (match_dup 0)
7919                                       (const_int 8)
7920                                       (const_int 8))
7921                      (zero_extract:SI (match_dup 0)
7922                                       (const_int 8)
7923                                       (const_int 8))))
7924               (clobber (reg:CC FLAGS_REG))])]
7925   "operands[0] = gen_lowpart (SImode, operands[0]);")
7926
7927 (define_insn "*anddi_2"
7928   [(set (reg FLAGS_REG)
7929         (compare
7930          (and:DI
7931           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7932           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7933          (const_int 0)))
7934    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7935         (and:DI (match_dup 1) (match_dup 2)))]
7936   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7937    && ix86_binary_operator_ok (AND, DImode, operands)"
7938   "@
7939    and{l}\t{%k2, %k0|%k0, %k2}
7940    and{q}\t{%2, %0|%0, %2}
7941    and{q}\t{%2, %0|%0, %2}"
7942   [(set_attr "type" "alu")
7943    (set_attr "mode" "SI,DI,DI")])
7944
7945 (define_insn "*andqi_2_maybe_si"
7946   [(set (reg FLAGS_REG)
7947         (compare (and:QI
7948                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7949                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7950                  (const_int 0)))
7951    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7952         (and:QI (match_dup 1) (match_dup 2)))]
7953   "ix86_binary_operator_ok (AND, QImode, operands)
7954    && ix86_match_ccmode (insn,
7955                          CONST_INT_P (operands[2])
7956                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7957 {
7958   if (which_alternative == 2)
7959     {
7960       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7961         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7962       return "and{l}\t{%2, %k0|%k0, %2}";
7963     }
7964   return "and{b}\t{%2, %0|%0, %2}";
7965 }
7966   [(set_attr "type" "alu")
7967    (set_attr "mode" "QI,QI,SI")])
7968
7969 (define_insn "*and<mode>_2"
7970   [(set (reg FLAGS_REG)
7971         (compare (and:SWI124
7972                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7973                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7974                  (const_int 0)))
7975    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7976         (and:SWI124 (match_dup 1) (match_dup 2)))]
7977   "ix86_match_ccmode (insn, CCNOmode)
7978    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7979   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7980   [(set_attr "type" "alu")
7981    (set_attr "mode" "<MODE>")])
7982
7983 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7984 (define_insn "*andsi_2_zext"
7985   [(set (reg FLAGS_REG)
7986         (compare (and:SI
7987                   (match_operand:SI 1 "nonimmediate_operand" "%0")
7988                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
7989                  (const_int 0)))
7990    (set (match_operand:DI 0 "register_operand" "=r")
7991         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7992   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7993    && ix86_binary_operator_ok (AND, SImode, operands)"
7994   "and{l}\t{%2, %k0|%k0, %2}"
7995   [(set_attr "type" "alu")
7996    (set_attr "mode" "SI")])
7997
7998 (define_insn "*andqi_2_slp"
7999   [(set (reg FLAGS_REG)
8000         (compare (and:QI
8001                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8002                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8003                  (const_int 0)))
8004    (set (strict_low_part (match_dup 0))
8005         (and:QI (match_dup 0) (match_dup 1)))]
8006   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8007    && ix86_match_ccmode (insn, CCNOmode)
8008    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8009   "and{b}\t{%1, %0|%0, %1}"
8010   [(set_attr "type" "alu1")
8011    (set_attr "mode" "QI")])
8012
8013 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8014 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8015 ;; for a QImode operand, which of course failed.
8016 (define_insn "andqi_ext_0"
8017   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8018                          (const_int 8)
8019                          (const_int 8))
8020         (and:SI
8021           (zero_extract:SI
8022             (match_operand 1 "ext_register_operand" "0")
8023             (const_int 8)
8024             (const_int 8))
8025           (match_operand 2 "const_int_operand" "n")))
8026    (clobber (reg:CC FLAGS_REG))]
8027   ""
8028   "and{b}\t{%2, %h0|%h0, %2}"
8029   [(set_attr "type" "alu")
8030    (set_attr "length_immediate" "1")
8031    (set_attr "modrm" "1")
8032    (set_attr "mode" "QI")])
8033
8034 ;; Generated by peephole translating test to and.  This shows up
8035 ;; often in fp comparisons.
8036 (define_insn "*andqi_ext_0_cc"
8037   [(set (reg FLAGS_REG)
8038         (compare
8039           (and:SI
8040             (zero_extract:SI
8041               (match_operand 1 "ext_register_operand" "0")
8042               (const_int 8)
8043               (const_int 8))
8044             (match_operand 2 "const_int_operand" "n"))
8045           (const_int 0)))
8046    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8047                          (const_int 8)
8048                          (const_int 8))
8049         (and:SI
8050           (zero_extract:SI
8051             (match_dup 1)
8052             (const_int 8)
8053             (const_int 8))
8054           (match_dup 2)))]
8055   "ix86_match_ccmode (insn, CCNOmode)"
8056   "and{b}\t{%2, %h0|%h0, %2}"
8057   [(set_attr "type" "alu")
8058    (set_attr "length_immediate" "1")
8059    (set_attr "modrm" "1")
8060    (set_attr "mode" "QI")])
8061
8062 (define_insn "*andqi_ext_1_rex64"
8063   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8064                          (const_int 8)
8065                          (const_int 8))
8066         (and:SI
8067           (zero_extract:SI
8068             (match_operand 1 "ext_register_operand" "0")
8069             (const_int 8)
8070             (const_int 8))
8071           (zero_extend:SI
8072             (match_operand 2 "ext_register_operand" "Q"))))
8073    (clobber (reg:CC FLAGS_REG))]
8074   "TARGET_64BIT"
8075   "and{b}\t{%2, %h0|%h0, %2}"
8076   [(set_attr "type" "alu")
8077    (set_attr "length_immediate" "0")
8078    (set_attr "mode" "QI")])
8079
8080 (define_insn "*andqi_ext_1"
8081   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8082                          (const_int 8)
8083                          (const_int 8))
8084         (and:SI
8085           (zero_extract:SI
8086             (match_operand 1 "ext_register_operand" "0")
8087             (const_int 8)
8088             (const_int 8))
8089           (zero_extend:SI
8090             (match_operand:QI 2 "general_operand" "Qm"))))
8091    (clobber (reg:CC FLAGS_REG))]
8092   "!TARGET_64BIT"
8093   "and{b}\t{%2, %h0|%h0, %2}"
8094   [(set_attr "type" "alu")
8095    (set_attr "length_immediate" "0")
8096    (set_attr "mode" "QI")])
8097
8098 (define_insn "*andqi_ext_2"
8099   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8100                          (const_int 8)
8101                          (const_int 8))
8102         (and:SI
8103           (zero_extract:SI
8104             (match_operand 1 "ext_register_operand" "%0")
8105             (const_int 8)
8106             (const_int 8))
8107           (zero_extract:SI
8108             (match_operand 2 "ext_register_operand" "Q")
8109             (const_int 8)
8110             (const_int 8))))
8111    (clobber (reg:CC FLAGS_REG))]
8112   ""
8113   "and{b}\t{%h2, %h0|%h0, %h2}"
8114   [(set_attr "type" "alu")
8115    (set_attr "length_immediate" "0")
8116    (set_attr "mode" "QI")])
8117
8118 ;; Convert wide AND instructions with immediate operand to shorter QImode
8119 ;; equivalents when possible.
8120 ;; Don't do the splitting with memory operands, since it introduces risk
8121 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8122 ;; for size, but that can (should?) be handled by generic code instead.
8123 (define_split
8124   [(set (match_operand 0 "register_operand" "")
8125         (and (match_operand 1 "register_operand" "")
8126              (match_operand 2 "const_int_operand" "")))
8127    (clobber (reg:CC FLAGS_REG))]
8128    "reload_completed
8129     && QI_REG_P (operands[0])
8130     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8131     && !(~INTVAL (operands[2]) & ~(255 << 8))
8132     && GET_MODE (operands[0]) != QImode"
8133   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8134                    (and:SI (zero_extract:SI (match_dup 1)
8135                                             (const_int 8) (const_int 8))
8136                            (match_dup 2)))
8137               (clobber (reg:CC FLAGS_REG))])]
8138 {
8139   operands[0] = gen_lowpart (SImode, operands[0]);
8140   operands[1] = gen_lowpart (SImode, operands[1]);
8141   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8142 })
8143
8144 ;; Since AND can be encoded with sign extended immediate, this is only
8145 ;; profitable when 7th bit is not set.
8146 (define_split
8147   [(set (match_operand 0 "register_operand" "")
8148         (and (match_operand 1 "general_operand" "")
8149              (match_operand 2 "const_int_operand" "")))
8150    (clobber (reg:CC FLAGS_REG))]
8151    "reload_completed
8152     && ANY_QI_REG_P (operands[0])
8153     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8154     && !(~INTVAL (operands[2]) & ~255)
8155     && !(INTVAL (operands[2]) & 128)
8156     && GET_MODE (operands[0]) != QImode"
8157   [(parallel [(set (strict_low_part (match_dup 0))
8158                    (and:QI (match_dup 1)
8159                            (match_dup 2)))
8160               (clobber (reg:CC FLAGS_REG))])]
8161 {
8162   operands[0] = gen_lowpart (QImode, operands[0]);
8163   operands[1] = gen_lowpart (QImode, operands[1]);
8164   operands[2] = gen_lowpart (QImode, operands[2]);
8165 })
8166 \f
8167 ;; Logical inclusive and exclusive OR instructions
8168
8169 ;; %%% This used to optimize known byte-wide and operations to memory.
8170 ;; If this is considered useful, it should be done with splitters.
8171
8172 (define_expand "<code><mode>3"
8173   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8174         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8175                      (match_operand:SWIM 2 "<general_operand>" "")))]
8176   ""
8177   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8178
8179 (define_insn "*<code><mode>_1"
8180   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8181         (any_or:SWI248
8182          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8183          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8184    (clobber (reg:CC FLAGS_REG))]
8185   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8186   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8187   [(set_attr "type" "alu")
8188    (set_attr "mode" "<MODE>")])
8189
8190 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8191 (define_insn "*<code>qi_1"
8192   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8193         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8194                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8195    (clobber (reg:CC FLAGS_REG))]
8196   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8197   "@
8198    <logic>{b}\t{%2, %0|%0, %2}
8199    <logic>{b}\t{%2, %0|%0, %2}
8200    <logic>{l}\t{%k2, %k0|%k0, %k2}"
8201   [(set_attr "type" "alu")
8202    (set_attr "mode" "QI,QI,SI")])
8203
8204 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8205 (define_insn "*<code>si_1_zext"
8206   [(set (match_operand:DI 0 "register_operand" "=r")
8207         (zero_extend:DI
8208          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8209                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8210    (clobber (reg:CC FLAGS_REG))]
8211   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8212   "<logic>{l}\t{%2, %k0|%k0, %2}"
8213   [(set_attr "type" "alu")
8214    (set_attr "mode" "SI")])
8215
8216 (define_insn "*<code>si_1_zext_imm"
8217   [(set (match_operand:DI 0 "register_operand" "=r")
8218         (any_or:DI
8219          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8220          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8221    (clobber (reg:CC FLAGS_REG))]
8222   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8223   "<logic>{l}\t{%2, %k0|%k0, %2}"
8224   [(set_attr "type" "alu")
8225    (set_attr "mode" "SI")])
8226
8227 (define_insn "*<code>qi_1_slp"
8228   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8229         (any_or:QI (match_dup 0)
8230                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8231    (clobber (reg:CC FLAGS_REG))]
8232   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8233    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8234   "<logic>{b}\t{%1, %0|%0, %1}"
8235   [(set_attr "type" "alu1")
8236    (set_attr "mode" "QI")])
8237
8238 (define_insn "*<code><mode>_2"
8239   [(set (reg FLAGS_REG)
8240         (compare (any_or:SWI
8241                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8242                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8243                  (const_int 0)))
8244    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8245         (any_or:SWI (match_dup 1) (match_dup 2)))]
8246   "ix86_match_ccmode (insn, CCNOmode)
8247    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8248   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8249   [(set_attr "type" "alu")
8250    (set_attr "mode" "<MODE>")])
8251
8252 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8253 ;; ??? Special case for immediate operand is missing - it is tricky.
8254 (define_insn "*<code>si_2_zext"
8255   [(set (reg FLAGS_REG)
8256         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8257                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
8258                  (const_int 0)))
8259    (set (match_operand:DI 0 "register_operand" "=r")
8260         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8261   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8262    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8263   "<logic>{l}\t{%2, %k0|%k0, %2}"
8264   [(set_attr "type" "alu")
8265    (set_attr "mode" "SI")])
8266
8267 (define_insn "*<code>si_2_zext_imm"
8268   [(set (reg FLAGS_REG)
8269         (compare (any_or:SI
8270                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8271                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8272                  (const_int 0)))
8273    (set (match_operand:DI 0 "register_operand" "=r")
8274         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8275   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8276    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8277   "<logic>{l}\t{%2, %k0|%k0, %2}"
8278   [(set_attr "type" "alu")
8279    (set_attr "mode" "SI")])
8280
8281 (define_insn "*<code>qi_2_slp"
8282   [(set (reg FLAGS_REG)
8283         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8284                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8285                  (const_int 0)))
8286    (set (strict_low_part (match_dup 0))
8287         (any_or:QI (match_dup 0) (match_dup 1)))]
8288   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8289    && ix86_match_ccmode (insn, CCNOmode)
8290    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8291   "<logic>{b}\t{%1, %0|%0, %1}"
8292   [(set_attr "type" "alu1")
8293    (set_attr "mode" "QI")])
8294
8295 (define_insn "*<code><mode>_3"
8296   [(set (reg FLAGS_REG)
8297         (compare (any_or:SWI
8298                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8299                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8300                  (const_int 0)))
8301    (clobber (match_scratch:SWI 0 "=<r>"))]
8302   "ix86_match_ccmode (insn, CCNOmode)
8303    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8304   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8305   [(set_attr "type" "alu")
8306    (set_attr "mode" "<MODE>")])
8307
8308 (define_insn "*<code>qi_ext_0"
8309   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8310                          (const_int 8)
8311                          (const_int 8))
8312         (any_or:SI
8313           (zero_extract:SI
8314             (match_operand 1 "ext_register_operand" "0")
8315             (const_int 8)
8316             (const_int 8))
8317           (match_operand 2 "const_int_operand" "n")))
8318    (clobber (reg:CC FLAGS_REG))]
8319   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8320   "<logic>{b}\t{%2, %h0|%h0, %2}"
8321   [(set_attr "type" "alu")
8322    (set_attr "length_immediate" "1")
8323    (set_attr "modrm" "1")
8324    (set_attr "mode" "QI")])
8325
8326 (define_insn "*<code>qi_ext_1_rex64"
8327   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8328                          (const_int 8)
8329                          (const_int 8))
8330         (any_or:SI
8331           (zero_extract:SI
8332             (match_operand 1 "ext_register_operand" "0")
8333             (const_int 8)
8334             (const_int 8))
8335           (zero_extend:SI
8336             (match_operand 2 "ext_register_operand" "Q"))))
8337    (clobber (reg:CC FLAGS_REG))]
8338   "TARGET_64BIT
8339    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8340   "<logic>{b}\t{%2, %h0|%h0, %2}"
8341   [(set_attr "type" "alu")
8342    (set_attr "length_immediate" "0")
8343    (set_attr "mode" "QI")])
8344
8345 (define_insn "*<code>qi_ext_1"
8346   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8347                          (const_int 8)
8348                          (const_int 8))
8349         (any_or:SI
8350           (zero_extract:SI
8351             (match_operand 1 "ext_register_operand" "0")
8352             (const_int 8)
8353             (const_int 8))
8354           (zero_extend:SI
8355             (match_operand:QI 2 "general_operand" "Qm"))))
8356    (clobber (reg:CC FLAGS_REG))]
8357   "!TARGET_64BIT
8358    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8359   "<logic>{b}\t{%2, %h0|%h0, %2}"
8360   [(set_attr "type" "alu")
8361    (set_attr "length_immediate" "0")
8362    (set_attr "mode" "QI")])
8363
8364 (define_insn "*<code>qi_ext_2"
8365   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8366                          (const_int 8)
8367                          (const_int 8))
8368         (any_or:SI
8369           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8370                            (const_int 8)
8371                            (const_int 8))
8372           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8373                            (const_int 8)
8374                            (const_int 8))))
8375    (clobber (reg:CC FLAGS_REG))]
8376   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8377   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8378   [(set_attr "type" "alu")
8379    (set_attr "length_immediate" "0")
8380    (set_attr "mode" "QI")])
8381
8382 (define_split
8383   [(set (match_operand 0 "register_operand" "")
8384         (any_or (match_operand 1 "register_operand" "")
8385                 (match_operand 2 "const_int_operand" "")))
8386    (clobber (reg:CC FLAGS_REG))]
8387    "reload_completed
8388     && QI_REG_P (operands[0])
8389     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8390     && !(INTVAL (operands[2]) & ~(255 << 8))
8391     && GET_MODE (operands[0]) != QImode"
8392   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8393                    (any_or:SI (zero_extract:SI (match_dup 1)
8394                                                (const_int 8) (const_int 8))
8395                               (match_dup 2)))
8396               (clobber (reg:CC FLAGS_REG))])]
8397 {
8398   operands[0] = gen_lowpart (SImode, operands[0]);
8399   operands[1] = gen_lowpart (SImode, operands[1]);
8400   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8401 })
8402
8403 ;; Since OR can be encoded with sign extended immediate, this is only
8404 ;; profitable when 7th bit is set.
8405 (define_split
8406   [(set (match_operand 0 "register_operand" "")
8407         (any_or (match_operand 1 "general_operand" "")
8408                 (match_operand 2 "const_int_operand" "")))
8409    (clobber (reg:CC FLAGS_REG))]
8410    "reload_completed
8411     && ANY_QI_REG_P (operands[0])
8412     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8413     && !(INTVAL (operands[2]) & ~255)
8414     && (INTVAL (operands[2]) & 128)
8415     && GET_MODE (operands[0]) != QImode"
8416   [(parallel [(set (strict_low_part (match_dup 0))
8417                    (any_or:QI (match_dup 1)
8418                               (match_dup 2)))
8419               (clobber (reg:CC FLAGS_REG))])]
8420 {
8421   operands[0] = gen_lowpart (QImode, operands[0]);
8422   operands[1] = gen_lowpart (QImode, operands[1]);
8423   operands[2] = gen_lowpart (QImode, operands[2]);
8424 })
8425
8426 (define_expand "xorqi_cc_ext_1"
8427   [(parallel [
8428      (set (reg:CCNO FLAGS_REG)
8429           (compare:CCNO
8430             (xor:SI
8431               (zero_extract:SI
8432                 (match_operand 1 "ext_register_operand" "")
8433                 (const_int 8)
8434                 (const_int 8))
8435               (match_operand:QI 2 "general_operand" ""))
8436             (const_int 0)))
8437      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8438                            (const_int 8)
8439                            (const_int 8))
8440           (xor:SI
8441             (zero_extract:SI
8442              (match_dup 1)
8443              (const_int 8)
8444              (const_int 8))
8445             (match_dup 2)))])])
8446
8447 (define_insn "*xorqi_cc_ext_1_rex64"
8448   [(set (reg FLAGS_REG)
8449         (compare
8450           (xor:SI
8451             (zero_extract:SI
8452               (match_operand 1 "ext_register_operand" "0")
8453               (const_int 8)
8454               (const_int 8))
8455             (match_operand:QI 2 "nonmemory_operand" "Qn"))
8456           (const_int 0)))
8457    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8458                          (const_int 8)
8459                          (const_int 8))
8460         (xor:SI
8461           (zero_extract:SI
8462            (match_dup 1)
8463            (const_int 8)
8464            (const_int 8))
8465           (match_dup 2)))]
8466   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8467   "xor{b}\t{%2, %h0|%h0, %2}"
8468   [(set_attr "type" "alu")
8469    (set_attr "modrm" "1")
8470    (set_attr "mode" "QI")])
8471
8472 (define_insn "*xorqi_cc_ext_1"
8473   [(set (reg FLAGS_REG)
8474         (compare
8475           (xor:SI
8476             (zero_extract:SI
8477               (match_operand 1 "ext_register_operand" "0")
8478               (const_int 8)
8479               (const_int 8))
8480             (match_operand:QI 2 "general_operand" "qmn"))
8481           (const_int 0)))
8482    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8483                          (const_int 8)
8484                          (const_int 8))
8485         (xor:SI
8486           (zero_extract:SI
8487            (match_dup 1)
8488            (const_int 8)
8489            (const_int 8))
8490           (match_dup 2)))]
8491   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8492   "xor{b}\t{%2, %h0|%h0, %2}"
8493   [(set_attr "type" "alu")
8494    (set_attr "modrm" "1")
8495    (set_attr "mode" "QI")])
8496 \f
8497 ;; Negation instructions
8498
8499 (define_expand "neg<mode>2"
8500   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8501         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8502   ""
8503   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8504
8505 (define_insn_and_split "*neg<dwi>2_doubleword"
8506   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8507         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8508    (clobber (reg:CC FLAGS_REG))]
8509   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8510   "#"
8511   "reload_completed"
8512   [(parallel
8513     [(set (reg:CCZ FLAGS_REG)
8514           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8515      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8516    (parallel
8517     [(set (match_dup 2)
8518           (plus:DWIH (match_dup 3)
8519                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8520                                 (const_int 0))))
8521      (clobber (reg:CC FLAGS_REG))])
8522    (parallel
8523     [(set (match_dup 2)
8524           (neg:DWIH (match_dup 2)))
8525      (clobber (reg:CC FLAGS_REG))])]
8526   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8527
8528 (define_insn "*neg<mode>2_1"
8529   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8530         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8531    (clobber (reg:CC FLAGS_REG))]
8532   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8533   "neg{<imodesuffix>}\t%0"
8534   [(set_attr "type" "negnot")
8535    (set_attr "mode" "<MODE>")])
8536
8537 ;; Combine is quite creative about this pattern.
8538 (define_insn "*negsi2_1_zext"
8539   [(set (match_operand:DI 0 "register_operand" "=r")
8540         (lshiftrt:DI
8541           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8542                              (const_int 32)))
8543         (const_int 32)))
8544    (clobber (reg:CC FLAGS_REG))]
8545   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8546   "neg{l}\t%k0"
8547   [(set_attr "type" "negnot")
8548    (set_attr "mode" "SI")])
8549
8550 ;; The problem with neg is that it does not perform (compare x 0),
8551 ;; it really performs (compare 0 x), which leaves us with the zero
8552 ;; flag being the only useful item.
8553
8554 (define_insn "*neg<mode>2_cmpz"
8555   [(set (reg:CCZ FLAGS_REG)
8556         (compare:CCZ
8557           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8558                    (const_int 0)))
8559    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8560         (neg:SWI (match_dup 1)))]
8561   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8562   "neg{<imodesuffix>}\t%0"
8563   [(set_attr "type" "negnot")
8564    (set_attr "mode" "<MODE>")])
8565
8566 (define_insn "*negsi2_cmpz_zext"
8567   [(set (reg:CCZ FLAGS_REG)
8568         (compare:CCZ
8569           (lshiftrt:DI
8570             (neg:DI (ashift:DI
8571                       (match_operand:DI 1 "register_operand" "0")
8572                       (const_int 32)))
8573             (const_int 32))
8574           (const_int 0)))
8575    (set (match_operand:DI 0 "register_operand" "=r")
8576         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8577                                         (const_int 32)))
8578                      (const_int 32)))]
8579   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8580   "neg{l}\t%k0"
8581   [(set_attr "type" "negnot")
8582    (set_attr "mode" "SI")])
8583
8584 ;; Changing of sign for FP values is doable using integer unit too.
8585
8586 (define_expand "<code><mode>2"
8587   [(set (match_operand:X87MODEF 0 "register_operand" "")
8588         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8589   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8590   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8591
8592 (define_insn "*absneg<mode>2_mixed"
8593   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8594         (match_operator:MODEF 3 "absneg_operator"
8595           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8596    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8597    (clobber (reg:CC FLAGS_REG))]
8598   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8599   "#")
8600
8601 (define_insn "*absneg<mode>2_sse"
8602   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8603         (match_operator:MODEF 3 "absneg_operator"
8604           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8605    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8606    (clobber (reg:CC FLAGS_REG))]
8607   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8608   "#")
8609
8610 (define_insn "*absneg<mode>2_i387"
8611   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8612         (match_operator:X87MODEF 3 "absneg_operator"
8613           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8614    (use (match_operand 2 "" ""))
8615    (clobber (reg:CC FLAGS_REG))]
8616   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8617   "#")
8618
8619 (define_expand "<code>tf2"
8620   [(set (match_operand:TF 0 "register_operand" "")
8621         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8622   "TARGET_SSE2"
8623   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8624
8625 (define_insn "*absnegtf2_sse"
8626   [(set (match_operand:TF 0 "register_operand" "=x,x")
8627         (match_operator:TF 3 "absneg_operator"
8628           [(match_operand:TF 1 "register_operand" "0,x")]))
8629    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8630    (clobber (reg:CC FLAGS_REG))]
8631   "TARGET_SSE2"
8632   "#")
8633
8634 ;; Splitters for fp abs and neg.
8635
8636 (define_split
8637   [(set (match_operand 0 "fp_register_operand" "")
8638         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8639    (use (match_operand 2 "" ""))
8640    (clobber (reg:CC FLAGS_REG))]
8641   "reload_completed"
8642   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8643
8644 (define_split
8645   [(set (match_operand 0 "register_operand" "")
8646         (match_operator 3 "absneg_operator"
8647           [(match_operand 1 "register_operand" "")]))
8648    (use (match_operand 2 "nonimmediate_operand" ""))
8649    (clobber (reg:CC FLAGS_REG))]
8650   "reload_completed && SSE_REG_P (operands[0])"
8651   [(set (match_dup 0) (match_dup 3))]
8652 {
8653   enum machine_mode mode = GET_MODE (operands[0]);
8654   enum machine_mode vmode = GET_MODE (operands[2]);
8655   rtx tmp;
8656
8657   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8658   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8659   if (operands_match_p (operands[0], operands[2]))
8660     {
8661       tmp = operands[1];
8662       operands[1] = operands[2];
8663       operands[2] = tmp;
8664     }
8665   if (GET_CODE (operands[3]) == ABS)
8666     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8667   else
8668     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8669   operands[3] = tmp;
8670 })
8671
8672 (define_split
8673   [(set (match_operand:SF 0 "register_operand" "")
8674         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8675    (use (match_operand:V4SF 2 "" ""))
8676    (clobber (reg:CC FLAGS_REG))]
8677   "reload_completed"
8678   [(parallel [(set (match_dup 0) (match_dup 1))
8679               (clobber (reg:CC FLAGS_REG))])]
8680 {
8681   rtx tmp;
8682   operands[0] = gen_lowpart (SImode, operands[0]);
8683   if (GET_CODE (operands[1]) == ABS)
8684     {
8685       tmp = gen_int_mode (0x7fffffff, SImode);
8686       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8687     }
8688   else
8689     {
8690       tmp = gen_int_mode (0x80000000, SImode);
8691       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8692     }
8693   operands[1] = tmp;
8694 })
8695
8696 (define_split
8697   [(set (match_operand:DF 0 "register_operand" "")
8698         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8699    (use (match_operand 2 "" ""))
8700    (clobber (reg:CC FLAGS_REG))]
8701   "reload_completed"
8702   [(parallel [(set (match_dup 0) (match_dup 1))
8703               (clobber (reg:CC FLAGS_REG))])]
8704 {
8705   rtx tmp;
8706   if (TARGET_64BIT)
8707     {
8708       tmp = gen_lowpart (DImode, operands[0]);
8709       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8710       operands[0] = tmp;
8711
8712       if (GET_CODE (operands[1]) == ABS)
8713         tmp = const0_rtx;
8714       else
8715         tmp = gen_rtx_NOT (DImode, tmp);
8716     }
8717   else
8718     {
8719       operands[0] = gen_highpart (SImode, operands[0]);
8720       if (GET_CODE (operands[1]) == ABS)
8721         {
8722           tmp = gen_int_mode (0x7fffffff, SImode);
8723           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8724         }
8725       else
8726         {
8727           tmp = gen_int_mode (0x80000000, SImode);
8728           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8729         }
8730     }
8731   operands[1] = tmp;
8732 })
8733
8734 (define_split
8735   [(set (match_operand:XF 0 "register_operand" "")
8736         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8737    (use (match_operand 2 "" ""))
8738    (clobber (reg:CC FLAGS_REG))]
8739   "reload_completed"
8740   [(parallel [(set (match_dup 0) (match_dup 1))
8741               (clobber (reg:CC FLAGS_REG))])]
8742 {
8743   rtx tmp;
8744   operands[0] = gen_rtx_REG (SImode,
8745                              true_regnum (operands[0])
8746                              + (TARGET_64BIT ? 1 : 2));
8747   if (GET_CODE (operands[1]) == ABS)
8748     {
8749       tmp = GEN_INT (0x7fff);
8750       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8751     }
8752   else
8753     {
8754       tmp = GEN_INT (0x8000);
8755       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8756     }
8757   operands[1] = tmp;
8758 })
8759
8760 ;; Conditionalize these after reload. If they match before reload, we
8761 ;; lose the clobber and ability to use integer instructions.
8762
8763 (define_insn "*<code><mode>2_1"
8764   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8765         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8766   "TARGET_80387
8767    && (reload_completed
8768        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8769   "f<absneg_mnemonic>"
8770   [(set_attr "type" "fsgn")
8771    (set_attr "mode" "<MODE>")])
8772
8773 (define_insn "*<code>extendsfdf2"
8774   [(set (match_operand:DF 0 "register_operand" "=f")
8775         (absneg:DF (float_extend:DF
8776                      (match_operand:SF 1 "register_operand" "0"))))]
8777   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8778   "f<absneg_mnemonic>"
8779   [(set_attr "type" "fsgn")
8780    (set_attr "mode" "DF")])
8781
8782 (define_insn "*<code>extendsfxf2"
8783   [(set (match_operand:XF 0 "register_operand" "=f")
8784         (absneg:XF (float_extend:XF
8785                      (match_operand:SF 1 "register_operand" "0"))))]
8786   "TARGET_80387"
8787   "f<absneg_mnemonic>"
8788   [(set_attr "type" "fsgn")
8789    (set_attr "mode" "XF")])
8790
8791 (define_insn "*<code>extenddfxf2"
8792   [(set (match_operand:XF 0 "register_operand" "=f")
8793         (absneg:XF (float_extend:XF
8794                      (match_operand:DF 1 "register_operand" "0"))))]
8795   "TARGET_80387"
8796   "f<absneg_mnemonic>"
8797   [(set_attr "type" "fsgn")
8798    (set_attr "mode" "XF")])
8799
8800 ;; Copysign instructions
8801
8802 (define_mode_iterator CSGNMODE [SF DF TF])
8803 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8804
8805 (define_expand "copysign<mode>3"
8806   [(match_operand:CSGNMODE 0 "register_operand" "")
8807    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8808    (match_operand:CSGNMODE 2 "register_operand" "")]
8809   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8810    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8811   "ix86_expand_copysign (operands); DONE;")
8812
8813 (define_insn_and_split "copysign<mode>3_const"
8814   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8815         (unspec:CSGNMODE
8816           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8817            (match_operand:CSGNMODE 2 "register_operand" "0")
8818            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8819           UNSPEC_COPYSIGN))]
8820   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8821    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8822   "#"
8823   "&& reload_completed"
8824   [(const_int 0)]
8825   "ix86_split_copysign_const (operands); DONE;")
8826
8827 (define_insn "copysign<mode>3_var"
8828   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8829         (unspec:CSGNMODE
8830           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8831            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8832            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8833            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8834           UNSPEC_COPYSIGN))
8835    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8836   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8837    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8838   "#")
8839
8840 (define_split
8841   [(set (match_operand:CSGNMODE 0 "register_operand" "")
8842         (unspec:CSGNMODE
8843           [(match_operand:CSGNMODE 2 "register_operand" "")
8844            (match_operand:CSGNMODE 3 "register_operand" "")
8845            (match_operand:<CSGNVMODE> 4 "" "")
8846            (match_operand:<CSGNVMODE> 5 "" "")]
8847           UNSPEC_COPYSIGN))
8848    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8849   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8850     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8851    && reload_completed"
8852   [(const_int 0)]
8853   "ix86_split_copysign_var (operands); DONE;")
8854 \f
8855 ;; One complement instructions
8856
8857 (define_expand "one_cmpl<mode>2"
8858   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8859         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8860   ""
8861   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8862
8863 (define_insn "*one_cmpl<mode>2_1"
8864   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8865         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8866   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8867   "not{<imodesuffix>}\t%0"
8868   [(set_attr "type" "negnot")
8869    (set_attr "mode" "<MODE>")])
8870
8871 ;; %%% Potential partial reg stall on alternative 1.  What to do?
8872 (define_insn "*one_cmplqi2_1"
8873   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8874         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8875   "ix86_unary_operator_ok (NOT, QImode, operands)"
8876   "@
8877    not{b}\t%0
8878    not{l}\t%k0"
8879   [(set_attr "type" "negnot")
8880    (set_attr "mode" "QI,SI")])
8881
8882 ;; ??? Currently never generated - xor is used instead.
8883 (define_insn "*one_cmplsi2_1_zext"
8884   [(set (match_operand:DI 0 "register_operand" "=r")
8885         (zero_extend:DI
8886           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8887   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8888   "not{l}\t%k0"
8889   [(set_attr "type" "negnot")
8890    (set_attr "mode" "SI")])
8891
8892 (define_insn "*one_cmpl<mode>2_2"
8893   [(set (reg FLAGS_REG)
8894         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8895                  (const_int 0)))
8896    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8897         (not:SWI (match_dup 1)))]
8898   "ix86_match_ccmode (insn, CCNOmode)
8899    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8900   "#"
8901   [(set_attr "type" "alu1")
8902    (set_attr "mode" "<MODE>")])
8903
8904 (define_split
8905   [(set (match_operand 0 "flags_reg_operand" "")
8906         (match_operator 2 "compare_operator"
8907           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8908            (const_int 0)]))
8909    (set (match_operand:SWI 1 "nonimmediate_operand" "")
8910         (not:SWI (match_dup 3)))]
8911   "ix86_match_ccmode (insn, CCNOmode)"
8912   [(parallel [(set (match_dup 0)
8913                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8914                                     (const_int 0)]))
8915               (set (match_dup 1)
8916                    (xor:SWI (match_dup 3) (const_int -1)))])])
8917
8918 ;; ??? Currently never generated - xor is used instead.
8919 (define_insn "*one_cmplsi2_2_zext"
8920   [(set (reg FLAGS_REG)
8921         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8922                  (const_int 0)))
8923    (set (match_operand:DI 0 "register_operand" "=r")
8924         (zero_extend:DI (not:SI (match_dup 1))))]
8925   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8926    && ix86_unary_operator_ok (NOT, SImode, operands)"
8927   "#"
8928   [(set_attr "type" "alu1")
8929    (set_attr "mode" "SI")])
8930
8931 (define_split
8932   [(set (match_operand 0 "flags_reg_operand" "")
8933         (match_operator 2 "compare_operator"
8934           [(not:SI (match_operand:SI 3 "register_operand" ""))
8935            (const_int 0)]))
8936    (set (match_operand:DI 1 "register_operand" "")
8937         (zero_extend:DI (not:SI (match_dup 3))))]
8938   "ix86_match_ccmode (insn, CCNOmode)"
8939   [(parallel [(set (match_dup 0)
8940                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8941                                     (const_int 0)]))
8942               (set (match_dup 1)
8943                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8944 \f
8945 ;; Shift instructions
8946
8947 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8948 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
8949 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8950 ;; from the assembler input.
8951 ;;
8952 ;; This instruction shifts the target reg/mem as usual, but instead of
8953 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
8954 ;; is a left shift double, bits are taken from the high order bits of
8955 ;; reg, else if the insn is a shift right double, bits are taken from the
8956 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
8957 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8958 ;;
8959 ;; Since sh[lr]d does not change the `reg' operand, that is done
8960 ;; separately, making all shifts emit pairs of shift double and normal
8961 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
8962 ;; support a 63 bit shift, each shift where the count is in a reg expands
8963 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8964 ;;
8965 ;; If the shift count is a constant, we need never emit more than one
8966 ;; shift pair, instead using moves and sign extension for counts greater
8967 ;; than 31.
8968
8969 (define_expand "ashl<mode>3"
8970   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8971         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8972                       (match_operand:QI 2 "nonmemory_operand" "")))]
8973   ""
8974   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8975
8976 (define_insn "*ashl<mode>3_doubleword"
8977   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8978         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8979                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8980    (clobber (reg:CC FLAGS_REG))]
8981   ""
8982   "#"
8983   [(set_attr "type" "multi")])
8984
8985 (define_split
8986   [(set (match_operand:DWI 0 "register_operand" "")
8987         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8988                     (match_operand:QI 2 "nonmemory_operand" "")))
8989    (clobber (reg:CC FLAGS_REG))]
8990   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8991   [(const_int 0)]
8992   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8993
8994 ;; By default we don't ask for a scratch register, because when DWImode
8995 ;; values are manipulated, registers are already at a premium.  But if
8996 ;; we have one handy, we won't turn it away.
8997
8998 (define_peephole2
8999   [(match_scratch:DWIH 3 "r")
9000    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9001                    (ashift:<DWI>
9002                      (match_operand:<DWI> 1 "nonmemory_operand" "")
9003                      (match_operand:QI 2 "nonmemory_operand" "")))
9004               (clobber (reg:CC FLAGS_REG))])
9005    (match_dup 3)]
9006   "TARGET_CMOVE"
9007   [(const_int 0)]
9008   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9009
9010 (define_insn "x86_64_shld"
9011   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9012         (ior:DI (ashift:DI (match_dup 0)
9013                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9014                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9015                   (minus:QI (const_int 64) (match_dup 2)))))
9016    (clobber (reg:CC FLAGS_REG))]
9017   "TARGET_64BIT"
9018   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9019   [(set_attr "type" "ishift")
9020    (set_attr "prefix_0f" "1")
9021    (set_attr "mode" "DI")
9022    (set_attr "athlon_decode" "vector")
9023    (set_attr "amdfam10_decode" "vector")
9024    (set_attr "bdver1_decode" "vector")])
9025
9026 (define_insn "x86_shld"
9027   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9028         (ior:SI (ashift:SI (match_dup 0)
9029                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9030                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9031                   (minus:QI (const_int 32) (match_dup 2)))))
9032    (clobber (reg:CC FLAGS_REG))]
9033   ""
9034   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9035   [(set_attr "type" "ishift")
9036    (set_attr "prefix_0f" "1")
9037    (set_attr "mode" "SI")
9038    (set_attr "pent_pair" "np")
9039    (set_attr "athlon_decode" "vector")
9040    (set_attr "amdfam10_decode" "vector")
9041    (set_attr "bdver1_decode" "vector")])
9042
9043 (define_expand "x86_shift<mode>_adj_1"
9044   [(set (reg:CCZ FLAGS_REG)
9045         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9046                              (match_dup 4))
9047                      (const_int 0)))
9048    (set (match_operand:SWI48 0 "register_operand" "")
9049         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9050                             (match_operand:SWI48 1 "register_operand" "")
9051                             (match_dup 0)))
9052    (set (match_dup 1)
9053         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9054                             (match_operand:SWI48 3 "register_operand" "")
9055                             (match_dup 1)))]
9056   "TARGET_CMOVE"
9057   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9058
9059 (define_expand "x86_shift<mode>_adj_2"
9060   [(use (match_operand:SWI48 0 "register_operand" ""))
9061    (use (match_operand:SWI48 1 "register_operand" ""))
9062    (use (match_operand:QI 2 "register_operand" ""))]
9063   ""
9064 {
9065   rtx label = gen_label_rtx ();
9066   rtx tmp;
9067
9068   emit_insn (gen_testqi_ccz_1 (operands[2],
9069                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9070
9071   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9072   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9073   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9074                               gen_rtx_LABEL_REF (VOIDmode, label),
9075                               pc_rtx);
9076   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9077   JUMP_LABEL (tmp) = label;
9078
9079   emit_move_insn (operands[0], operands[1]);
9080   ix86_expand_clear (operands[1]);
9081
9082   emit_label (label);
9083   LABEL_NUSES (label) = 1;
9084
9085   DONE;
9086 })
9087
9088 ;; Avoid useless masking of count operand.
9089 (define_insn "*ashl<mode>3_mask"
9090   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9091         (ashift:SWI48
9092           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9093           (subreg:QI
9094             (and:SI
9095               (match_operand:SI 2 "register_operand" "c")
9096               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9097    (clobber (reg:CC FLAGS_REG))]
9098   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9099    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9100       == GET_MODE_BITSIZE (<MODE>mode)-1"
9101 {
9102   return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9103 }
9104   [(set_attr "type" "ishift")
9105    (set_attr "mode" "<MODE>")])
9106
9107 (define_insn "*bmi2_ashl<mode>3_1"
9108   [(set (match_operand:SWI48 0 "register_operand" "=r")
9109         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9110                       (match_operand:SWI48 2 "register_operand" "r")))]
9111   "TARGET_BMI2"
9112   "shlx\t{%2, %1, %0|%0, %1, %2}"
9113   [(set_attr "type" "ishiftx")
9114    (set_attr "mode" "<MODE>")])
9115
9116 (define_insn "*ashl<mode>3_1"
9117   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9118         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9119                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9120    (clobber (reg:CC FLAGS_REG))]
9121   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9122 {
9123   switch (get_attr_type (insn))
9124     {
9125     case TYPE_LEA:
9126     case TYPE_ISHIFTX:
9127       return "#";
9128
9129     case TYPE_ALU:
9130       gcc_assert (operands[2] == const1_rtx);
9131       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9132       return "add{<imodesuffix>}\t%0, %0";
9133
9134     default:
9135       if (operands[2] == const1_rtx
9136           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9137         return "sal{<imodesuffix>}\t%0";
9138       else
9139         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9140     }
9141 }
9142   [(set_attr "isa" "*,*,bmi2")
9143    (set (attr "type")
9144      (cond [(eq_attr "alternative" "1")
9145               (const_string "lea")
9146             (eq_attr "alternative" "2")
9147               (const_string "ishiftx")
9148             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9149                       (match_operand 0 "register_operand" ""))
9150                  (match_operand 2 "const1_operand" ""))
9151               (const_string "alu")
9152            ]
9153            (const_string "ishift")))
9154    (set (attr "length_immediate")
9155      (if_then_else
9156        (ior (eq_attr "type" "alu")
9157             (and (eq_attr "type" "ishift")
9158                  (and (match_operand 2 "const1_operand" "")
9159                       (ior (match_test "TARGET_SHIFT1")
9160                            (match_test "optimize_function_for_size_p (cfun)")))))
9161        (const_string "0")
9162        (const_string "*")))
9163    (set_attr "mode" "<MODE>")])
9164
9165 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9166 (define_split
9167   [(set (match_operand:SWI48 0 "register_operand" "")
9168         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9169                       (match_operand:QI 2 "register_operand" "")))
9170    (clobber (reg:CC FLAGS_REG))]
9171   "TARGET_BMI2 && reload_completed"
9172   [(set (match_dup 0)
9173         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9174   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9175
9176 (define_insn "*bmi2_ashlsi3_1_zext"
9177   [(set (match_operand:DI 0 "register_operand" "=r")
9178         (zero_extend:DI
9179           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9180                      (match_operand:SI 2 "register_operand" "r"))))]
9181   "TARGET_64BIT && TARGET_BMI2"
9182   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9183   [(set_attr "type" "ishiftx")
9184    (set_attr "mode" "SI")])
9185
9186 (define_insn "*ashlsi3_1_zext"
9187   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9188         (zero_extend:DI
9189           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9190                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9191    (clobber (reg:CC FLAGS_REG))]
9192   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9193 {
9194   switch (get_attr_type (insn))
9195     {
9196     case TYPE_LEA:
9197     case TYPE_ISHIFTX:
9198       return "#";
9199
9200     case TYPE_ALU:
9201       gcc_assert (operands[2] == const1_rtx);
9202       return "add{l}\t%k0, %k0";
9203
9204     default:
9205       if (operands[2] == const1_rtx
9206           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9207         return "sal{l}\t%k0";
9208       else
9209         return "sal{l}\t{%2, %k0|%k0, %2}";
9210     }
9211 }
9212   [(set_attr "isa" "*,*,bmi2")
9213    (set (attr "type")
9214      (cond [(eq_attr "alternative" "1")
9215               (const_string "lea")
9216             (eq_attr "alternative" "2")
9217               (const_string "ishiftx")
9218             (and (match_test "TARGET_DOUBLE_WITH_ADD")
9219                  (match_operand 2 "const1_operand" ""))
9220               (const_string "alu")
9221            ]
9222            (const_string "ishift")))
9223    (set (attr "length_immediate")
9224      (if_then_else
9225        (ior (eq_attr "type" "alu")
9226             (and (eq_attr "type" "ishift")
9227                  (and (match_operand 2 "const1_operand" "")
9228                       (ior (match_test "TARGET_SHIFT1")
9229                            (match_test "optimize_function_for_size_p (cfun)")))))
9230        (const_string "0")
9231        (const_string "*")))
9232    (set_attr "mode" "SI")])
9233
9234 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9235 (define_split
9236   [(set (match_operand:DI 0 "register_operand" "")
9237         (zero_extend:DI
9238           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9239                      (match_operand:QI 2 "register_operand" ""))))
9240    (clobber (reg:CC FLAGS_REG))]
9241   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9242   [(set (match_dup 0)
9243         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9244   "operands[2] = gen_lowpart (SImode, operands[2]);")
9245
9246 (define_insn "*ashlhi3_1"
9247   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9248         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9249                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9250    (clobber (reg:CC FLAGS_REG))]
9251   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9252 {
9253   switch (get_attr_type (insn))
9254     {
9255     case TYPE_LEA:
9256       return "#";
9257
9258     case TYPE_ALU:
9259       gcc_assert (operands[2] == const1_rtx);
9260       return "add{w}\t%0, %0";
9261
9262     default:
9263       if (operands[2] == const1_rtx
9264           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9265         return "sal{w}\t%0";
9266       else
9267         return "sal{w}\t{%2, %0|%0, %2}";
9268     }
9269 }
9270   [(set (attr "type")
9271      (cond [(eq_attr "alternative" "1")
9272               (const_string "lea")
9273             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9274                       (match_operand 0 "register_operand" ""))
9275                  (match_operand 2 "const1_operand" ""))
9276               (const_string "alu")
9277            ]
9278            (const_string "ishift")))
9279    (set (attr "length_immediate")
9280      (if_then_else
9281        (ior (eq_attr "type" "alu")
9282             (and (eq_attr "type" "ishift")
9283                  (and (match_operand 2 "const1_operand" "")
9284                       (ior (match_test "TARGET_SHIFT1")
9285                            (match_test "optimize_function_for_size_p (cfun)")))))
9286        (const_string "0")
9287        (const_string "*")))
9288    (set_attr "mode" "HI,SI")])
9289
9290 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9291 (define_insn "*ashlqi3_1"
9292   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9293         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9294                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9295    (clobber (reg:CC FLAGS_REG))]
9296   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9297 {
9298   switch (get_attr_type (insn))
9299     {
9300     case TYPE_LEA:
9301       return "#";
9302
9303     case TYPE_ALU:
9304       gcc_assert (operands[2] == const1_rtx);
9305       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9306         return "add{l}\t%k0, %k0";
9307       else
9308         return "add{b}\t%0, %0";
9309
9310     default:
9311       if (operands[2] == const1_rtx
9312           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9313         {
9314           if (get_attr_mode (insn) == MODE_SI)
9315             return "sal{l}\t%k0";
9316           else
9317             return "sal{b}\t%0";
9318         }
9319       else
9320         {
9321           if (get_attr_mode (insn) == MODE_SI)
9322             return "sal{l}\t{%2, %k0|%k0, %2}";
9323           else
9324             return "sal{b}\t{%2, %0|%0, %2}";
9325         }
9326     }
9327 }
9328   [(set (attr "type")
9329      (cond [(eq_attr "alternative" "2")
9330               (const_string "lea")
9331             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9332                       (match_operand 0 "register_operand" ""))
9333                  (match_operand 2 "const1_operand" ""))
9334               (const_string "alu")
9335            ]
9336            (const_string "ishift")))
9337    (set (attr "length_immediate")
9338      (if_then_else
9339        (ior (eq_attr "type" "alu")
9340             (and (eq_attr "type" "ishift")
9341                  (and (match_operand 2 "const1_operand" "")
9342                       (ior (match_test "TARGET_SHIFT1")
9343                            (match_test "optimize_function_for_size_p (cfun)")))))
9344        (const_string "0")
9345        (const_string "*")))
9346    (set_attr "mode" "QI,SI,SI")])
9347
9348 (define_insn "*ashlqi3_1_slp"
9349   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9350         (ashift:QI (match_dup 0)
9351                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9352    (clobber (reg:CC FLAGS_REG))]
9353   "(optimize_function_for_size_p (cfun)
9354     || !TARGET_PARTIAL_FLAG_REG_STALL
9355     || (operands[1] == const1_rtx
9356         && (TARGET_SHIFT1
9357             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9358 {
9359   switch (get_attr_type (insn))
9360     {
9361     case TYPE_ALU:
9362       gcc_assert (operands[1] == const1_rtx);
9363       return "add{b}\t%0, %0";
9364
9365     default:
9366       if (operands[1] == const1_rtx
9367           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9368         return "sal{b}\t%0";
9369       else
9370         return "sal{b}\t{%1, %0|%0, %1}";
9371     }
9372 }
9373   [(set (attr "type")
9374      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9375                       (match_operand 0 "register_operand" ""))
9376                  (match_operand 1 "const1_operand" ""))
9377               (const_string "alu")
9378            ]
9379            (const_string "ishift1")))
9380    (set (attr "length_immediate")
9381      (if_then_else
9382        (ior (eq_attr "type" "alu")
9383             (and (eq_attr "type" "ishift1")
9384                  (and (match_operand 1 "const1_operand" "")
9385                       (ior (match_test "TARGET_SHIFT1")
9386                            (match_test "optimize_function_for_size_p (cfun)")))))
9387        (const_string "0")
9388        (const_string "*")))
9389    (set_attr "mode" "QI")])
9390
9391 ;; Convert ashift to the lea pattern to avoid flags dependency.
9392 (define_split
9393   [(set (match_operand 0 "register_operand" "")
9394         (ashift (match_operand 1 "index_register_operand" "")
9395                 (match_operand:QI 2 "const_int_operand" "")))
9396    (clobber (reg:CC FLAGS_REG))]
9397   "GET_MODE (operands[0]) == GET_MODE (operands[1])
9398    && reload_completed
9399    && true_regnum (operands[0]) != true_regnum (operands[1])"
9400   [(const_int 0)]
9401 {
9402   enum machine_mode mode = GET_MODE (operands[0]);
9403   rtx pat;
9404
9405   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9406     { 
9407       mode = SImode; 
9408       operands[0] = gen_lowpart (mode, operands[0]);
9409       operands[1] = gen_lowpart (mode, operands[1]);
9410     }
9411
9412   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9413
9414   pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9415
9416   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9417   DONE;
9418 })
9419
9420 ;; Convert ashift to the lea pattern to avoid flags dependency.
9421 (define_split
9422   [(set (match_operand:DI 0 "register_operand" "")
9423         (zero_extend:DI
9424           (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9425                      (match_operand:QI 2 "const_int_operand" ""))))
9426    (clobber (reg:CC FLAGS_REG))]
9427   "TARGET_64BIT && reload_completed
9428    && true_regnum (operands[0]) != true_regnum (operands[1])"
9429   [(set (match_dup 0)
9430         (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9431 {
9432   operands[1] = gen_lowpart (DImode, operands[1]);
9433   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9434 })
9435
9436 ;; This pattern can't accept a variable shift count, since shifts by
9437 ;; zero don't affect the flags.  We assume that shifts by constant
9438 ;; zero are optimized away.
9439 (define_insn "*ashl<mode>3_cmp"
9440   [(set (reg FLAGS_REG)
9441         (compare
9442           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9443                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9444           (const_int 0)))
9445    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9446         (ashift:SWI (match_dup 1) (match_dup 2)))]
9447   "(optimize_function_for_size_p (cfun)
9448     || !TARGET_PARTIAL_FLAG_REG_STALL
9449     || (operands[2] == const1_rtx
9450         && (TARGET_SHIFT1
9451             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9452    && ix86_match_ccmode (insn, CCGOCmode)
9453    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9454 {
9455   switch (get_attr_type (insn))
9456     {
9457     case TYPE_ALU:
9458       gcc_assert (operands[2] == const1_rtx);
9459       return "add{<imodesuffix>}\t%0, %0";
9460
9461     default:
9462       if (operands[2] == const1_rtx
9463           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9464         return "sal{<imodesuffix>}\t%0";
9465       else
9466         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9467     }
9468 }
9469   [(set (attr "type")
9470      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9471                       (match_operand 0 "register_operand" ""))
9472                  (match_operand 2 "const1_operand" ""))
9473               (const_string "alu")
9474            ]
9475            (const_string "ishift")))
9476    (set (attr "length_immediate")
9477      (if_then_else
9478        (ior (eq_attr "type" "alu")
9479             (and (eq_attr "type" "ishift")
9480                  (and (match_operand 2 "const1_operand" "")
9481                       (ior (match_test "TARGET_SHIFT1")
9482                            (match_test "optimize_function_for_size_p (cfun)")))))
9483        (const_string "0")
9484        (const_string "*")))
9485    (set_attr "mode" "<MODE>")])
9486
9487 (define_insn "*ashlsi3_cmp_zext"
9488   [(set (reg FLAGS_REG)
9489         (compare
9490           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9491                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9492           (const_int 0)))
9493    (set (match_operand:DI 0 "register_operand" "=r")
9494         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9495   "TARGET_64BIT
9496    && (optimize_function_for_size_p (cfun)
9497        || !TARGET_PARTIAL_FLAG_REG_STALL
9498        || (operands[2] == const1_rtx
9499            && (TARGET_SHIFT1
9500                || TARGET_DOUBLE_WITH_ADD)))
9501    && ix86_match_ccmode (insn, CCGOCmode)
9502    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9503 {
9504   switch (get_attr_type (insn))
9505     {
9506     case TYPE_ALU:
9507       gcc_assert (operands[2] == const1_rtx);
9508       return "add{l}\t%k0, %k0";
9509
9510     default:
9511       if (operands[2] == const1_rtx
9512           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9513         return "sal{l}\t%k0";
9514       else
9515         return "sal{l}\t{%2, %k0|%k0, %2}";
9516     }
9517 }
9518   [(set (attr "type")
9519      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9520                  (match_operand 2 "const1_operand" ""))
9521               (const_string "alu")
9522            ]
9523            (const_string "ishift")))
9524    (set (attr "length_immediate")
9525      (if_then_else
9526        (ior (eq_attr "type" "alu")
9527             (and (eq_attr "type" "ishift")
9528                  (and (match_operand 2 "const1_operand" "")
9529                       (ior (match_test "TARGET_SHIFT1")
9530                            (match_test "optimize_function_for_size_p (cfun)")))))
9531        (const_string "0")
9532        (const_string "*")))
9533    (set_attr "mode" "SI")])
9534
9535 (define_insn "*ashl<mode>3_cconly"
9536   [(set (reg FLAGS_REG)
9537         (compare
9538           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9539                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9540           (const_int 0)))
9541    (clobber (match_scratch:SWI 0 "=<r>"))]
9542   "(optimize_function_for_size_p (cfun)
9543     || !TARGET_PARTIAL_FLAG_REG_STALL
9544     || (operands[2] == const1_rtx
9545         && (TARGET_SHIFT1
9546             || TARGET_DOUBLE_WITH_ADD)))
9547    && ix86_match_ccmode (insn, CCGOCmode)"
9548 {
9549   switch (get_attr_type (insn))
9550     {
9551     case TYPE_ALU:
9552       gcc_assert (operands[2] == const1_rtx);
9553       return "add{<imodesuffix>}\t%0, %0";
9554
9555     default:
9556       if (operands[2] == const1_rtx
9557           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9558         return "sal{<imodesuffix>}\t%0";
9559       else
9560         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9561     }
9562 }
9563   [(set (attr "type")
9564      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9565                       (match_operand 0 "register_operand" ""))
9566                  (match_operand 2 "const1_operand" ""))
9567               (const_string "alu")
9568            ]
9569            (const_string "ishift")))
9570    (set (attr "length_immediate")
9571      (if_then_else
9572        (ior (eq_attr "type" "alu")
9573             (and (eq_attr "type" "ishift")
9574                  (and (match_operand 2 "const1_operand" "")
9575                       (ior (match_test "TARGET_SHIFT1")
9576                            (match_test "optimize_function_for_size_p (cfun)")))))
9577        (const_string "0")
9578        (const_string "*")))
9579    (set_attr "mode" "<MODE>")])
9580
9581 ;; See comment above `ashl<mode>3' about how this works.
9582
9583 (define_expand "<shift_insn><mode>3"
9584   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9585         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9586                            (match_operand:QI 2 "nonmemory_operand" "")))]
9587   ""
9588   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9589
9590 ;; Avoid useless masking of count operand.
9591 (define_insn "*<shift_insn><mode>3_mask"
9592   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9593         (any_shiftrt:SWI48
9594           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9595           (subreg:QI
9596             (and:SI
9597               (match_operand:SI 2 "register_operand" "c")
9598               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9599    (clobber (reg:CC FLAGS_REG))]
9600   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9601    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9602       == GET_MODE_BITSIZE (<MODE>mode)-1"
9603 {
9604   return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9605 }
9606   [(set_attr "type" "ishift")
9607    (set_attr "mode" "<MODE>")])
9608
9609 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9610   [(set (match_operand:DWI 0 "register_operand" "=r")
9611         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9612                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9613    (clobber (reg:CC FLAGS_REG))]
9614   ""
9615   "#"
9616   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9617   [(const_int 0)]
9618   "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9619   [(set_attr "type" "multi")])
9620
9621 ;; By default we don't ask for a scratch register, because when DWImode
9622 ;; values are manipulated, registers are already at a premium.  But if
9623 ;; we have one handy, we won't turn it away.
9624
9625 (define_peephole2
9626   [(match_scratch:DWIH 3 "r")
9627    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9628                    (any_shiftrt:<DWI>
9629                      (match_operand:<DWI> 1 "register_operand" "")
9630                      (match_operand:QI 2 "nonmemory_operand" "")))
9631               (clobber (reg:CC FLAGS_REG))])
9632    (match_dup 3)]
9633   "TARGET_CMOVE"
9634   [(const_int 0)]
9635   "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9636
9637 (define_insn "x86_64_shrd"
9638   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9639         (ior:DI (ashiftrt:DI (match_dup 0)
9640                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9641                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9642                   (minus:QI (const_int 64) (match_dup 2)))))
9643    (clobber (reg:CC FLAGS_REG))]
9644   "TARGET_64BIT"
9645   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9646   [(set_attr "type" "ishift")
9647    (set_attr "prefix_0f" "1")
9648    (set_attr "mode" "DI")
9649    (set_attr "athlon_decode" "vector")
9650    (set_attr "amdfam10_decode" "vector")
9651    (set_attr "bdver1_decode" "vector")])
9652
9653 (define_insn "x86_shrd"
9654   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9655         (ior:SI (ashiftrt:SI (match_dup 0)
9656                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9657                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9658                   (minus:QI (const_int 32) (match_dup 2)))))
9659    (clobber (reg:CC FLAGS_REG))]
9660   ""
9661   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9662   [(set_attr "type" "ishift")
9663    (set_attr "prefix_0f" "1")
9664    (set_attr "mode" "SI")
9665    (set_attr "pent_pair" "np")
9666    (set_attr "athlon_decode" "vector")
9667    (set_attr "amdfam10_decode" "vector")
9668    (set_attr "bdver1_decode" "vector")])
9669
9670 (define_insn "ashrdi3_cvt"
9671   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9672         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9673                      (match_operand:QI 2 "const_int_operand" "")))
9674    (clobber (reg:CC FLAGS_REG))]
9675   "TARGET_64BIT && INTVAL (operands[2]) == 63
9676    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9677    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9678   "@
9679    {cqto|cqo}
9680    sar{q}\t{%2, %0|%0, %2}"
9681   [(set_attr "type" "imovx,ishift")
9682    (set_attr "prefix_0f" "0,*")
9683    (set_attr "length_immediate" "0,*")
9684    (set_attr "modrm" "0,1")
9685    (set_attr "mode" "DI")])
9686
9687 (define_insn "ashrsi3_cvt"
9688   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9689         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9690                      (match_operand:QI 2 "const_int_operand" "")))
9691    (clobber (reg:CC FLAGS_REG))]
9692   "INTVAL (operands[2]) == 31
9693    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9694    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9695   "@
9696    {cltd|cdq}
9697    sar{l}\t{%2, %0|%0, %2}"
9698   [(set_attr "type" "imovx,ishift")
9699    (set_attr "prefix_0f" "0,*")
9700    (set_attr "length_immediate" "0,*")
9701    (set_attr "modrm" "0,1")
9702    (set_attr "mode" "SI")])
9703
9704 (define_insn "*ashrsi3_cvt_zext"
9705   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9706         (zero_extend:DI
9707           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9708                        (match_operand:QI 2 "const_int_operand" ""))))
9709    (clobber (reg:CC FLAGS_REG))]
9710   "TARGET_64BIT && INTVAL (operands[2]) == 31
9711    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9712    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9713   "@
9714    {cltd|cdq}
9715    sar{l}\t{%2, %k0|%k0, %2}"
9716   [(set_attr "type" "imovx,ishift")
9717    (set_attr "prefix_0f" "0,*")
9718    (set_attr "length_immediate" "0,*")
9719    (set_attr "modrm" "0,1")
9720    (set_attr "mode" "SI")])
9721
9722 (define_expand "x86_shift<mode>_adj_3"
9723   [(use (match_operand:SWI48 0 "register_operand" ""))
9724    (use (match_operand:SWI48 1 "register_operand" ""))
9725    (use (match_operand:QI 2 "register_operand" ""))]
9726   ""
9727 {
9728   rtx label = gen_label_rtx ();
9729   rtx tmp;
9730
9731   emit_insn (gen_testqi_ccz_1 (operands[2],
9732                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9733
9734   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9735   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9736   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9737                               gen_rtx_LABEL_REF (VOIDmode, label),
9738                               pc_rtx);
9739   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9740   JUMP_LABEL (tmp) = label;
9741
9742   emit_move_insn (operands[0], operands[1]);
9743   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9744                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9745   emit_label (label);
9746   LABEL_NUSES (label) = 1;
9747
9748   DONE;
9749 })
9750
9751 (define_insn "*bmi2_<shift_insn><mode>3_1"
9752   [(set (match_operand:SWI48 0 "register_operand" "=r")
9753         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9754                            (match_operand:SWI48 2 "register_operand" "r")))]
9755   "TARGET_BMI2"
9756   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9757   [(set_attr "type" "ishiftx")
9758    (set_attr "mode" "<MODE>")])
9759
9760 (define_insn "*<shift_insn><mode>3_1"
9761   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9762         (any_shiftrt:SWI48
9763           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9764           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9765    (clobber (reg:CC FLAGS_REG))]
9766   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9767 {
9768   switch (get_attr_type (insn))
9769     {
9770     case TYPE_ISHIFTX:
9771       return "#";
9772
9773     default:
9774       if (operands[2] == const1_rtx
9775           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9776         return "<shift>{<imodesuffix>}\t%0";
9777       else
9778         return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9779     }
9780 }
9781   [(set_attr "isa" "*,bmi2")
9782    (set_attr "type" "ishift,ishiftx")
9783    (set (attr "length_immediate")
9784      (if_then_else
9785        (and (match_operand 2 "const1_operand" "")
9786             (ior (match_test "TARGET_SHIFT1")
9787                  (match_test "optimize_function_for_size_p (cfun)")))
9788        (const_string "0")
9789        (const_string "*")))
9790    (set_attr "mode" "<MODE>")])
9791
9792 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9793 (define_split
9794   [(set (match_operand:SWI48 0 "register_operand" "")
9795         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9796                            (match_operand:QI 2 "register_operand" "")))
9797    (clobber (reg:CC FLAGS_REG))]
9798   "TARGET_BMI2 && reload_completed"
9799   [(set (match_dup 0)
9800         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9801   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9802
9803 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9804   [(set (match_operand:DI 0 "register_operand" "=r")
9805         (zero_extend:DI
9806           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9807                           (match_operand:SI 2 "register_operand" "r"))))]
9808   "TARGET_64BIT && TARGET_BMI2"
9809   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9810   [(set_attr "type" "ishiftx")
9811    (set_attr "mode" "SI")])
9812
9813 (define_insn "*<shift_insn>si3_1_zext"
9814   [(set (match_operand:DI 0 "register_operand" "=r,r")
9815         (zero_extend:DI
9816           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9817                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9818    (clobber (reg:CC FLAGS_REG))]
9819   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9820 {
9821   switch (get_attr_type (insn))
9822     {
9823     case TYPE_ISHIFTX:
9824       return "#";
9825
9826     default:
9827       if (operands[2] == const1_rtx
9828           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9829         return "<shift>{l}\t%k0";
9830       else
9831         return "<shift>{l}\t{%2, %k0|%k0, %2}";
9832     }
9833 }
9834   [(set_attr "isa" "*,bmi2")
9835    (set_attr "type" "ishift,ishiftx")
9836    (set (attr "length_immediate")
9837      (if_then_else
9838        (and (match_operand 2 "const1_operand" "")
9839             (ior (match_test "TARGET_SHIFT1")
9840                  (match_test "optimize_function_for_size_p (cfun)")))
9841        (const_string "0")
9842        (const_string "*")))
9843    (set_attr "mode" "SI")])
9844
9845 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9846 (define_split
9847   [(set (match_operand:DI 0 "register_operand" "")
9848         (zero_extend:DI
9849           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9850                           (match_operand:QI 2 "register_operand" ""))))
9851    (clobber (reg:CC FLAGS_REG))]
9852   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9853   [(set (match_dup 0)
9854         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9855   "operands[2] = gen_lowpart (SImode, operands[2]);")
9856
9857 (define_insn "*<shift_insn><mode>3_1"
9858   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9859         (any_shiftrt:SWI12
9860           (match_operand:SWI12 1 "nonimmediate_operand" "0")
9861           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9862    (clobber (reg:CC FLAGS_REG))]
9863   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9864 {
9865   if (operands[2] == const1_rtx
9866       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9867     return "<shift>{<imodesuffix>}\t%0";
9868   else
9869     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9870 }
9871   [(set_attr "type" "ishift")
9872    (set (attr "length_immediate")
9873      (if_then_else
9874        (and (match_operand 2 "const1_operand" "")
9875             (ior (match_test "TARGET_SHIFT1")
9876                  (match_test "optimize_function_for_size_p (cfun)")))
9877        (const_string "0")
9878        (const_string "*")))
9879    (set_attr "mode" "<MODE>")])
9880
9881 (define_insn "*<shift_insn>qi3_1_slp"
9882   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9883         (any_shiftrt:QI (match_dup 0)
9884                         (match_operand:QI 1 "nonmemory_operand" "cI")))
9885    (clobber (reg:CC FLAGS_REG))]
9886   "(optimize_function_for_size_p (cfun)
9887     || !TARGET_PARTIAL_REG_STALL
9888     || (operands[1] == const1_rtx
9889         && TARGET_SHIFT1))"
9890 {
9891   if (operands[1] == const1_rtx
9892       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9893     return "<shift>{b}\t%0";
9894   else
9895     return "<shift>{b}\t{%1, %0|%0, %1}";
9896 }
9897   [(set_attr "type" "ishift1")
9898    (set (attr "length_immediate")
9899      (if_then_else
9900        (and (match_operand 1 "const1_operand" "")
9901             (ior (match_test "TARGET_SHIFT1")
9902                  (match_test "optimize_function_for_size_p (cfun)")))
9903        (const_string "0")
9904        (const_string "*")))
9905    (set_attr "mode" "QI")])
9906
9907 ;; This pattern can't accept a variable shift count, since shifts by
9908 ;; zero don't affect the flags.  We assume that shifts by constant
9909 ;; zero are optimized away.
9910 (define_insn "*<shift_insn><mode>3_cmp"
9911   [(set (reg FLAGS_REG)
9912         (compare
9913           (any_shiftrt:SWI
9914             (match_operand:SWI 1 "nonimmediate_operand" "0")
9915             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9916           (const_int 0)))
9917    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9918         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9919   "(optimize_function_for_size_p (cfun)
9920     || !TARGET_PARTIAL_FLAG_REG_STALL
9921     || (operands[2] == const1_rtx
9922         && TARGET_SHIFT1))
9923    && ix86_match_ccmode (insn, CCGOCmode)
9924    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9925 {
9926   if (operands[2] == const1_rtx
9927       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9928     return "<shift>{<imodesuffix>}\t%0";
9929   else
9930     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9931 }
9932   [(set_attr "type" "ishift")
9933    (set (attr "length_immediate")
9934      (if_then_else
9935        (and (match_operand 2 "const1_operand" "")
9936             (ior (match_test "TARGET_SHIFT1")
9937                  (match_test "optimize_function_for_size_p (cfun)")))
9938        (const_string "0")
9939        (const_string "*")))
9940    (set_attr "mode" "<MODE>")])
9941
9942 (define_insn "*<shift_insn>si3_cmp_zext"
9943   [(set (reg FLAGS_REG)
9944         (compare
9945           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9946                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
9947           (const_int 0)))
9948    (set (match_operand:DI 0 "register_operand" "=r")
9949         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9950   "TARGET_64BIT
9951    && (optimize_function_for_size_p (cfun)
9952        || !TARGET_PARTIAL_FLAG_REG_STALL
9953        || (operands[2] == const1_rtx
9954            && TARGET_SHIFT1))
9955    && ix86_match_ccmode (insn, CCGOCmode)
9956    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9957 {
9958   if (operands[2] == const1_rtx
9959       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9960     return "<shift>{l}\t%k0";
9961   else
9962     return "<shift>{l}\t{%2, %k0|%k0, %2}";
9963 }
9964   [(set_attr "type" "ishift")
9965    (set (attr "length_immediate")
9966      (if_then_else
9967        (and (match_operand 2 "const1_operand" "")
9968             (ior (match_test "TARGET_SHIFT1")
9969                  (match_test "optimize_function_for_size_p (cfun)")))
9970        (const_string "0")
9971        (const_string "*")))
9972    (set_attr "mode" "SI")])
9973
9974 (define_insn "*<shift_insn><mode>3_cconly"
9975   [(set (reg FLAGS_REG)
9976         (compare
9977           (any_shiftrt:SWI
9978             (match_operand:SWI 1 "register_operand" "0")
9979             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9980           (const_int 0)))
9981    (clobber (match_scratch:SWI 0 "=<r>"))]
9982   "(optimize_function_for_size_p (cfun)
9983     || !TARGET_PARTIAL_FLAG_REG_STALL
9984     || (operands[2] == const1_rtx
9985         && TARGET_SHIFT1))
9986    && ix86_match_ccmode (insn, CCGOCmode)"
9987 {
9988   if (operands[2] == const1_rtx
9989       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9990     return "<shift>{<imodesuffix>}\t%0";
9991   else
9992     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9993 }
9994   [(set_attr "type" "ishift")
9995    (set (attr "length_immediate")
9996      (if_then_else
9997        (and (match_operand 2 "const1_operand" "")
9998             (ior (match_test "TARGET_SHIFT1")
9999                  (match_test "optimize_function_for_size_p (cfun)")))
10000        (const_string "0")
10001        (const_string "*")))
10002    (set_attr "mode" "<MODE>")])
10003 \f
10004 ;; Rotate instructions
10005
10006 (define_expand "<rotate_insn>ti3"
10007   [(set (match_operand:TI 0 "register_operand" "")
10008         (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10009                        (match_operand:QI 2 "nonmemory_operand" "")))]
10010   "TARGET_64BIT"
10011 {
10012   if (const_1_to_63_operand (operands[2], VOIDmode))
10013     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10014                 (operands[0], operands[1], operands[2]));
10015   else
10016     FAIL;
10017
10018   DONE;
10019 })
10020
10021 (define_expand "<rotate_insn>di3"
10022   [(set (match_operand:DI 0 "shiftdi_operand" "")
10023         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10024                        (match_operand:QI 2 "nonmemory_operand" "")))]
10025  ""
10026 {
10027   if (TARGET_64BIT)
10028     ix86_expand_binary_operator (<CODE>, DImode, operands);
10029   else if (const_1_to_31_operand (operands[2], VOIDmode))
10030     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10031                 (operands[0], operands[1], operands[2]));
10032   else
10033     FAIL;
10034
10035   DONE;
10036 })
10037
10038 (define_expand "<rotate_insn><mode>3"
10039   [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10040         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10041                             (match_operand:QI 2 "nonmemory_operand" "")))]
10042   ""
10043   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10044
10045 ;; Avoid useless masking of count operand.
10046 (define_insn "*<rotate_insn><mode>3_mask"
10047   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10048         (any_rotate:SWI48
10049           (match_operand:SWI48 1 "nonimmediate_operand" "0")
10050           (subreg:QI
10051             (and:SI
10052               (match_operand:SI 2 "register_operand" "c")
10053               (match_operand:SI 3 "const_int_operand" "n")) 0)))
10054    (clobber (reg:CC FLAGS_REG))]
10055   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10056    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10057       == GET_MODE_BITSIZE (<MODE>mode)-1"
10058 {
10059   return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10060 }
10061   [(set_attr "type" "rotate")
10062    (set_attr "mode" "<MODE>")])
10063
10064 ;; Implement rotation using two double-precision
10065 ;; shift instructions and a scratch register.
10066
10067 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10068  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10069        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10070                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10071   (clobber (reg:CC FLAGS_REG))
10072   (clobber (match_scratch:DWIH 3 "=&r"))]
10073  ""
10074  "#"
10075  "reload_completed"
10076  [(set (match_dup 3) (match_dup 4))
10077   (parallel
10078    [(set (match_dup 4)
10079          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10080                    (lshiftrt:DWIH (match_dup 5)
10081                                   (minus:QI (match_dup 6) (match_dup 2)))))
10082     (clobber (reg:CC FLAGS_REG))])
10083   (parallel
10084    [(set (match_dup 5)
10085          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10086                    (lshiftrt:DWIH (match_dup 3)
10087                                   (minus:QI (match_dup 6) (match_dup 2)))))
10088     (clobber (reg:CC FLAGS_REG))])]
10089 {
10090   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10091
10092   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10093 })
10094
10095 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10096  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10097        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10098                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10099   (clobber (reg:CC FLAGS_REG))
10100   (clobber (match_scratch:DWIH 3 "=&r"))]
10101  ""
10102  "#"
10103  "reload_completed"
10104  [(set (match_dup 3) (match_dup 4))
10105   (parallel
10106    [(set (match_dup 4)
10107          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10108                    (ashift:DWIH (match_dup 5)
10109                                 (minus:QI (match_dup 6) (match_dup 2)))))
10110     (clobber (reg:CC FLAGS_REG))])
10111   (parallel
10112    [(set (match_dup 5)
10113          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10114                    (ashift:DWIH (match_dup 3)
10115                                 (minus:QI (match_dup 6) (match_dup 2)))))
10116     (clobber (reg:CC FLAGS_REG))])]
10117 {
10118   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10119
10120   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10121 })
10122
10123 (define_insn "*bmi2_rorx<mode>3_1"
10124   [(set (match_operand:SWI48 0 "register_operand" "=r")
10125         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10126                         (match_operand:QI 2 "immediate_operand" "<S>")))]
10127   "TARGET_BMI2"
10128   "rorx\t{%2, %1, %0|%0, %1, %2}"
10129   [(set_attr "type" "rotatex")
10130    (set_attr "mode" "<MODE>")])
10131
10132 (define_insn "*<rotate_insn><mode>3_1"
10133   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10134         (any_rotate:SWI48
10135           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10136           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10137    (clobber (reg:CC FLAGS_REG))]
10138   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10139 {
10140   switch (get_attr_type (insn))
10141     {
10142     case TYPE_ROTATEX:
10143       return "#";
10144
10145     default:
10146       if (operands[2] == const1_rtx
10147           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10148         return "<rotate>{<imodesuffix>}\t%0";
10149       else
10150         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10151     }
10152 }
10153   [(set_attr "isa" "*,bmi2")
10154    (set_attr "type" "rotate,rotatex")
10155    (set (attr "length_immediate")
10156      (if_then_else
10157        (and (eq_attr "type" "rotate")
10158             (and (match_operand 2 "const1_operand" "")
10159                  (ior (match_test "TARGET_SHIFT1")
10160                       (match_test "optimize_function_for_size_p (cfun)"))))
10161        (const_string "0")
10162        (const_string "*")))
10163    (set_attr "mode" "<MODE>")])
10164
10165 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10166 (define_split
10167   [(set (match_operand:SWI48 0 "register_operand" "")
10168         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10169                       (match_operand:QI 2 "immediate_operand" "")))
10170    (clobber (reg:CC FLAGS_REG))]
10171   "TARGET_BMI2 && reload_completed"
10172   [(set (match_dup 0)
10173         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10174 {
10175   operands[2]
10176     = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10177 })
10178
10179 (define_split
10180   [(set (match_operand:SWI48 0 "register_operand" "")
10181         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10182                         (match_operand:QI 2 "immediate_operand" "")))
10183    (clobber (reg:CC FLAGS_REG))]
10184   "TARGET_BMI2 && reload_completed"
10185   [(set (match_dup 0)
10186         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10187
10188 (define_insn "*bmi2_rorxsi3_1_zext"
10189   [(set (match_operand:DI 0 "register_operand" "=r")
10190         (zero_extend:DI
10191           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10192                        (match_operand:QI 2 "immediate_operand" "I"))))]
10193   "TARGET_64BIT && TARGET_BMI2"
10194   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10195   [(set_attr "type" "rotatex")
10196    (set_attr "mode" "SI")])
10197
10198 (define_insn "*<rotate_insn>si3_1_zext"
10199   [(set (match_operand:DI 0 "register_operand" "=r,r")
10200         (zero_extend:DI
10201           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10202                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10203    (clobber (reg:CC FLAGS_REG))]
10204   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10205 {
10206   switch (get_attr_type (insn))
10207     {
10208     case TYPE_ROTATEX:
10209       return "#";
10210
10211     default:
10212       if (operands[2] == const1_rtx
10213           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10214         return "<rotate>{l}\t%k0";
10215       else
10216         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10217     }
10218 }
10219   [(set_attr "isa" "*,bmi2")
10220    (set_attr "type" "rotate,rotatex")
10221    (set (attr "length_immediate")
10222      (if_then_else
10223        (and (eq_attr "type" "rotate")
10224             (and (match_operand 2 "const1_operand" "")
10225                  (ior (match_test "TARGET_SHIFT1")
10226                       (match_test "optimize_function_for_size_p (cfun)"))))
10227        (const_string "0")
10228        (const_string "*")))
10229    (set_attr "mode" "SI")])
10230
10231 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10232 (define_split
10233   [(set (match_operand:DI 0 "register_operand" "")
10234         (zero_extend:DI
10235           (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10236                      (match_operand:QI 2 "immediate_operand" ""))))
10237    (clobber (reg:CC FLAGS_REG))]
10238   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10239   [(set (match_dup 0)
10240         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10241 {
10242   operands[2]
10243     = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10244 })
10245
10246 (define_split
10247   [(set (match_operand:DI 0 "register_operand" "")
10248         (zero_extend:DI
10249           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10250                        (match_operand:QI 2 "immediate_operand" ""))))
10251    (clobber (reg:CC FLAGS_REG))]
10252   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10253   [(set (match_dup 0)
10254         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10255
10256 (define_insn "*<rotate_insn><mode>3_1"
10257   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10258         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10259                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10260    (clobber (reg:CC FLAGS_REG))]
10261   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10262 {
10263   if (operands[2] == const1_rtx
10264       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10265     return "<rotate>{<imodesuffix>}\t%0";
10266   else
10267     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10268 }
10269   [(set_attr "type" "rotate")
10270    (set (attr "length_immediate")
10271      (if_then_else
10272        (and (match_operand 2 "const1_operand" "")
10273             (ior (match_test "TARGET_SHIFT1")
10274                  (match_test "optimize_function_for_size_p (cfun)")))
10275        (const_string "0")
10276        (const_string "*")))
10277    (set_attr "mode" "<MODE>")])
10278
10279 (define_insn "*<rotate_insn>qi3_1_slp"
10280   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10281         (any_rotate:QI (match_dup 0)
10282                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10283    (clobber (reg:CC FLAGS_REG))]
10284   "(optimize_function_for_size_p (cfun)
10285     || !TARGET_PARTIAL_REG_STALL
10286     || (operands[1] == const1_rtx
10287         && TARGET_SHIFT1))"
10288 {
10289   if (operands[1] == const1_rtx
10290       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10291     return "<rotate>{b}\t%0";
10292   else
10293     return "<rotate>{b}\t{%1, %0|%0, %1}";
10294 }
10295   [(set_attr "type" "rotate1")
10296    (set (attr "length_immediate")
10297      (if_then_else
10298        (and (match_operand 1 "const1_operand" "")
10299             (ior (match_test "TARGET_SHIFT1")
10300                  (match_test "optimize_function_for_size_p (cfun)")))
10301        (const_string "0")
10302        (const_string "*")))
10303    (set_attr "mode" "QI")])
10304
10305 (define_split
10306  [(set (match_operand:HI 0 "register_operand" "")
10307        (any_rotate:HI (match_dup 0) (const_int 8)))
10308   (clobber (reg:CC FLAGS_REG))]
10309  "reload_completed
10310   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10311  [(parallel [(set (strict_low_part (match_dup 0))
10312                   (bswap:HI (match_dup 0)))
10313              (clobber (reg:CC FLAGS_REG))])])
10314 \f
10315 ;; Bit set / bit test instructions
10316
10317 (define_expand "extv"
10318   [(set (match_operand:SI 0 "register_operand" "")
10319         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10320                          (match_operand:SI 2 "const8_operand" "")
10321                          (match_operand:SI 3 "const8_operand" "")))]
10322   ""
10323 {
10324   /* Handle extractions from %ah et al.  */
10325   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10326     FAIL;
10327
10328   /* From mips.md: extract_bit_field doesn't verify that our source
10329      matches the predicate, so check it again here.  */
10330   if (! ext_register_operand (operands[1], VOIDmode))
10331     FAIL;
10332 })
10333
10334 (define_expand "extzv"
10335   [(set (match_operand:SI 0 "register_operand" "")
10336         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10337                          (match_operand:SI 2 "const8_operand" "")
10338                          (match_operand:SI 3 "const8_operand" "")))]
10339   ""
10340 {
10341   /* Handle extractions from %ah et al.  */
10342   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10343     FAIL;
10344
10345   /* From mips.md: extract_bit_field doesn't verify that our source
10346      matches the predicate, so check it again here.  */
10347   if (! ext_register_operand (operands[1], VOIDmode))
10348     FAIL;
10349 })
10350
10351 (define_expand "insv"
10352   [(set (zero_extract (match_operand 0 "register_operand" "")
10353                       (match_operand 1 "const_int_operand" "")
10354                       (match_operand 2 "const_int_operand" ""))
10355         (match_operand 3 "register_operand" ""))]
10356   ""
10357 {
10358   rtx (*gen_mov_insv_1) (rtx, rtx);
10359
10360   if (ix86_expand_pinsr (operands))
10361     DONE;
10362
10363   /* Handle insertions to %ah et al.  */
10364   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10365     FAIL;
10366
10367   /* From mips.md: insert_bit_field doesn't verify that our source
10368      matches the predicate, so check it again here.  */
10369   if (! ext_register_operand (operands[0], VOIDmode))
10370     FAIL;
10371
10372   gen_mov_insv_1 = (TARGET_64BIT
10373                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10374
10375   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10376   DONE;
10377 })
10378
10379 ;; %%% bts, btr, btc, bt.
10380 ;; In general these instructions are *slow* when applied to memory,
10381 ;; since they enforce atomic operation.  When applied to registers,
10382 ;; it depends on the cpu implementation.  They're never faster than
10383 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10384 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10385 ;; within the instruction itself, so operating on bits in the high
10386 ;; 32-bits of a register becomes easier.
10387 ;;
10388 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10389 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10390 ;; negdf respectively, so they can never be disabled entirely.
10391
10392 (define_insn "*btsq"
10393   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10394                          (const_int 1)
10395                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10396         (const_int 1))
10397    (clobber (reg:CC FLAGS_REG))]
10398   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10399   "bts{q}\t{%1, %0|%0, %1}"
10400   [(set_attr "type" "alu1")
10401    (set_attr "prefix_0f" "1")
10402    (set_attr "mode" "DI")])
10403
10404 (define_insn "*btrq"
10405   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10406                          (const_int 1)
10407                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10408         (const_int 0))
10409    (clobber (reg:CC FLAGS_REG))]
10410   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10411   "btr{q}\t{%1, %0|%0, %1}"
10412   [(set_attr "type" "alu1")
10413    (set_attr "prefix_0f" "1")
10414    (set_attr "mode" "DI")])
10415
10416 (define_insn "*btcq"
10417   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10418                          (const_int 1)
10419                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10420         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10421    (clobber (reg:CC FLAGS_REG))]
10422   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10423   "btc{q}\t{%1, %0|%0, %1}"
10424   [(set_attr "type" "alu1")
10425    (set_attr "prefix_0f" "1")
10426    (set_attr "mode" "DI")])
10427
10428 ;; Allow Nocona to avoid these instructions if a register is available.
10429
10430 (define_peephole2
10431   [(match_scratch:DI 2 "r")
10432    (parallel [(set (zero_extract:DI
10433                      (match_operand:DI 0 "register_operand" "")
10434                      (const_int 1)
10435                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10436                    (const_int 1))
10437               (clobber (reg:CC FLAGS_REG))])]
10438   "TARGET_64BIT && !TARGET_USE_BT"
10439   [(const_int 0)]
10440 {
10441   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10442   rtx op1;
10443
10444   if (HOST_BITS_PER_WIDE_INT >= 64)
10445     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10446   else if (i < HOST_BITS_PER_WIDE_INT)
10447     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10448   else
10449     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10450
10451   op1 = immed_double_const (lo, hi, DImode);
10452   if (i >= 31)
10453     {
10454       emit_move_insn (operands[2], op1);
10455       op1 = operands[2];
10456     }
10457
10458   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10459   DONE;
10460 })
10461
10462 (define_peephole2
10463   [(match_scratch:DI 2 "r")
10464    (parallel [(set (zero_extract:DI
10465                      (match_operand:DI 0 "register_operand" "")
10466                      (const_int 1)
10467                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10468                    (const_int 0))
10469               (clobber (reg:CC FLAGS_REG))])]
10470   "TARGET_64BIT && !TARGET_USE_BT"
10471   [(const_int 0)]
10472 {
10473   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10474   rtx op1;
10475
10476   if (HOST_BITS_PER_WIDE_INT >= 64)
10477     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10478   else if (i < HOST_BITS_PER_WIDE_INT)
10479     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10480   else
10481     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10482
10483   op1 = immed_double_const (~lo, ~hi, DImode);
10484   if (i >= 32)
10485     {
10486       emit_move_insn (operands[2], op1);
10487       op1 = operands[2];
10488     }
10489
10490   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10491   DONE;
10492 })
10493
10494 (define_peephole2
10495   [(match_scratch:DI 2 "r")
10496    (parallel [(set (zero_extract:DI
10497                      (match_operand:DI 0 "register_operand" "")
10498                      (const_int 1)
10499                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10500               (not:DI (zero_extract:DI
10501                         (match_dup 0) (const_int 1) (match_dup 1))))
10502               (clobber (reg:CC FLAGS_REG))])]
10503   "TARGET_64BIT && !TARGET_USE_BT"
10504   [(const_int 0)]
10505 {
10506   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10507   rtx op1;
10508
10509   if (HOST_BITS_PER_WIDE_INT >= 64)
10510     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10511   else if (i < HOST_BITS_PER_WIDE_INT)
10512     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10513   else
10514     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10515
10516   op1 = immed_double_const (lo, hi, DImode);
10517   if (i >= 31)
10518     {
10519       emit_move_insn (operands[2], op1);
10520       op1 = operands[2];
10521     }
10522
10523   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10524   DONE;
10525 })
10526
10527 (define_insn "*bt<mode>"
10528   [(set (reg:CCC FLAGS_REG)
10529         (compare:CCC
10530           (zero_extract:SWI48
10531             (match_operand:SWI48 0 "register_operand" "r")
10532             (const_int 1)
10533             (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10534           (const_int 0)))]
10535   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10536   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10537   [(set_attr "type" "alu1")
10538    (set_attr "prefix_0f" "1")
10539    (set_attr "mode" "<MODE>")])
10540 \f
10541 ;; Store-flag instructions.
10542
10543 ;; For all sCOND expanders, also expand the compare or test insn that
10544 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10545
10546 (define_insn_and_split "*setcc_di_1"
10547   [(set (match_operand:DI 0 "register_operand" "=q")
10548         (match_operator:DI 1 "ix86_comparison_operator"
10549           [(reg FLAGS_REG) (const_int 0)]))]
10550   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10551   "#"
10552   "&& reload_completed"
10553   [(set (match_dup 2) (match_dup 1))
10554    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10555 {
10556   PUT_MODE (operands[1], QImode);
10557   operands[2] = gen_lowpart (QImode, operands[0]);
10558 })
10559
10560 (define_insn_and_split "*setcc_si_1_and"
10561   [(set (match_operand:SI 0 "register_operand" "=q")
10562         (match_operator:SI 1 "ix86_comparison_operator"
10563           [(reg FLAGS_REG) (const_int 0)]))
10564    (clobber (reg:CC FLAGS_REG))]
10565   "!TARGET_PARTIAL_REG_STALL
10566    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10567   "#"
10568   "&& reload_completed"
10569   [(set (match_dup 2) (match_dup 1))
10570    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10571               (clobber (reg:CC FLAGS_REG))])]
10572 {
10573   PUT_MODE (operands[1], QImode);
10574   operands[2] = gen_lowpart (QImode, operands[0]);
10575 })
10576
10577 (define_insn_and_split "*setcc_si_1_movzbl"
10578   [(set (match_operand:SI 0 "register_operand" "=q")
10579         (match_operator:SI 1 "ix86_comparison_operator"
10580           [(reg FLAGS_REG) (const_int 0)]))]
10581   "!TARGET_PARTIAL_REG_STALL
10582    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10583   "#"
10584   "&& reload_completed"
10585   [(set (match_dup 2) (match_dup 1))
10586    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10587 {
10588   PUT_MODE (operands[1], QImode);
10589   operands[2] = gen_lowpart (QImode, operands[0]);
10590 })
10591
10592 (define_insn "*setcc_qi"
10593   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10594         (match_operator:QI 1 "ix86_comparison_operator"
10595           [(reg FLAGS_REG) (const_int 0)]))]
10596   ""
10597   "set%C1\t%0"
10598   [(set_attr "type" "setcc")
10599    (set_attr "mode" "QI")])
10600
10601 (define_insn "*setcc_qi_slp"
10602   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10603         (match_operator:QI 1 "ix86_comparison_operator"
10604           [(reg FLAGS_REG) (const_int 0)]))]
10605   ""
10606   "set%C1\t%0"
10607   [(set_attr "type" "setcc")
10608    (set_attr "mode" "QI")])
10609
10610 ;; In general it is not safe to assume too much about CCmode registers,
10611 ;; so simplify-rtx stops when it sees a second one.  Under certain
10612 ;; conditions this is safe on x86, so help combine not create
10613 ;;
10614 ;;      seta    %al
10615 ;;      testb   %al, %al
10616 ;;      sete    %al
10617
10618 (define_split
10619   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10620         (ne:QI (match_operator 1 "ix86_comparison_operator"
10621                  [(reg FLAGS_REG) (const_int 0)])
10622             (const_int 0)))]
10623   ""
10624   [(set (match_dup 0) (match_dup 1))]
10625   "PUT_MODE (operands[1], QImode);")
10626
10627 (define_split
10628   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10629         (ne:QI (match_operator 1 "ix86_comparison_operator"
10630                  [(reg FLAGS_REG) (const_int 0)])
10631             (const_int 0)))]
10632   ""
10633   [(set (match_dup 0) (match_dup 1))]
10634   "PUT_MODE (operands[1], QImode);")
10635
10636 (define_split
10637   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10638         (eq:QI (match_operator 1 "ix86_comparison_operator"
10639                  [(reg FLAGS_REG) (const_int 0)])
10640             (const_int 0)))]
10641   ""
10642   [(set (match_dup 0) (match_dup 1))]
10643 {
10644   rtx new_op1 = copy_rtx (operands[1]);
10645   operands[1] = new_op1;
10646   PUT_MODE (new_op1, QImode);
10647   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10648                                              GET_MODE (XEXP (new_op1, 0))));
10649
10650   /* Make sure that (a) the CCmode we have for the flags is strong
10651      enough for the reversed compare or (b) we have a valid FP compare.  */
10652   if (! ix86_comparison_operator (new_op1, VOIDmode))
10653     FAIL;
10654 })
10655
10656 (define_split
10657   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10658         (eq:QI (match_operator 1 "ix86_comparison_operator"
10659                  [(reg FLAGS_REG) (const_int 0)])
10660             (const_int 0)))]
10661   ""
10662   [(set (match_dup 0) (match_dup 1))]
10663 {
10664   rtx new_op1 = copy_rtx (operands[1]);
10665   operands[1] = new_op1;
10666   PUT_MODE (new_op1, QImode);
10667   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10668                                              GET_MODE (XEXP (new_op1, 0))));
10669
10670   /* Make sure that (a) the CCmode we have for the flags is strong
10671      enough for the reversed compare or (b) we have a valid FP compare.  */
10672   if (! ix86_comparison_operator (new_op1, VOIDmode))
10673     FAIL;
10674 })
10675
10676 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10677 ;; subsequent logical operations are used to imitate conditional moves.
10678 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10679 ;; it directly.
10680
10681 (define_insn "setcc_<mode>_sse"
10682   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10683         (match_operator:MODEF 3 "sse_comparison_operator"
10684           [(match_operand:MODEF 1 "register_operand" "0,x")
10685            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10686   "SSE_FLOAT_MODE_P (<MODE>mode)"
10687   "@
10688    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10689    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10690   [(set_attr "isa" "noavx,avx")
10691    (set_attr "type" "ssecmp")
10692    (set_attr "length_immediate" "1")
10693    (set_attr "prefix" "orig,vex")
10694    (set_attr "mode" "<MODE>")])
10695 \f
10696 ;; Basic conditional jump instructions.
10697 ;; We ignore the overflow flag for signed branch instructions.
10698
10699 (define_insn "*jcc_1"
10700   [(set (pc)
10701         (if_then_else (match_operator 1 "ix86_comparison_operator"
10702                                       [(reg FLAGS_REG) (const_int 0)])
10703                       (label_ref (match_operand 0 "" ""))
10704                       (pc)))]
10705   ""
10706   "%+j%C1\t%l0"
10707   [(set_attr "type" "ibr")
10708    (set_attr "modrm" "0")
10709    (set (attr "length")
10710            (if_then_else (and (ge (minus (match_dup 0) (pc))
10711                                   (const_int -126))
10712                               (lt (minus (match_dup 0) (pc))
10713                                   (const_int 128)))
10714              (const_int 2)
10715              (const_int 6)))])
10716
10717 (define_insn "*jcc_2"
10718   [(set (pc)
10719         (if_then_else (match_operator 1 "ix86_comparison_operator"
10720                                       [(reg FLAGS_REG) (const_int 0)])
10721                       (pc)
10722                       (label_ref (match_operand 0 "" ""))))]
10723   ""
10724   "%+j%c1\t%l0"
10725   [(set_attr "type" "ibr")
10726    (set_attr "modrm" "0")
10727    (set (attr "length")
10728            (if_then_else (and (ge (minus (match_dup 0) (pc))
10729                                   (const_int -126))
10730                               (lt (minus (match_dup 0) (pc))
10731                                   (const_int 128)))
10732              (const_int 2)
10733              (const_int 6)))])
10734
10735 ;; In general it is not safe to assume too much about CCmode registers,
10736 ;; so simplify-rtx stops when it sees a second one.  Under certain
10737 ;; conditions this is safe on x86, so help combine not create
10738 ;;
10739 ;;      seta    %al
10740 ;;      testb   %al, %al
10741 ;;      je      Lfoo
10742
10743 (define_split
10744   [(set (pc)
10745         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10746                                       [(reg FLAGS_REG) (const_int 0)])
10747                           (const_int 0))
10748                       (label_ref (match_operand 1 "" ""))
10749                       (pc)))]
10750   ""
10751   [(set (pc)
10752         (if_then_else (match_dup 0)
10753                       (label_ref (match_dup 1))
10754                       (pc)))]
10755   "PUT_MODE (operands[0], VOIDmode);")
10756
10757 (define_split
10758   [(set (pc)
10759         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10760                                       [(reg FLAGS_REG) (const_int 0)])
10761                           (const_int 0))
10762                       (label_ref (match_operand 1 "" ""))
10763                       (pc)))]
10764   ""
10765   [(set (pc)
10766         (if_then_else (match_dup 0)
10767                       (label_ref (match_dup 1))
10768                       (pc)))]
10769 {
10770   rtx new_op0 = copy_rtx (operands[0]);
10771   operands[0] = new_op0;
10772   PUT_MODE (new_op0, VOIDmode);
10773   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10774                                              GET_MODE (XEXP (new_op0, 0))));
10775
10776   /* Make sure that (a) the CCmode we have for the flags is strong
10777      enough for the reversed compare or (b) we have a valid FP compare.  */
10778   if (! ix86_comparison_operator (new_op0, VOIDmode))
10779     FAIL;
10780 })
10781
10782 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10783 ;; pass generates from shift insn with QImode operand.  Actually, the mode
10784 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10785 ;; appropriate modulo of the bit offset value.
10786
10787 (define_insn_and_split "*jcc_bt<mode>"
10788   [(set (pc)
10789         (if_then_else (match_operator 0 "bt_comparison_operator"
10790                         [(zero_extract:SWI48
10791                            (match_operand:SWI48 1 "register_operand" "r")
10792                            (const_int 1)
10793                            (zero_extend:SI
10794                              (match_operand:QI 2 "register_operand" "r")))
10795                          (const_int 0)])
10796                       (label_ref (match_operand 3 "" ""))
10797                       (pc)))
10798    (clobber (reg:CC FLAGS_REG))]
10799   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10800   "#"
10801   "&& 1"
10802   [(set (reg:CCC FLAGS_REG)
10803         (compare:CCC
10804           (zero_extract:SWI48
10805             (match_dup 1)
10806             (const_int 1)
10807             (match_dup 2))
10808           (const_int 0)))
10809    (set (pc)
10810         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10811                       (label_ref (match_dup 3))
10812                       (pc)))]
10813 {
10814   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10815
10816   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10817 })
10818
10819 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10820 ;; also for DImode, this is what combine produces.
10821 (define_insn_and_split "*jcc_bt<mode>_mask"
10822   [(set (pc)
10823         (if_then_else (match_operator 0 "bt_comparison_operator"
10824                         [(zero_extract:SWI48
10825                            (match_operand:SWI48 1 "register_operand" "r")
10826                            (const_int 1)
10827                            (and:SI
10828                              (match_operand:SI 2 "register_operand" "r")
10829                              (match_operand:SI 3 "const_int_operand" "n")))])
10830                       (label_ref (match_operand 4 "" ""))
10831                       (pc)))
10832    (clobber (reg:CC FLAGS_REG))]
10833   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10834    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10835       == GET_MODE_BITSIZE (<MODE>mode)-1"
10836   "#"
10837   "&& 1"
10838   [(set (reg:CCC FLAGS_REG)
10839         (compare:CCC
10840           (zero_extract:SWI48
10841             (match_dup 1)
10842             (const_int 1)
10843             (match_dup 2))
10844           (const_int 0)))
10845    (set (pc)
10846         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10847                       (label_ref (match_dup 4))
10848                       (pc)))]
10849 {
10850   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10851
10852   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10853 })
10854
10855 (define_insn_and_split "*jcc_btsi_1"
10856   [(set (pc)
10857         (if_then_else (match_operator 0 "bt_comparison_operator"
10858                         [(and:SI
10859                            (lshiftrt:SI
10860                              (match_operand:SI 1 "register_operand" "r")
10861                              (match_operand:QI 2 "register_operand" "r"))
10862                            (const_int 1))
10863                          (const_int 0)])
10864                       (label_ref (match_operand 3 "" ""))
10865                       (pc)))
10866    (clobber (reg:CC FLAGS_REG))]
10867   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10868   "#"
10869   "&& 1"
10870   [(set (reg:CCC FLAGS_REG)
10871         (compare:CCC
10872           (zero_extract:SI
10873             (match_dup 1)
10874             (const_int 1)
10875             (match_dup 2))
10876           (const_int 0)))
10877    (set (pc)
10878         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10879                       (label_ref (match_dup 3))
10880                       (pc)))]
10881 {
10882   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10883
10884   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10885 })
10886
10887 ;; avoid useless masking of bit offset operand
10888 (define_insn_and_split "*jcc_btsi_mask_1"
10889   [(set (pc)
10890         (if_then_else
10891           (match_operator 0 "bt_comparison_operator"
10892             [(and:SI
10893                (lshiftrt:SI
10894                  (match_operand:SI 1 "register_operand" "r")
10895                  (subreg:QI
10896                    (and:SI
10897                      (match_operand:SI 2 "register_operand" "r")
10898                      (match_operand:SI 3 "const_int_operand" "n")) 0))
10899                (const_int 1))
10900              (const_int 0)])
10901           (label_ref (match_operand 4 "" ""))
10902           (pc)))
10903    (clobber (reg:CC FLAGS_REG))]
10904   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10905    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10906   "#"
10907   "&& 1"
10908   [(set (reg:CCC FLAGS_REG)
10909         (compare:CCC
10910           (zero_extract:SI
10911             (match_dup 1)
10912             (const_int 1)
10913             (match_dup 2))
10914           (const_int 0)))
10915    (set (pc)
10916         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10917                       (label_ref (match_dup 4))
10918                       (pc)))]
10919   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10920
10921 ;; Define combination compare-and-branch fp compare instructions to help
10922 ;; combine.
10923
10924 (define_insn "*fp_jcc_1_387"
10925   [(set (pc)
10926         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10927                         [(match_operand 1 "register_operand" "f")
10928                          (match_operand 2 "nonimmediate_operand" "fm")])
10929           (label_ref (match_operand 3 "" ""))
10930           (pc)))
10931    (clobber (reg:CCFP FPSR_REG))
10932    (clobber (reg:CCFP FLAGS_REG))
10933    (clobber (match_scratch:HI 4 "=a"))]
10934   "TARGET_80387
10935    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10936    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10937    && SELECT_CC_MODE (GET_CODE (operands[0]),
10938                       operands[1], operands[2]) == CCFPmode
10939    && !TARGET_CMOVE"
10940   "#")
10941
10942 (define_insn "*fp_jcc_1r_387"
10943   [(set (pc)
10944         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10945                         [(match_operand 1 "register_operand" "f")
10946                          (match_operand 2 "nonimmediate_operand" "fm")])
10947           (pc)
10948           (label_ref (match_operand 3 "" ""))))
10949    (clobber (reg:CCFP FPSR_REG))
10950    (clobber (reg:CCFP FLAGS_REG))
10951    (clobber (match_scratch:HI 4 "=a"))]
10952   "TARGET_80387
10953    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10954    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10955    && SELECT_CC_MODE (GET_CODE (operands[0]),
10956                       operands[1], operands[2]) == CCFPmode
10957    && !TARGET_CMOVE"
10958   "#")
10959
10960 (define_insn "*fp_jcc_2_387"
10961   [(set (pc)
10962         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10963                         [(match_operand 1 "register_operand" "f")
10964                          (match_operand 2 "register_operand" "f")])
10965           (label_ref (match_operand 3 "" ""))
10966           (pc)))
10967    (clobber (reg:CCFP FPSR_REG))
10968    (clobber (reg:CCFP FLAGS_REG))
10969    (clobber (match_scratch:HI 4 "=a"))]
10970   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10971    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10972    && !TARGET_CMOVE"
10973   "#")
10974
10975 (define_insn "*fp_jcc_2r_387"
10976   [(set (pc)
10977         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10978                         [(match_operand 1 "register_operand" "f")
10979                          (match_operand 2 "register_operand" "f")])
10980           (pc)
10981           (label_ref (match_operand 3 "" ""))))
10982    (clobber (reg:CCFP FPSR_REG))
10983    (clobber (reg:CCFP FLAGS_REG))
10984    (clobber (match_scratch:HI 4 "=a"))]
10985   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10986    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10987    && !TARGET_CMOVE"
10988   "#")
10989
10990 (define_insn "*fp_jcc_3_387"
10991   [(set (pc)
10992         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10993                         [(match_operand 1 "register_operand" "f")
10994                          (match_operand 2 "const0_operand" "")])
10995           (label_ref (match_operand 3 "" ""))
10996           (pc)))
10997    (clobber (reg:CCFP FPSR_REG))
10998    (clobber (reg:CCFP FLAGS_REG))
10999    (clobber (match_scratch:HI 4 "=a"))]
11000   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11001    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11002    && SELECT_CC_MODE (GET_CODE (operands[0]),
11003                       operands[1], operands[2]) == CCFPmode
11004    && !TARGET_CMOVE"
11005   "#")
11006
11007 (define_split
11008   [(set (pc)
11009         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11010                         [(match_operand 1 "register_operand" "")
11011                          (match_operand 2 "nonimmediate_operand" "")])
11012           (match_operand 3 "" "")
11013           (match_operand 4 "" "")))
11014    (clobber (reg:CCFP FPSR_REG))
11015    (clobber (reg:CCFP FLAGS_REG))]
11016   "reload_completed"
11017   [(const_int 0)]
11018 {
11019   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11020                         operands[3], operands[4], NULL_RTX, NULL_RTX);
11021   DONE;
11022 })
11023
11024 (define_split
11025   [(set (pc)
11026         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11027                         [(match_operand 1 "register_operand" "")
11028                          (match_operand 2 "general_operand" "")])
11029           (match_operand 3 "" "")
11030           (match_operand 4 "" "")))
11031    (clobber (reg:CCFP FPSR_REG))
11032    (clobber (reg:CCFP FLAGS_REG))
11033    (clobber (match_scratch:HI 5 "=a"))]
11034   "reload_completed"
11035   [(const_int 0)]
11036 {
11037   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11038                         operands[3], operands[4], operands[5], NULL_RTX);
11039   DONE;
11040 })
11041
11042 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11043 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11044 ;; with a precedence over other operators and is always put in the first
11045 ;; place. Swap condition and operands to match ficom instruction.
11046
11047 (define_insn "*fp_jcc_4_<mode>_387"
11048   [(set (pc)
11049         (if_then_else
11050           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11051             [(match_operator 1 "float_operator"
11052               [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11053              (match_operand 3 "register_operand" "f,f")])
11054           (label_ref (match_operand 4 "" ""))
11055           (pc)))
11056    (clobber (reg:CCFP FPSR_REG))
11057    (clobber (reg:CCFP FLAGS_REG))
11058    (clobber (match_scratch:HI 5 "=a,a"))]
11059   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11060    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11061    && GET_MODE (operands[1]) == GET_MODE (operands[3])
11062    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11063    && !TARGET_CMOVE"
11064   "#")
11065
11066 (define_split
11067   [(set (pc)
11068         (if_then_else
11069           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11070             [(match_operator 1 "float_operator"
11071               [(match_operand:SWI24 2 "memory_operand" "")])
11072              (match_operand 3 "register_operand" "")])
11073           (match_operand 4 "" "")
11074           (match_operand 5 "" "")))
11075    (clobber (reg:CCFP FPSR_REG))
11076    (clobber (reg:CCFP FLAGS_REG))
11077    (clobber (match_scratch:HI 6 "=a"))]
11078   "reload_completed"
11079   [(const_int 0)]
11080 {
11081   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11082
11083   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11084                         operands[3], operands[7],
11085                         operands[4], operands[5], operands[6], NULL_RTX);
11086   DONE;
11087 })
11088
11089 ;; %%% Kill this when reload knows how to do it.
11090 (define_split
11091   [(set (pc)
11092         (if_then_else
11093           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11094             [(match_operator 1 "float_operator"
11095               [(match_operand:SWI24 2 "register_operand" "")])
11096              (match_operand 3 "register_operand" "")])
11097           (match_operand 4 "" "")
11098           (match_operand 5 "" "")))
11099    (clobber (reg:CCFP FPSR_REG))
11100    (clobber (reg:CCFP FLAGS_REG))
11101    (clobber (match_scratch:HI 6 "=a"))]
11102   "reload_completed"
11103   [(const_int 0)]
11104 {
11105   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11106   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11107
11108   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11109                         operands[3], operands[7],
11110                         operands[4], operands[5], operands[6], operands[2]);
11111   DONE;
11112 })
11113 \f
11114 ;; Unconditional and other jump instructions
11115
11116 (define_insn "jump"
11117   [(set (pc)
11118         (label_ref (match_operand 0 "" "")))]
11119   ""
11120   "jmp\t%l0"
11121   [(set_attr "type" "ibr")
11122    (set (attr "length")
11123            (if_then_else (and (ge (minus (match_dup 0) (pc))
11124                                   (const_int -126))
11125                               (lt (minus (match_dup 0) (pc))
11126                                   (const_int 128)))
11127              (const_int 2)
11128              (const_int 5)))
11129    (set_attr "modrm" "0")])
11130
11131 (define_expand "indirect_jump"
11132   [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11133
11134 (define_insn "*indirect_jump"
11135   [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11136   ""
11137   "jmp\t%A0"
11138   [(set_attr "type" "ibr")
11139    (set_attr "length_immediate" "0")])
11140
11141 (define_expand "tablejump"
11142   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11143               (use (label_ref (match_operand 1 "" "")))])]
11144   ""
11145 {
11146   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11147      relative.  Convert the relative address to an absolute address.  */
11148   if (flag_pic)
11149     {
11150       rtx op0, op1;
11151       enum rtx_code code;
11152
11153       /* We can't use @GOTOFF for text labels on VxWorks;
11154          see gotoff_operand.  */
11155       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11156         {
11157           code = PLUS;
11158           op0 = operands[0];
11159           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11160         }
11161       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11162         {
11163           code = PLUS;
11164           op0 = operands[0];
11165           op1 = pic_offset_table_rtx;
11166         }
11167       else
11168         {
11169           code = MINUS;
11170           op0 = pic_offset_table_rtx;
11171           op1 = operands[0];
11172         }
11173
11174       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11175                                          OPTAB_DIRECT);
11176     }
11177   else if (TARGET_X32)
11178     operands[0] = convert_memory_address (Pmode, operands[0]);
11179 })
11180
11181 (define_insn "*tablejump_1"
11182   [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11183    (use (label_ref (match_operand 1 "" "")))]
11184   ""
11185   "jmp\t%A0"
11186   [(set_attr "type" "ibr")
11187    (set_attr "length_immediate" "0")])
11188 \f
11189 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11190
11191 (define_peephole2
11192   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11193    (set (match_operand:QI 1 "register_operand" "")
11194         (match_operator:QI 2 "ix86_comparison_operator"
11195           [(reg FLAGS_REG) (const_int 0)]))
11196    (set (match_operand 3 "q_regs_operand" "")
11197         (zero_extend (match_dup 1)))]
11198   "(peep2_reg_dead_p (3, operands[1])
11199     || operands_match_p (operands[1], operands[3]))
11200    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11201   [(set (match_dup 4) (match_dup 0))
11202    (set (strict_low_part (match_dup 5))
11203         (match_dup 2))]
11204 {
11205   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11206   operands[5] = gen_lowpart (QImode, operands[3]);
11207   ix86_expand_clear (operands[3]);
11208 })
11209
11210 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11211
11212 (define_peephole2
11213   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11214    (set (match_operand:QI 1 "register_operand" "")
11215         (match_operator:QI 2 "ix86_comparison_operator"
11216           [(reg FLAGS_REG) (const_int 0)]))
11217    (parallel [(set (match_operand 3 "q_regs_operand" "")
11218                    (zero_extend (match_dup 1)))
11219               (clobber (reg:CC FLAGS_REG))])]
11220   "(peep2_reg_dead_p (3, operands[1])
11221     || operands_match_p (operands[1], operands[3]))
11222    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11223   [(set (match_dup 4) (match_dup 0))
11224    (set (strict_low_part (match_dup 5))
11225         (match_dup 2))]
11226 {
11227   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11228   operands[5] = gen_lowpart (QImode, operands[3]);
11229   ix86_expand_clear (operands[3]);
11230 })
11231 \f
11232 ;; Call instructions.
11233
11234 ;; The predicates normally associated with named expanders are not properly
11235 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11236 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11237
11238 ;; P6 processors will jump to the address after the decrement when %esp
11239 ;; is used as a call operand, so they will execute return address as a code.
11240 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11241
11242 ;; Register constraint for call instruction.
11243 (define_mode_attr c [(SI "l") (DI "r")])
11244
11245 ;; Call subroutine returning no value.
11246
11247 (define_expand "call"
11248   [(call (match_operand:QI 0 "" "")
11249          (match_operand 1 "" ""))
11250    (use (match_operand 2 "" ""))]
11251   ""
11252 {
11253   ix86_expand_call (NULL, operands[0], operands[1],
11254                     operands[2], NULL, false);
11255   DONE;
11256 })
11257
11258 (define_expand "sibcall"
11259   [(call (match_operand:QI 0 "" "")
11260          (match_operand 1 "" ""))
11261    (use (match_operand 2 "" ""))]
11262   ""
11263 {
11264   ix86_expand_call (NULL, operands[0], operands[1],
11265                     operands[2], NULL, true);
11266   DONE;
11267 })
11268
11269 (define_insn_and_split "*call_vzeroupper"
11270   [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11271          (match_operand 1 "" ""))
11272    (unspec [(match_operand 2 "const_int_operand" "")]
11273            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11274   "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11275   "#"
11276   "&& reload_completed"
11277   [(const_int 0)]
11278   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11279   [(set_attr "type" "call")])
11280
11281 (define_insn "*call"
11282   [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11283          (match_operand 1 "" ""))]
11284   "!SIBLING_CALL_P (insn)"
11285   "* return ix86_output_call_insn (insn, operands[0]);"
11286   [(set_attr "type" "call")])
11287
11288 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11289   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11290          (match_operand 1 "" ""))
11291    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11292    (clobber (reg:TI XMM6_REG))
11293    (clobber (reg:TI XMM7_REG))
11294    (clobber (reg:TI XMM8_REG))
11295    (clobber (reg:TI XMM9_REG))
11296    (clobber (reg:TI XMM10_REG))
11297    (clobber (reg:TI XMM11_REG))
11298    (clobber (reg:TI XMM12_REG))
11299    (clobber (reg:TI XMM13_REG))
11300    (clobber (reg:TI XMM14_REG))
11301    (clobber (reg:TI XMM15_REG))
11302    (clobber (reg:DI SI_REG))
11303    (clobber (reg:DI DI_REG))
11304    (unspec [(match_operand 2 "const_int_operand" "")]
11305            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11306   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11307   "#"
11308   "&& reload_completed"
11309   [(const_int 0)]
11310   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11311   [(set_attr "type" "call")])
11312
11313 (define_insn "*call_rex64_ms_sysv"
11314   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11315          (match_operand 1 "" ""))
11316    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11317    (clobber (reg:TI XMM6_REG))
11318    (clobber (reg:TI XMM7_REG))
11319    (clobber (reg:TI XMM8_REG))
11320    (clobber (reg:TI XMM9_REG))
11321    (clobber (reg:TI XMM10_REG))
11322    (clobber (reg:TI XMM11_REG))
11323    (clobber (reg:TI XMM12_REG))
11324    (clobber (reg:TI XMM13_REG))
11325    (clobber (reg:TI XMM14_REG))
11326    (clobber (reg:TI XMM15_REG))
11327    (clobber (reg:DI SI_REG))
11328    (clobber (reg:DI DI_REG))]
11329   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11330   "* return ix86_output_call_insn (insn, operands[0]);"
11331   [(set_attr "type" "call")])
11332
11333 (define_insn_and_split "*sibcall_vzeroupper"
11334   [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11335          (match_operand 1 "" ""))
11336    (unspec [(match_operand 2 "const_int_operand" "")]
11337            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11338   "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11339   "#"
11340   "&& reload_completed"
11341   [(const_int 0)]
11342   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11343   [(set_attr "type" "call")])
11344
11345 (define_insn "*sibcall"
11346   [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11347          (match_operand 1 "" ""))]
11348   "SIBLING_CALL_P (insn)"
11349   "* return ix86_output_call_insn (insn, operands[0]);"
11350   [(set_attr "type" "call")])
11351
11352 (define_expand "call_pop"
11353   [(parallel [(call (match_operand:QI 0 "" "")
11354                     (match_operand:SI 1 "" ""))
11355               (set (reg:SI SP_REG)
11356                    (plus:SI (reg:SI SP_REG)
11357                             (match_operand:SI 3 "" "")))])]
11358   "!TARGET_64BIT"
11359 {
11360   ix86_expand_call (NULL, operands[0], operands[1],
11361                     operands[2], operands[3], false);
11362   DONE;
11363 })
11364
11365 (define_insn_and_split "*call_pop_vzeroupper"
11366   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11367          (match_operand:SI 1 "" ""))
11368    (set (reg:SI SP_REG)
11369         (plus:SI (reg:SI SP_REG)
11370                  (match_operand:SI 2 "immediate_operand" "i")))
11371    (unspec [(match_operand 3 "const_int_operand" "")]
11372            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11373   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11374   "#"
11375   "&& reload_completed"
11376   [(const_int 0)]
11377   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11378   [(set_attr "type" "call")])
11379
11380 (define_insn "*call_pop"
11381   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11382          (match_operand 1 "" ""))
11383    (set (reg:SI SP_REG)
11384         (plus:SI (reg:SI SP_REG)
11385                  (match_operand:SI 2 "immediate_operand" "i")))]
11386   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11387   "* return ix86_output_call_insn (insn, operands[0]);"
11388   [(set_attr "type" "call")])
11389
11390 (define_insn_and_split "*sibcall_pop_vzeroupper"
11391   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11392          (match_operand 1 "" ""))
11393    (set (reg:SI SP_REG)
11394         (plus:SI (reg:SI SP_REG)
11395                  (match_operand:SI 2 "immediate_operand" "i")))
11396    (unspec [(match_operand 3 "const_int_operand" "")]
11397            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11398   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11399   "#"
11400   "&& reload_completed"
11401   [(const_int 0)]
11402   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11403   [(set_attr "type" "call")])
11404
11405 (define_insn "*sibcall_pop"
11406   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11407          (match_operand 1 "" ""))
11408    (set (reg:SI SP_REG)
11409         (plus:SI (reg:SI SP_REG)
11410                  (match_operand:SI 2 "immediate_operand" "i")))]
11411   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11412   "* return ix86_output_call_insn (insn, operands[0]);"
11413   [(set_attr "type" "call")])
11414
11415 ;; Call subroutine, returning value in operand 0
11416
11417 (define_expand "call_value"
11418   [(set (match_operand 0 "" "")
11419         (call (match_operand:QI 1 "" "")
11420               (match_operand 2 "" "")))
11421    (use (match_operand 3 "" ""))]
11422   ""
11423 {
11424   ix86_expand_call (operands[0], operands[1], operands[2],
11425                     operands[3], NULL, false);
11426   DONE;
11427 })
11428
11429 (define_expand "sibcall_value"
11430   [(set (match_operand 0 "" "")
11431         (call (match_operand:QI 1 "" "")
11432               (match_operand 2 "" "")))
11433    (use (match_operand 3 "" ""))]
11434   ""
11435 {
11436   ix86_expand_call (operands[0], operands[1], operands[2],
11437                     operands[3], NULL, true);
11438   DONE;
11439 })
11440
11441 (define_insn_and_split "*call_value_vzeroupper"
11442   [(set (match_operand 0 "" "")
11443         (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11444               (match_operand 2 "" "")))
11445    (unspec [(match_operand 3 "const_int_operand" "")]
11446            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11447   "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11448   "#"
11449   "&& reload_completed"
11450   [(const_int 0)]
11451   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11452   [(set_attr "type" "callv")])
11453
11454 (define_insn "*call_value"
11455   [(set (match_operand 0 "" "")
11456         (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11457               (match_operand 2 "" "")))]
11458   "!SIBLING_CALL_P (insn)"
11459   "* return ix86_output_call_insn (insn, operands[1]);"
11460   [(set_attr "type" "callv")])
11461
11462 (define_insn_and_split "*sibcall_value_vzeroupper"
11463   [(set (match_operand 0 "" "")
11464         (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11465               (match_operand 2 "" "")))
11466    (unspec [(match_operand 3 "const_int_operand" "")]
11467            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11468   "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11469   "#"
11470   "&& reload_completed"
11471   [(const_int 0)]
11472   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11473   [(set_attr "type" "callv")])
11474
11475 (define_insn "*sibcall_value"
11476   [(set (match_operand 0 "" "")
11477         (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11478               (match_operand 2 "" "")))]
11479   "SIBLING_CALL_P (insn)"
11480   "* return ix86_output_call_insn (insn, operands[1]);"
11481   [(set_attr "type" "callv")])
11482
11483 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11484   [(set (match_operand 0 "" "")
11485         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11486               (match_operand 2 "" "")))
11487    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11488    (clobber (reg:TI XMM6_REG))
11489    (clobber (reg:TI XMM7_REG))
11490    (clobber (reg:TI XMM8_REG))
11491    (clobber (reg:TI XMM9_REG))
11492    (clobber (reg:TI XMM10_REG))
11493    (clobber (reg:TI XMM11_REG))
11494    (clobber (reg:TI XMM12_REG))
11495    (clobber (reg:TI XMM13_REG))
11496    (clobber (reg:TI XMM14_REG))
11497    (clobber (reg:TI XMM15_REG))
11498    (clobber (reg:DI SI_REG))
11499    (clobber (reg:DI DI_REG))
11500    (unspec [(match_operand 3 "const_int_operand" "")]
11501            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11502   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11503   "#"
11504   "&& reload_completed"
11505   [(const_int 0)]
11506   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11507   [(set_attr "type" "callv")])
11508
11509 (define_insn "*call_value_rex64_ms_sysv"
11510   [(set (match_operand 0 "" "")
11511         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11512               (match_operand 2 "" "")))
11513    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11514    (clobber (reg:TI XMM6_REG))
11515    (clobber (reg:TI XMM7_REG))
11516    (clobber (reg:TI XMM8_REG))
11517    (clobber (reg:TI XMM9_REG))
11518    (clobber (reg:TI XMM10_REG))
11519    (clobber (reg:TI XMM11_REG))
11520    (clobber (reg:TI XMM12_REG))
11521    (clobber (reg:TI XMM13_REG))
11522    (clobber (reg:TI XMM14_REG))
11523    (clobber (reg:TI XMM15_REG))
11524    (clobber (reg:DI SI_REG))
11525    (clobber (reg:DI DI_REG))]
11526   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11527   "* return ix86_output_call_insn (insn, operands[1]);"
11528   [(set_attr "type" "callv")])
11529
11530 (define_expand "call_value_pop"
11531   [(parallel [(set (match_operand 0 "" "")
11532                    (call (match_operand:QI 1 "" "")
11533                          (match_operand:SI 2 "" "")))
11534               (set (reg:SI SP_REG)
11535                    (plus:SI (reg:SI SP_REG)
11536                             (match_operand:SI 4 "" "")))])]
11537   "!TARGET_64BIT"
11538 {
11539   ix86_expand_call (operands[0], operands[1], operands[2],
11540                     operands[3], operands[4], false);
11541   DONE;
11542 })
11543
11544 (define_insn_and_split "*call_value_pop_vzeroupper"
11545   [(set (match_operand 0 "" "")
11546         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11547               (match_operand 2 "" "")))
11548    (set (reg:SI SP_REG)
11549         (plus:SI (reg:SI SP_REG)
11550                  (match_operand:SI 3 "immediate_operand" "i")))
11551    (unspec [(match_operand 4 "const_int_operand" "")]
11552            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11553   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11554   "#"
11555   "&& reload_completed"
11556   [(const_int 0)]
11557   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11558   [(set_attr "type" "callv")])
11559
11560 (define_insn "*call_value_pop"
11561   [(set (match_operand 0 "" "")
11562         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11563               (match_operand 2 "" "")))
11564    (set (reg:SI SP_REG)
11565         (plus:SI (reg:SI SP_REG)
11566                  (match_operand:SI 3 "immediate_operand" "i")))]
11567   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11568   "* return ix86_output_call_insn (insn, operands[1]);"
11569   [(set_attr "type" "callv")])
11570
11571 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11572   [(set (match_operand 0 "" "")
11573         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11574               (match_operand 2 "" "")))
11575    (set (reg:SI SP_REG)
11576         (plus:SI (reg:SI SP_REG)
11577                  (match_operand:SI 3 "immediate_operand" "i")))
11578    (unspec [(match_operand 4 "const_int_operand" "")]
11579            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11580   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11581   "#"
11582   "&& reload_completed"
11583   [(const_int 0)]
11584   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11585   [(set_attr "type" "callv")])
11586
11587 (define_insn "*sibcall_value_pop"
11588   [(set (match_operand 0 "" "")
11589         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11590               (match_operand 2 "" "")))
11591    (set (reg:SI SP_REG)
11592         (plus:SI (reg:SI SP_REG)
11593                  (match_operand:SI 3 "immediate_operand" "i")))]
11594   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11595   "* return ix86_output_call_insn (insn, operands[1]);"
11596   [(set_attr "type" "callv")])
11597
11598 ;; Call subroutine returning any type.
11599
11600 (define_expand "untyped_call"
11601   [(parallel [(call (match_operand 0 "" "")
11602                     (const_int 0))
11603               (match_operand 1 "" "")
11604               (match_operand 2 "" "")])]
11605   ""
11606 {
11607   int i;
11608
11609   /* In order to give reg-stack an easier job in validating two
11610      coprocessor registers as containing a possible return value,
11611      simply pretend the untyped call returns a complex long double
11612      value. 
11613
11614      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11615      and should have the default ABI.  */
11616
11617   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11618                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11619                     operands[0], const0_rtx,
11620                     GEN_INT ((TARGET_64BIT
11621                               ? (ix86_abi == SYSV_ABI
11622                                  ? X86_64_SSE_REGPARM_MAX
11623                                  : X86_64_MS_SSE_REGPARM_MAX)
11624                               : X86_32_SSE_REGPARM_MAX)
11625                              - 1),
11626                     NULL, false);
11627
11628   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11629     {
11630       rtx set = XVECEXP (operands[2], 0, i);
11631       emit_move_insn (SET_DEST (set), SET_SRC (set));
11632     }
11633
11634   /* The optimizer does not know that the call sets the function value
11635      registers we stored in the result block.  We avoid problems by
11636      claiming that all hard registers are used and clobbered at this
11637      point.  */
11638   emit_insn (gen_blockage ());
11639
11640   DONE;
11641 })
11642 \f
11643 ;; Prologue and epilogue instructions
11644
11645 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11646 ;; all of memory.  This blocks insns from being moved across this point.
11647
11648 (define_insn "blockage"
11649   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11650   ""
11651   ""
11652   [(set_attr "length" "0")])
11653
11654 ;; Do not schedule instructions accessing memory across this point.
11655
11656 (define_expand "memory_blockage"
11657   [(set (match_dup 0)
11658         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11659   ""
11660 {
11661   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11662   MEM_VOLATILE_P (operands[0]) = 1;
11663 })
11664
11665 (define_insn "*memory_blockage"
11666   [(set (match_operand:BLK 0 "" "")
11667         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11668   ""
11669   ""
11670   [(set_attr "length" "0")])
11671
11672 ;; As USE insns aren't meaningful after reload, this is used instead
11673 ;; to prevent deleting instructions setting registers for PIC code
11674 (define_insn "prologue_use"
11675   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11676   ""
11677   ""
11678   [(set_attr "length" "0")])
11679
11680 ;; Insn emitted into the body of a function to return from a function.
11681 ;; This is only done if the function's epilogue is known to be simple.
11682 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11683
11684 (define_expand "return"
11685   [(simple_return)]
11686   "ix86_can_use_return_insn_p ()"
11687 {
11688   ix86_maybe_emit_epilogue_vzeroupper ();
11689   if (crtl->args.pops_args)
11690     {
11691       rtx popc = GEN_INT (crtl->args.pops_args);
11692       emit_jump_insn (gen_simple_return_pop_internal (popc));
11693       DONE;
11694     }
11695 })
11696
11697 ;; We need to disable this for TARGET_SEH, as otherwise
11698 ;; shrink-wrapped prologue gets enabled too.  This might exceed
11699 ;; the maximum size of prologue in unwind information.
11700
11701 (define_expand "simple_return"
11702   [(simple_return)]
11703   "!TARGET_SEH"
11704 {
11705   ix86_maybe_emit_epilogue_vzeroupper ();
11706   if (crtl->args.pops_args)
11707     {
11708       rtx popc = GEN_INT (crtl->args.pops_args);
11709       emit_jump_insn (gen_simple_return_pop_internal (popc));
11710       DONE;
11711     }
11712 })
11713
11714 (define_insn "simple_return_internal"
11715   [(simple_return)]
11716   "reload_completed"
11717   "ret"
11718   [(set_attr "length" "1")
11719    (set_attr "atom_unit" "jeu")
11720    (set_attr "length_immediate" "0")
11721    (set_attr "modrm" "0")])
11722
11723 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11724 ;; instruction Athlon and K8 have.
11725
11726 (define_insn "simple_return_internal_long"
11727   [(simple_return)
11728    (unspec [(const_int 0)] UNSPEC_REP)]
11729   "reload_completed"
11730   "rep\;ret"
11731   [(set_attr "length" "2")
11732    (set_attr "atom_unit" "jeu")
11733    (set_attr "length_immediate" "0")
11734    (set_attr "prefix_rep" "1")
11735    (set_attr "modrm" "0")])
11736
11737 (define_insn "simple_return_pop_internal"
11738   [(simple_return)
11739    (use (match_operand:SI 0 "const_int_operand" ""))]
11740   "reload_completed"
11741   "ret\t%0"
11742   [(set_attr "length" "3")
11743    (set_attr "atom_unit" "jeu")
11744    (set_attr "length_immediate" "2")
11745    (set_attr "modrm" "0")])
11746
11747 (define_insn "simple_return_indirect_internal"
11748   [(simple_return)
11749    (use (match_operand:SI 0 "register_operand" "r"))]
11750   "reload_completed"
11751   "jmp\t%A0"
11752   [(set_attr "type" "ibr")
11753    (set_attr "length_immediate" "0")])
11754
11755 (define_insn "nop"
11756   [(const_int 0)]
11757   ""
11758   "nop"
11759   [(set_attr "length" "1")
11760    (set_attr "length_immediate" "0")
11761    (set_attr "modrm" "0")])
11762
11763 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
11764 (define_insn "nops"
11765   [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11766                     UNSPECV_NOPS)]
11767   "reload_completed"
11768 {
11769   int num = INTVAL (operands[0]);
11770
11771   gcc_assert (num >= 1 && num <= 8);
11772
11773   while (num--)
11774     fputs ("\tnop\n", asm_out_file);
11775
11776   return "";
11777 }
11778   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11779    (set_attr "length_immediate" "0")
11780    (set_attr "modrm" "0")])
11781
11782 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11783 ;; branch prediction penalty for the third jump in a 16-byte
11784 ;; block on K8.
11785
11786 (define_insn "pad"
11787   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11788   ""
11789 {
11790 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11791   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11792 #else
11793   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11794      The align insn is used to avoid 3 jump instructions in the row to improve
11795      branch prediction and the benefits hardly outweigh the cost of extra 8
11796      nops on the average inserted by full alignment pseudo operation.  */
11797 #endif
11798   return "";
11799 }
11800   [(set_attr "length" "16")])
11801
11802 (define_expand "prologue"
11803   [(const_int 0)]
11804   ""
11805   "ix86_expand_prologue (); DONE;")
11806
11807 (define_insn "set_got"
11808   [(set (match_operand:SI 0 "register_operand" "=r")
11809         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11810    (clobber (reg:CC FLAGS_REG))]
11811   "!TARGET_64BIT"
11812   "* return output_set_got (operands[0], NULL_RTX);"
11813   [(set_attr "type" "multi")
11814    (set_attr "length" "12")])
11815
11816 (define_insn "set_got_labelled"
11817   [(set (match_operand:SI 0 "register_operand" "=r")
11818         (unspec:SI [(label_ref (match_operand 1 "" ""))]
11819          UNSPEC_SET_GOT))
11820    (clobber (reg:CC FLAGS_REG))]
11821   "!TARGET_64BIT"
11822   "* return output_set_got (operands[0], operands[1]);"
11823   [(set_attr "type" "multi")
11824    (set_attr "length" "12")])
11825
11826 (define_insn "set_got_rex64"
11827   [(set (match_operand:DI 0 "register_operand" "=r")
11828         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11829   "TARGET_64BIT"
11830   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11831   [(set_attr "type" "lea")
11832    (set_attr "length_address" "4")
11833    (set_attr "mode" "DI")])
11834
11835 (define_insn "set_rip_rex64"
11836   [(set (match_operand:DI 0 "register_operand" "=r")
11837         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11838   "TARGET_64BIT"
11839   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11840   [(set_attr "type" "lea")
11841    (set_attr "length_address" "4")
11842    (set_attr "mode" "DI")])
11843
11844 (define_insn "set_got_offset_rex64"
11845   [(set (match_operand:DI 0 "register_operand" "=r")
11846         (unspec:DI
11847           [(label_ref (match_operand 1 "" ""))]
11848           UNSPEC_SET_GOT_OFFSET))]
11849   "TARGET_LP64"
11850   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11851   [(set_attr "type" "imov")
11852    (set_attr "length_immediate" "0")
11853    (set_attr "length_address" "8")
11854    (set_attr "mode" "DI")])
11855
11856 (define_expand "epilogue"
11857   [(const_int 0)]
11858   ""
11859   "ix86_expand_epilogue (1); DONE;")
11860
11861 (define_expand "sibcall_epilogue"
11862   [(const_int 0)]
11863   ""
11864   "ix86_expand_epilogue (0); DONE;")
11865
11866 (define_expand "eh_return"
11867   [(use (match_operand 0 "register_operand" ""))]
11868   ""
11869 {
11870   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11871
11872   /* Tricky bit: we write the address of the handler to which we will
11873      be returning into someone else's stack frame, one word below the
11874      stack address we wish to restore.  */
11875   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11876   tmp = plus_constant (tmp, -UNITS_PER_WORD);
11877   tmp = gen_rtx_MEM (Pmode, tmp);
11878   emit_move_insn (tmp, ra);
11879
11880   emit_jump_insn (gen_eh_return_internal ());
11881   emit_barrier ();
11882   DONE;
11883 })
11884
11885 (define_insn_and_split "eh_return_internal"
11886   [(eh_return)]
11887   ""
11888   "#"
11889   "epilogue_completed"
11890   [(const_int 0)]
11891   "ix86_expand_epilogue (2); DONE;")
11892
11893 (define_insn "leave"
11894   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11895    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11896    (clobber (mem:BLK (scratch)))]
11897   "!TARGET_64BIT"
11898   "leave"
11899   [(set_attr "type" "leave")])
11900
11901 (define_insn "leave_rex64"
11902   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11903    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11904    (clobber (mem:BLK (scratch)))]
11905   "TARGET_64BIT"
11906   "leave"
11907   [(set_attr "type" "leave")])
11908 \f
11909 ;; Handle -fsplit-stack.
11910
11911 (define_expand "split_stack_prologue"
11912   [(const_int 0)]
11913   ""
11914 {
11915   ix86_expand_split_stack_prologue ();
11916   DONE;
11917 })
11918
11919 ;; In order to support the call/return predictor, we use a return
11920 ;; instruction which the middle-end doesn't see.
11921 (define_insn "split_stack_return"
11922   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11923                      UNSPECV_SPLIT_STACK_RETURN)]
11924   ""
11925 {
11926   if (operands[0] == const0_rtx)
11927     return "ret";
11928   else
11929     return "ret\t%0";
11930 }
11931   [(set_attr "atom_unit" "jeu")
11932    (set_attr "modrm" "0")
11933    (set (attr "length")
11934         (if_then_else (match_operand:SI 0 "const0_operand" "")
11935                       (const_int 1)
11936                       (const_int 3)))
11937    (set (attr "length_immediate")
11938         (if_then_else (match_operand:SI 0 "const0_operand" "")
11939                       (const_int 0)
11940                       (const_int 2)))])
11941
11942 ;; If there are operand 0 bytes available on the stack, jump to
11943 ;; operand 1.
11944
11945 (define_expand "split_stack_space_check"
11946   [(set (pc) (if_then_else
11947               (ltu (minus (reg SP_REG)
11948                           (match_operand 0 "register_operand" ""))
11949                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11950               (label_ref (match_operand 1 "" ""))
11951               (pc)))]
11952   ""
11953 {
11954   rtx reg, size, limit;
11955
11956   reg = gen_reg_rtx (Pmode);
11957   size = force_reg (Pmode, operands[0]);
11958   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11959   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11960                           UNSPEC_STACK_CHECK);
11961   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11962   ix86_expand_branch (GEU, reg, limit, operands[1]);
11963
11964   DONE;
11965 })
11966 \f
11967 ;; Bit manipulation instructions.
11968
11969 (define_expand "ffs<mode>2"
11970   [(set (match_dup 2) (const_int -1))
11971    (parallel [(set (reg:CCZ FLAGS_REG)
11972                    (compare:CCZ
11973                      (match_operand:SWI48 1 "nonimmediate_operand" "")
11974                      (const_int 0)))
11975               (set (match_operand:SWI48 0 "register_operand" "")
11976                    (ctz:SWI48 (match_dup 1)))])
11977    (set (match_dup 0) (if_then_else:SWI48
11978                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
11979                         (match_dup 2)
11980                         (match_dup 0)))
11981    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11982               (clobber (reg:CC FLAGS_REG))])]
11983   ""
11984 {
11985   if (<MODE>mode == SImode && !TARGET_CMOVE)
11986     {
11987       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11988       DONE;
11989     }
11990   operands[2] = gen_reg_rtx (<MODE>mode);
11991 })
11992
11993 (define_insn_and_split "ffssi2_no_cmove"
11994   [(set (match_operand:SI 0 "register_operand" "=r")
11995         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11996    (clobber (match_scratch:SI 2 "=&q"))
11997    (clobber (reg:CC FLAGS_REG))]
11998   "!TARGET_CMOVE"
11999   "#"
12000   "&& reload_completed"
12001   [(parallel [(set (reg:CCZ FLAGS_REG)
12002                    (compare:CCZ (match_dup 1) (const_int 0)))
12003               (set (match_dup 0) (ctz:SI (match_dup 1)))])
12004    (set (strict_low_part (match_dup 3))
12005         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12006    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12007               (clobber (reg:CC FLAGS_REG))])
12008    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12009               (clobber (reg:CC FLAGS_REG))])
12010    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12011               (clobber (reg:CC FLAGS_REG))])]
12012 {
12013   operands[3] = gen_lowpart (QImode, operands[2]);
12014   ix86_expand_clear (operands[2]);
12015 })
12016
12017 (define_insn "*ffs<mode>_1"
12018   [(set (reg:CCZ FLAGS_REG)
12019         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12020                      (const_int 0)))
12021    (set (match_operand:SWI48 0 "register_operand" "=r")
12022         (ctz:SWI48 (match_dup 1)))]
12023   ""
12024   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12025   [(set_attr "type" "alu1")
12026    (set_attr "prefix_0f" "1")
12027    (set_attr "mode" "<MODE>")])
12028
12029 (define_insn "ctz<mode>2"
12030   [(set (match_operand:SWI248 0 "register_operand" "=r")
12031         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12032    (clobber (reg:CC FLAGS_REG))]
12033   ""
12034 {
12035   if (TARGET_BMI)
12036     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12037   else
12038     return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12039 }
12040   [(set_attr "type" "alu1")
12041    (set_attr "prefix_0f" "1")
12042    (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12043    (set_attr "mode" "<MODE>")])
12044
12045 (define_expand "clz<mode>2"
12046   [(parallel
12047      [(set (match_operand:SWI248 0 "register_operand" "")
12048            (minus:SWI248
12049              (match_dup 2)
12050              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12051       (clobber (reg:CC FLAGS_REG))])
12052    (parallel
12053      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12054       (clobber (reg:CC FLAGS_REG))])]
12055   ""
12056 {
12057   if (TARGET_LZCNT)
12058     {
12059       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12060       DONE;
12061     }
12062   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12063 })
12064
12065 (define_insn "clz<mode>2_lzcnt"
12066   [(set (match_operand:SWI248 0 "register_operand" "=r")
12067         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12068    (clobber (reg:CC FLAGS_REG))]
12069   "TARGET_LZCNT"
12070   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12071   [(set_attr "prefix_rep" "1")
12072    (set_attr "type" "bitmanip")
12073    (set_attr "mode" "<MODE>")])
12074
12075 ;; BMI instructions.
12076 (define_insn "*bmi_andn_<mode>"
12077   [(set (match_operand:SWI48 0 "register_operand" "=r")
12078         (and:SWI48
12079           (not:SWI48
12080             (match_operand:SWI48 1 "register_operand" "r"))
12081             (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12082    (clobber (reg:CC FLAGS_REG))]
12083   "TARGET_BMI"
12084   "andn\t{%2, %1, %0|%0, %1, %2}"
12085   [(set_attr "type" "bitmanip")
12086    (set_attr "mode" "<MODE>")])
12087
12088 (define_insn "bmi_bextr_<mode>"
12089   [(set (match_operand:SWI48 0 "register_operand" "=r")
12090         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12091                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12092                        UNSPEC_BEXTR))
12093    (clobber (reg:CC FLAGS_REG))]
12094   "TARGET_BMI"
12095   "bextr\t{%2, %1, %0|%0, %1, %2}"
12096   [(set_attr "type" "bitmanip")
12097    (set_attr "mode" "<MODE>")])
12098
12099 (define_insn "*bmi_blsi_<mode>"
12100   [(set (match_operand:SWI48 0 "register_operand" "=r")
12101         (and:SWI48
12102           (neg:SWI48
12103             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12104           (match_dup 1)))
12105    (clobber (reg:CC FLAGS_REG))]
12106   "TARGET_BMI"
12107   "blsi\t{%1, %0|%0, %1}"
12108   [(set_attr "type" "bitmanip")
12109    (set_attr "mode" "<MODE>")])
12110
12111 (define_insn "*bmi_blsmsk_<mode>"
12112   [(set (match_operand:SWI48 0 "register_operand" "=r")
12113         (xor:SWI48
12114           (plus:SWI48
12115             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12116             (const_int -1))
12117           (match_dup 1)))
12118    (clobber (reg:CC FLAGS_REG))]
12119   "TARGET_BMI"
12120   "blsmsk\t{%1, %0|%0, %1}"
12121   [(set_attr "type" "bitmanip")
12122    (set_attr "mode" "<MODE>")])
12123
12124 (define_insn "*bmi_blsr_<mode>"
12125   [(set (match_operand:SWI48 0 "register_operand" "=r")
12126         (and:SWI48
12127           (plus:SWI48
12128             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12129             (const_int -1))
12130           (match_dup 1)))
12131    (clobber (reg:CC FLAGS_REG))]
12132    "TARGET_BMI"
12133    "blsr\t{%1, %0|%0, %1}"
12134   [(set_attr "type" "bitmanip")
12135    (set_attr "mode" "<MODE>")])
12136
12137 ;; BMI2 instructions.
12138 (define_insn "bmi2_bzhi_<mode>3"
12139   [(set (match_operand:SWI48 0 "register_operand" "=r")
12140         (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12141                    (lshiftrt:SWI48 (const_int -1)
12142                                    (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12143    (clobber (reg:CC FLAGS_REG))]
12144   "TARGET_BMI2"
12145   "bzhi\t{%2, %1, %0|%0, %1, %2}"
12146   [(set_attr "type" "bitmanip")
12147    (set_attr "prefix" "vex")
12148    (set_attr "mode" "<MODE>")])
12149
12150 (define_insn "bmi2_pdep_<mode>3"
12151   [(set (match_operand:SWI48 0 "register_operand" "=r")
12152         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12153                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12154                        UNSPEC_PDEP))]
12155   "TARGET_BMI2"
12156   "pdep\t{%2, %1, %0|%0, %1, %2}"
12157   [(set_attr "type" "bitmanip")
12158    (set_attr "prefix" "vex")
12159    (set_attr "mode" "<MODE>")])
12160
12161 (define_insn "bmi2_pext_<mode>3"
12162   [(set (match_operand:SWI48 0 "register_operand" "=r")
12163         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12164                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12165                        UNSPEC_PEXT))]
12166   "TARGET_BMI2"
12167   "pext\t{%2, %1, %0|%0, %1, %2}"
12168   [(set_attr "type" "bitmanip")
12169    (set_attr "prefix" "vex")
12170    (set_attr "mode" "<MODE>")])
12171
12172 ;; TBM instructions.
12173 (define_insn "tbm_bextri_<mode>"
12174   [(set (match_operand:SWI48 0 "register_operand" "=r")
12175         (zero_extract:SWI48
12176           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12177           (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12178           (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12179    (clobber (reg:CC FLAGS_REG))]
12180    "TARGET_TBM"
12181 {
12182   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12183   return "bextr\t{%2, %1, %0|%0, %1, %2}";
12184 }
12185   [(set_attr "type" "bitmanip")
12186    (set_attr "mode" "<MODE>")])
12187
12188 (define_insn "*tbm_blcfill_<mode>"
12189   [(set (match_operand:SWI48 0 "register_operand" "=r")
12190         (and:SWI48
12191           (plus:SWI48
12192             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12193             (const_int 1))
12194           (match_dup 1)))
12195    (clobber (reg:CC FLAGS_REG))]
12196    "TARGET_TBM"
12197    "blcfill\t{%1, %0|%0, %1}"
12198   [(set_attr "type" "bitmanip")
12199    (set_attr "mode" "<MODE>")])
12200
12201 (define_insn "*tbm_blci_<mode>"
12202   [(set (match_operand:SWI48 0 "register_operand" "=r")
12203         (ior:SWI48
12204           (not:SWI48
12205             (plus:SWI48
12206               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12207               (const_int 1)))
12208           (match_dup 1)))
12209    (clobber (reg:CC FLAGS_REG))]
12210    "TARGET_TBM"
12211    "blci\t{%1, %0|%0, %1}"
12212   [(set_attr "type" "bitmanip")
12213    (set_attr "mode" "<MODE>")])
12214
12215 (define_insn "*tbm_blcic_<mode>"
12216   [(set (match_operand:SWI48 0 "register_operand" "=r")
12217         (and:SWI48
12218           (plus:SWI48
12219             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12220             (const_int 1))
12221           (not:SWI48
12222             (match_dup 1))))
12223    (clobber (reg:CC FLAGS_REG))]
12224    "TARGET_TBM"
12225    "blcic\t{%1, %0|%0, %1}"
12226   [(set_attr "type" "bitmanip")
12227    (set_attr "mode" "<MODE>")])
12228
12229 (define_insn "*tbm_blcmsk_<mode>"
12230   [(set (match_operand:SWI48 0 "register_operand" "=r")
12231         (xor:SWI48
12232           (plus:SWI48
12233             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12234             (const_int 1))
12235           (match_dup 1)))
12236    (clobber (reg:CC FLAGS_REG))]
12237    "TARGET_TBM"
12238    "blcmsk\t{%1, %0|%0, %1}"
12239   [(set_attr "type" "bitmanip")
12240    (set_attr "mode" "<MODE>")])
12241
12242 (define_insn "*tbm_blcs_<mode>"
12243   [(set (match_operand:SWI48 0 "register_operand" "=r")
12244         (ior:SWI48
12245           (plus:SWI48
12246             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12247             (const_int 1))
12248           (match_dup 1)))
12249    (clobber (reg:CC FLAGS_REG))]
12250    "TARGET_TBM"
12251    "blcs\t{%1, %0|%0, %1}"
12252   [(set_attr "type" "bitmanip")
12253    (set_attr "mode" "<MODE>")])
12254
12255 (define_insn "*tbm_blsfill_<mode>"
12256   [(set (match_operand:SWI48 0 "register_operand" "=r")
12257         (ior:SWI48
12258           (plus:SWI48
12259             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12260             (const_int -1))
12261           (match_dup 1)))
12262    (clobber (reg:CC FLAGS_REG))]
12263    "TARGET_TBM"
12264    "blsfill\t{%1, %0|%0, %1}"
12265   [(set_attr "type" "bitmanip")
12266    (set_attr "mode" "<MODE>")])
12267
12268 (define_insn "*tbm_blsic_<mode>"
12269   [(set (match_operand:SWI48 0 "register_operand" "=r")
12270         (ior:SWI48
12271           (plus:SWI48
12272             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12273             (const_int -1))
12274           (not:SWI48
12275             (match_dup 1))))
12276    (clobber (reg:CC FLAGS_REG))]
12277    "TARGET_TBM"
12278    "blsic\t{%1, %0|%0, %1}"
12279   [(set_attr "type" "bitmanip")
12280    (set_attr "mode" "<MODE>")])
12281
12282 (define_insn "*tbm_t1mskc_<mode>"
12283   [(set (match_operand:SWI48 0 "register_operand" "=r")
12284         (ior:SWI48
12285           (plus:SWI48
12286             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12287             (const_int 1))
12288           (not:SWI48
12289             (match_dup 1))))
12290    (clobber (reg:CC FLAGS_REG))]
12291    "TARGET_TBM"
12292    "t1mskc\t{%1, %0|%0, %1}"
12293   [(set_attr "type" "bitmanip")
12294    (set_attr "mode" "<MODE>")])
12295
12296 (define_insn "*tbm_tzmsk_<mode>"
12297   [(set (match_operand:SWI48 0 "register_operand" "=r")
12298         (and:SWI48
12299           (plus:SWI48
12300             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12301             (const_int -1))
12302           (not:SWI48
12303             (match_dup 1))))
12304    (clobber (reg:CC FLAGS_REG))]
12305    "TARGET_TBM"
12306    "tzmsk\t{%1, %0|%0, %1}"
12307   [(set_attr "type" "bitmanip")
12308    (set_attr "mode" "<MODE>")])
12309
12310 (define_insn "bsr_rex64"
12311   [(set (match_operand:DI 0 "register_operand" "=r")
12312         (minus:DI (const_int 63)
12313                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12314    (clobber (reg:CC FLAGS_REG))]
12315   "TARGET_64BIT"
12316   "bsr{q}\t{%1, %0|%0, %1}"
12317   [(set_attr "type" "alu1")
12318    (set_attr "prefix_0f" "1")
12319    (set_attr "mode" "DI")])
12320
12321 (define_insn "bsr"
12322   [(set (match_operand:SI 0 "register_operand" "=r")
12323         (minus:SI (const_int 31)
12324                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12325    (clobber (reg:CC FLAGS_REG))]
12326   ""
12327   "bsr{l}\t{%1, %0|%0, %1}"
12328   [(set_attr "type" "alu1")
12329    (set_attr "prefix_0f" "1")
12330    (set_attr "mode" "SI")])
12331
12332 (define_insn "*bsrhi"
12333   [(set (match_operand:HI 0 "register_operand" "=r")
12334         (minus:HI (const_int 15)
12335                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12336    (clobber (reg:CC FLAGS_REG))]
12337   ""
12338   "bsr{w}\t{%1, %0|%0, %1}"
12339   [(set_attr "type" "alu1")
12340    (set_attr "prefix_0f" "1")
12341    (set_attr "mode" "HI")])
12342
12343 (define_insn "popcount<mode>2"
12344   [(set (match_operand:SWI248 0 "register_operand" "=r")
12345         (popcount:SWI248
12346           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12347    (clobber (reg:CC FLAGS_REG))]
12348   "TARGET_POPCNT"
12349 {
12350 #if TARGET_MACHO
12351   return "popcnt\t{%1, %0|%0, %1}";
12352 #else
12353   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12354 #endif
12355 }
12356   [(set_attr "prefix_rep" "1")
12357    (set_attr "type" "bitmanip")
12358    (set_attr "mode" "<MODE>")])
12359
12360 (define_insn "*popcount<mode>2_cmp"
12361   [(set (reg FLAGS_REG)
12362         (compare
12363           (popcount:SWI248
12364             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12365           (const_int 0)))
12366    (set (match_operand:SWI248 0 "register_operand" "=r")
12367         (popcount:SWI248 (match_dup 1)))]
12368   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12369 {
12370 #if TARGET_MACHO
12371   return "popcnt\t{%1, %0|%0, %1}";
12372 #else
12373   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12374 #endif
12375 }
12376   [(set_attr "prefix_rep" "1")
12377    (set_attr "type" "bitmanip")
12378    (set_attr "mode" "<MODE>")])
12379
12380 (define_insn "*popcountsi2_cmp_zext"
12381   [(set (reg FLAGS_REG)
12382         (compare
12383           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12384           (const_int 0)))
12385    (set (match_operand:DI 0 "register_operand" "=r")
12386         (zero_extend:DI(popcount:SI (match_dup 1))))]
12387   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12388 {
12389 #if TARGET_MACHO
12390   return "popcnt\t{%1, %0|%0, %1}";
12391 #else
12392   return "popcnt{l}\t{%1, %0|%0, %1}";
12393 #endif
12394 }
12395   [(set_attr "prefix_rep" "1")
12396    (set_attr "type" "bitmanip")
12397    (set_attr "mode" "SI")])
12398
12399 (define_expand "bswap<mode>2"
12400   [(set (match_operand:SWI48 0 "register_operand" "")
12401         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12402   ""
12403 {
12404   if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12405     {
12406       rtx x = operands[0];
12407
12408       emit_move_insn (x, operands[1]);
12409       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12410       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12411       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12412       DONE;
12413     }
12414 })
12415
12416 (define_insn "*bswap<mode>2_movbe"
12417   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12418         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12419   "TARGET_MOVBE
12420    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12421   "@
12422     bswap\t%0
12423     movbe\t{%1, %0|%0, %1}
12424     movbe\t{%1, %0|%0, %1}"
12425   [(set_attr "type" "bitmanip,imov,imov")
12426    (set_attr "modrm" "0,1,1")
12427    (set_attr "prefix_0f" "*,1,1")
12428    (set_attr "prefix_extra" "*,1,1")
12429    (set_attr "mode" "<MODE>")])
12430
12431 (define_insn "*bswap<mode>2_1"
12432   [(set (match_operand:SWI48 0 "register_operand" "=r")
12433         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12434   "TARGET_BSWAP"
12435   "bswap\t%0"
12436   [(set_attr "type" "bitmanip")
12437    (set_attr "modrm" "0")
12438    (set_attr "mode" "<MODE>")])
12439
12440 (define_insn "*bswaphi_lowpart_1"
12441   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12442         (bswap:HI (match_dup 0)))
12443    (clobber (reg:CC FLAGS_REG))]
12444   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12445   "@
12446     xchg{b}\t{%h0, %b0|%b0, %h0}
12447     rol{w}\t{$8, %0|%0, 8}"
12448   [(set_attr "length" "2,4")
12449    (set_attr "mode" "QI,HI")])
12450
12451 (define_insn "bswaphi_lowpart"
12452   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12453         (bswap:HI (match_dup 0)))
12454    (clobber (reg:CC FLAGS_REG))]
12455   ""
12456   "rol{w}\t{$8, %0|%0, 8}"
12457   [(set_attr "length" "4")
12458    (set_attr "mode" "HI")])
12459
12460 (define_expand "paritydi2"
12461   [(set (match_operand:DI 0 "register_operand" "")
12462         (parity:DI (match_operand:DI 1 "register_operand" "")))]
12463   "! TARGET_POPCNT"
12464 {
12465   rtx scratch = gen_reg_rtx (QImode);
12466   rtx cond;
12467
12468   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12469                                 NULL_RTX, operands[1]));
12470
12471   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12472                          gen_rtx_REG (CCmode, FLAGS_REG),
12473                          const0_rtx);
12474   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12475
12476   if (TARGET_64BIT)
12477     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12478   else
12479     {
12480       rtx tmp = gen_reg_rtx (SImode);
12481
12482       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12483       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12484     }
12485   DONE;
12486 })
12487
12488 (define_expand "paritysi2"
12489   [(set (match_operand:SI 0 "register_operand" "")
12490         (parity:SI (match_operand:SI 1 "register_operand" "")))]
12491   "! TARGET_POPCNT"
12492 {
12493   rtx scratch = gen_reg_rtx (QImode);
12494   rtx cond;
12495
12496   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12497
12498   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12499                          gen_rtx_REG (CCmode, FLAGS_REG),
12500                          const0_rtx);
12501   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12502
12503   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12504   DONE;
12505 })
12506
12507 (define_insn_and_split "paritydi2_cmp"
12508   [(set (reg:CC FLAGS_REG)
12509         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12510                    UNSPEC_PARITY))
12511    (clobber (match_scratch:DI 0 "=r"))
12512    (clobber (match_scratch:SI 1 "=&r"))
12513    (clobber (match_scratch:HI 2 "=Q"))]
12514   "! TARGET_POPCNT"
12515   "#"
12516   "&& reload_completed"
12517   [(parallel
12518      [(set (match_dup 1)
12519            (xor:SI (match_dup 1) (match_dup 4)))
12520       (clobber (reg:CC FLAGS_REG))])
12521    (parallel
12522      [(set (reg:CC FLAGS_REG)
12523            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12524       (clobber (match_dup 1))
12525       (clobber (match_dup 2))])]
12526 {
12527   operands[4] = gen_lowpart (SImode, operands[3]);
12528
12529   if (TARGET_64BIT)
12530     {
12531       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12532       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12533     }
12534   else
12535     operands[1] = gen_highpart (SImode, operands[3]);
12536 })
12537
12538 (define_insn_and_split "paritysi2_cmp"
12539   [(set (reg:CC FLAGS_REG)
12540         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12541                    UNSPEC_PARITY))
12542    (clobber (match_scratch:SI 0 "=r"))
12543    (clobber (match_scratch:HI 1 "=&Q"))]
12544   "! TARGET_POPCNT"
12545   "#"
12546   "&& reload_completed"
12547   [(parallel
12548      [(set (match_dup 1)
12549            (xor:HI (match_dup 1) (match_dup 3)))
12550       (clobber (reg:CC FLAGS_REG))])
12551    (parallel
12552      [(set (reg:CC FLAGS_REG)
12553            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12554       (clobber (match_dup 1))])]
12555 {
12556   operands[3] = gen_lowpart (HImode, operands[2]);
12557
12558   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12559   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12560 })
12561
12562 (define_insn "*parityhi2_cmp"
12563   [(set (reg:CC FLAGS_REG)
12564         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12565                    UNSPEC_PARITY))
12566    (clobber (match_scratch:HI 0 "=Q"))]
12567   "! TARGET_POPCNT"
12568   "xor{b}\t{%h0, %b0|%b0, %h0}"
12569   [(set_attr "length" "2")
12570    (set_attr "mode" "HI")])
12571
12572 \f
12573 ;; Thread-local storage patterns for ELF.
12574 ;;
12575 ;; Note that these code sequences must appear exactly as shown
12576 ;; in order to allow linker relaxation.
12577
12578 (define_insn "*tls_global_dynamic_32_gnu"
12579   [(set (match_operand:SI 0 "register_operand" "=a")
12580         (unspec:SI
12581          [(match_operand:SI 1 "register_operand" "b")
12582           (match_operand:SI 2 "tls_symbolic_operand" "")
12583           (match_operand:SI 3 "constant_call_address_operand" "z")]
12584          UNSPEC_TLS_GD))
12585    (clobber (match_scratch:SI 4 "=d"))
12586    (clobber (match_scratch:SI 5 "=c"))
12587    (clobber (reg:CC FLAGS_REG))]
12588   "!TARGET_64BIT && TARGET_GNU_TLS"
12589 {
12590   output_asm_insn
12591     ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12592   if (TARGET_SUN_TLS)
12593 #ifdef HAVE_AS_IX86_TLSGDPLT
12594     return "call\t%a2@tlsgdplt";
12595 #else
12596     return "call\t%p3@plt";
12597 #endif
12598   return "call\t%P3";
12599 }
12600   [(set_attr "type" "multi")
12601    (set_attr "length" "12")])
12602
12603 (define_expand "tls_global_dynamic_32"
12604   [(parallel
12605     [(set (match_operand:SI 0 "register_operand" "")
12606           (unspec:SI [(match_operand:SI 2 "register_operand" "")
12607                       (match_operand:SI 1 "tls_symbolic_operand" "")
12608                       (match_operand:SI 3 "constant_call_address_operand" "")]
12609                      UNSPEC_TLS_GD))
12610      (clobber (match_scratch:SI 4 ""))
12611      (clobber (match_scratch:SI 5 ""))
12612      (clobber (reg:CC FLAGS_REG))])])
12613
12614 (define_insn "*tls_global_dynamic_64"
12615   [(set (match_operand:DI 0 "register_operand" "=a")
12616         (call:DI
12617          (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12618          (match_operand:DI 3 "" "")))
12619    (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12620               UNSPEC_TLS_GD)]
12621   "TARGET_64BIT"
12622 {
12623   if (!TARGET_X32)
12624     fputs (ASM_BYTE "0x66\n", asm_out_file);
12625   output_asm_insn
12626     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12627   fputs (ASM_SHORT "0x6666\n", asm_out_file);
12628   fputs ("\trex64\n", asm_out_file);
12629   if (TARGET_SUN_TLS)
12630     return "call\t%p2@plt";
12631   return "call\t%P2";
12632 }
12633   [(set_attr "type" "multi")
12634    (set (attr "length")
12635         (symbol_ref "TARGET_X32 ? 15 : 16"))])
12636
12637 (define_expand "tls_global_dynamic_64"
12638   [(parallel
12639     [(set (match_operand:DI 0 "register_operand" "")
12640           (call:DI
12641            (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12642            (const_int 0)))
12643      (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12644                 UNSPEC_TLS_GD)])])
12645
12646 (define_insn "*tls_local_dynamic_base_32_gnu"
12647   [(set (match_operand:SI 0 "register_operand" "=a")
12648         (unspec:SI
12649          [(match_operand:SI 1 "register_operand" "b")
12650           (match_operand:SI 2 "constant_call_address_operand" "z")]
12651          UNSPEC_TLS_LD_BASE))
12652    (clobber (match_scratch:SI 3 "=d"))
12653    (clobber (match_scratch:SI 4 "=c"))
12654    (clobber (reg:CC FLAGS_REG))]
12655   "!TARGET_64BIT && TARGET_GNU_TLS"
12656 {
12657   output_asm_insn
12658     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12659   if (TARGET_SUN_TLS)
12660 #ifdef HAVE_AS_IX86_TLSLDMPLT
12661     return "call\t%&@tlsldmplt";
12662 #else
12663     return "call\t%p2@plt";
12664 #endif
12665   return "call\t%P2";
12666 }
12667   [(set_attr "type" "multi")
12668    (set_attr "length" "11")])
12669
12670 (define_expand "tls_local_dynamic_base_32"
12671   [(parallel
12672      [(set (match_operand:SI 0 "register_operand" "")
12673            (unspec:SI
12674             [(match_operand:SI 1 "register_operand" "")
12675              (match_operand:SI 2 "constant_call_address_operand" "")]
12676             UNSPEC_TLS_LD_BASE))
12677       (clobber (match_scratch:SI 3 ""))
12678       (clobber (match_scratch:SI 4 ""))
12679       (clobber (reg:CC FLAGS_REG))])])
12680
12681 (define_insn "*tls_local_dynamic_base_64"
12682   [(set (match_operand:DI 0 "register_operand" "=a")
12683         (call:DI
12684          (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12685          (match_operand:DI 2 "" "")))
12686    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12687   "TARGET_64BIT"
12688 {
12689   output_asm_insn
12690     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12691   if (TARGET_SUN_TLS)
12692     return "call\t%p1@plt";
12693   return "call\t%P1";
12694 }
12695   [(set_attr "type" "multi")
12696    (set_attr "length" "12")])
12697
12698 (define_expand "tls_local_dynamic_base_64"
12699   [(parallel
12700      [(set (match_operand:DI 0 "register_operand" "")
12701            (call:DI
12702             (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12703             (const_int 0)))
12704       (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12705
12706 ;; Local dynamic of a single variable is a lose.  Show combine how
12707 ;; to convert that back to global dynamic.
12708
12709 (define_insn_and_split "*tls_local_dynamic_32_once"
12710   [(set (match_operand:SI 0 "register_operand" "=a")
12711         (plus:SI
12712          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12713                      (match_operand:SI 2 "constant_call_address_operand" "z")]
12714                     UNSPEC_TLS_LD_BASE)
12715          (const:SI (unspec:SI
12716                     [(match_operand:SI 3 "tls_symbolic_operand" "")]
12717                     UNSPEC_DTPOFF))))
12718    (clobber (match_scratch:SI 4 "=d"))
12719    (clobber (match_scratch:SI 5 "=c"))
12720    (clobber (reg:CC FLAGS_REG))]
12721   ""
12722   "#"
12723   ""
12724   [(parallel
12725      [(set (match_dup 0)
12726            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12727                       UNSPEC_TLS_GD))
12728       (clobber (match_dup 4))
12729       (clobber (match_dup 5))
12730       (clobber (reg:CC FLAGS_REG))])])
12731
12732 ;; Segment register for the thread base ptr load
12733 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12734
12735 ;; Load and add the thread base pointer from %<tp_seg>:0.
12736 (define_insn "*load_tp_x32"
12737   [(set (match_operand:SI 0 "register_operand" "=r")
12738         (unspec:SI [(const_int 0)] UNSPEC_TP))]
12739   "TARGET_X32"
12740   "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12741   [(set_attr "type" "imov")
12742    (set_attr "modrm" "0")
12743    (set_attr "length" "7")
12744    (set_attr "memory" "load")
12745    (set_attr "imm_disp" "false")])
12746
12747 (define_insn "*load_tp_x32_zext"
12748   [(set (match_operand:DI 0 "register_operand" "=r")
12749         (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12750   "TARGET_X32"
12751   "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12752   [(set_attr "type" "imov")
12753    (set_attr "modrm" "0")
12754    (set_attr "length" "7")
12755    (set_attr "memory" "load")
12756    (set_attr "imm_disp" "false")])
12757
12758 (define_insn "*load_tp_<mode>"
12759   [(set (match_operand:P 0 "register_operand" "=r")
12760         (unspec:P [(const_int 0)] UNSPEC_TP))]
12761   "!TARGET_X32"
12762   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12763   [(set_attr "type" "imov")
12764    (set_attr "modrm" "0")
12765    (set_attr "length" "7")
12766    (set_attr "memory" "load")
12767    (set_attr "imm_disp" "false")])
12768
12769 (define_insn "*add_tp_x32"
12770   [(set (match_operand:SI 0 "register_operand" "=r")
12771         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12772                  (match_operand:SI 1 "register_operand" "0")))
12773    (clobber (reg:CC FLAGS_REG))]
12774   "TARGET_X32"
12775   "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12776   [(set_attr "type" "alu")
12777    (set_attr "modrm" "0")
12778    (set_attr "length" "7")
12779    (set_attr "memory" "load")
12780    (set_attr "imm_disp" "false")])
12781
12782 (define_insn "*add_tp_x32_zext"
12783   [(set (match_operand:DI 0 "register_operand" "=r")
12784         (zero_extend:DI
12785           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12786                    (match_operand:SI 1 "register_operand" "0"))))
12787    (clobber (reg:CC FLAGS_REG))]
12788   "TARGET_X32"
12789   "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12790   [(set_attr "type" "alu")
12791    (set_attr "modrm" "0")
12792    (set_attr "length" "7")
12793    (set_attr "memory" "load")
12794    (set_attr "imm_disp" "false")])
12795
12796 (define_insn "*add_tp_<mode>"
12797   [(set (match_operand:P 0 "register_operand" "=r")
12798         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12799                 (match_operand:P 1 "register_operand" "0")))
12800    (clobber (reg:CC FLAGS_REG))]
12801   "!TARGET_X32"
12802   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12803   [(set_attr "type" "alu")
12804    (set_attr "modrm" "0")
12805    (set_attr "length" "7")
12806    (set_attr "memory" "load")
12807    (set_attr "imm_disp" "false")])
12808
12809 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12810 ;; %rax as destination of the initial executable code sequence.
12811 (define_insn "tls_initial_exec_64_sun"
12812   [(set (match_operand:DI 0 "register_operand" "=a")
12813         (unspec:DI
12814          [(match_operand:DI 1 "tls_symbolic_operand" "")]
12815          UNSPEC_TLS_IE_SUN))
12816    (clobber (reg:CC FLAGS_REG))]
12817   "TARGET_64BIT && TARGET_SUN_TLS"
12818 {
12819   output_asm_insn
12820     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12821   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12822 }
12823   [(set_attr "type" "multi")])
12824
12825 ;; GNU2 TLS patterns can be split.
12826
12827 (define_expand "tls_dynamic_gnu2_32"
12828   [(set (match_dup 3)
12829         (plus:SI (match_operand:SI 2 "register_operand" "")
12830                  (const:SI
12831                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12832                              UNSPEC_TLSDESC))))
12833    (parallel
12834     [(set (match_operand:SI 0 "register_operand" "")
12835           (unspec:SI [(match_dup 1) (match_dup 3)
12836                       (match_dup 2) (reg:SI SP_REG)]
12837                       UNSPEC_TLSDESC))
12838      (clobber (reg:CC FLAGS_REG))])]
12839   "!TARGET_64BIT && TARGET_GNU2_TLS"
12840 {
12841   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12842   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12843 })
12844
12845 (define_insn "*tls_dynamic_gnu2_lea_32"
12846   [(set (match_operand:SI 0 "register_operand" "=r")
12847         (plus:SI (match_operand:SI 1 "register_operand" "b")
12848                  (const:SI
12849                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12850                               UNSPEC_TLSDESC))))]
12851   "!TARGET_64BIT && TARGET_GNU2_TLS"
12852   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
12853   [(set_attr "type" "lea")
12854    (set_attr "mode" "SI")
12855    (set_attr "length" "6")
12856    (set_attr "length_address" "4")])
12857
12858 (define_insn "*tls_dynamic_gnu2_call_32"
12859   [(set (match_operand:SI 0 "register_operand" "=a")
12860         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12861                     (match_operand:SI 2 "register_operand" "0")
12862                     ;; we have to make sure %ebx still points to the GOT
12863                     (match_operand:SI 3 "register_operand" "b")
12864                     (reg:SI SP_REG)]
12865                    UNSPEC_TLSDESC))
12866    (clobber (reg:CC FLAGS_REG))]
12867   "!TARGET_64BIT && TARGET_GNU2_TLS"
12868   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12869   [(set_attr "type" "call")
12870    (set_attr "length" "2")
12871    (set_attr "length_address" "0")])
12872
12873 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12874   [(set (match_operand:SI 0 "register_operand" "=&a")
12875         (plus:SI
12876          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12877                      (match_operand:SI 4 "" "")
12878                      (match_operand:SI 2 "register_operand" "b")
12879                      (reg:SI SP_REG)]
12880                     UNSPEC_TLSDESC)
12881          (const:SI (unspec:SI
12882                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
12883                     UNSPEC_DTPOFF))))
12884    (clobber (reg:CC FLAGS_REG))]
12885   "!TARGET_64BIT && TARGET_GNU2_TLS"
12886   "#"
12887   ""
12888   [(set (match_dup 0) (match_dup 5))]
12889 {
12890   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12891   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12892 })
12893
12894 (define_expand "tls_dynamic_gnu2_64"
12895   [(set (match_dup 2)
12896         (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12897                    UNSPEC_TLSDESC))
12898    (parallel
12899     [(set (match_operand:DI 0 "register_operand" "")
12900           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12901                      UNSPEC_TLSDESC))
12902      (clobber (reg:CC FLAGS_REG))])]
12903   "TARGET_64BIT && TARGET_GNU2_TLS"
12904 {
12905   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12906   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12907 })
12908
12909 (define_insn "*tls_dynamic_gnu2_lea_64"
12910   [(set (match_operand:DI 0 "register_operand" "=r")
12911         (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12912                    UNSPEC_TLSDESC))]
12913   "TARGET_64BIT && TARGET_GNU2_TLS"
12914   "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
12915   [(set_attr "type" "lea")
12916    (set_attr "mode" "DI")
12917    (set_attr "length" "7")
12918    (set_attr "length_address" "4")])
12919
12920 (define_insn "*tls_dynamic_gnu2_call_64"
12921   [(set (match_operand:DI 0 "register_operand" "=a")
12922         (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12923                     (match_operand:DI 2 "register_operand" "0")
12924                     (reg:DI SP_REG)]
12925                    UNSPEC_TLSDESC))
12926    (clobber (reg:CC FLAGS_REG))]
12927   "TARGET_64BIT && TARGET_GNU2_TLS"
12928   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12929   [(set_attr "type" "call")
12930    (set_attr "length" "2")
12931    (set_attr "length_address" "0")])
12932
12933 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12934   [(set (match_operand:DI 0 "register_operand" "=&a")
12935         (plus:DI
12936          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12937                      (match_operand:DI 3 "" "")
12938                      (reg:DI SP_REG)]
12939                     UNSPEC_TLSDESC)
12940          (const:DI (unspec:DI
12941                     [(match_operand 1 "tls_symbolic_operand" "")]
12942                     UNSPEC_DTPOFF))))
12943    (clobber (reg:CC FLAGS_REG))]
12944   "TARGET_64BIT && TARGET_GNU2_TLS"
12945   "#"
12946   ""
12947   [(set (match_dup 0) (match_dup 4))]
12948 {
12949   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12950   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12951 })
12952 \f
12953 ;; These patterns match the binary 387 instructions for addM3, subM3,
12954 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
12955 ;; SFmode.  The first is the normal insn, the second the same insn but
12956 ;; with one operand a conversion, and the third the same insn but with
12957 ;; the other operand a conversion.  The conversion may be SFmode or
12958 ;; SImode if the target mode DFmode, but only SImode if the target mode
12959 ;; is SFmode.
12960
12961 ;; Gcc is slightly more smart about handling normal two address instructions
12962 ;; so use special patterns for add and mull.
12963
12964 (define_insn "*fop_<mode>_comm_mixed"
12965   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12966         (match_operator:MODEF 3 "binary_fp_operator"
12967           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12968            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12969   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12970    && COMMUTATIVE_ARITH_P (operands[3])
12971    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12972   "* return output_387_binary_op (insn, operands);"
12973   [(set (attr "type")
12974         (if_then_else (eq_attr "alternative" "1,2")
12975            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12976               (const_string "ssemul")
12977               (const_string "sseadd"))
12978            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12979               (const_string "fmul")
12980               (const_string "fop"))))
12981    (set_attr "isa" "*,noavx,avx")
12982    (set_attr "prefix" "orig,orig,vex")
12983    (set_attr "mode" "<MODE>")])
12984
12985 (define_insn "*fop_<mode>_comm_sse"
12986   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12987         (match_operator:MODEF 3 "binary_fp_operator"
12988           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12989            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12990   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12991    && COMMUTATIVE_ARITH_P (operands[3])
12992    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12993   "* return output_387_binary_op (insn, operands);"
12994   [(set (attr "type")
12995         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12996            (const_string "ssemul")
12997            (const_string "sseadd")))
12998    (set_attr "isa" "noavx,avx")
12999    (set_attr "prefix" "orig,vex")
13000    (set_attr "mode" "<MODE>")])
13001
13002 (define_insn "*fop_<mode>_comm_i387"
13003   [(set (match_operand:MODEF 0 "register_operand" "=f")
13004         (match_operator:MODEF 3 "binary_fp_operator"
13005           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13006            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13007   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13008    && COMMUTATIVE_ARITH_P (operands[3])
13009    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13010   "* return output_387_binary_op (insn, operands);"
13011   [(set (attr "type")
13012         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13013            (const_string "fmul")
13014            (const_string "fop")))
13015    (set_attr "mode" "<MODE>")])
13016
13017 (define_insn "*fop_<mode>_1_mixed"
13018   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13019         (match_operator:MODEF 3 "binary_fp_operator"
13020           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13021            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13022   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13023    && !COMMUTATIVE_ARITH_P (operands[3])
13024    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13025   "* return output_387_binary_op (insn, operands);"
13026   [(set (attr "type")
13027         (cond [(and (eq_attr "alternative" "2,3")
13028                     (match_operand:MODEF 3 "mult_operator" ""))
13029                  (const_string "ssemul")
13030                (and (eq_attr "alternative" "2,3")
13031                     (match_operand:MODEF 3 "div_operator" ""))
13032                  (const_string "ssediv")
13033                (eq_attr "alternative" "2,3")
13034                  (const_string "sseadd")
13035                (match_operand:MODEF 3 "mult_operator" "")
13036                  (const_string "fmul")
13037                (match_operand:MODEF 3 "div_operator" "")
13038                  (const_string "fdiv")
13039               ]
13040               (const_string "fop")))
13041    (set_attr "isa" "*,*,noavx,avx")
13042    (set_attr "prefix" "orig,orig,orig,vex")
13043    (set_attr "mode" "<MODE>")])
13044
13045 (define_insn "*rcpsf2_sse"
13046   [(set (match_operand:SF 0 "register_operand" "=x")
13047         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13048                    UNSPEC_RCP))]
13049   "TARGET_SSE_MATH"
13050   "%vrcpss\t{%1, %d0|%d0, %1}"
13051   [(set_attr "type" "sse")
13052    (set_attr "atom_sse_attr" "rcp")
13053    (set_attr "prefix" "maybe_vex")
13054    (set_attr "mode" "SF")])
13055
13056 (define_insn "*fop_<mode>_1_sse"
13057   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13058         (match_operator:MODEF 3 "binary_fp_operator"
13059           [(match_operand:MODEF 1 "register_operand" "0,x")
13060            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13061   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13062    && !COMMUTATIVE_ARITH_P (operands[3])"
13063   "* return output_387_binary_op (insn, operands);"
13064   [(set (attr "type")
13065         (cond [(match_operand:MODEF 3 "mult_operator" "")
13066                  (const_string "ssemul")
13067                (match_operand:MODEF 3 "div_operator" "")
13068                  (const_string "ssediv")
13069               ]
13070               (const_string "sseadd")))
13071    (set_attr "isa" "noavx,avx")
13072    (set_attr "prefix" "orig,vex")
13073    (set_attr "mode" "<MODE>")])
13074
13075 ;; This pattern is not fully shadowed by the pattern above.
13076 (define_insn "*fop_<mode>_1_i387"
13077   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13078         (match_operator:MODEF 3 "binary_fp_operator"
13079           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13080            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13081   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13082    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13083    && !COMMUTATIVE_ARITH_P (operands[3])
13084    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13085   "* return output_387_binary_op (insn, operands);"
13086   [(set (attr "type")
13087         (cond [(match_operand:MODEF 3 "mult_operator" "")
13088                  (const_string "fmul")
13089                (match_operand:MODEF 3 "div_operator" "")
13090                  (const_string "fdiv")
13091               ]
13092               (const_string "fop")))
13093    (set_attr "mode" "<MODE>")])
13094
13095 ;; ??? Add SSE splitters for these!
13096 (define_insn "*fop_<MODEF:mode>_2_i387"
13097   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13098         (match_operator:MODEF 3 "binary_fp_operator"
13099           [(float:MODEF
13100              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13101            (match_operand:MODEF 2 "register_operand" "0,0")]))]
13102   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13103    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13104    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13105   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13106   [(set (attr "type")
13107         (cond [(match_operand:MODEF 3 "mult_operator" "")
13108                  (const_string "fmul")
13109                (match_operand:MODEF 3 "div_operator" "")
13110                  (const_string "fdiv")
13111               ]
13112               (const_string "fop")))
13113    (set_attr "fp_int_src" "true")
13114    (set_attr "mode" "<SWI24:MODE>")])
13115
13116 (define_insn "*fop_<MODEF:mode>_3_i387"
13117   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13118         (match_operator:MODEF 3 "binary_fp_operator"
13119           [(match_operand:MODEF 1 "register_operand" "0,0")
13120            (float:MODEF
13121              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13122   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13123    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13124    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13125   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13126   [(set (attr "type")
13127         (cond [(match_operand:MODEF 3 "mult_operator" "")
13128                  (const_string "fmul")
13129                (match_operand:MODEF 3 "div_operator" "")
13130                  (const_string "fdiv")
13131               ]
13132               (const_string "fop")))
13133    (set_attr "fp_int_src" "true")
13134    (set_attr "mode" "<MODE>")])
13135
13136 (define_insn "*fop_df_4_i387"
13137   [(set (match_operand:DF 0 "register_operand" "=f,f")
13138         (match_operator:DF 3 "binary_fp_operator"
13139            [(float_extend:DF
13140              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13141             (match_operand:DF 2 "register_operand" "0,f")]))]
13142   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13143    && !(TARGET_SSE2 && TARGET_SSE_MATH)
13144    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13145   "* return output_387_binary_op (insn, operands);"
13146   [(set (attr "type")
13147         (cond [(match_operand:DF 3 "mult_operator" "")
13148                  (const_string "fmul")
13149                (match_operand:DF 3 "div_operator" "")
13150                  (const_string "fdiv")
13151               ]
13152               (const_string "fop")))
13153    (set_attr "mode" "SF")])
13154
13155 (define_insn "*fop_df_5_i387"
13156   [(set (match_operand:DF 0 "register_operand" "=f,f")
13157         (match_operator:DF 3 "binary_fp_operator"
13158           [(match_operand:DF 1 "register_operand" "0,f")
13159            (float_extend:DF
13160             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13161   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13162    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13163   "* return output_387_binary_op (insn, operands);"
13164   [(set (attr "type")
13165         (cond [(match_operand:DF 3 "mult_operator" "")
13166                  (const_string "fmul")
13167                (match_operand:DF 3 "div_operator" "")
13168                  (const_string "fdiv")
13169               ]
13170               (const_string "fop")))
13171    (set_attr "mode" "SF")])
13172
13173 (define_insn "*fop_df_6_i387"
13174   [(set (match_operand:DF 0 "register_operand" "=f,f")
13175         (match_operator:DF 3 "binary_fp_operator"
13176           [(float_extend:DF
13177             (match_operand:SF 1 "register_operand" "0,f"))
13178            (float_extend:DF
13179             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13180   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13181    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13182   "* return output_387_binary_op (insn, operands);"
13183   [(set (attr "type")
13184         (cond [(match_operand:DF 3 "mult_operator" "")
13185                  (const_string "fmul")
13186                (match_operand:DF 3 "div_operator" "")
13187                  (const_string "fdiv")
13188               ]
13189               (const_string "fop")))
13190    (set_attr "mode" "SF")])
13191
13192 (define_insn "*fop_xf_comm_i387"
13193   [(set (match_operand:XF 0 "register_operand" "=f")
13194         (match_operator:XF 3 "binary_fp_operator"
13195                         [(match_operand:XF 1 "register_operand" "%0")
13196                          (match_operand:XF 2 "register_operand" "f")]))]
13197   "TARGET_80387
13198    && COMMUTATIVE_ARITH_P (operands[3])"
13199   "* return output_387_binary_op (insn, operands);"
13200   [(set (attr "type")
13201         (if_then_else (match_operand:XF 3 "mult_operator" "")
13202            (const_string "fmul")
13203            (const_string "fop")))
13204    (set_attr "mode" "XF")])
13205
13206 (define_insn "*fop_xf_1_i387"
13207   [(set (match_operand:XF 0 "register_operand" "=f,f")
13208         (match_operator:XF 3 "binary_fp_operator"
13209                         [(match_operand:XF 1 "register_operand" "0,f")
13210                          (match_operand:XF 2 "register_operand" "f,0")]))]
13211   "TARGET_80387
13212    && !COMMUTATIVE_ARITH_P (operands[3])"
13213   "* return output_387_binary_op (insn, operands);"
13214   [(set (attr "type")
13215         (cond [(match_operand:XF 3 "mult_operator" "")
13216                  (const_string "fmul")
13217                (match_operand:XF 3 "div_operator" "")
13218                  (const_string "fdiv")
13219               ]
13220               (const_string "fop")))
13221    (set_attr "mode" "XF")])
13222
13223 (define_insn "*fop_xf_2_i387"
13224   [(set (match_operand:XF 0 "register_operand" "=f,f")
13225         (match_operator:XF 3 "binary_fp_operator"
13226           [(float:XF
13227              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13228            (match_operand:XF 2 "register_operand" "0,0")]))]
13229   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13230   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13231   [(set (attr "type")
13232         (cond [(match_operand:XF 3 "mult_operator" "")
13233                  (const_string "fmul")
13234                (match_operand:XF 3 "div_operator" "")
13235                  (const_string "fdiv")
13236               ]
13237               (const_string "fop")))
13238    (set_attr "fp_int_src" "true")
13239    (set_attr "mode" "<MODE>")])
13240
13241 (define_insn "*fop_xf_3_i387"
13242   [(set (match_operand:XF 0 "register_operand" "=f,f")
13243         (match_operator:XF 3 "binary_fp_operator"
13244           [(match_operand:XF 1 "register_operand" "0,0")
13245            (float:XF
13246              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13247   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13248   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13249   [(set (attr "type")
13250         (cond [(match_operand:XF 3 "mult_operator" "")
13251                  (const_string "fmul")
13252                (match_operand:XF 3 "div_operator" "")
13253                  (const_string "fdiv")
13254               ]
13255               (const_string "fop")))
13256    (set_attr "fp_int_src" "true")
13257    (set_attr "mode" "<MODE>")])
13258
13259 (define_insn "*fop_xf_4_i387"
13260   [(set (match_operand:XF 0 "register_operand" "=f,f")
13261         (match_operator:XF 3 "binary_fp_operator"
13262            [(float_extend:XF
13263               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13264             (match_operand:XF 2 "register_operand" "0,f")]))]
13265   "TARGET_80387"
13266   "* return output_387_binary_op (insn, operands);"
13267   [(set (attr "type")
13268         (cond [(match_operand:XF 3 "mult_operator" "")
13269                  (const_string "fmul")
13270                (match_operand:XF 3 "div_operator" "")
13271                  (const_string "fdiv")
13272               ]
13273               (const_string "fop")))
13274    (set_attr "mode" "<MODE>")])
13275
13276 (define_insn "*fop_xf_5_i387"
13277   [(set (match_operand:XF 0 "register_operand" "=f,f")
13278         (match_operator:XF 3 "binary_fp_operator"
13279           [(match_operand:XF 1 "register_operand" "0,f")
13280            (float_extend:XF
13281              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13282   "TARGET_80387"
13283   "* return output_387_binary_op (insn, operands);"
13284   [(set (attr "type")
13285         (cond [(match_operand:XF 3 "mult_operator" "")
13286                  (const_string "fmul")
13287                (match_operand:XF 3 "div_operator" "")
13288                  (const_string "fdiv")
13289               ]
13290               (const_string "fop")))
13291    (set_attr "mode" "<MODE>")])
13292
13293 (define_insn "*fop_xf_6_i387"
13294   [(set (match_operand:XF 0 "register_operand" "=f,f")
13295         (match_operator:XF 3 "binary_fp_operator"
13296           [(float_extend:XF
13297              (match_operand:MODEF 1 "register_operand" "0,f"))
13298            (float_extend:XF
13299              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13300   "TARGET_80387"
13301   "* return output_387_binary_op (insn, operands);"
13302   [(set (attr "type")
13303         (cond [(match_operand:XF 3 "mult_operator" "")
13304                  (const_string "fmul")
13305                (match_operand:XF 3 "div_operator" "")
13306                  (const_string "fdiv")
13307               ]
13308               (const_string "fop")))
13309    (set_attr "mode" "<MODE>")])
13310
13311 (define_split
13312   [(set (match_operand 0 "register_operand" "")
13313         (match_operator 3 "binary_fp_operator"
13314            [(float (match_operand:SWI24 1 "register_operand" ""))
13315             (match_operand 2 "register_operand" "")]))]
13316   "reload_completed
13317    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13318    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13319   [(const_int 0)]
13320 {
13321   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13322   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13323   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13324                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13325                                           GET_MODE (operands[3]),
13326                                           operands[4],
13327                                           operands[2])));
13328   ix86_free_from_memory (GET_MODE (operands[1]));
13329   DONE;
13330 })
13331
13332 (define_split
13333   [(set (match_operand 0 "register_operand" "")
13334         (match_operator 3 "binary_fp_operator"
13335            [(match_operand 1 "register_operand" "")
13336             (float (match_operand:SWI24 2 "register_operand" ""))]))]
13337   "reload_completed
13338    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13339    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13340   [(const_int 0)]
13341 {
13342   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13343   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13344   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13345                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13346                                           GET_MODE (operands[3]),
13347                                           operands[1],
13348                                           operands[4])));
13349   ix86_free_from_memory (GET_MODE (operands[2]));
13350   DONE;
13351 })
13352 \f
13353 ;; FPU special functions.
13354
13355 ;; This pattern implements a no-op XFmode truncation for
13356 ;; all fancy i386 XFmode math functions.
13357
13358 (define_insn "truncxf<mode>2_i387_noop_unspec"
13359   [(set (match_operand:MODEF 0 "register_operand" "=f")
13360         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13361         UNSPEC_TRUNC_NOOP))]
13362   "TARGET_USE_FANCY_MATH_387"
13363   "* return output_387_reg_move (insn, operands);"
13364   [(set_attr "type" "fmov")
13365    (set_attr "mode" "<MODE>")])
13366
13367 (define_insn "sqrtxf2"
13368   [(set (match_operand:XF 0 "register_operand" "=f")
13369         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13370   "TARGET_USE_FANCY_MATH_387"
13371   "fsqrt"
13372   [(set_attr "type" "fpspc")
13373    (set_attr "mode" "XF")
13374    (set_attr "athlon_decode" "direct")
13375    (set_attr "amdfam10_decode" "direct")
13376    (set_attr "bdver1_decode" "direct")])
13377
13378 (define_insn "sqrt_extend<mode>xf2_i387"
13379   [(set (match_operand:XF 0 "register_operand" "=f")
13380         (sqrt:XF
13381           (float_extend:XF
13382             (match_operand:MODEF 1 "register_operand" "0"))))]
13383   "TARGET_USE_FANCY_MATH_387"
13384   "fsqrt"
13385   [(set_attr "type" "fpspc")
13386    (set_attr "mode" "XF")
13387    (set_attr "athlon_decode" "direct")
13388    (set_attr "amdfam10_decode" "direct")
13389    (set_attr "bdver1_decode" "direct")])
13390
13391 (define_insn "*rsqrtsf2_sse"
13392   [(set (match_operand:SF 0 "register_operand" "=x")
13393         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13394                    UNSPEC_RSQRT))]
13395   "TARGET_SSE_MATH"
13396   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13397   [(set_attr "type" "sse")
13398    (set_attr "atom_sse_attr" "rcp")
13399    (set_attr "prefix" "maybe_vex")
13400    (set_attr "mode" "SF")])
13401
13402 (define_expand "rsqrtsf2"
13403   [(set (match_operand:SF 0 "register_operand" "")
13404         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13405                    UNSPEC_RSQRT))]
13406   "TARGET_SSE_MATH"
13407 {
13408   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13409   DONE;
13410 })
13411
13412 (define_insn "*sqrt<mode>2_sse"
13413   [(set (match_operand:MODEF 0 "register_operand" "=x")
13414         (sqrt:MODEF
13415           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13416   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13417   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13418   [(set_attr "type" "sse")
13419    (set_attr "atom_sse_attr" "sqrt")
13420    (set_attr "prefix" "maybe_vex")
13421    (set_attr "mode" "<MODE>")
13422    (set_attr "athlon_decode" "*")
13423    (set_attr "amdfam10_decode" "*")
13424    (set_attr "bdver1_decode" "*")])
13425
13426 (define_expand "sqrt<mode>2"
13427   [(set (match_operand:MODEF 0 "register_operand" "")
13428         (sqrt:MODEF
13429           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13430   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13431    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13432 {
13433   if (<MODE>mode == SFmode
13434       && TARGET_SSE_MATH
13435       && TARGET_RECIP_SQRT
13436       && !optimize_function_for_size_p (cfun)
13437       && flag_finite_math_only && !flag_trapping_math
13438       && flag_unsafe_math_optimizations)
13439     {
13440       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13441       DONE;
13442     }
13443
13444   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13445     {
13446       rtx op0 = gen_reg_rtx (XFmode);
13447       rtx op1 = force_reg (<MODE>mode, operands[1]);
13448
13449       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13450       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13451       DONE;
13452    }
13453 })
13454
13455 (define_insn "fpremxf4_i387"
13456   [(set (match_operand:XF 0 "register_operand" "=f")
13457         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13458                     (match_operand:XF 3 "register_operand" "1")]
13459                    UNSPEC_FPREM_F))
13460    (set (match_operand:XF 1 "register_operand" "=u")
13461         (unspec:XF [(match_dup 2) (match_dup 3)]
13462                    UNSPEC_FPREM_U))
13463    (set (reg:CCFP FPSR_REG)
13464         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13465                      UNSPEC_C2_FLAG))]
13466   "TARGET_USE_FANCY_MATH_387"
13467   "fprem"
13468   [(set_attr "type" "fpspc")
13469    (set_attr "mode" "XF")])
13470
13471 (define_expand "fmodxf3"
13472   [(use (match_operand:XF 0 "register_operand" ""))
13473    (use (match_operand:XF 1 "general_operand" ""))
13474    (use (match_operand:XF 2 "general_operand" ""))]
13475   "TARGET_USE_FANCY_MATH_387"
13476 {
13477   rtx label = gen_label_rtx ();
13478
13479   rtx op1 = gen_reg_rtx (XFmode);
13480   rtx op2 = gen_reg_rtx (XFmode);
13481
13482   emit_move_insn (op2, operands[2]);
13483   emit_move_insn (op1, operands[1]);
13484
13485   emit_label (label);
13486   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13487   ix86_emit_fp_unordered_jump (label);
13488   LABEL_NUSES (label) = 1;
13489
13490   emit_move_insn (operands[0], op1);
13491   DONE;
13492 })
13493
13494 (define_expand "fmod<mode>3"
13495   [(use (match_operand:MODEF 0 "register_operand" ""))
13496    (use (match_operand:MODEF 1 "general_operand" ""))
13497    (use (match_operand:MODEF 2 "general_operand" ""))]
13498   "TARGET_USE_FANCY_MATH_387"
13499 {
13500   rtx (*gen_truncxf) (rtx, rtx);
13501
13502   rtx label = gen_label_rtx ();
13503
13504   rtx op1 = gen_reg_rtx (XFmode);
13505   rtx op2 = gen_reg_rtx (XFmode);
13506
13507   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13508   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13509
13510   emit_label (label);
13511   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13512   ix86_emit_fp_unordered_jump (label);
13513   LABEL_NUSES (label) = 1;
13514
13515   /* Truncate the result properly for strict SSE math.  */
13516   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13517       && !TARGET_MIX_SSE_I387)
13518     gen_truncxf = gen_truncxf<mode>2;
13519   else
13520     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13521
13522   emit_insn (gen_truncxf (operands[0], op1));
13523   DONE;
13524 })
13525
13526 (define_insn "fprem1xf4_i387"
13527   [(set (match_operand:XF 0 "register_operand" "=f")
13528         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13529                     (match_operand:XF 3 "register_operand" "1")]
13530                    UNSPEC_FPREM1_F))
13531    (set (match_operand:XF 1 "register_operand" "=u")
13532         (unspec:XF [(match_dup 2) (match_dup 3)]
13533                    UNSPEC_FPREM1_U))
13534    (set (reg:CCFP FPSR_REG)
13535         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13536                      UNSPEC_C2_FLAG))]
13537   "TARGET_USE_FANCY_MATH_387"
13538   "fprem1"
13539   [(set_attr "type" "fpspc")
13540    (set_attr "mode" "XF")])
13541
13542 (define_expand "remainderxf3"
13543   [(use (match_operand:XF 0 "register_operand" ""))
13544    (use (match_operand:XF 1 "general_operand" ""))
13545    (use (match_operand:XF 2 "general_operand" ""))]
13546   "TARGET_USE_FANCY_MATH_387"
13547 {
13548   rtx label = gen_label_rtx ();
13549
13550   rtx op1 = gen_reg_rtx (XFmode);
13551   rtx op2 = gen_reg_rtx (XFmode);
13552
13553   emit_move_insn (op2, operands[2]);
13554   emit_move_insn (op1, operands[1]);
13555
13556   emit_label (label);
13557   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13558   ix86_emit_fp_unordered_jump (label);
13559   LABEL_NUSES (label) = 1;
13560
13561   emit_move_insn (operands[0], op1);
13562   DONE;
13563 })
13564
13565 (define_expand "remainder<mode>3"
13566   [(use (match_operand:MODEF 0 "register_operand" ""))
13567    (use (match_operand:MODEF 1 "general_operand" ""))
13568    (use (match_operand:MODEF 2 "general_operand" ""))]
13569   "TARGET_USE_FANCY_MATH_387"
13570 {
13571   rtx (*gen_truncxf) (rtx, rtx);
13572
13573   rtx label = gen_label_rtx ();
13574
13575   rtx op1 = gen_reg_rtx (XFmode);
13576   rtx op2 = gen_reg_rtx (XFmode);
13577
13578   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13579   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13580
13581   emit_label (label);
13582
13583   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13584   ix86_emit_fp_unordered_jump (label);
13585   LABEL_NUSES (label) = 1;
13586
13587   /* Truncate the result properly for strict SSE math.  */
13588   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13589       && !TARGET_MIX_SSE_I387)
13590     gen_truncxf = gen_truncxf<mode>2;
13591   else
13592     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13593
13594   emit_insn (gen_truncxf (operands[0], op1));
13595   DONE;
13596 })
13597
13598 (define_insn "*sinxf2_i387"
13599   [(set (match_operand:XF 0 "register_operand" "=f")
13600         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13601   "TARGET_USE_FANCY_MATH_387
13602    && flag_unsafe_math_optimizations"
13603   "fsin"
13604   [(set_attr "type" "fpspc")
13605    (set_attr "mode" "XF")])
13606
13607 (define_insn "*sin_extend<mode>xf2_i387"
13608   [(set (match_operand:XF 0 "register_operand" "=f")
13609         (unspec:XF [(float_extend:XF
13610                       (match_operand:MODEF 1 "register_operand" "0"))]
13611                    UNSPEC_SIN))]
13612   "TARGET_USE_FANCY_MATH_387
13613    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13614        || TARGET_MIX_SSE_I387)
13615    && flag_unsafe_math_optimizations"
13616   "fsin"
13617   [(set_attr "type" "fpspc")
13618    (set_attr "mode" "XF")])
13619
13620 (define_insn "*cosxf2_i387"
13621   [(set (match_operand:XF 0 "register_operand" "=f")
13622         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13623   "TARGET_USE_FANCY_MATH_387
13624    && flag_unsafe_math_optimizations"
13625   "fcos"
13626   [(set_attr "type" "fpspc")
13627    (set_attr "mode" "XF")])
13628
13629 (define_insn "*cos_extend<mode>xf2_i387"
13630   [(set (match_operand:XF 0 "register_operand" "=f")
13631         (unspec:XF [(float_extend:XF
13632                       (match_operand:MODEF 1 "register_operand" "0"))]
13633                    UNSPEC_COS))]
13634   "TARGET_USE_FANCY_MATH_387
13635    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13636        || TARGET_MIX_SSE_I387)
13637    && flag_unsafe_math_optimizations"
13638   "fcos"
13639   [(set_attr "type" "fpspc")
13640    (set_attr "mode" "XF")])
13641
13642 ;; When sincos pattern is defined, sin and cos builtin functions will be
13643 ;; expanded to sincos pattern with one of its outputs left unused.
13644 ;; CSE pass will figure out if two sincos patterns can be combined,
13645 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13646 ;; depending on the unused output.
13647
13648 (define_insn "sincosxf3"
13649   [(set (match_operand:XF 0 "register_operand" "=f")
13650         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13651                    UNSPEC_SINCOS_COS))
13652    (set (match_operand:XF 1 "register_operand" "=u")
13653         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13654   "TARGET_USE_FANCY_MATH_387
13655    && flag_unsafe_math_optimizations"
13656   "fsincos"
13657   [(set_attr "type" "fpspc")
13658    (set_attr "mode" "XF")])
13659
13660 (define_split
13661   [(set (match_operand:XF 0 "register_operand" "")
13662         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13663                    UNSPEC_SINCOS_COS))
13664    (set (match_operand:XF 1 "register_operand" "")
13665         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13666   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13667    && can_create_pseudo_p ()"
13668   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13669
13670 (define_split
13671   [(set (match_operand:XF 0 "register_operand" "")
13672         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13673                    UNSPEC_SINCOS_COS))
13674    (set (match_operand:XF 1 "register_operand" "")
13675         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13676   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13677    && can_create_pseudo_p ()"
13678   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13679
13680 (define_insn "sincos_extend<mode>xf3_i387"
13681   [(set (match_operand:XF 0 "register_operand" "=f")
13682         (unspec:XF [(float_extend:XF
13683                       (match_operand:MODEF 2 "register_operand" "0"))]
13684                    UNSPEC_SINCOS_COS))
13685    (set (match_operand:XF 1 "register_operand" "=u")
13686         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13687   "TARGET_USE_FANCY_MATH_387
13688    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13689        || TARGET_MIX_SSE_I387)
13690    && flag_unsafe_math_optimizations"
13691   "fsincos"
13692   [(set_attr "type" "fpspc")
13693    (set_attr "mode" "XF")])
13694
13695 (define_split
13696   [(set (match_operand:XF 0 "register_operand" "")
13697         (unspec:XF [(float_extend:XF
13698                       (match_operand:MODEF 2 "register_operand" ""))]
13699                    UNSPEC_SINCOS_COS))
13700    (set (match_operand:XF 1 "register_operand" "")
13701         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13702   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13703    && can_create_pseudo_p ()"
13704   [(set (match_dup 1)
13705         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13706
13707 (define_split
13708   [(set (match_operand:XF 0 "register_operand" "")
13709         (unspec:XF [(float_extend:XF
13710                       (match_operand:MODEF 2 "register_operand" ""))]
13711                    UNSPEC_SINCOS_COS))
13712    (set (match_operand:XF 1 "register_operand" "")
13713         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13714   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13715    && can_create_pseudo_p ()"
13716   [(set (match_dup 0)
13717         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13718
13719 (define_expand "sincos<mode>3"
13720   [(use (match_operand:MODEF 0 "register_operand" ""))
13721    (use (match_operand:MODEF 1 "register_operand" ""))
13722    (use (match_operand:MODEF 2 "register_operand" ""))]
13723   "TARGET_USE_FANCY_MATH_387
13724    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13725        || TARGET_MIX_SSE_I387)
13726    && flag_unsafe_math_optimizations"
13727 {
13728   rtx op0 = gen_reg_rtx (XFmode);
13729   rtx op1 = gen_reg_rtx (XFmode);
13730
13731   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13732   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13733   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13734   DONE;
13735 })
13736
13737 (define_insn "fptanxf4_i387"
13738   [(set (match_operand:XF 0 "register_operand" "=f")
13739         (match_operand:XF 3 "const_double_operand" "F"))
13740    (set (match_operand:XF 1 "register_operand" "=u")
13741         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13742                    UNSPEC_TAN))]
13743   "TARGET_USE_FANCY_MATH_387
13744    && flag_unsafe_math_optimizations
13745    && standard_80387_constant_p (operands[3]) == 2"
13746   "fptan"
13747   [(set_attr "type" "fpspc")
13748    (set_attr "mode" "XF")])
13749
13750 (define_insn "fptan_extend<mode>xf4_i387"
13751   [(set (match_operand:MODEF 0 "register_operand" "=f")
13752         (match_operand:MODEF 3 "const_double_operand" "F"))
13753    (set (match_operand:XF 1 "register_operand" "=u")
13754         (unspec:XF [(float_extend:XF
13755                       (match_operand:MODEF 2 "register_operand" "0"))]
13756                    UNSPEC_TAN))]
13757   "TARGET_USE_FANCY_MATH_387
13758    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13759        || TARGET_MIX_SSE_I387)
13760    && flag_unsafe_math_optimizations
13761    && standard_80387_constant_p (operands[3]) == 2"
13762   "fptan"
13763   [(set_attr "type" "fpspc")
13764    (set_attr "mode" "XF")])
13765
13766 (define_expand "tanxf2"
13767   [(use (match_operand:XF 0 "register_operand" ""))
13768    (use (match_operand:XF 1 "register_operand" ""))]
13769   "TARGET_USE_FANCY_MATH_387
13770    && flag_unsafe_math_optimizations"
13771 {
13772   rtx one = gen_reg_rtx (XFmode);
13773   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13774
13775   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13776   DONE;
13777 })
13778
13779 (define_expand "tan<mode>2"
13780   [(use (match_operand:MODEF 0 "register_operand" ""))
13781    (use (match_operand:MODEF 1 "register_operand" ""))]
13782   "TARGET_USE_FANCY_MATH_387
13783    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13784        || TARGET_MIX_SSE_I387)
13785    && flag_unsafe_math_optimizations"
13786 {
13787   rtx op0 = gen_reg_rtx (XFmode);
13788
13789   rtx one = gen_reg_rtx (<MODE>mode);
13790   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13791
13792   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13793                                              operands[1], op2));
13794   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13795   DONE;
13796 })
13797
13798 (define_insn "*fpatanxf3_i387"
13799   [(set (match_operand:XF 0 "register_operand" "=f")
13800         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13801                     (match_operand:XF 2 "register_operand" "u")]
13802                    UNSPEC_FPATAN))
13803    (clobber (match_scratch:XF 3 "=2"))]
13804   "TARGET_USE_FANCY_MATH_387
13805    && flag_unsafe_math_optimizations"
13806   "fpatan"
13807   [(set_attr "type" "fpspc")
13808    (set_attr "mode" "XF")])
13809
13810 (define_insn "fpatan_extend<mode>xf3_i387"
13811   [(set (match_operand:XF 0 "register_operand" "=f")
13812         (unspec:XF [(float_extend:XF
13813                       (match_operand:MODEF 1 "register_operand" "0"))
13814                     (float_extend:XF
13815                       (match_operand:MODEF 2 "register_operand" "u"))]
13816                    UNSPEC_FPATAN))
13817    (clobber (match_scratch:XF 3 "=2"))]
13818   "TARGET_USE_FANCY_MATH_387
13819    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13820        || TARGET_MIX_SSE_I387)
13821    && flag_unsafe_math_optimizations"
13822   "fpatan"
13823   [(set_attr "type" "fpspc")
13824    (set_attr "mode" "XF")])
13825
13826 (define_expand "atan2xf3"
13827   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13828                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
13829                                (match_operand:XF 1 "register_operand" "")]
13830                               UNSPEC_FPATAN))
13831               (clobber (match_scratch:XF 3 ""))])]
13832   "TARGET_USE_FANCY_MATH_387
13833    && flag_unsafe_math_optimizations")
13834
13835 (define_expand "atan2<mode>3"
13836   [(use (match_operand:MODEF 0 "register_operand" ""))
13837    (use (match_operand:MODEF 1 "register_operand" ""))
13838    (use (match_operand:MODEF 2 "register_operand" ""))]
13839   "TARGET_USE_FANCY_MATH_387
13840    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13841        || TARGET_MIX_SSE_I387)
13842    && flag_unsafe_math_optimizations"
13843 {
13844   rtx op0 = gen_reg_rtx (XFmode);
13845
13846   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13847   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13848   DONE;
13849 })
13850
13851 (define_expand "atanxf2"
13852   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13853                    (unspec:XF [(match_dup 2)
13854                                (match_operand:XF 1 "register_operand" "")]
13855                               UNSPEC_FPATAN))
13856               (clobber (match_scratch:XF 3 ""))])]
13857   "TARGET_USE_FANCY_MATH_387
13858    && flag_unsafe_math_optimizations"
13859 {
13860   operands[2] = gen_reg_rtx (XFmode);
13861   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13862 })
13863
13864 (define_expand "atan<mode>2"
13865   [(use (match_operand:MODEF 0 "register_operand" ""))
13866    (use (match_operand:MODEF 1 "register_operand" ""))]
13867   "TARGET_USE_FANCY_MATH_387
13868    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13869        || TARGET_MIX_SSE_I387)
13870    && flag_unsafe_math_optimizations"
13871 {
13872   rtx op0 = gen_reg_rtx (XFmode);
13873
13874   rtx op2 = gen_reg_rtx (<MODE>mode);
13875   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13876
13877   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13878   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13879   DONE;
13880 })
13881
13882 (define_expand "asinxf2"
13883   [(set (match_dup 2)
13884         (mult:XF (match_operand:XF 1 "register_operand" "")
13885                  (match_dup 1)))
13886    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13887    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13888    (parallel [(set (match_operand:XF 0 "register_operand" "")
13889                    (unspec:XF [(match_dup 5) (match_dup 1)]
13890                               UNSPEC_FPATAN))
13891               (clobber (match_scratch:XF 6 ""))])]
13892   "TARGET_USE_FANCY_MATH_387
13893    && flag_unsafe_math_optimizations"
13894 {
13895   int i;
13896
13897   if (optimize_insn_for_size_p ())
13898     FAIL;
13899
13900   for (i = 2; i < 6; i++)
13901     operands[i] = gen_reg_rtx (XFmode);
13902
13903   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13904 })
13905
13906 (define_expand "asin<mode>2"
13907   [(use (match_operand:MODEF 0 "register_operand" ""))
13908    (use (match_operand:MODEF 1 "general_operand" ""))]
13909  "TARGET_USE_FANCY_MATH_387
13910    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13911        || TARGET_MIX_SSE_I387)
13912    && flag_unsafe_math_optimizations"
13913 {
13914   rtx op0 = gen_reg_rtx (XFmode);
13915   rtx op1 = gen_reg_rtx (XFmode);
13916
13917   if (optimize_insn_for_size_p ())
13918     FAIL;
13919
13920   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13921   emit_insn (gen_asinxf2 (op0, op1));
13922   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13923   DONE;
13924 })
13925
13926 (define_expand "acosxf2"
13927   [(set (match_dup 2)
13928         (mult:XF (match_operand:XF 1 "register_operand" "")
13929                  (match_dup 1)))
13930    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13931    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13932    (parallel [(set (match_operand:XF 0 "register_operand" "")
13933                    (unspec:XF [(match_dup 1) (match_dup 5)]
13934                               UNSPEC_FPATAN))
13935               (clobber (match_scratch:XF 6 ""))])]
13936   "TARGET_USE_FANCY_MATH_387
13937    && flag_unsafe_math_optimizations"
13938 {
13939   int i;
13940
13941   if (optimize_insn_for_size_p ())
13942     FAIL;
13943
13944   for (i = 2; i < 6; i++)
13945     operands[i] = gen_reg_rtx (XFmode);
13946
13947   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13948 })
13949
13950 (define_expand "acos<mode>2"
13951   [(use (match_operand:MODEF 0 "register_operand" ""))
13952    (use (match_operand:MODEF 1 "general_operand" ""))]
13953  "TARGET_USE_FANCY_MATH_387
13954    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13955        || TARGET_MIX_SSE_I387)
13956    && flag_unsafe_math_optimizations"
13957 {
13958   rtx op0 = gen_reg_rtx (XFmode);
13959   rtx op1 = gen_reg_rtx (XFmode);
13960
13961   if (optimize_insn_for_size_p ())
13962     FAIL;
13963
13964   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13965   emit_insn (gen_acosxf2 (op0, op1));
13966   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13967   DONE;
13968 })
13969
13970 (define_insn "fyl2xxf3_i387"
13971   [(set (match_operand:XF 0 "register_operand" "=f")
13972         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13973                     (match_operand:XF 2 "register_operand" "u")]
13974                    UNSPEC_FYL2X))
13975    (clobber (match_scratch:XF 3 "=2"))]
13976   "TARGET_USE_FANCY_MATH_387
13977    && flag_unsafe_math_optimizations"
13978   "fyl2x"
13979   [(set_attr "type" "fpspc")
13980    (set_attr "mode" "XF")])
13981
13982 (define_insn "fyl2x_extend<mode>xf3_i387"
13983   [(set (match_operand:XF 0 "register_operand" "=f")
13984         (unspec:XF [(float_extend:XF
13985                       (match_operand:MODEF 1 "register_operand" "0"))
13986                     (match_operand:XF 2 "register_operand" "u")]
13987                    UNSPEC_FYL2X))
13988    (clobber (match_scratch:XF 3 "=2"))]
13989   "TARGET_USE_FANCY_MATH_387
13990    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13991        || TARGET_MIX_SSE_I387)
13992    && flag_unsafe_math_optimizations"
13993   "fyl2x"
13994   [(set_attr "type" "fpspc")
13995    (set_attr "mode" "XF")])
13996
13997 (define_expand "logxf2"
13998   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13999                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14000                                (match_dup 2)] UNSPEC_FYL2X))
14001               (clobber (match_scratch:XF 3 ""))])]
14002   "TARGET_USE_FANCY_MATH_387
14003    && flag_unsafe_math_optimizations"
14004 {
14005   operands[2] = gen_reg_rtx (XFmode);
14006   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14007 })
14008
14009 (define_expand "log<mode>2"
14010   [(use (match_operand:MODEF 0 "register_operand" ""))
14011    (use (match_operand:MODEF 1 "register_operand" ""))]
14012   "TARGET_USE_FANCY_MATH_387
14013    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14014        || TARGET_MIX_SSE_I387)
14015    && flag_unsafe_math_optimizations"
14016 {
14017   rtx op0 = gen_reg_rtx (XFmode);
14018
14019   rtx op2 = gen_reg_rtx (XFmode);
14020   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14021
14022   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14023   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14024   DONE;
14025 })
14026
14027 (define_expand "log10xf2"
14028   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14029                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14030                                (match_dup 2)] UNSPEC_FYL2X))
14031               (clobber (match_scratch:XF 3 ""))])]
14032   "TARGET_USE_FANCY_MATH_387
14033    && flag_unsafe_math_optimizations"
14034 {
14035   operands[2] = gen_reg_rtx (XFmode);
14036   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14037 })
14038
14039 (define_expand "log10<mode>2"
14040   [(use (match_operand:MODEF 0 "register_operand" ""))
14041    (use (match_operand:MODEF 1 "register_operand" ""))]
14042   "TARGET_USE_FANCY_MATH_387
14043    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14044        || TARGET_MIX_SSE_I387)
14045    && flag_unsafe_math_optimizations"
14046 {
14047   rtx op0 = gen_reg_rtx (XFmode);
14048
14049   rtx op2 = gen_reg_rtx (XFmode);
14050   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14051
14052   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14053   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14054   DONE;
14055 })
14056
14057 (define_expand "log2xf2"
14058   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14059                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14060                                (match_dup 2)] UNSPEC_FYL2X))
14061               (clobber (match_scratch:XF 3 ""))])]
14062   "TARGET_USE_FANCY_MATH_387
14063    && flag_unsafe_math_optimizations"
14064 {
14065   operands[2] = gen_reg_rtx (XFmode);
14066   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14067 })
14068
14069 (define_expand "log2<mode>2"
14070   [(use (match_operand:MODEF 0 "register_operand" ""))
14071    (use (match_operand:MODEF 1 "register_operand" ""))]
14072   "TARGET_USE_FANCY_MATH_387
14073    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14074        || TARGET_MIX_SSE_I387)
14075    && flag_unsafe_math_optimizations"
14076 {
14077   rtx op0 = gen_reg_rtx (XFmode);
14078
14079   rtx op2 = gen_reg_rtx (XFmode);
14080   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14081
14082   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14083   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14084   DONE;
14085 })
14086
14087 (define_insn "fyl2xp1xf3_i387"
14088   [(set (match_operand:XF 0 "register_operand" "=f")
14089         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14090                     (match_operand:XF 2 "register_operand" "u")]
14091                    UNSPEC_FYL2XP1))
14092    (clobber (match_scratch:XF 3 "=2"))]
14093   "TARGET_USE_FANCY_MATH_387
14094    && flag_unsafe_math_optimizations"
14095   "fyl2xp1"
14096   [(set_attr "type" "fpspc")
14097    (set_attr "mode" "XF")])
14098
14099 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14100   [(set (match_operand:XF 0 "register_operand" "=f")
14101         (unspec:XF [(float_extend:XF
14102                       (match_operand:MODEF 1 "register_operand" "0"))
14103                     (match_operand:XF 2 "register_operand" "u")]
14104                    UNSPEC_FYL2XP1))
14105    (clobber (match_scratch:XF 3 "=2"))]
14106   "TARGET_USE_FANCY_MATH_387
14107    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14108        || TARGET_MIX_SSE_I387)
14109    && flag_unsafe_math_optimizations"
14110   "fyl2xp1"
14111   [(set_attr "type" "fpspc")
14112    (set_attr "mode" "XF")])
14113
14114 (define_expand "log1pxf2"
14115   [(use (match_operand:XF 0 "register_operand" ""))
14116    (use (match_operand:XF 1 "register_operand" ""))]
14117   "TARGET_USE_FANCY_MATH_387
14118    && flag_unsafe_math_optimizations"
14119 {
14120   if (optimize_insn_for_size_p ())
14121     FAIL;
14122
14123   ix86_emit_i387_log1p (operands[0], operands[1]);
14124   DONE;
14125 })
14126
14127 (define_expand "log1p<mode>2"
14128   [(use (match_operand:MODEF 0 "register_operand" ""))
14129    (use (match_operand:MODEF 1 "register_operand" ""))]
14130   "TARGET_USE_FANCY_MATH_387
14131    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14132        || TARGET_MIX_SSE_I387)
14133    && flag_unsafe_math_optimizations"
14134 {
14135   rtx op0;
14136
14137   if (optimize_insn_for_size_p ())
14138     FAIL;
14139
14140   op0 = gen_reg_rtx (XFmode);
14141
14142   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14143
14144   ix86_emit_i387_log1p (op0, operands[1]);
14145   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14146   DONE;
14147 })
14148
14149 (define_insn "fxtractxf3_i387"
14150   [(set (match_operand:XF 0 "register_operand" "=f")
14151         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14152                    UNSPEC_XTRACT_FRACT))
14153    (set (match_operand:XF 1 "register_operand" "=u")
14154         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14155   "TARGET_USE_FANCY_MATH_387
14156    && flag_unsafe_math_optimizations"
14157   "fxtract"
14158   [(set_attr "type" "fpspc")
14159    (set_attr "mode" "XF")])
14160
14161 (define_insn "fxtract_extend<mode>xf3_i387"
14162   [(set (match_operand:XF 0 "register_operand" "=f")
14163         (unspec:XF [(float_extend:XF
14164                       (match_operand:MODEF 2 "register_operand" "0"))]
14165                    UNSPEC_XTRACT_FRACT))
14166    (set (match_operand:XF 1 "register_operand" "=u")
14167         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14168   "TARGET_USE_FANCY_MATH_387
14169    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14170        || TARGET_MIX_SSE_I387)
14171    && flag_unsafe_math_optimizations"
14172   "fxtract"
14173   [(set_attr "type" "fpspc")
14174    (set_attr "mode" "XF")])
14175
14176 (define_expand "logbxf2"
14177   [(parallel [(set (match_dup 2)
14178                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14179                               UNSPEC_XTRACT_FRACT))
14180               (set (match_operand:XF 0 "register_operand" "")
14181                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14182   "TARGET_USE_FANCY_MATH_387
14183    && flag_unsafe_math_optimizations"
14184   "operands[2] = gen_reg_rtx (XFmode);")
14185
14186 (define_expand "logb<mode>2"
14187   [(use (match_operand:MODEF 0 "register_operand" ""))
14188    (use (match_operand:MODEF 1 "register_operand" ""))]
14189   "TARGET_USE_FANCY_MATH_387
14190    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14191        || TARGET_MIX_SSE_I387)
14192    && flag_unsafe_math_optimizations"
14193 {
14194   rtx op0 = gen_reg_rtx (XFmode);
14195   rtx op1 = gen_reg_rtx (XFmode);
14196
14197   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14198   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14199   DONE;
14200 })
14201
14202 (define_expand "ilogbxf2"
14203   [(use (match_operand:SI 0 "register_operand" ""))
14204    (use (match_operand:XF 1 "register_operand" ""))]
14205   "TARGET_USE_FANCY_MATH_387
14206    && flag_unsafe_math_optimizations"
14207 {
14208   rtx op0, op1;
14209
14210   if (optimize_insn_for_size_p ())
14211     FAIL;
14212
14213   op0 = gen_reg_rtx (XFmode);
14214   op1 = gen_reg_rtx (XFmode);
14215
14216   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14217   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14218   DONE;
14219 })
14220
14221 (define_expand "ilogb<mode>2"
14222   [(use (match_operand:SI 0 "register_operand" ""))
14223    (use (match_operand:MODEF 1 "register_operand" ""))]
14224   "TARGET_USE_FANCY_MATH_387
14225    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14226        || TARGET_MIX_SSE_I387)
14227    && flag_unsafe_math_optimizations"
14228 {
14229   rtx op0, op1;
14230
14231   if (optimize_insn_for_size_p ())
14232     FAIL;
14233
14234   op0 = gen_reg_rtx (XFmode);
14235   op1 = gen_reg_rtx (XFmode);
14236
14237   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14238   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14239   DONE;
14240 })
14241
14242 (define_insn "*f2xm1xf2_i387"
14243   [(set (match_operand:XF 0 "register_operand" "=f")
14244         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14245                    UNSPEC_F2XM1))]
14246   "TARGET_USE_FANCY_MATH_387
14247    && flag_unsafe_math_optimizations"
14248   "f2xm1"
14249   [(set_attr "type" "fpspc")
14250    (set_attr "mode" "XF")])
14251
14252 (define_insn "*fscalexf4_i387"
14253   [(set (match_operand:XF 0 "register_operand" "=f")
14254         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14255                     (match_operand:XF 3 "register_operand" "1")]
14256                    UNSPEC_FSCALE_FRACT))
14257    (set (match_operand:XF 1 "register_operand" "=u")
14258         (unspec:XF [(match_dup 2) (match_dup 3)]
14259                    UNSPEC_FSCALE_EXP))]
14260   "TARGET_USE_FANCY_MATH_387
14261    && flag_unsafe_math_optimizations"
14262   "fscale"
14263   [(set_attr "type" "fpspc")
14264    (set_attr "mode" "XF")])
14265
14266 (define_expand "expNcorexf3"
14267   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14268                                (match_operand:XF 2 "register_operand" "")))
14269    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14270    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14271    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14272    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14273    (parallel [(set (match_operand:XF 0 "register_operand" "")
14274                    (unspec:XF [(match_dup 8) (match_dup 4)]
14275                               UNSPEC_FSCALE_FRACT))
14276               (set (match_dup 9)
14277                    (unspec:XF [(match_dup 8) (match_dup 4)]
14278                               UNSPEC_FSCALE_EXP))])]
14279   "TARGET_USE_FANCY_MATH_387
14280    && flag_unsafe_math_optimizations"
14281 {
14282   int i;
14283
14284   if (optimize_insn_for_size_p ())
14285     FAIL;
14286
14287   for (i = 3; i < 10; i++)
14288     operands[i] = gen_reg_rtx (XFmode);
14289
14290   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14291 })
14292
14293 (define_expand "expxf2"
14294   [(use (match_operand:XF 0 "register_operand" ""))
14295    (use (match_operand:XF 1 "register_operand" ""))]
14296   "TARGET_USE_FANCY_MATH_387
14297    && flag_unsafe_math_optimizations"
14298 {
14299   rtx op2;
14300
14301   if (optimize_insn_for_size_p ())
14302     FAIL;
14303
14304   op2 = gen_reg_rtx (XFmode);
14305   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14306
14307   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14308   DONE;
14309 })
14310
14311 (define_expand "exp<mode>2"
14312   [(use (match_operand:MODEF 0 "register_operand" ""))
14313    (use (match_operand:MODEF 1 "general_operand" ""))]
14314  "TARGET_USE_FANCY_MATH_387
14315    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14316        || TARGET_MIX_SSE_I387)
14317    && flag_unsafe_math_optimizations"
14318 {
14319   rtx op0, op1;
14320
14321   if (optimize_insn_for_size_p ())
14322     FAIL;
14323
14324   op0 = gen_reg_rtx (XFmode);
14325   op1 = gen_reg_rtx (XFmode);
14326
14327   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14328   emit_insn (gen_expxf2 (op0, op1));
14329   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14330   DONE;
14331 })
14332
14333 (define_expand "exp10xf2"
14334   [(use (match_operand:XF 0 "register_operand" ""))
14335    (use (match_operand:XF 1 "register_operand" ""))]
14336   "TARGET_USE_FANCY_MATH_387
14337    && flag_unsafe_math_optimizations"
14338 {
14339   rtx op2;
14340
14341   if (optimize_insn_for_size_p ())
14342     FAIL;
14343
14344   op2 = gen_reg_rtx (XFmode);
14345   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14346
14347   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14348   DONE;
14349 })
14350
14351 (define_expand "exp10<mode>2"
14352   [(use (match_operand:MODEF 0 "register_operand" ""))
14353    (use (match_operand:MODEF 1 "general_operand" ""))]
14354  "TARGET_USE_FANCY_MATH_387
14355    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14356        || TARGET_MIX_SSE_I387)
14357    && flag_unsafe_math_optimizations"
14358 {
14359   rtx op0, op1;
14360
14361   if (optimize_insn_for_size_p ())
14362     FAIL;
14363
14364   op0 = gen_reg_rtx (XFmode);
14365   op1 = gen_reg_rtx (XFmode);
14366
14367   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14368   emit_insn (gen_exp10xf2 (op0, op1));
14369   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14370   DONE;
14371 })
14372
14373 (define_expand "exp2xf2"
14374   [(use (match_operand:XF 0 "register_operand" ""))
14375    (use (match_operand:XF 1 "register_operand" ""))]
14376   "TARGET_USE_FANCY_MATH_387
14377    && flag_unsafe_math_optimizations"
14378 {
14379   rtx op2;
14380
14381   if (optimize_insn_for_size_p ())
14382     FAIL;
14383
14384   op2 = gen_reg_rtx (XFmode);
14385   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14386
14387   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14388   DONE;
14389 })
14390
14391 (define_expand "exp2<mode>2"
14392   [(use (match_operand:MODEF 0 "register_operand" ""))
14393    (use (match_operand:MODEF 1 "general_operand" ""))]
14394  "TARGET_USE_FANCY_MATH_387
14395    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14396        || TARGET_MIX_SSE_I387)
14397    && flag_unsafe_math_optimizations"
14398 {
14399   rtx op0, op1;
14400
14401   if (optimize_insn_for_size_p ())
14402     FAIL;
14403
14404   op0 = gen_reg_rtx (XFmode);
14405   op1 = gen_reg_rtx (XFmode);
14406
14407   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14408   emit_insn (gen_exp2xf2 (op0, op1));
14409   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14410   DONE;
14411 })
14412
14413 (define_expand "expm1xf2"
14414   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14415                                (match_dup 2)))
14416    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14417    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14418    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14419    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14420    (parallel [(set (match_dup 7)
14421                    (unspec:XF [(match_dup 6) (match_dup 4)]
14422                               UNSPEC_FSCALE_FRACT))
14423               (set (match_dup 8)
14424                    (unspec:XF [(match_dup 6) (match_dup 4)]
14425                               UNSPEC_FSCALE_EXP))])
14426    (parallel [(set (match_dup 10)
14427                    (unspec:XF [(match_dup 9) (match_dup 8)]
14428                               UNSPEC_FSCALE_FRACT))
14429               (set (match_dup 11)
14430                    (unspec:XF [(match_dup 9) (match_dup 8)]
14431                               UNSPEC_FSCALE_EXP))])
14432    (set (match_dup 12) (minus:XF (match_dup 10)
14433                                  (float_extend:XF (match_dup 13))))
14434    (set (match_operand:XF 0 "register_operand" "")
14435         (plus:XF (match_dup 12) (match_dup 7)))]
14436   "TARGET_USE_FANCY_MATH_387
14437    && flag_unsafe_math_optimizations"
14438 {
14439   int i;
14440
14441   if (optimize_insn_for_size_p ())
14442     FAIL;
14443
14444   for (i = 2; i < 13; i++)
14445     operands[i] = gen_reg_rtx (XFmode);
14446
14447   operands[13]
14448     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14449
14450   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14451 })
14452
14453 (define_expand "expm1<mode>2"
14454   [(use (match_operand:MODEF 0 "register_operand" ""))
14455    (use (match_operand:MODEF 1 "general_operand" ""))]
14456  "TARGET_USE_FANCY_MATH_387
14457    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14458        || TARGET_MIX_SSE_I387)
14459    && flag_unsafe_math_optimizations"
14460 {
14461   rtx op0, op1;
14462
14463   if (optimize_insn_for_size_p ())
14464     FAIL;
14465
14466   op0 = gen_reg_rtx (XFmode);
14467   op1 = gen_reg_rtx (XFmode);
14468
14469   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14470   emit_insn (gen_expm1xf2 (op0, op1));
14471   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14472   DONE;
14473 })
14474
14475 (define_expand "ldexpxf3"
14476   [(set (match_dup 3)
14477         (float:XF (match_operand:SI 2 "register_operand" "")))
14478    (parallel [(set (match_operand:XF 0 " register_operand" "")
14479                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14480                                (match_dup 3)]
14481                               UNSPEC_FSCALE_FRACT))
14482               (set (match_dup 4)
14483                    (unspec:XF [(match_dup 1) (match_dup 3)]
14484                               UNSPEC_FSCALE_EXP))])]
14485   "TARGET_USE_FANCY_MATH_387
14486    && flag_unsafe_math_optimizations"
14487 {
14488   if (optimize_insn_for_size_p ())
14489     FAIL;
14490
14491   operands[3] = gen_reg_rtx (XFmode);
14492   operands[4] = gen_reg_rtx (XFmode);
14493 })
14494
14495 (define_expand "ldexp<mode>3"
14496   [(use (match_operand:MODEF 0 "register_operand" ""))
14497    (use (match_operand:MODEF 1 "general_operand" ""))
14498    (use (match_operand:SI 2 "register_operand" ""))]
14499  "TARGET_USE_FANCY_MATH_387
14500    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14501        || TARGET_MIX_SSE_I387)
14502    && flag_unsafe_math_optimizations"
14503 {
14504   rtx op0, op1;
14505
14506   if (optimize_insn_for_size_p ())
14507     FAIL;
14508
14509   op0 = gen_reg_rtx (XFmode);
14510   op1 = gen_reg_rtx (XFmode);
14511
14512   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14513   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14514   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14515   DONE;
14516 })
14517
14518 (define_expand "scalbxf3"
14519   [(parallel [(set (match_operand:XF 0 " register_operand" "")
14520                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14521                                (match_operand:XF 2 "register_operand" "")]
14522                               UNSPEC_FSCALE_FRACT))
14523               (set (match_dup 3)
14524                    (unspec:XF [(match_dup 1) (match_dup 2)]
14525                               UNSPEC_FSCALE_EXP))])]
14526   "TARGET_USE_FANCY_MATH_387
14527    && flag_unsafe_math_optimizations"
14528 {
14529   if (optimize_insn_for_size_p ())
14530     FAIL;
14531
14532   operands[3] = gen_reg_rtx (XFmode);
14533 })
14534
14535 (define_expand "scalb<mode>3"
14536   [(use (match_operand:MODEF 0 "register_operand" ""))
14537    (use (match_operand:MODEF 1 "general_operand" ""))
14538    (use (match_operand:MODEF 2 "general_operand" ""))]
14539  "TARGET_USE_FANCY_MATH_387
14540    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14541        || TARGET_MIX_SSE_I387)
14542    && flag_unsafe_math_optimizations"
14543 {
14544   rtx op0, op1, op2;
14545
14546   if (optimize_insn_for_size_p ())
14547     FAIL;
14548
14549   op0 = gen_reg_rtx (XFmode);
14550   op1 = gen_reg_rtx (XFmode);
14551   op2 = gen_reg_rtx (XFmode);
14552
14553   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14554   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14555   emit_insn (gen_scalbxf3 (op0, op1, op2));
14556   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14557   DONE;
14558 })
14559
14560 (define_expand "significandxf2"
14561   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14562                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14563                               UNSPEC_XTRACT_FRACT))
14564               (set (match_dup 2)
14565                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14566   "TARGET_USE_FANCY_MATH_387
14567    && flag_unsafe_math_optimizations"
14568   "operands[2] = gen_reg_rtx (XFmode);")
14569
14570 (define_expand "significand<mode>2"
14571   [(use (match_operand:MODEF 0 "register_operand" ""))
14572    (use (match_operand:MODEF 1 "register_operand" ""))]
14573   "TARGET_USE_FANCY_MATH_387
14574    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14575        || TARGET_MIX_SSE_I387)
14576    && flag_unsafe_math_optimizations"
14577 {
14578   rtx op0 = gen_reg_rtx (XFmode);
14579   rtx op1 = gen_reg_rtx (XFmode);
14580
14581   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14582   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14583   DONE;
14584 })
14585 \f
14586
14587 (define_insn "sse4_1_round<mode>2"
14588   [(set (match_operand:MODEF 0 "register_operand" "=x")
14589         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14590                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14591                       UNSPEC_ROUND))]
14592   "TARGET_ROUND"
14593   "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14594   [(set_attr "type" "ssecvt")
14595    (set_attr "prefix_extra" "1")
14596    (set_attr "prefix" "maybe_vex")
14597    (set_attr "mode" "<MODE>")])
14598
14599 (define_insn "rintxf2"
14600   [(set (match_operand:XF 0 "register_operand" "=f")
14601         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14602                    UNSPEC_FRNDINT))]
14603   "TARGET_USE_FANCY_MATH_387
14604    && flag_unsafe_math_optimizations"
14605   "frndint"
14606   [(set_attr "type" "fpspc")
14607    (set_attr "mode" "XF")])
14608
14609 (define_expand "rint<mode>2"
14610   [(use (match_operand:MODEF 0 "register_operand" ""))
14611    (use (match_operand:MODEF 1 "register_operand" ""))]
14612   "(TARGET_USE_FANCY_MATH_387
14613     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14614         || TARGET_MIX_SSE_I387)
14615     && flag_unsafe_math_optimizations)
14616    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14617        && !flag_trapping_math)"
14618 {
14619   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14620       && !flag_trapping_math)
14621     {
14622       if (TARGET_ROUND)
14623         emit_insn (gen_sse4_1_round<mode>2
14624                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14625       else if (optimize_insn_for_size_p ())
14626         FAIL;
14627       else
14628         ix86_expand_rint (operands[0], operands[1]);
14629     }
14630   else
14631     {
14632       rtx op0 = gen_reg_rtx (XFmode);
14633       rtx op1 = gen_reg_rtx (XFmode);
14634
14635       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14636       emit_insn (gen_rintxf2 (op0, op1));
14637
14638       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14639     }
14640   DONE;
14641 })
14642
14643 (define_expand "round<mode>2"
14644   [(match_operand:X87MODEF 0 "register_operand" "")
14645    (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14646   "(TARGET_USE_FANCY_MATH_387
14647     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14648         || TARGET_MIX_SSE_I387)
14649     && flag_unsafe_math_optimizations)
14650    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14651        && !flag_trapping_math && !flag_rounding_math)"
14652 {
14653   if (optimize_insn_for_size_p ())
14654     FAIL;
14655
14656   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14657       && !flag_trapping_math && !flag_rounding_math)
14658     {
14659       if (TARGET_ROUND)
14660         {
14661           operands[1] = force_reg (<MODE>mode, operands[1]);
14662           ix86_expand_round_sse4 (operands[0], operands[1]);
14663         }
14664       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14665         ix86_expand_round (operands[0], operands[1]);
14666       else
14667         ix86_expand_rounddf_32 (operands[0], operands[1]);
14668     }
14669   else
14670     {
14671       operands[1] = force_reg (<MODE>mode, operands[1]);
14672       ix86_emit_i387_round (operands[0], operands[1]);
14673     }
14674   DONE;
14675 })
14676
14677 (define_insn_and_split "*fistdi2_1"
14678   [(set (match_operand:DI 0 "nonimmediate_operand" "")
14679         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14680                    UNSPEC_FIST))]
14681   "TARGET_USE_FANCY_MATH_387
14682    && can_create_pseudo_p ()"
14683   "#"
14684   "&& 1"
14685   [(const_int 0)]
14686 {
14687   if (memory_operand (operands[0], VOIDmode))
14688     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14689   else
14690     {
14691       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14692       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14693                                          operands[2]));
14694     }
14695   DONE;
14696 }
14697   [(set_attr "type" "fpspc")
14698    (set_attr "mode" "DI")])
14699
14700 (define_insn "fistdi2"
14701   [(set (match_operand:DI 0 "memory_operand" "=m")
14702         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14703                    UNSPEC_FIST))
14704    (clobber (match_scratch:XF 2 "=&1f"))]
14705   "TARGET_USE_FANCY_MATH_387"
14706   "* return output_fix_trunc (insn, operands, false);"
14707   [(set_attr "type" "fpspc")
14708    (set_attr "mode" "DI")])
14709
14710 (define_insn "fistdi2_with_temp"
14711   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14712         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14713                    UNSPEC_FIST))
14714    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14715    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14716   "TARGET_USE_FANCY_MATH_387"
14717   "#"
14718   [(set_attr "type" "fpspc")
14719    (set_attr "mode" "DI")])
14720
14721 (define_split
14722   [(set (match_operand:DI 0 "register_operand" "")
14723         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14724                    UNSPEC_FIST))
14725    (clobber (match_operand:DI 2 "memory_operand" ""))
14726    (clobber (match_scratch 3 ""))]
14727   "reload_completed"
14728   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14729               (clobber (match_dup 3))])
14730    (set (match_dup 0) (match_dup 2))])
14731
14732 (define_split
14733   [(set (match_operand:DI 0 "memory_operand" "")
14734         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14735                    UNSPEC_FIST))
14736    (clobber (match_operand:DI 2 "memory_operand" ""))
14737    (clobber (match_scratch 3 ""))]
14738   "reload_completed"
14739   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14740               (clobber (match_dup 3))])])
14741
14742 (define_insn_and_split "*fist<mode>2_1"
14743   [(set (match_operand:SWI24 0 "register_operand" "")
14744         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14745                       UNSPEC_FIST))]
14746   "TARGET_USE_FANCY_MATH_387
14747    && can_create_pseudo_p ()"
14748   "#"
14749   "&& 1"
14750   [(const_int 0)]
14751 {
14752   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14753   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14754                                         operands[2]));
14755   DONE;
14756 }
14757   [(set_attr "type" "fpspc")
14758    (set_attr "mode" "<MODE>")])
14759
14760 (define_insn "fist<mode>2"
14761   [(set (match_operand:SWI24 0 "memory_operand" "=m")
14762         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14763                       UNSPEC_FIST))]
14764   "TARGET_USE_FANCY_MATH_387"
14765   "* return output_fix_trunc (insn, operands, false);"
14766   [(set_attr "type" "fpspc")
14767    (set_attr "mode" "<MODE>")])
14768
14769 (define_insn "fist<mode>2_with_temp"
14770   [(set (match_operand:SWI24 0 "register_operand" "=r")
14771         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14772                       UNSPEC_FIST))
14773    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14774   "TARGET_USE_FANCY_MATH_387"
14775   "#"
14776   [(set_attr "type" "fpspc")
14777    (set_attr "mode" "<MODE>")])
14778
14779 (define_split
14780   [(set (match_operand:SWI24 0 "register_operand" "")
14781         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14782                       UNSPEC_FIST))
14783    (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14784   "reload_completed"
14785   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14786    (set (match_dup 0) (match_dup 2))])
14787
14788 (define_split
14789   [(set (match_operand:SWI24 0 "memory_operand" "")
14790         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14791                       UNSPEC_FIST))
14792    (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14793   "reload_completed"
14794   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14795
14796 (define_expand "lrintxf<mode>2"
14797   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14798      (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14799                      UNSPEC_FIST))]
14800   "TARGET_USE_FANCY_MATH_387")
14801
14802 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14803   [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14804      (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14805                         UNSPEC_FIX_NOTRUNC))]
14806   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14807    && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14808
14809 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14810   [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14811    (match_operand:X87MODEF 1 "register_operand" "")]
14812   "(TARGET_USE_FANCY_MATH_387
14813     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14814         || TARGET_MIX_SSE_I387)
14815     && flag_unsafe_math_optimizations)
14816    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14817        && <SWI248x:MODE>mode != HImode 
14818        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14819        && !flag_trapping_math && !flag_rounding_math)"
14820 {
14821   if (optimize_insn_for_size_p ())
14822     FAIL;
14823
14824   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14825       && <SWI248x:MODE>mode != HImode
14826       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14827       && !flag_trapping_math && !flag_rounding_math)
14828     ix86_expand_lround (operands[0], operands[1]);
14829   else
14830     ix86_emit_i387_round (operands[0], operands[1]);
14831   DONE;
14832 })
14833
14834 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14835 (define_insn_and_split "frndintxf2_floor"
14836   [(set (match_operand:XF 0 "register_operand" "")
14837         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14838          UNSPEC_FRNDINT_FLOOR))
14839    (clobber (reg:CC FLAGS_REG))]
14840   "TARGET_USE_FANCY_MATH_387
14841    && flag_unsafe_math_optimizations
14842    && can_create_pseudo_p ()"
14843   "#"
14844   "&& 1"
14845   [(const_int 0)]
14846 {
14847   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14848
14849   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14850   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14851
14852   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14853                                         operands[2], operands[3]));
14854   DONE;
14855 }
14856   [(set_attr "type" "frndint")
14857    (set_attr "i387_cw" "floor")
14858    (set_attr "mode" "XF")])
14859
14860 (define_insn "frndintxf2_floor_i387"
14861   [(set (match_operand:XF 0 "register_operand" "=f")
14862         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14863          UNSPEC_FRNDINT_FLOOR))
14864    (use (match_operand:HI 2 "memory_operand" "m"))
14865    (use (match_operand:HI 3 "memory_operand" "m"))]
14866   "TARGET_USE_FANCY_MATH_387
14867    && flag_unsafe_math_optimizations"
14868   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14869   [(set_attr "type" "frndint")
14870    (set_attr "i387_cw" "floor")
14871    (set_attr "mode" "XF")])
14872
14873 (define_expand "floorxf2"
14874   [(use (match_operand:XF 0 "register_operand" ""))
14875    (use (match_operand:XF 1 "register_operand" ""))]
14876   "TARGET_USE_FANCY_MATH_387
14877    && flag_unsafe_math_optimizations"
14878 {
14879   if (optimize_insn_for_size_p ())
14880     FAIL;
14881   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14882   DONE;
14883 })
14884
14885 (define_expand "floor<mode>2"
14886   [(use (match_operand:MODEF 0 "register_operand" ""))
14887    (use (match_operand:MODEF 1 "register_operand" ""))]
14888   "(TARGET_USE_FANCY_MATH_387
14889     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14890         || TARGET_MIX_SSE_I387)
14891     && flag_unsafe_math_optimizations)
14892    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14893        && !flag_trapping_math)"
14894 {
14895   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14896       && !flag_trapping_math)
14897     {
14898       if (TARGET_ROUND)
14899         emit_insn (gen_sse4_1_round<mode>2
14900                    (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14901       else if (optimize_insn_for_size_p ())
14902         FAIL;
14903       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14904         ix86_expand_floorceil (operands[0], operands[1], true);
14905       else
14906         ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14907     }
14908   else
14909     {
14910       rtx op0, op1;
14911
14912       if (optimize_insn_for_size_p ())
14913         FAIL;
14914
14915       op0 = gen_reg_rtx (XFmode);
14916       op1 = gen_reg_rtx (XFmode);
14917       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14918       emit_insn (gen_frndintxf2_floor (op0, op1));
14919
14920       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14921     }
14922   DONE;
14923 })
14924
14925 (define_insn_and_split "*fist<mode>2_floor_1"
14926   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14927         (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14928                         UNSPEC_FIST_FLOOR))
14929    (clobber (reg:CC FLAGS_REG))]
14930   "TARGET_USE_FANCY_MATH_387
14931    && flag_unsafe_math_optimizations
14932    && can_create_pseudo_p ()"
14933   "#"
14934   "&& 1"
14935   [(const_int 0)]
14936 {
14937   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14938
14939   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14940   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14941   if (memory_operand (operands[0], VOIDmode))
14942     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14943                                       operands[2], operands[3]));
14944   else
14945     {
14946       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14947       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14948                                                   operands[2], operands[3],
14949                                                   operands[4]));
14950     }
14951   DONE;
14952 }
14953   [(set_attr "type" "fistp")
14954    (set_attr "i387_cw" "floor")
14955    (set_attr "mode" "<MODE>")])
14956
14957 (define_insn "fistdi2_floor"
14958   [(set (match_operand:DI 0 "memory_operand" "=m")
14959         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14960                    UNSPEC_FIST_FLOOR))
14961    (use (match_operand:HI 2 "memory_operand" "m"))
14962    (use (match_operand:HI 3 "memory_operand" "m"))
14963    (clobber (match_scratch:XF 4 "=&1f"))]
14964   "TARGET_USE_FANCY_MATH_387
14965    && flag_unsafe_math_optimizations"
14966   "* return output_fix_trunc (insn, operands, false);"
14967   [(set_attr "type" "fistp")
14968    (set_attr "i387_cw" "floor")
14969    (set_attr "mode" "DI")])
14970
14971 (define_insn "fistdi2_floor_with_temp"
14972   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14973         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14974                    UNSPEC_FIST_FLOOR))
14975    (use (match_operand:HI 2 "memory_operand" "m,m"))
14976    (use (match_operand:HI 3 "memory_operand" "m,m"))
14977    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14978    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14979   "TARGET_USE_FANCY_MATH_387
14980    && flag_unsafe_math_optimizations"
14981   "#"
14982   [(set_attr "type" "fistp")
14983    (set_attr "i387_cw" "floor")
14984    (set_attr "mode" "DI")])
14985
14986 (define_split
14987   [(set (match_operand:DI 0 "register_operand" "")
14988         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14989                    UNSPEC_FIST_FLOOR))
14990    (use (match_operand:HI 2 "memory_operand" ""))
14991    (use (match_operand:HI 3 "memory_operand" ""))
14992    (clobber (match_operand:DI 4 "memory_operand" ""))
14993    (clobber (match_scratch 5 ""))]
14994   "reload_completed"
14995   [(parallel [(set (match_dup 4)
14996                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14997               (use (match_dup 2))
14998               (use (match_dup 3))
14999               (clobber (match_dup 5))])
15000    (set (match_dup 0) (match_dup 4))])
15001
15002 (define_split
15003   [(set (match_operand:DI 0 "memory_operand" "")
15004         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15005                    UNSPEC_FIST_FLOOR))
15006    (use (match_operand:HI 2 "memory_operand" ""))
15007    (use (match_operand:HI 3 "memory_operand" ""))
15008    (clobber (match_operand:DI 4 "memory_operand" ""))
15009    (clobber (match_scratch 5 ""))]
15010   "reload_completed"
15011   [(parallel [(set (match_dup 0)
15012                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15013               (use (match_dup 2))
15014               (use (match_dup 3))
15015               (clobber (match_dup 5))])])
15016
15017 (define_insn "fist<mode>2_floor"
15018   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15019         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15020                       UNSPEC_FIST_FLOOR))
15021    (use (match_operand:HI 2 "memory_operand" "m"))
15022    (use (match_operand:HI 3 "memory_operand" "m"))]
15023   "TARGET_USE_FANCY_MATH_387
15024    && flag_unsafe_math_optimizations"
15025   "* return output_fix_trunc (insn, operands, false);"
15026   [(set_attr "type" "fistp")
15027    (set_attr "i387_cw" "floor")
15028    (set_attr "mode" "<MODE>")])
15029
15030 (define_insn "fist<mode>2_floor_with_temp"
15031   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15032         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15033                       UNSPEC_FIST_FLOOR))
15034    (use (match_operand:HI 2 "memory_operand" "m,m"))
15035    (use (match_operand:HI 3 "memory_operand" "m,m"))
15036    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15037   "TARGET_USE_FANCY_MATH_387
15038    && flag_unsafe_math_optimizations"
15039   "#"
15040   [(set_attr "type" "fistp")
15041    (set_attr "i387_cw" "floor")
15042    (set_attr "mode" "<MODE>")])
15043
15044 (define_split
15045   [(set (match_operand:SWI24 0 "register_operand" "")
15046         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15047                       UNSPEC_FIST_FLOOR))
15048    (use (match_operand:HI 2 "memory_operand" ""))
15049    (use (match_operand:HI 3 "memory_operand" ""))
15050    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15051   "reload_completed"
15052   [(parallel [(set (match_dup 4)
15053                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15054               (use (match_dup 2))
15055               (use (match_dup 3))])
15056    (set (match_dup 0) (match_dup 4))])
15057
15058 (define_split
15059   [(set (match_operand:SWI24 0 "memory_operand" "")
15060         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15061                       UNSPEC_FIST_FLOOR))
15062    (use (match_operand:HI 2 "memory_operand" ""))
15063    (use (match_operand:HI 3 "memory_operand" ""))
15064    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15065   "reload_completed"
15066   [(parallel [(set (match_dup 0)
15067                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15068               (use (match_dup 2))
15069               (use (match_dup 3))])])
15070
15071 (define_expand "lfloorxf<mode>2"
15072   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15073                    (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15074                                    UNSPEC_FIST_FLOOR))
15075               (clobber (reg:CC FLAGS_REG))])]
15076   "TARGET_USE_FANCY_MATH_387
15077    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15078    && flag_unsafe_math_optimizations")
15079
15080 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15081   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15082    (match_operand:MODEF 1 "register_operand" "")]
15083   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15084    && !flag_trapping_math"
15085 {
15086   if (TARGET_64BIT && optimize_insn_for_size_p ())
15087     FAIL;
15088   ix86_expand_lfloorceil (operands[0], operands[1], true);
15089   DONE;
15090 })
15091
15092 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15093 (define_insn_and_split "frndintxf2_ceil"
15094   [(set (match_operand:XF 0 "register_operand" "")
15095         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15096          UNSPEC_FRNDINT_CEIL))
15097    (clobber (reg:CC FLAGS_REG))]
15098   "TARGET_USE_FANCY_MATH_387
15099    && flag_unsafe_math_optimizations
15100    && can_create_pseudo_p ()"
15101   "#"
15102   "&& 1"
15103   [(const_int 0)]
15104 {
15105   ix86_optimize_mode_switching[I387_CEIL] = 1;
15106
15107   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15108   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15109
15110   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15111                                        operands[2], operands[3]));
15112   DONE;
15113 }
15114   [(set_attr "type" "frndint")
15115    (set_attr "i387_cw" "ceil")
15116    (set_attr "mode" "XF")])
15117
15118 (define_insn "frndintxf2_ceil_i387"
15119   [(set (match_operand:XF 0 "register_operand" "=f")
15120         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15121          UNSPEC_FRNDINT_CEIL))
15122    (use (match_operand:HI 2 "memory_operand" "m"))
15123    (use (match_operand:HI 3 "memory_operand" "m"))]
15124   "TARGET_USE_FANCY_MATH_387
15125    && flag_unsafe_math_optimizations"
15126   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15127   [(set_attr "type" "frndint")
15128    (set_attr "i387_cw" "ceil")
15129    (set_attr "mode" "XF")])
15130
15131 (define_expand "ceilxf2"
15132   [(use (match_operand:XF 0 "register_operand" ""))
15133    (use (match_operand:XF 1 "register_operand" ""))]
15134   "TARGET_USE_FANCY_MATH_387
15135    && flag_unsafe_math_optimizations"
15136 {
15137   if (optimize_insn_for_size_p ())
15138     FAIL;
15139   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15140   DONE;
15141 })
15142
15143 (define_expand "ceil<mode>2"
15144   [(use (match_operand:MODEF 0 "register_operand" ""))
15145    (use (match_operand:MODEF 1 "register_operand" ""))]
15146   "(TARGET_USE_FANCY_MATH_387
15147     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15148         || TARGET_MIX_SSE_I387)
15149     && flag_unsafe_math_optimizations)
15150    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15151        && !flag_trapping_math)"
15152 {
15153   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15154       && !flag_trapping_math)
15155     {
15156       if (TARGET_ROUND)
15157         emit_insn (gen_sse4_1_round<mode>2
15158                    (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15159       else if (optimize_insn_for_size_p ())
15160         FAIL;
15161       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15162         ix86_expand_floorceil (operands[0], operands[1], false);
15163       else
15164         ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15165     }
15166   else
15167     {
15168       rtx op0, op1;
15169
15170       if (optimize_insn_for_size_p ())
15171         FAIL;
15172
15173       op0 = gen_reg_rtx (XFmode);
15174       op1 = gen_reg_rtx (XFmode);
15175       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15176       emit_insn (gen_frndintxf2_ceil (op0, op1));
15177
15178       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15179     }
15180   DONE;
15181 })
15182
15183 (define_insn_and_split "*fist<mode>2_ceil_1"
15184   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15185         (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15186                         UNSPEC_FIST_CEIL))
15187    (clobber (reg:CC FLAGS_REG))]
15188   "TARGET_USE_FANCY_MATH_387
15189    && flag_unsafe_math_optimizations
15190    && can_create_pseudo_p ()"
15191   "#"
15192   "&& 1"
15193   [(const_int 0)]
15194 {
15195   ix86_optimize_mode_switching[I387_CEIL] = 1;
15196
15197   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15198   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15199   if (memory_operand (operands[0], VOIDmode))
15200     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15201                                      operands[2], operands[3]));
15202   else
15203     {
15204       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15205       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15206                                                  operands[2], operands[3],
15207                                                  operands[4]));
15208     }
15209   DONE;
15210 }
15211   [(set_attr "type" "fistp")
15212    (set_attr "i387_cw" "ceil")
15213    (set_attr "mode" "<MODE>")])
15214
15215 (define_insn "fistdi2_ceil"
15216   [(set (match_operand:DI 0 "memory_operand" "=m")
15217         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15218                    UNSPEC_FIST_CEIL))
15219    (use (match_operand:HI 2 "memory_operand" "m"))
15220    (use (match_operand:HI 3 "memory_operand" "m"))
15221    (clobber (match_scratch:XF 4 "=&1f"))]
15222   "TARGET_USE_FANCY_MATH_387
15223    && flag_unsafe_math_optimizations"
15224   "* return output_fix_trunc (insn, operands, false);"
15225   [(set_attr "type" "fistp")
15226    (set_attr "i387_cw" "ceil")
15227    (set_attr "mode" "DI")])
15228
15229 (define_insn "fistdi2_ceil_with_temp"
15230   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15231         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15232                    UNSPEC_FIST_CEIL))
15233    (use (match_operand:HI 2 "memory_operand" "m,m"))
15234    (use (match_operand:HI 3 "memory_operand" "m,m"))
15235    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15236    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15237   "TARGET_USE_FANCY_MATH_387
15238    && flag_unsafe_math_optimizations"
15239   "#"
15240   [(set_attr "type" "fistp")
15241    (set_attr "i387_cw" "ceil")
15242    (set_attr "mode" "DI")])
15243
15244 (define_split
15245   [(set (match_operand:DI 0 "register_operand" "")
15246         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15247                    UNSPEC_FIST_CEIL))
15248    (use (match_operand:HI 2 "memory_operand" ""))
15249    (use (match_operand:HI 3 "memory_operand" ""))
15250    (clobber (match_operand:DI 4 "memory_operand" ""))
15251    (clobber (match_scratch 5 ""))]
15252   "reload_completed"
15253   [(parallel [(set (match_dup 4)
15254                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15255               (use (match_dup 2))
15256               (use (match_dup 3))
15257               (clobber (match_dup 5))])
15258    (set (match_dup 0) (match_dup 4))])
15259
15260 (define_split
15261   [(set (match_operand:DI 0 "memory_operand" "")
15262         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15263                    UNSPEC_FIST_CEIL))
15264    (use (match_operand:HI 2 "memory_operand" ""))
15265    (use (match_operand:HI 3 "memory_operand" ""))
15266    (clobber (match_operand:DI 4 "memory_operand" ""))
15267    (clobber (match_scratch 5 ""))]
15268   "reload_completed"
15269   [(parallel [(set (match_dup 0)
15270                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15271               (use (match_dup 2))
15272               (use (match_dup 3))
15273               (clobber (match_dup 5))])])
15274
15275 (define_insn "fist<mode>2_ceil"
15276   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15277         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15278                       UNSPEC_FIST_CEIL))
15279    (use (match_operand:HI 2 "memory_operand" "m"))
15280    (use (match_operand:HI 3 "memory_operand" "m"))]
15281   "TARGET_USE_FANCY_MATH_387
15282    && flag_unsafe_math_optimizations"
15283   "* return output_fix_trunc (insn, operands, false);"
15284   [(set_attr "type" "fistp")
15285    (set_attr "i387_cw" "ceil")
15286    (set_attr "mode" "<MODE>")])
15287
15288 (define_insn "fist<mode>2_ceil_with_temp"
15289   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15290         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15291                       UNSPEC_FIST_CEIL))
15292    (use (match_operand:HI 2 "memory_operand" "m,m"))
15293    (use (match_operand:HI 3 "memory_operand" "m,m"))
15294    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15295   "TARGET_USE_FANCY_MATH_387
15296    && flag_unsafe_math_optimizations"
15297   "#"
15298   [(set_attr "type" "fistp")
15299    (set_attr "i387_cw" "ceil")
15300    (set_attr "mode" "<MODE>")])
15301
15302 (define_split
15303   [(set (match_operand:SWI24 0 "register_operand" "")
15304         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15305                       UNSPEC_FIST_CEIL))
15306    (use (match_operand:HI 2 "memory_operand" ""))
15307    (use (match_operand:HI 3 "memory_operand" ""))
15308    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15309   "reload_completed"
15310   [(parallel [(set (match_dup 4)
15311                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15312               (use (match_dup 2))
15313               (use (match_dup 3))])
15314    (set (match_dup 0) (match_dup 4))])
15315
15316 (define_split
15317   [(set (match_operand:SWI24 0 "memory_operand" "")
15318         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15319                       UNSPEC_FIST_CEIL))
15320    (use (match_operand:HI 2 "memory_operand" ""))
15321    (use (match_operand:HI 3 "memory_operand" ""))
15322    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15323   "reload_completed"
15324   [(parallel [(set (match_dup 0)
15325                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15326               (use (match_dup 2))
15327               (use (match_dup 3))])])
15328
15329 (define_expand "lceilxf<mode>2"
15330   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15331                    (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15332                                    UNSPEC_FIST_CEIL))
15333               (clobber (reg:CC FLAGS_REG))])]
15334   "TARGET_USE_FANCY_MATH_387
15335    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15336    && flag_unsafe_math_optimizations")
15337
15338 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15339   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15340    (match_operand:MODEF 1 "register_operand" "")]
15341   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15342    && !flag_trapping_math"
15343 {
15344   ix86_expand_lfloorceil (operands[0], operands[1], false);
15345   DONE;
15346 })
15347
15348 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15349 (define_insn_and_split "frndintxf2_trunc"
15350   [(set (match_operand:XF 0 "register_operand" "")
15351         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15352          UNSPEC_FRNDINT_TRUNC))
15353    (clobber (reg:CC FLAGS_REG))]
15354   "TARGET_USE_FANCY_MATH_387
15355    && flag_unsafe_math_optimizations
15356    && can_create_pseudo_p ()"
15357   "#"
15358   "&& 1"
15359   [(const_int 0)]
15360 {
15361   ix86_optimize_mode_switching[I387_TRUNC] = 1;
15362
15363   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15364   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15365
15366   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15367                                         operands[2], operands[3]));
15368   DONE;
15369 }
15370   [(set_attr "type" "frndint")
15371    (set_attr "i387_cw" "trunc")
15372    (set_attr "mode" "XF")])
15373
15374 (define_insn "frndintxf2_trunc_i387"
15375   [(set (match_operand:XF 0 "register_operand" "=f")
15376         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15377          UNSPEC_FRNDINT_TRUNC))
15378    (use (match_operand:HI 2 "memory_operand" "m"))
15379    (use (match_operand:HI 3 "memory_operand" "m"))]
15380   "TARGET_USE_FANCY_MATH_387
15381    && flag_unsafe_math_optimizations"
15382   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15383   [(set_attr "type" "frndint")
15384    (set_attr "i387_cw" "trunc")
15385    (set_attr "mode" "XF")])
15386
15387 (define_expand "btruncxf2"
15388   [(use (match_operand:XF 0 "register_operand" ""))
15389    (use (match_operand:XF 1 "register_operand" ""))]
15390   "TARGET_USE_FANCY_MATH_387
15391    && flag_unsafe_math_optimizations"
15392 {
15393   if (optimize_insn_for_size_p ())
15394     FAIL;
15395   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15396   DONE;
15397 })
15398
15399 (define_expand "btrunc<mode>2"
15400   [(use (match_operand:MODEF 0 "register_operand" ""))
15401    (use (match_operand:MODEF 1 "register_operand" ""))]
15402   "(TARGET_USE_FANCY_MATH_387
15403     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15404         || TARGET_MIX_SSE_I387)
15405     && flag_unsafe_math_optimizations)
15406    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15407        && !flag_trapping_math)"
15408 {
15409   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15410       && !flag_trapping_math)
15411     {
15412       if (TARGET_ROUND)
15413         emit_insn (gen_sse4_1_round<mode>2
15414                    (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15415       else if (optimize_insn_for_size_p ())
15416         FAIL;
15417       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15418         ix86_expand_trunc (operands[0], operands[1]);
15419       else
15420         ix86_expand_truncdf_32 (operands[0], operands[1]);
15421     }
15422   else
15423     {
15424       rtx op0, op1;
15425
15426       if (optimize_insn_for_size_p ())
15427         FAIL;
15428
15429       op0 = gen_reg_rtx (XFmode);
15430       op1 = gen_reg_rtx (XFmode);
15431       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15432       emit_insn (gen_frndintxf2_trunc (op0, op1));
15433
15434       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15435     }
15436   DONE;
15437 })
15438
15439 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15440 (define_insn_and_split "frndintxf2_mask_pm"
15441   [(set (match_operand:XF 0 "register_operand" "")
15442         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15443          UNSPEC_FRNDINT_MASK_PM))
15444    (clobber (reg:CC FLAGS_REG))]
15445   "TARGET_USE_FANCY_MATH_387
15446    && flag_unsafe_math_optimizations
15447    && can_create_pseudo_p ()"
15448   "#"
15449   "&& 1"
15450   [(const_int 0)]
15451 {
15452   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15453
15454   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15455   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15456
15457   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15458                                           operands[2], operands[3]));
15459   DONE;
15460 }
15461   [(set_attr "type" "frndint")
15462    (set_attr "i387_cw" "mask_pm")
15463    (set_attr "mode" "XF")])
15464
15465 (define_insn "frndintxf2_mask_pm_i387"
15466   [(set (match_operand:XF 0 "register_operand" "=f")
15467         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15468          UNSPEC_FRNDINT_MASK_PM))
15469    (use (match_operand:HI 2 "memory_operand" "m"))
15470    (use (match_operand:HI 3 "memory_operand" "m"))]
15471   "TARGET_USE_FANCY_MATH_387
15472    && flag_unsafe_math_optimizations"
15473   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15474   [(set_attr "type" "frndint")
15475    (set_attr "i387_cw" "mask_pm")
15476    (set_attr "mode" "XF")])
15477
15478 (define_expand "nearbyintxf2"
15479   [(use (match_operand:XF 0 "register_operand" ""))
15480    (use (match_operand:XF 1 "register_operand" ""))]
15481   "TARGET_USE_FANCY_MATH_387
15482    && flag_unsafe_math_optimizations"
15483 {
15484   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15485   DONE;
15486 })
15487
15488 (define_expand "nearbyint<mode>2"
15489   [(use (match_operand:MODEF 0 "register_operand" ""))
15490    (use (match_operand:MODEF 1 "register_operand" ""))]
15491   "TARGET_USE_FANCY_MATH_387
15492    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15493        || TARGET_MIX_SSE_I387)
15494    && flag_unsafe_math_optimizations"
15495 {
15496   rtx op0 = gen_reg_rtx (XFmode);
15497   rtx op1 = gen_reg_rtx (XFmode);
15498
15499   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15500   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15501
15502   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15503   DONE;
15504 })
15505
15506 (define_insn "fxam<mode>2_i387"
15507   [(set (match_operand:HI 0 "register_operand" "=a")
15508         (unspec:HI
15509           [(match_operand:X87MODEF 1 "register_operand" "f")]
15510           UNSPEC_FXAM))]
15511   "TARGET_USE_FANCY_MATH_387"
15512   "fxam\n\tfnstsw\t%0"
15513   [(set_attr "type" "multi")
15514    (set_attr "length" "4")
15515    (set_attr "unit" "i387")
15516    (set_attr "mode" "<MODE>")])
15517
15518 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15519   [(set (match_operand:HI 0 "register_operand" "")
15520         (unspec:HI
15521           [(match_operand:MODEF 1 "memory_operand" "")]
15522           UNSPEC_FXAM_MEM))]
15523   "TARGET_USE_FANCY_MATH_387
15524    && can_create_pseudo_p ()"
15525   "#"
15526   "&& 1"
15527   [(set (match_dup 2)(match_dup 1))
15528    (set (match_dup 0)
15529         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15530 {
15531   operands[2] = gen_reg_rtx (<MODE>mode);
15532
15533   MEM_VOLATILE_P (operands[1]) = 1;
15534 }
15535   [(set_attr "type" "multi")
15536    (set_attr "unit" "i387")
15537    (set_attr "mode" "<MODE>")])
15538
15539 (define_expand "isinfxf2"
15540   [(use (match_operand:SI 0 "register_operand" ""))
15541    (use (match_operand:XF 1 "register_operand" ""))]
15542   "TARGET_USE_FANCY_MATH_387
15543    && TARGET_C99_FUNCTIONS"
15544 {
15545   rtx mask = GEN_INT (0x45);
15546   rtx val = GEN_INT (0x05);
15547
15548   rtx cond;
15549
15550   rtx scratch = gen_reg_rtx (HImode);
15551   rtx res = gen_reg_rtx (QImode);
15552
15553   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15554
15555   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15556   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15557   cond = gen_rtx_fmt_ee (EQ, QImode,
15558                          gen_rtx_REG (CCmode, FLAGS_REG),
15559                          const0_rtx);
15560   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15561   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15562   DONE;
15563 })
15564
15565 (define_expand "isinf<mode>2"
15566   [(use (match_operand:SI 0 "register_operand" ""))
15567    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15568   "TARGET_USE_FANCY_MATH_387
15569    && TARGET_C99_FUNCTIONS
15570    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15571 {
15572   rtx mask = GEN_INT (0x45);
15573   rtx val = GEN_INT (0x05);
15574
15575   rtx cond;
15576
15577   rtx scratch = gen_reg_rtx (HImode);
15578   rtx res = gen_reg_rtx (QImode);
15579
15580   /* Remove excess precision by forcing value through memory. */
15581   if (memory_operand (operands[1], VOIDmode))
15582     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15583   else
15584     {
15585       rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
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], false)"))
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], false)"))
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")