OSDN Git Service

6e2c1230de3742229afb4037e8d63190ce6f6c04
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 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 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
43 ;;      delimiter.
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;;      %b0 would print %al if operands[0] is reg 0.
46 ;; w --  likewise, print the HImode name of the register.
47 ;; k --  likewise, print the SImode name of the register.
48 ;; q --  likewise, print the DImode name of the register.
49 ;; x --  likewise, print the V4SFmode name of the register.
50 ;; t --  likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; p -- print raw symbol name.
57 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
58 ;; & -- print some in-use local-dynamic symbol name.
59 ;; H -- print a memory address offset by 8; used for sse high-parts
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; @ -- print a segment register of thread base pointer load
64
65 (define_c_enum "unspec" [
66   ;; Relocation specifiers
67   UNSPEC_GOT
68   UNSPEC_GOTOFF
69   UNSPEC_GOTPCREL
70   UNSPEC_GOTTPOFF
71   UNSPEC_TPOFF
72   UNSPEC_NTPOFF
73   UNSPEC_DTPOFF
74   UNSPEC_GOTNTPOFF
75   UNSPEC_INDNTPOFF
76   UNSPEC_PLTOFF
77   UNSPEC_MACHOPIC_OFFSET
78   UNSPEC_PCREL
79
80   ;; Prologue support
81   UNSPEC_STACK_ALLOC
82   UNSPEC_SET_GOT
83   UNSPEC_REG_SAVE
84   UNSPEC_DEF_CFA
85   UNSPEC_SET_RIP
86   UNSPEC_SET_GOT_OFFSET
87   UNSPEC_MEMORY_BLOCKAGE
88   UNSPEC_STACK_CHECK
89
90   ;; TLS support
91   UNSPEC_TP
92   UNSPEC_TLS_GD
93   UNSPEC_TLS_LD_BASE
94   UNSPEC_TLSDESC
95   UNSPEC_TLS_IE_SUN
96
97   ;; Other random patterns
98   UNSPEC_SCAS
99   UNSPEC_FNSTSW
100   UNSPEC_SAHF
101   UNSPEC_PARITY
102   UNSPEC_FSTCW
103   UNSPEC_ADD_CARRY
104   UNSPEC_FLDCW
105   UNSPEC_REP
106   UNSPEC_LD_MPIC        ; load_macho_picbase
107   UNSPEC_TRUNC_NOOP
108   UNSPEC_DIV_ALREADY_SPLIT
109   UNSPEC_MS_TO_SYSV_CALL
110   UNSPEC_CALL_NEEDS_VZEROUPPER
111   UNSPEC_PAUSE
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 RDRAND support
174   UNSPEC_RDRAND
175
176   ;; For BMI support
177   UNSPEC_BEXTR
178
179   ;; For BMI2 support
180   UNSPEC_PDEP
181   UNSPEC_PEXT
182 ])
183
184 (define_c_enum "unspecv" [
185   UNSPECV_BLOCKAGE
186   UNSPECV_STACK_PROBE
187   UNSPECV_PROBE_STACK_RANGE
188   UNSPECV_ALIGN
189   UNSPECV_PROLOGUE_USE
190   UNSPECV_SPLIT_STACK_RETURN
191   UNSPECV_CLD
192   UNSPECV_NOPS
193   UNSPECV_RDTSC
194   UNSPECV_RDTSCP
195   UNSPECV_RDPMC
196   UNSPECV_LLWP_INTRINSIC
197   UNSPECV_SLWP_INTRINSIC
198   UNSPECV_LWPVAL_INTRINSIC
199   UNSPECV_LWPINS_INTRINSIC
200   UNSPECV_RDFSBASE
201   UNSPECV_RDGSBASE
202   UNSPECV_WRFSBASE
203   UNSPECV_WRGSBASE
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,bmi2"
632   (const_string "base"))
633
634 (define_attr "enabled" ""
635   (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
636          (eq_attr "isa" "sse2_noavx")
637            (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
638          (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
639          (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
640          (eq_attr "isa" "sse4_noavx")
641            (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
642          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
643          (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
644          (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
645         ]
646         (const_int 1)))
647
648 ;; Describe a user's asm statement.
649 (define_asm_attributes
650   [(set_attr "length" "128")
651    (set_attr "type" "multi")])
652
653 (define_code_iterator plusminus [plus minus])
654
655 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
656
657 ;; Base name for define_insn
658 (define_code_attr plusminus_insn
659   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
660    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
661
662 ;; Base name for insn mnemonic.
663 (define_code_attr plusminus_mnemonic
664   [(plus "add") (ss_plus "adds") (us_plus "addus")
665    (minus "sub") (ss_minus "subs") (us_minus "subus")])
666 (define_code_attr plusminus_carry_mnemonic
667   [(plus "adc") (minus "sbb")])
668
669 ;; Mark commutative operators as such in constraints.
670 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
671                         (minus "") (ss_minus "") (us_minus "")])
672
673 ;; Mapping of max and min
674 (define_code_iterator maxmin [smax smin umax umin])
675
676 ;; Mapping of signed max and min
677 (define_code_iterator smaxmin [smax smin])
678
679 ;; Mapping of unsigned max and min
680 (define_code_iterator umaxmin [umax umin])
681
682 ;; Base name for integer and FP insn mnemonic
683 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
684                               (umax "maxu") (umin "minu")])
685 (define_code_attr maxmin_float [(smax "max") (smin "min")])
686
687 ;; Mapping of logic operators
688 (define_code_iterator any_logic [and ior xor])
689 (define_code_iterator any_or [ior xor])
690
691 ;; Base name for insn mnemonic.
692 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
693
694 ;; Mapping of logic-shift operators
695 (define_code_iterator any_lshift [ashift lshiftrt])
696
697 ;; Mapping of shift-right operators
698 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
699
700 ;; Base name for define_insn
701 (define_code_attr shift_insn
702   [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
703
704 ;; Base name for insn mnemonic.
705 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
706 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
707
708 ;; Mapping of rotate operators
709 (define_code_iterator any_rotate [rotate rotatert])
710
711 ;; Base name for define_insn
712 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
713
714 ;; Base name for insn mnemonic.
715 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
716
717 ;; Mapping of abs neg operators
718 (define_code_iterator absneg [abs neg])
719
720 ;; Base name for x87 insn mnemonic.
721 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
722
723 ;; Used in signed and unsigned widening multiplications.
724 (define_code_iterator any_extend [sign_extend zero_extend])
725
726 ;; Prefix for insn menmonic.
727 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
728
729 ;; Prefix for define_insn
730 (define_code_attr u [(sign_extend "") (zero_extend "u")])
731 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
732
733 ;; All integer modes.
734 (define_mode_iterator SWI1248x [QI HI SI DI])
735
736 ;; All integer modes without QImode.
737 (define_mode_iterator SWI248x [HI SI DI])
738
739 ;; All integer modes without QImode and HImode.
740 (define_mode_iterator SWI48x [SI DI])
741
742 ;; All integer modes without SImode and DImode.
743 (define_mode_iterator SWI12 [QI HI])
744
745 ;; All integer modes without DImode.
746 (define_mode_iterator SWI124 [QI HI SI])
747
748 ;; All integer modes without QImode and DImode.
749 (define_mode_iterator SWI24 [HI SI])
750
751 ;; Single word integer modes.
752 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
753
754 ;; Single word integer modes without QImode.
755 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
756
757 ;; Single word integer modes without QImode and HImode.
758 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
759
760 ;; All math-dependant single and double word integer modes.
761 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
762                              (HI "TARGET_HIMODE_MATH")
763                              SI DI (TI "TARGET_64BIT")])
764
765 ;; Math-dependant single word integer modes.
766 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
767                             (HI "TARGET_HIMODE_MATH")
768                             SI (DI "TARGET_64BIT")])
769
770 ;; Math-dependant integer modes without DImode.
771 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
772                                (HI "TARGET_HIMODE_MATH")
773                                SI])
774
775 ;; Math-dependant single word integer modes without QImode.
776 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
777                                SI (DI "TARGET_64BIT")])
778
779 ;; Double word integer modes.
780 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
781                            (TI "TARGET_64BIT")])
782
783 ;; Double word integer modes as mode attribute.
784 (define_mode_attr DWI [(SI "DI") (DI "TI")])
785 (define_mode_attr dwi [(SI "di") (DI "ti")])
786
787 ;; Half mode for double word integer modes.
788 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
789                             (DI "TARGET_64BIT")])
790
791 ;; Instruction suffix for integer modes.
792 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
793
794 ;; Pointer size prefix for integer modes (Intel asm dialect)
795 (define_mode_attr iptrsize [(QI "BYTE")
796                             (HI "WORD")
797                             (SI "DWORD")
798                             (DI "QWORD")])
799
800 ;; Register class for integer modes.
801 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
802
803 ;; Immediate operand constraint for integer modes.
804 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
805
806 ;; General operand constraint for word modes.
807 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
808
809 ;; Immediate operand constraint for double integer modes.
810 (define_mode_attr di [(SI "nF") (DI "e")])
811
812 ;; Immediate operand constraint for shifts.
813 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
814
815 ;; General operand predicate for integer modes.
816 (define_mode_attr general_operand
817         [(QI "general_operand")
818          (HI "general_operand")
819          (SI "x86_64_general_operand")
820          (DI "x86_64_general_operand")
821          (TI "x86_64_general_operand")])
822
823 ;; General sign/zero extend operand predicate for integer modes.
824 (define_mode_attr general_szext_operand
825         [(QI "general_operand")
826          (HI "general_operand")
827          (SI "x86_64_szext_general_operand")
828          (DI "x86_64_szext_general_operand")])
829
830 ;; Immediate operand predicate for integer modes.
831 (define_mode_attr immediate_operand
832         [(QI "immediate_operand")
833          (HI "immediate_operand")
834          (SI "x86_64_immediate_operand")
835          (DI "x86_64_immediate_operand")])
836
837 ;; Nonmemory operand predicate for integer modes.
838 (define_mode_attr nonmemory_operand
839         [(QI "nonmemory_operand")
840          (HI "nonmemory_operand")
841          (SI "x86_64_nonmemory_operand")
842          (DI "x86_64_nonmemory_operand")])
843
844 ;; Operand predicate for shifts.
845 (define_mode_attr shift_operand
846         [(QI "nonimmediate_operand")
847          (HI "nonimmediate_operand")
848          (SI "nonimmediate_operand")
849          (DI "shiftdi_operand")
850          (TI "register_operand")])
851
852 ;; Operand predicate for shift argument.
853 (define_mode_attr shift_immediate_operand
854         [(QI "const_1_to_31_operand")
855          (HI "const_1_to_31_operand")
856          (SI "const_1_to_31_operand")
857          (DI "const_1_to_63_operand")])
858
859 ;; Input operand predicate for arithmetic left shifts.
860 (define_mode_attr ashl_input_operand
861         [(QI "nonimmediate_operand")
862          (HI "nonimmediate_operand")
863          (SI "nonimmediate_operand")
864          (DI "ashldi_input_operand")
865          (TI "reg_or_pm1_operand")])
866
867 ;; SSE and x87 SFmode and DFmode floating point modes
868 (define_mode_iterator MODEF [SF DF])
869
870 ;; All x87 floating point modes
871 (define_mode_iterator X87MODEF [SF DF XF])
872
873 ;; SSE instruction suffix for various modes
874 (define_mode_attr ssemodesuffix
875   [(SF "ss") (DF "sd")
876    (V8SF "ps") (V4DF "pd")
877    (V4SF "ps") (V2DF "pd")
878    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
879    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
880
881 ;; SSE vector suffix for floating point modes
882 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
883
884 ;; SSE vector mode corresponding to a scalar mode
885 (define_mode_attr ssevecmode
886   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
887
888 ;; Instruction suffix for REX 64bit operators.
889 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
890
891 ;; This mode iterator allows :P to be used for patterns that operate on
892 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
893 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
894
895 ;; This mode iterator allows :PTR to be used for patterns that operate on
896 ;; ptr_mode sized quantities.
897 (define_mode_iterator PTR
898   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
899 \f
900 ;; Scheduling descriptions
901
902 (include "pentium.md")
903 (include "ppro.md")
904 (include "k6.md")
905 (include "athlon.md")
906 (include "bdver1.md")
907 (include "geode.md")
908 (include "atom.md")
909 (include "core2.md")
910
911 \f
912 ;; Operand and operator predicates and constraints
913
914 (include "predicates.md")
915 (include "constraints.md")
916
917 \f
918 ;; Compare and branch/compare and store instructions.
919
920 (define_expand "cbranch<mode>4"
921   [(set (reg:CC FLAGS_REG)
922         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
923                     (match_operand:SDWIM 2 "<general_operand>" "")))
924    (set (pc) (if_then_else
925                (match_operator 0 "ordered_comparison_operator"
926                 [(reg:CC FLAGS_REG) (const_int 0)])
927                (label_ref (match_operand 3 "" ""))
928                (pc)))]
929   ""
930 {
931   if (MEM_P (operands[1]) && MEM_P (operands[2]))
932     operands[1] = force_reg (<MODE>mode, operands[1]);
933   ix86_expand_branch (GET_CODE (operands[0]),
934                       operands[1], operands[2], operands[3]);
935   DONE;
936 })
937
938 (define_expand "cstore<mode>4"
939   [(set (reg:CC FLAGS_REG)
940         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
941                     (match_operand:SWIM 3 "<general_operand>" "")))
942    (set (match_operand:QI 0 "register_operand" "")
943         (match_operator 1 "ordered_comparison_operator"
944           [(reg:CC FLAGS_REG) (const_int 0)]))]
945   ""
946 {
947   if (MEM_P (operands[2]) && MEM_P (operands[3]))
948     operands[2] = force_reg (<MODE>mode, operands[2]);
949   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
950                      operands[2], operands[3]);
951   DONE;
952 })
953
954 (define_expand "cmp<mode>_1"
955   [(set (reg:CC FLAGS_REG)
956         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
957                     (match_operand:SWI48 1 "<general_operand>" "")))])
958
959 (define_insn "*cmp<mode>_ccno_1"
960   [(set (reg FLAGS_REG)
961         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
962                  (match_operand:SWI 1 "const0_operand" "")))]
963   "ix86_match_ccmode (insn, CCNOmode)"
964   "@
965    test{<imodesuffix>}\t%0, %0
966    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
967   [(set_attr "type" "test,icmp")
968    (set_attr "length_immediate" "0,1")
969    (set_attr "mode" "<MODE>")])
970
971 (define_insn "*cmp<mode>_1"
972   [(set (reg FLAGS_REG)
973         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
974                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
975   "ix86_match_ccmode (insn, CCmode)"
976   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
977   [(set_attr "type" "icmp")
978    (set_attr "mode" "<MODE>")])
979
980 (define_insn "*cmp<mode>_minus_1"
981   [(set (reg FLAGS_REG)
982         (compare
983           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
984                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
985           (const_int 0)))]
986   "ix86_match_ccmode (insn, CCGOCmode)"
987   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
988   [(set_attr "type" "icmp")
989    (set_attr "mode" "<MODE>")])
990
991 (define_insn "*cmpqi_ext_1"
992   [(set (reg FLAGS_REG)
993         (compare
994           (match_operand:QI 0 "general_operand" "Qm")
995           (subreg:QI
996             (zero_extract:SI
997               (match_operand 1 "ext_register_operand" "Q")
998               (const_int 8)
999               (const_int 8)) 0)))]
1000   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1001   "cmp{b}\t{%h1, %0|%0, %h1}"
1002   [(set_attr "type" "icmp")
1003    (set_attr "mode" "QI")])
1004
1005 (define_insn "*cmpqi_ext_1_rex64"
1006   [(set (reg FLAGS_REG)
1007         (compare
1008           (match_operand:QI 0 "register_operand" "Q")
1009           (subreg:QI
1010             (zero_extract:SI
1011               (match_operand 1 "ext_register_operand" "Q")
1012               (const_int 8)
1013               (const_int 8)) 0)))]
1014   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1015   "cmp{b}\t{%h1, %0|%0, %h1}"
1016   [(set_attr "type" "icmp")
1017    (set_attr "mode" "QI")])
1018
1019 (define_insn "*cmpqi_ext_2"
1020   [(set (reg FLAGS_REG)
1021         (compare
1022           (subreg:QI
1023             (zero_extract:SI
1024               (match_operand 0 "ext_register_operand" "Q")
1025               (const_int 8)
1026               (const_int 8)) 0)
1027           (match_operand:QI 1 "const0_operand" "")))]
1028   "ix86_match_ccmode (insn, CCNOmode)"
1029   "test{b}\t%h0, %h0"
1030   [(set_attr "type" "test")
1031    (set_attr "length_immediate" "0")
1032    (set_attr "mode" "QI")])
1033
1034 (define_expand "cmpqi_ext_3"
1035   [(set (reg:CC FLAGS_REG)
1036         (compare:CC
1037           (subreg:QI
1038             (zero_extract:SI
1039               (match_operand 0 "ext_register_operand" "")
1040               (const_int 8)
1041               (const_int 8)) 0)
1042           (match_operand:QI 1 "immediate_operand" "")))])
1043
1044 (define_insn "*cmpqi_ext_3_insn"
1045   [(set (reg FLAGS_REG)
1046         (compare
1047           (subreg:QI
1048             (zero_extract:SI
1049               (match_operand 0 "ext_register_operand" "Q")
1050               (const_int 8)
1051               (const_int 8)) 0)
1052           (match_operand:QI 1 "general_operand" "Qmn")))]
1053   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1054   "cmp{b}\t{%1, %h0|%h0, %1}"
1055   [(set_attr "type" "icmp")
1056    (set_attr "modrm" "1")
1057    (set_attr "mode" "QI")])
1058
1059 (define_insn "*cmpqi_ext_3_insn_rex64"
1060   [(set (reg FLAGS_REG)
1061         (compare
1062           (subreg:QI
1063             (zero_extract:SI
1064               (match_operand 0 "ext_register_operand" "Q")
1065               (const_int 8)
1066               (const_int 8)) 0)
1067           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1068   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1069   "cmp{b}\t{%1, %h0|%h0, %1}"
1070   [(set_attr "type" "icmp")
1071    (set_attr "modrm" "1")
1072    (set_attr "mode" "QI")])
1073
1074 (define_insn "*cmpqi_ext_4"
1075   [(set (reg FLAGS_REG)
1076         (compare
1077           (subreg:QI
1078             (zero_extract:SI
1079               (match_operand 0 "ext_register_operand" "Q")
1080               (const_int 8)
1081               (const_int 8)) 0)
1082           (subreg:QI
1083             (zero_extract:SI
1084               (match_operand 1 "ext_register_operand" "Q")
1085               (const_int 8)
1086               (const_int 8)) 0)))]
1087   "ix86_match_ccmode (insn, CCmode)"
1088   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1089   [(set_attr "type" "icmp")
1090    (set_attr "mode" "QI")])
1091
1092 ;; These implement float point compares.
1093 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1094 ;; which would allow mix and match FP modes on the compares.  Which is what
1095 ;; the old patterns did, but with many more of them.
1096
1097 (define_expand "cbranchxf4"
1098   [(set (reg:CC FLAGS_REG)
1099         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1100                     (match_operand:XF 2 "nonmemory_operand" "")))
1101    (set (pc) (if_then_else
1102               (match_operator 0 "ix86_fp_comparison_operator"
1103                [(reg:CC FLAGS_REG)
1104                 (const_int 0)])
1105               (label_ref (match_operand 3 "" ""))
1106               (pc)))]
1107   "TARGET_80387"
1108 {
1109   ix86_expand_branch (GET_CODE (operands[0]),
1110                       operands[1], operands[2], operands[3]);
1111   DONE;
1112 })
1113
1114 (define_expand "cstorexf4"
1115   [(set (reg:CC FLAGS_REG)
1116         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1117                     (match_operand:XF 3 "nonmemory_operand" "")))
1118    (set (match_operand:QI 0 "register_operand" "")
1119               (match_operator 1 "ix86_fp_comparison_operator"
1120                [(reg:CC FLAGS_REG)
1121                 (const_int 0)]))]
1122   "TARGET_80387"
1123 {
1124   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1125                      operands[2], operands[3]);
1126   DONE;
1127 })
1128
1129 (define_expand "cbranch<mode>4"
1130   [(set (reg:CC FLAGS_REG)
1131         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1132                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1133    (set (pc) (if_then_else
1134               (match_operator 0 "ix86_fp_comparison_operator"
1135                [(reg:CC FLAGS_REG)
1136                 (const_int 0)])
1137               (label_ref (match_operand 3 "" ""))
1138               (pc)))]
1139   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1140 {
1141   ix86_expand_branch (GET_CODE (operands[0]),
1142                       operands[1], operands[2], operands[3]);
1143   DONE;
1144 })
1145
1146 (define_expand "cstore<mode>4"
1147   [(set (reg:CC FLAGS_REG)
1148         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1149                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1150    (set (match_operand:QI 0 "register_operand" "")
1151               (match_operator 1 "ix86_fp_comparison_operator"
1152                [(reg:CC FLAGS_REG)
1153                 (const_int 0)]))]
1154   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1155 {
1156   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1157                      operands[2], operands[3]);
1158   DONE;
1159 })
1160
1161 (define_expand "cbranchcc4"
1162   [(set (pc) (if_then_else
1163               (match_operator 0 "comparison_operator"
1164                [(match_operand 1 "flags_reg_operand" "")
1165                 (match_operand 2 "const0_operand" "")])
1166               (label_ref (match_operand 3 "" ""))
1167               (pc)))]
1168   ""
1169 {
1170   ix86_expand_branch (GET_CODE (operands[0]),
1171                       operands[1], operands[2], operands[3]);
1172   DONE;
1173 })
1174
1175 (define_expand "cstorecc4"
1176   [(set (match_operand:QI 0 "register_operand" "")
1177               (match_operator 1 "comparison_operator"
1178                [(match_operand 2 "flags_reg_operand" "")
1179                 (match_operand 3 "const0_operand" "")]))]
1180   ""
1181 {
1182   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1183                      operands[2], operands[3]);
1184   DONE;
1185 })
1186
1187
1188 ;; FP compares, step 1:
1189 ;; Set the FP condition codes.
1190 ;;
1191 ;; CCFPmode     compare with exceptions
1192 ;; CCFPUmode    compare with no exceptions
1193
1194 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1195 ;; used to manage the reg stack popping would not be preserved.
1196
1197 (define_insn "*cmpfp_0"
1198   [(set (match_operand:HI 0 "register_operand" "=a")
1199         (unspec:HI
1200           [(compare:CCFP
1201              (match_operand 1 "register_operand" "f")
1202              (match_operand 2 "const0_operand" ""))]
1203         UNSPEC_FNSTSW))]
1204   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1205    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1206   "* return output_fp_compare (insn, operands, false, false);"
1207   [(set_attr "type" "multi")
1208    (set_attr "unit" "i387")
1209    (set (attr "mode")
1210      (cond [(match_operand:SF 1 "" "")
1211               (const_string "SF")
1212             (match_operand:DF 1 "" "")
1213               (const_string "DF")
1214            ]
1215            (const_string "XF")))])
1216
1217 (define_insn_and_split "*cmpfp_0_cc"
1218   [(set (reg:CCFP FLAGS_REG)
1219         (compare:CCFP
1220           (match_operand 1 "register_operand" "f")
1221           (match_operand 2 "const0_operand" "")))
1222    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1223   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1224    && TARGET_SAHF && !TARGET_CMOVE
1225    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1226   "#"
1227   "&& reload_completed"
1228   [(set (match_dup 0)
1229         (unspec:HI
1230           [(compare:CCFP (match_dup 1)(match_dup 2))]
1231         UNSPEC_FNSTSW))
1232    (set (reg:CC FLAGS_REG)
1233         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1234   ""
1235   [(set_attr "type" "multi")
1236    (set_attr "unit" "i387")
1237    (set (attr "mode")
1238      (cond [(match_operand:SF 1 "" "")
1239               (const_string "SF")
1240             (match_operand:DF 1 "" "")
1241               (const_string "DF")
1242            ]
1243            (const_string "XF")))])
1244
1245 (define_insn "*cmpfp_xf"
1246   [(set (match_operand:HI 0 "register_operand" "=a")
1247         (unspec:HI
1248           [(compare:CCFP
1249              (match_operand:XF 1 "register_operand" "f")
1250              (match_operand:XF 2 "register_operand" "f"))]
1251           UNSPEC_FNSTSW))]
1252   "TARGET_80387"
1253   "* return output_fp_compare (insn, operands, false, false);"
1254   [(set_attr "type" "multi")
1255    (set_attr "unit" "i387")
1256    (set_attr "mode" "XF")])
1257
1258 (define_insn_and_split "*cmpfp_xf_cc"
1259   [(set (reg:CCFP FLAGS_REG)
1260         (compare:CCFP
1261           (match_operand:XF 1 "register_operand" "f")
1262           (match_operand:XF 2 "register_operand" "f")))
1263    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1264   "TARGET_80387
1265    && TARGET_SAHF && !TARGET_CMOVE"
1266   "#"
1267   "&& reload_completed"
1268   [(set (match_dup 0)
1269         (unspec:HI
1270           [(compare:CCFP (match_dup 1)(match_dup 2))]
1271         UNSPEC_FNSTSW))
1272    (set (reg:CC FLAGS_REG)
1273         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1274   ""
1275   [(set_attr "type" "multi")
1276    (set_attr "unit" "i387")
1277    (set_attr "mode" "XF")])
1278
1279 (define_insn "*cmpfp_<mode>"
1280   [(set (match_operand:HI 0 "register_operand" "=a")
1281         (unspec:HI
1282           [(compare:CCFP
1283              (match_operand:MODEF 1 "register_operand" "f")
1284              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1285           UNSPEC_FNSTSW))]
1286   "TARGET_80387"
1287   "* return output_fp_compare (insn, operands, false, false);"
1288   [(set_attr "type" "multi")
1289    (set_attr "unit" "i387")
1290    (set_attr "mode" "<MODE>")])
1291
1292 (define_insn_and_split "*cmpfp_<mode>_cc"
1293   [(set (reg:CCFP FLAGS_REG)
1294         (compare:CCFP
1295           (match_operand:MODEF 1 "register_operand" "f")
1296           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1297    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1298   "TARGET_80387
1299    && TARGET_SAHF && !TARGET_CMOVE"
1300   "#"
1301   "&& reload_completed"
1302   [(set (match_dup 0)
1303         (unspec:HI
1304           [(compare:CCFP (match_dup 1)(match_dup 2))]
1305         UNSPEC_FNSTSW))
1306    (set (reg:CC FLAGS_REG)
1307         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1308   ""
1309   [(set_attr "type" "multi")
1310    (set_attr "unit" "i387")
1311    (set_attr "mode" "<MODE>")])
1312
1313 (define_insn "*cmpfp_u"
1314   [(set (match_operand:HI 0 "register_operand" "=a")
1315         (unspec:HI
1316           [(compare:CCFPU
1317              (match_operand 1 "register_operand" "f")
1318              (match_operand 2 "register_operand" "f"))]
1319           UNSPEC_FNSTSW))]
1320   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1321    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1322   "* return output_fp_compare (insn, operands, false, true);"
1323   [(set_attr "type" "multi")
1324    (set_attr "unit" "i387")
1325    (set (attr "mode")
1326      (cond [(match_operand:SF 1 "" "")
1327               (const_string "SF")
1328             (match_operand:DF 1 "" "")
1329               (const_string "DF")
1330            ]
1331            (const_string "XF")))])
1332
1333 (define_insn_and_split "*cmpfp_u_cc"
1334   [(set (reg:CCFPU FLAGS_REG)
1335         (compare:CCFPU
1336           (match_operand 1 "register_operand" "f")
1337           (match_operand 2 "register_operand" "f")))
1338    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1339   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1340    && TARGET_SAHF && !TARGET_CMOVE
1341    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1342   "#"
1343   "&& reload_completed"
1344   [(set (match_dup 0)
1345         (unspec:HI
1346           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1347         UNSPEC_FNSTSW))
1348    (set (reg:CC FLAGS_REG)
1349         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1350   ""
1351   [(set_attr "type" "multi")
1352    (set_attr "unit" "i387")
1353    (set (attr "mode")
1354      (cond [(match_operand:SF 1 "" "")
1355               (const_string "SF")
1356             (match_operand:DF 1 "" "")
1357               (const_string "DF")
1358            ]
1359            (const_string "XF")))])
1360
1361 (define_insn "*cmpfp_<mode>"
1362   [(set (match_operand:HI 0 "register_operand" "=a")
1363         (unspec:HI
1364           [(compare:CCFP
1365              (match_operand 1 "register_operand" "f")
1366              (match_operator 3 "float_operator"
1367                [(match_operand:SWI24 2 "memory_operand" "m")]))]
1368           UNSPEC_FNSTSW))]
1369   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1370    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1371    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1372   "* return output_fp_compare (insn, operands, false, false);"
1373   [(set_attr "type" "multi")
1374    (set_attr "unit" "i387")
1375    (set_attr "fp_int_src" "true")
1376    (set_attr "mode" "<MODE>")])
1377
1378 (define_insn_and_split "*cmpfp_<mode>_cc"
1379   [(set (reg:CCFP FLAGS_REG)
1380         (compare:CCFP
1381           (match_operand 1 "register_operand" "f")
1382           (match_operator 3 "float_operator"
1383             [(match_operand:SWI24 2 "memory_operand" "m")])))
1384    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1385   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1386    && TARGET_SAHF && !TARGET_CMOVE
1387    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1388    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1389   "#"
1390   "&& reload_completed"
1391   [(set (match_dup 0)
1392         (unspec:HI
1393           [(compare:CCFP
1394              (match_dup 1)
1395              (match_op_dup 3 [(match_dup 2)]))]
1396         UNSPEC_FNSTSW))
1397    (set (reg:CC FLAGS_REG)
1398         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1399   ""
1400   [(set_attr "type" "multi")
1401    (set_attr "unit" "i387")
1402    (set_attr "fp_int_src" "true")
1403    (set_attr "mode" "<MODE>")])
1404
1405 ;; FP compares, step 2
1406 ;; Move the fpsw to ax.
1407
1408 (define_insn "x86_fnstsw_1"
1409   [(set (match_operand:HI 0 "register_operand" "=a")
1410         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1411   "TARGET_80387"
1412   "fnstsw\t%0"
1413   [(set (attr "length")
1414         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1415    (set_attr "mode" "SI")
1416    (set_attr "unit" "i387")])
1417
1418 ;; FP compares, step 3
1419 ;; Get ax into flags, general case.
1420
1421 (define_insn "x86_sahf_1"
1422   [(set (reg:CC FLAGS_REG)
1423         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1424                    UNSPEC_SAHF))]
1425   "TARGET_SAHF"
1426 {
1427 #ifndef HAVE_AS_IX86_SAHF
1428   if (TARGET_64BIT)
1429     return ASM_BYTE "0x9e";
1430   else
1431 #endif
1432   return "sahf";
1433 }
1434   [(set_attr "length" "1")
1435    (set_attr "athlon_decode" "vector")
1436    (set_attr "amdfam10_decode" "direct")
1437    (set_attr "bdver1_decode" "direct")
1438    (set_attr "mode" "SI")])
1439
1440 ;; Pentium Pro can do steps 1 through 3 in one go.
1441 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1442 ;; (these i387 instructions set flags directly)
1443 (define_insn "*cmpfp_i_mixed"
1444   [(set (reg:CCFP FLAGS_REG)
1445         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1446                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1447   "TARGET_MIX_SSE_I387
1448    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1449    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1450   "* return output_fp_compare (insn, operands, true, false);"
1451   [(set_attr "type" "fcmp,ssecomi")
1452    (set_attr "prefix" "orig,maybe_vex")
1453    (set (attr "mode")
1454      (if_then_else (match_operand:SF 1 "" "")
1455         (const_string "SF")
1456         (const_string "DF")))
1457    (set (attr "prefix_rep")
1458         (if_then_else (eq_attr "type" "ssecomi")
1459                       (const_string "0")
1460                       (const_string "*")))
1461    (set (attr "prefix_data16")
1462         (cond [(eq_attr "type" "fcmp")
1463                  (const_string "*")
1464                (eq_attr "mode" "DF")
1465                  (const_string "1")
1466               ]
1467               (const_string "0")))
1468    (set_attr "athlon_decode" "vector")
1469    (set_attr "amdfam10_decode" "direct")
1470    (set_attr "bdver1_decode" "double")])
1471
1472 (define_insn "*cmpfp_i_sse"
1473   [(set (reg:CCFP FLAGS_REG)
1474         (compare:CCFP (match_operand 0 "register_operand" "x")
1475                       (match_operand 1 "nonimmediate_operand" "xm")))]
1476   "TARGET_SSE_MATH
1477    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1478    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1479   "* return output_fp_compare (insn, operands, true, false);"
1480   [(set_attr "type" "ssecomi")
1481    (set_attr "prefix" "maybe_vex")
1482    (set (attr "mode")
1483      (if_then_else (match_operand:SF 1 "" "")
1484         (const_string "SF")
1485         (const_string "DF")))
1486    (set_attr "prefix_rep" "0")
1487    (set (attr "prefix_data16")
1488         (if_then_else (eq_attr "mode" "DF")
1489                       (const_string "1")
1490                       (const_string "0")))
1491    (set_attr "athlon_decode" "vector")
1492    (set_attr "amdfam10_decode" "direct")
1493    (set_attr "bdver1_decode" "double")])
1494
1495 (define_insn "*cmpfp_i_i387"
1496   [(set (reg:CCFP FLAGS_REG)
1497         (compare:CCFP (match_operand 0 "register_operand" "f")
1498                       (match_operand 1 "register_operand" "f")))]
1499   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1500    && TARGET_CMOVE
1501    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1502    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1503   "* return output_fp_compare (insn, operands, true, false);"
1504   [(set_attr "type" "fcmp")
1505    (set (attr "mode")
1506      (cond [(match_operand:SF 1 "" "")
1507               (const_string "SF")
1508             (match_operand:DF 1 "" "")
1509               (const_string "DF")
1510            ]
1511            (const_string "XF")))
1512    (set_attr "athlon_decode" "vector")
1513    (set_attr "amdfam10_decode" "direct")
1514    (set_attr "bdver1_decode" "double")])
1515
1516 (define_insn "*cmpfp_iu_mixed"
1517   [(set (reg:CCFPU FLAGS_REG)
1518         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1519                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1520   "TARGET_MIX_SSE_I387
1521    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1522    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1523   "* return output_fp_compare (insn, operands, true, true);"
1524   [(set_attr "type" "fcmp,ssecomi")
1525    (set_attr "prefix" "orig,maybe_vex")
1526    (set (attr "mode")
1527      (if_then_else (match_operand:SF 1 "" "")
1528         (const_string "SF")
1529         (const_string "DF")))
1530    (set (attr "prefix_rep")
1531         (if_then_else (eq_attr "type" "ssecomi")
1532                       (const_string "0")
1533                       (const_string "*")))
1534    (set (attr "prefix_data16")
1535         (cond [(eq_attr "type" "fcmp")
1536                  (const_string "*")
1537                (eq_attr "mode" "DF")
1538                  (const_string "1")
1539               ]
1540               (const_string "0")))
1541    (set_attr "athlon_decode" "vector")
1542    (set_attr "amdfam10_decode" "direct")
1543    (set_attr "bdver1_decode" "double")])
1544
1545 (define_insn "*cmpfp_iu_sse"
1546   [(set (reg:CCFPU FLAGS_REG)
1547         (compare:CCFPU (match_operand 0 "register_operand" "x")
1548                        (match_operand 1 "nonimmediate_operand" "xm")))]
1549   "TARGET_SSE_MATH
1550    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1551    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1552   "* return output_fp_compare (insn, operands, true, true);"
1553   [(set_attr "type" "ssecomi")
1554    (set_attr "prefix" "maybe_vex")
1555    (set (attr "mode")
1556      (if_then_else (match_operand:SF 1 "" "")
1557         (const_string "SF")
1558         (const_string "DF")))
1559    (set_attr "prefix_rep" "0")
1560    (set (attr "prefix_data16")
1561         (if_then_else (eq_attr "mode" "DF")
1562                       (const_string "1")
1563                       (const_string "0")))
1564    (set_attr "athlon_decode" "vector")
1565    (set_attr "amdfam10_decode" "direct")
1566    (set_attr "bdver1_decode" "double")])
1567
1568 (define_insn "*cmpfp_iu_387"
1569   [(set (reg:CCFPU FLAGS_REG)
1570         (compare:CCFPU (match_operand 0 "register_operand" "f")
1571                        (match_operand 1 "register_operand" "f")))]
1572   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1573    && TARGET_CMOVE
1574    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1575    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1576   "* return output_fp_compare (insn, operands, true, true);"
1577   [(set_attr "type" "fcmp")
1578    (set (attr "mode")
1579      (cond [(match_operand:SF 1 "" "")
1580               (const_string "SF")
1581             (match_operand:DF 1 "" "")
1582               (const_string "DF")
1583            ]
1584            (const_string "XF")))
1585    (set_attr "athlon_decode" "vector")
1586    (set_attr "amdfam10_decode" "direct")
1587    (set_attr "bdver1_decode" "direct")])
1588 \f
1589 ;; Push/pop instructions.
1590
1591 (define_insn "*push<mode>2"
1592   [(set (match_operand:DWI 0 "push_operand" "=<")
1593         (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1594   ""
1595   "#"
1596   [(set_attr "type" "multi")
1597    (set_attr "mode" "<MODE>")])
1598
1599 (define_split
1600   [(set (match_operand:TI 0 "push_operand" "")
1601         (match_operand:TI 1 "general_operand" ""))]
1602   "TARGET_64BIT && reload_completed
1603    && !SSE_REG_P (operands[1])"
1604   [(const_int 0)]
1605   "ix86_split_long_move (operands); DONE;")
1606
1607 (define_insn "*pushdi2_rex64"
1608   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1609         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1610   "TARGET_64BIT"
1611   "@
1612    push{q}\t%1
1613    #"
1614   [(set_attr "type" "push,multi")
1615    (set_attr "mode" "DI")])
1616
1617 ;; Convert impossible pushes of immediate to existing instructions.
1618 ;; First try to get scratch register and go through it.  In case this
1619 ;; fails, push sign extended lower part first and then overwrite
1620 ;; upper part by 32bit move.
1621 (define_peephole2
1622   [(match_scratch:DI 2 "r")
1623    (set (match_operand:DI 0 "push_operand" "")
1624         (match_operand:DI 1 "immediate_operand" ""))]
1625   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1626    && !x86_64_immediate_operand (operands[1], DImode)"
1627   [(set (match_dup 2) (match_dup 1))
1628    (set (match_dup 0) (match_dup 2))])
1629
1630 ;; We need to define this as both peepholer and splitter for case
1631 ;; peephole2 pass is not run.
1632 ;; "&& 1" is needed to keep it from matching the previous pattern.
1633 (define_peephole2
1634   [(set (match_operand:DI 0 "push_operand" "")
1635         (match_operand:DI 1 "immediate_operand" ""))]
1636   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1637    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1638   [(set (match_dup 0) (match_dup 1))
1639    (set (match_dup 2) (match_dup 3))]
1640 {
1641   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1642
1643   operands[1] = gen_lowpart (DImode, operands[2]);
1644   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1645                                                    GEN_INT (4)));
1646 })
1647
1648 (define_split
1649   [(set (match_operand:DI 0 "push_operand" "")
1650         (match_operand:DI 1 "immediate_operand" ""))]
1651   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1652                     ? epilogue_completed : reload_completed)
1653    && !symbolic_operand (operands[1], DImode)
1654    && !x86_64_immediate_operand (operands[1], DImode)"
1655   [(set (match_dup 0) (match_dup 1))
1656    (set (match_dup 2) (match_dup 3))]
1657 {
1658   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1659
1660   operands[1] = gen_lowpart (DImode, operands[2]);
1661   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1662                                                    GEN_INT (4)));
1663 })
1664
1665 (define_split
1666   [(set (match_operand:DI 0 "push_operand" "")
1667         (match_operand:DI 1 "general_operand" ""))]
1668   "!TARGET_64BIT && reload_completed
1669    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1670   [(const_int 0)]
1671   "ix86_split_long_move (operands); DONE;")
1672
1673 (define_insn "*pushsi2"
1674   [(set (match_operand:SI 0 "push_operand" "=<")
1675         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1676   "!TARGET_64BIT"
1677   "push{l}\t%1"
1678   [(set_attr "type" "push")
1679    (set_attr "mode" "SI")])
1680
1681 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1682 ;; "push a byte/word".  But actually we use pushl, which has the effect
1683 ;; of rounding the amount pushed up to a word.
1684
1685 ;; For TARGET_64BIT we always round up to 8 bytes.
1686 (define_insn "*push<mode>2_rex64"
1687   [(set (match_operand:SWI124 0 "push_operand" "=X")
1688         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1689   "TARGET_64BIT"
1690   "push{q}\t%q1"
1691   [(set_attr "type" "push")
1692    (set_attr "mode" "DI")])
1693
1694 (define_insn "*push<mode>2"
1695   [(set (match_operand:SWI12 0 "push_operand" "=X")
1696         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1697   "!TARGET_64BIT"
1698   "push{l}\t%k1"
1699   [(set_attr "type" "push")
1700    (set_attr "mode" "SI")])
1701
1702 (define_insn "*push<mode>2_prologue"
1703   [(set (match_operand:P 0 "push_operand" "=<")
1704         (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1705    (clobber (mem:BLK (scratch)))]
1706   ""
1707   "push{<imodesuffix>}\t%1"
1708   [(set_attr "type" "push")
1709    (set_attr "mode" "<MODE>")])
1710
1711 (define_insn "*pop<mode>1"
1712   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1713         (match_operand:P 1 "pop_operand" ">"))]
1714   ""
1715   "pop{<imodesuffix>}\t%0"
1716   [(set_attr "type" "pop")
1717    (set_attr "mode" "<MODE>")])
1718
1719 (define_insn "*pop<mode>1_epilogue"
1720   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1721         (match_operand:P 1 "pop_operand" ">"))
1722    (clobber (mem:BLK (scratch)))]
1723   ""
1724   "pop{<imodesuffix>}\t%0"
1725   [(set_attr "type" "pop")
1726    (set_attr "mode" "<MODE>")])
1727 \f
1728 ;; Move instructions.
1729
1730 (define_expand "movoi"
1731   [(set (match_operand:OI 0 "nonimmediate_operand" "")
1732         (match_operand:OI 1 "general_operand" ""))]
1733   "TARGET_AVX"
1734   "ix86_expand_move (OImode, operands); DONE;")
1735
1736 (define_expand "movti"
1737   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1738         (match_operand:TI 1 "nonimmediate_operand" ""))]
1739   "TARGET_64BIT || TARGET_SSE"
1740 {
1741   if (TARGET_64BIT)
1742     ix86_expand_move (TImode, operands);
1743   else if (push_operand (operands[0], TImode))
1744     ix86_expand_push (TImode, operands[1]);
1745   else
1746     ix86_expand_vector_move (TImode, operands);
1747   DONE;
1748 })
1749
1750 ;; This expands to what emit_move_complex would generate if we didn't
1751 ;; have a movti pattern.  Having this avoids problems with reload on
1752 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1753 ;; to have around all the time.
1754 (define_expand "movcdi"
1755   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1756         (match_operand:CDI 1 "general_operand" ""))]
1757   ""
1758 {
1759   if (push_operand (operands[0], CDImode))
1760     emit_move_complex_push (CDImode, operands[0], operands[1]);
1761   else
1762     emit_move_complex_parts (operands[0], operands[1]);
1763   DONE;
1764 })
1765
1766 (define_expand "mov<mode>"
1767   [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1768         (match_operand:SWI1248x 1 "general_operand" ""))]
1769   ""
1770   "ix86_expand_move (<MODE>mode, operands); DONE;")
1771
1772 (define_insn "*mov<mode>_xor"
1773   [(set (match_operand:SWI48 0 "register_operand" "=r")
1774         (match_operand:SWI48 1 "const0_operand" ""))
1775    (clobber (reg:CC FLAGS_REG))]
1776   "reload_completed"
1777   "xor{l}\t%k0, %k0"
1778   [(set_attr "type" "alu1")
1779    (set_attr "mode" "SI")
1780    (set_attr "length_immediate" "0")])
1781
1782 (define_insn "*mov<mode>_or"
1783   [(set (match_operand:SWI48 0 "register_operand" "=r")
1784         (match_operand:SWI48 1 "const_int_operand" ""))
1785    (clobber (reg:CC FLAGS_REG))]
1786   "reload_completed
1787    && operands[1] == constm1_rtx"
1788   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1789   [(set_attr "type" "alu1")
1790    (set_attr "mode" "<MODE>")
1791    (set_attr "length_immediate" "1")])
1792
1793 (define_insn "*movoi_internal_avx"
1794   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1795         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1796   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1797 {
1798   switch (which_alternative)
1799     {
1800     case 0:
1801       return standard_sse_constant_opcode (insn, operands[1]);
1802     case 1:
1803     case 2:
1804       if (misaligned_operand (operands[0], OImode)
1805           || misaligned_operand (operands[1], OImode))
1806         return "vmovdqu\t{%1, %0|%0, %1}";
1807       else
1808         return "vmovdqa\t{%1, %0|%0, %1}";
1809     default:
1810       gcc_unreachable ();
1811     }
1812 }
1813   [(set_attr "type" "sselog1,ssemov,ssemov")
1814    (set_attr "prefix" "vex")
1815    (set_attr "mode" "OI")])
1816
1817 (define_insn "*movti_internal_rex64"
1818   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1819         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1820   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1821 {
1822   switch (which_alternative)
1823     {
1824     case 0:
1825     case 1:
1826       return "#";
1827     case 2:
1828       return standard_sse_constant_opcode (insn, operands[1]);
1829     case 3:
1830     case 4:
1831       /* TDmode values are passed as TImode on the stack.  Moving them
1832          to stack may result in unaligned memory access.  */
1833       if (misaligned_operand (operands[0], TImode)
1834           || misaligned_operand (operands[1], TImode))
1835         {
1836           if (get_attr_mode (insn) == MODE_V4SF)
1837             return "%vmovups\t{%1, %0|%0, %1}";
1838           else
1839             return "%vmovdqu\t{%1, %0|%0, %1}";
1840         }
1841       else
1842         {
1843           if (get_attr_mode (insn) == MODE_V4SF)
1844             return "%vmovaps\t{%1, %0|%0, %1}";
1845           else
1846             return "%vmovdqa\t{%1, %0|%0, %1}";
1847         }
1848     default:
1849       gcc_unreachable ();
1850     }
1851 }
1852   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1853    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1854    (set (attr "mode")
1855         (cond [(eq_attr "alternative" "2,3")
1856                  (if_then_else
1857                    (match_test "optimize_function_for_size_p (cfun)")
1858                    (const_string "V4SF")
1859                    (const_string "TI"))
1860                (eq_attr "alternative" "4")
1861                  (if_then_else
1862                    (ior (match_test "TARGET_SSE_TYPELESS_STORES")
1863                         (match_test "optimize_function_for_size_p (cfun)"))
1864                    (const_string "V4SF")
1865                    (const_string "TI"))]
1866                (const_string "DI")))])
1867
1868 (define_split
1869   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1870         (match_operand:TI 1 "general_operand" ""))]
1871   "reload_completed
1872    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1873   [(const_int 0)]
1874   "ix86_split_long_move (operands); DONE;")
1875
1876 (define_insn "*movti_internal_sse"
1877   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1878         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1879   "TARGET_SSE && !TARGET_64BIT
1880    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1881 {
1882   switch (which_alternative)
1883     {
1884     case 0:
1885       return standard_sse_constant_opcode (insn, operands[1]);
1886     case 1:
1887     case 2:
1888       /* TDmode values are passed as TImode on the stack.  Moving them
1889          to stack may result in unaligned memory access.  */
1890       if (misaligned_operand (operands[0], TImode)
1891           || misaligned_operand (operands[1], TImode))
1892         {
1893           if (get_attr_mode (insn) == MODE_V4SF)
1894             return "%vmovups\t{%1, %0|%0, %1}";
1895           else
1896             return "%vmovdqu\t{%1, %0|%0, %1}";
1897         }
1898       else
1899         {
1900           if (get_attr_mode (insn) == MODE_V4SF)
1901             return "%vmovaps\t{%1, %0|%0, %1}";
1902           else
1903             return "%vmovdqa\t{%1, %0|%0, %1}";
1904         }
1905     default:
1906       gcc_unreachable ();
1907     }
1908 }
1909   [(set_attr "type" "sselog1,ssemov,ssemov")
1910    (set_attr "prefix" "maybe_vex")
1911    (set (attr "mode")
1912         (cond [(ior (not (match_test "TARGET_SSE2"))
1913                     (match_test "optimize_function_for_size_p (cfun)"))
1914                  (const_string "V4SF")
1915                (and (eq_attr "alternative" "2")
1916                     (match_test "TARGET_SSE_TYPELESS_STORES"))
1917                  (const_string "V4SF")]
1918               (const_string "TI")))])
1919
1920 (define_insn "*movdi_internal_rex64"
1921   [(set (match_operand:DI 0 "nonimmediate_operand"
1922           "=r,r  ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1923         (match_operand:DI 1 "general_operand"
1924           "Z ,rem,i,re,n ,C ,*y ,m  ,*Ym,r   ,C ,*x,*x,m ,*Yi,r   ,*Ym,*x"))]
1925   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1926 {
1927   switch (get_attr_type (insn))
1928     {
1929     case TYPE_SSECVT:
1930       if (SSE_REG_P (operands[0]))
1931         return "movq2dq\t{%1, %0|%0, %1}";
1932       else
1933         return "movdq2q\t{%1, %0|%0, %1}";
1934
1935     case TYPE_SSEMOV:
1936       if (get_attr_mode (insn) == MODE_TI)
1937         return "%vmovdqa\t{%1, %0|%0, %1}";
1938       /* Handle broken assemblers that require movd instead of movq.  */
1939       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1940         return "%vmovd\t{%1, %0|%0, %1}";
1941       else
1942         return "%vmovq\t{%1, %0|%0, %1}";
1943
1944     case TYPE_MMXMOV:
1945       /* Handle broken assemblers that require movd instead of movq.  */
1946       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1947         return "movd\t{%1, %0|%0, %1}";
1948       else
1949         return "movq\t{%1, %0|%0, %1}";
1950
1951     case TYPE_SSELOG1:
1952       return standard_sse_constant_opcode (insn, operands[1]);
1953
1954     case TYPE_MMX:
1955       return "pxor\t%0, %0";
1956
1957     case TYPE_MULTI:
1958       return "#";
1959
1960     case TYPE_LEA:
1961       return "lea{q}\t{%a1, %0|%0, %a1}";
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{%a1, %0|%0, %a1}";
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 "multi")
1978             (eq_attr "alternative" "5")
1979               (const_string "mmx")
1980             (eq_attr "alternative" "6,7,8,9")
1981               (const_string "mmxmov")
1982             (eq_attr "alternative" "10")
1983               (const_string "sselog1")
1984             (eq_attr "alternative" "11,12,13,14,15")
1985               (const_string "ssemov")
1986             (eq_attr "alternative" "16,17")
1987               (const_string "ssecvt")
1988             (match_operand 1 "pic_32bit_operand" "")
1989               (const_string "lea")
1990            ]
1991            (const_string "imov")))
1992    (set (attr "modrm")
1993      (if_then_else
1994        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
1995          (const_string "0")
1996          (const_string "*")))
1997    (set (attr "length_immediate")
1998      (if_then_else
1999        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2000          (const_string "8")
2001          (const_string "*")))
2002    (set (attr "prefix_rex")
2003      (if_then_else (eq_attr "alternative" "8,9")
2004        (const_string "1")
2005        (const_string "*")))
2006    (set (attr "prefix_data16")
2007      (if_then_else (eq_attr "alternative" "11")
2008        (const_string "1")
2009        (const_string "*")))
2010    (set (attr "prefix")
2011      (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2012        (const_string "maybe_vex")
2013        (const_string "orig")))
2014    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2015
2016 ;; Reload patterns to support multi-word load/store
2017 ;; with non-offsetable address.
2018 (define_expand "reload_noff_store"
2019   [(parallel [(match_operand 0 "memory_operand" "=m")
2020               (match_operand 1 "register_operand" "r")
2021               (match_operand:DI 2 "register_operand" "=&r")])]
2022   "TARGET_64BIT"
2023 {
2024   rtx mem = operands[0];
2025   rtx addr = XEXP (mem, 0);
2026
2027   emit_move_insn (operands[2], addr);
2028   mem = replace_equiv_address_nv (mem, operands[2]);
2029
2030   emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2031   DONE;
2032 })
2033
2034 (define_expand "reload_noff_load"
2035   [(parallel [(match_operand 0 "register_operand" "=r")
2036               (match_operand 1 "memory_operand" "m")
2037               (match_operand:DI 2 "register_operand" "=r")])]
2038   "TARGET_64BIT"
2039 {
2040   rtx mem = operands[1];
2041   rtx addr = XEXP (mem, 0);
2042
2043   emit_move_insn (operands[2], addr);
2044   mem = replace_equiv_address_nv (mem, operands[2]);
2045
2046   emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2047   DONE;
2048 })
2049
2050 ;; Convert impossible stores of immediate to existing instructions.
2051 ;; First try to get scratch register and go through it.  In case this
2052 ;; fails, move by 32bit parts.
2053 (define_peephole2
2054   [(match_scratch:DI 2 "r")
2055    (set (match_operand:DI 0 "memory_operand" "")
2056         (match_operand:DI 1 "immediate_operand" ""))]
2057   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2058    && !x86_64_immediate_operand (operands[1], DImode)"
2059   [(set (match_dup 2) (match_dup 1))
2060    (set (match_dup 0) (match_dup 2))])
2061
2062 ;; We need to define this as both peepholer and splitter for case
2063 ;; peephole2 pass is not run.
2064 ;; "&& 1" is needed to keep it from matching the previous pattern.
2065 (define_peephole2
2066   [(set (match_operand:DI 0 "memory_operand" "")
2067         (match_operand:DI 1 "immediate_operand" ""))]
2068   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2069    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2070   [(set (match_dup 2) (match_dup 3))
2071    (set (match_dup 4) (match_dup 5))]
2072   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2073
2074 (define_split
2075   [(set (match_operand:DI 0 "memory_operand" "")
2076         (match_operand:DI 1 "immediate_operand" ""))]
2077   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2078                     ? epilogue_completed : reload_completed)
2079    && !symbolic_operand (operands[1], DImode)
2080    && !x86_64_immediate_operand (operands[1], DImode)"
2081   [(set (match_dup 2) (match_dup 3))
2082    (set (match_dup 4) (match_dup 5))]
2083   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2084
2085 (define_insn "*movdi_internal"
2086   [(set (match_operand:DI 0 "nonimmediate_operand"
2087           "=r  ,o  ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2088         (match_operand:DI 1 "general_operand"
2089           "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2090   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2091 {
2092   switch (get_attr_type (insn))
2093     {
2094     case TYPE_SSECVT:
2095       if (SSE_REG_P (operands[0]))
2096         return "movq2dq\t{%1, %0|%0, %1}";
2097       else
2098         return "movdq2q\t{%1, %0|%0, %1}";
2099
2100     case TYPE_SSEMOV:
2101       switch (get_attr_mode (insn))
2102         {
2103         case MODE_TI:
2104           return "%vmovdqa\t{%1, %0|%0, %1}";
2105         case MODE_DI:
2106            return "%vmovq\t{%1, %0|%0, %1}";
2107         case MODE_V4SF:
2108           return "movaps\t{%1, %0|%0, %1}";
2109         case MODE_V2SF:
2110           return "movlps\t{%1, %0|%0, %1}";
2111         default:
2112           gcc_unreachable ();
2113         }
2114
2115     case TYPE_MMXMOV:
2116       return "movq\t{%1, %0|%0, %1}";
2117
2118     case TYPE_SSELOG1:
2119       return standard_sse_constant_opcode (insn, operands[1]);
2120
2121     case TYPE_MMX:
2122       return "pxor\t%0, %0";
2123
2124     case TYPE_MULTI:
2125       return "#";
2126
2127     default:
2128       gcc_unreachable ();
2129     }
2130 }
2131   [(set (attr "isa")
2132      (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2133               (const_string "sse2")
2134             (eq_attr "alternative" "9,10,11,12")
2135               (const_string "noavx")
2136            ]
2137            (const_string "*")))
2138    (set (attr "type")
2139      (cond [(eq_attr "alternative" "0,1")
2140               (const_string "multi")
2141             (eq_attr "alternative" "2")
2142               (const_string "mmx")
2143             (eq_attr "alternative" "3,4")
2144               (const_string "mmxmov")
2145             (eq_attr "alternative" "5,9")
2146               (const_string "sselog1")
2147             (eq_attr "alternative" "13,14")
2148               (const_string "ssecvt")
2149            ]
2150            (const_string "ssemov")))
2151    (set (attr "prefix")
2152      (if_then_else (eq_attr "alternative" "5,6,7,8")
2153        (const_string "maybe_vex")
2154        (const_string "orig")))
2155    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2156
2157 (define_split
2158   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2159         (match_operand:DI 1 "general_operand" ""))]
2160   "!TARGET_64BIT && reload_completed
2161    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2162    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2163   [(const_int 0)]
2164   "ix86_split_long_move (operands); DONE;")
2165
2166 (define_insn "*movsi_internal"
2167   [(set (match_operand:SI 0 "nonimmediate_operand"
2168                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2169         (match_operand:SI 1 "general_operand"
2170                         "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
2171   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2172 {
2173   switch (get_attr_type (insn))
2174     {
2175     case TYPE_SSELOG1:
2176       return standard_sse_constant_opcode (insn, operands[1]);
2177
2178     case TYPE_SSEMOV:
2179       switch (get_attr_mode (insn))
2180         {
2181         case MODE_TI:
2182           return "%vmovdqa\t{%1, %0|%0, %1}";
2183         case MODE_V4SF:
2184           return "%vmovaps\t{%1, %0|%0, %1}";
2185         case MODE_SI:
2186           return "%vmovd\t{%1, %0|%0, %1}";
2187         case MODE_SF:
2188           return "%vmovss\t{%1, %0|%0, %1}";
2189         default:
2190           gcc_unreachable ();
2191         }
2192
2193     case TYPE_MMX:
2194       return "pxor\t%0, %0";
2195
2196     case TYPE_MMXMOV:
2197       if (get_attr_mode (insn) == MODE_DI)
2198         return "movq\t{%1, %0|%0, %1}";
2199       return "movd\t{%1, %0|%0, %1}";
2200
2201     case TYPE_LEA:
2202       return "lea{l}\t{%a1, %0|%0, %a1}";
2203
2204     default:
2205       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2206       if (ix86_use_lea_for_mov (insn, operands))
2207         return "lea{l}\t{%a1, %0|%0, %a1}";
2208       else
2209         return "mov{l}\t{%1, %0|%0, %1}";
2210     }
2211 }
2212   [(set (attr "type")
2213      (cond [(eq_attr "alternative" "2")
2214               (const_string "mmx")
2215             (eq_attr "alternative" "3,4,5")
2216               (const_string "mmxmov")
2217             (eq_attr "alternative" "6")
2218               (const_string "sselog1")
2219             (eq_attr "alternative" "7,8,9,10,11")
2220               (const_string "ssemov")
2221             (match_operand 1 "pic_32bit_operand" "")
2222               (const_string "lea")
2223            ]
2224            (const_string "imov")))
2225    (set (attr "prefix")
2226      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2227        (const_string "orig")
2228        (const_string "maybe_vex")))
2229    (set (attr "prefix_data16")
2230      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2231        (const_string "1")
2232        (const_string "*")))
2233    (set (attr "mode")
2234      (cond [(eq_attr "alternative" "2,3")
2235               (const_string "DI")
2236             (eq_attr "alternative" "6,7")
2237               (if_then_else
2238                 (not (match_test "TARGET_SSE2"))
2239                 (const_string "V4SF")
2240                 (const_string "TI"))
2241             (and (eq_attr "alternative" "8,9,10,11")
2242                  (not (match_test "TARGET_SSE2")))
2243               (const_string "SF")
2244            ]
2245            (const_string "SI")))])
2246
2247 (define_insn "*movhi_internal"
2248   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2249         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2250   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2251 {
2252   switch (get_attr_type (insn))
2253     {
2254     case TYPE_IMOVX:
2255       /* movzwl is faster than movw on p2 due to partial word stalls,
2256          though not as fast as an aligned movl.  */
2257       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2258     default:
2259       if (get_attr_mode (insn) == MODE_SI)
2260         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2261       else
2262         return "mov{w}\t{%1, %0|%0, %1}";
2263     }
2264 }
2265   [(set (attr "type")
2266      (cond [(match_test "optimize_function_for_size_p (cfun)")
2267               (const_string "imov")
2268             (and (eq_attr "alternative" "0")
2269                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2270                       (not (match_test "TARGET_HIMODE_MATH"))))
2271               (const_string "imov")
2272             (and (eq_attr "alternative" "1,2")
2273                  (match_operand:HI 1 "aligned_operand" ""))
2274               (const_string "imov")
2275             (and (match_test "TARGET_MOVX")
2276                  (eq_attr "alternative" "0,2"))
2277               (const_string "imovx")
2278            ]
2279            (const_string "imov")))
2280     (set (attr "mode")
2281       (cond [(eq_attr "type" "imovx")
2282                (const_string "SI")
2283              (and (eq_attr "alternative" "1,2")
2284                   (match_operand:HI 1 "aligned_operand" ""))
2285                (const_string "SI")
2286              (and (eq_attr "alternative" "0")
2287                   (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2288                        (not (match_test "TARGET_HIMODE_MATH"))))
2289                (const_string "SI")
2290             ]
2291             (const_string "HI")))])
2292
2293 ;; Situation is quite tricky about when to choose full sized (SImode) move
2294 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2295 ;; partial register dependency machines (such as AMD Athlon), where QImode
2296 ;; moves issue extra dependency and for partial register stalls machines
2297 ;; that don't use QImode patterns (and QImode move cause stall on the next
2298 ;; instruction).
2299 ;;
2300 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2301 ;; register stall machines with, where we use QImode instructions, since
2302 ;; partial register stall can be caused there.  Then we use movzx.
2303 (define_insn "*movqi_internal"
2304   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2305         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2306   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2307 {
2308   switch (get_attr_type (insn))
2309     {
2310     case TYPE_IMOVX:
2311       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2312       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2313     default:
2314       if (get_attr_mode (insn) == MODE_SI)
2315         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2316       else
2317         return "mov{b}\t{%1, %0|%0, %1}";
2318     }
2319 }
2320   [(set (attr "type")
2321      (cond [(and (eq_attr "alternative" "5")
2322                  (not (match_operand:QI 1 "aligned_operand" "")))
2323               (const_string "imovx")
2324             (match_test "optimize_function_for_size_p (cfun)")
2325               (const_string "imov")
2326             (and (eq_attr "alternative" "3")
2327                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2328                       (not (match_test "TARGET_QIMODE_MATH"))))
2329               (const_string "imov")
2330             (eq_attr "alternative" "3,5")
2331               (const_string "imovx")
2332             (and (match_test "TARGET_MOVX")
2333                  (eq_attr "alternative" "2"))
2334               (const_string "imovx")
2335            ]
2336            (const_string "imov")))
2337    (set (attr "mode")
2338       (cond [(eq_attr "alternative" "3,4,5")
2339                (const_string "SI")
2340              (eq_attr "alternative" "6")
2341                (const_string "QI")
2342              (eq_attr "type" "imovx")
2343                (const_string "SI")
2344              (and (eq_attr "type" "imov")
2345                   (and (eq_attr "alternative" "0,1")
2346                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2347                             (and (not (match_test "optimize_function_for_size_p (cfun)"))
2348                                  (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2349                (const_string "SI")
2350              ;; Avoid partial register stalls when not using QImode arithmetic
2351              (and (eq_attr "type" "imov")
2352                   (and (eq_attr "alternative" "0,1")
2353                        (and (match_test "TARGET_PARTIAL_REG_STALL")
2354                             (not (match_test "TARGET_QIMODE_MATH")))))
2355                (const_string "SI")
2356            ]
2357            (const_string "QI")))])
2358
2359 ;; Stores and loads of ax to arbitrary constant address.
2360 ;; We fake an second form of instruction to force reload to load address
2361 ;; into register when rax is not available
2362 (define_insn "*movabs<mode>_1"
2363   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2364         (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2365   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2366   "@
2367    movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2368    mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2369   [(set_attr "type" "imov")
2370    (set_attr "modrm" "0,*")
2371    (set_attr "length_address" "8,0")
2372    (set_attr "length_immediate" "0,*")
2373    (set_attr "memory" "store")
2374    (set_attr "mode" "<MODE>")])
2375
2376 (define_insn "*movabs<mode>_2"
2377   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2378         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2379   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2380   "@
2381    movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2382    mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2383   [(set_attr "type" "imov")
2384    (set_attr "modrm" "0,*")
2385    (set_attr "length_address" "8,0")
2386    (set_attr "length_immediate" "0")
2387    (set_attr "memory" "load")
2388    (set_attr "mode" "<MODE>")])
2389
2390 (define_insn "*swap<mode>"
2391   [(set (match_operand:SWI48 0 "register_operand" "+r")
2392         (match_operand:SWI48 1 "register_operand" "+r"))
2393    (set (match_dup 1)
2394         (match_dup 0))]
2395   ""
2396   "xchg{<imodesuffix>}\t%1, %0"
2397   [(set_attr "type" "imov")
2398    (set_attr "mode" "<MODE>")
2399    (set_attr "pent_pair" "np")
2400    (set_attr "athlon_decode" "vector")
2401    (set_attr "amdfam10_decode" "double")
2402    (set_attr "bdver1_decode" "double")])
2403
2404 (define_insn "*swap<mode>_1"
2405   [(set (match_operand:SWI12 0 "register_operand" "+r")
2406         (match_operand:SWI12 1 "register_operand" "+r"))
2407    (set (match_dup 1)
2408         (match_dup 0))]
2409   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2410   "xchg{l}\t%k1, %k0"
2411   [(set_attr "type" "imov")
2412    (set_attr "mode" "SI")
2413    (set_attr "pent_pair" "np")
2414    (set_attr "athlon_decode" "vector")
2415    (set_attr "amdfam10_decode" "double")
2416    (set_attr "bdver1_decode" "double")])
2417
2418 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2419 ;; is disabled for AMDFAM10
2420 (define_insn "*swap<mode>_2"
2421   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2422         (match_operand:SWI12 1 "register_operand" "+<r>"))
2423    (set (match_dup 1)
2424         (match_dup 0))]
2425   "TARGET_PARTIAL_REG_STALL"
2426   "xchg{<imodesuffix>}\t%1, %0"
2427   [(set_attr "type" "imov")
2428    (set_attr "mode" "<MODE>")
2429    (set_attr "pent_pair" "np")
2430    (set_attr "athlon_decode" "vector")])
2431
2432 (define_expand "movstrict<mode>"
2433   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2434         (match_operand:SWI12 1 "general_operand" ""))]
2435   ""
2436 {
2437   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2438     FAIL;
2439   if (GET_CODE (operands[0]) == SUBREG
2440       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2441     FAIL;
2442   /* Don't generate memory->memory moves, go through a register */
2443   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2444     operands[1] = force_reg (<MODE>mode, operands[1]);
2445 })
2446
2447 (define_insn "*movstrict<mode>_1"
2448   [(set (strict_low_part
2449           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2450         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2451   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2452    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2453   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2454   [(set_attr "type" "imov")
2455    (set_attr "mode" "<MODE>")])
2456
2457 (define_insn "*movstrict<mode>_xor"
2458   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2459         (match_operand:SWI12 1 "const0_operand" ""))
2460    (clobber (reg:CC FLAGS_REG))]
2461   "reload_completed"
2462   "xor{<imodesuffix>}\t%0, %0"
2463   [(set_attr "type" "alu1")
2464    (set_attr "mode" "<MODE>")
2465    (set_attr "length_immediate" "0")])
2466
2467 (define_insn "*mov<mode>_extv_1"
2468   [(set (match_operand:SWI24 0 "register_operand" "=R")
2469         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2470                             (const_int 8)
2471                             (const_int 8)))]
2472   ""
2473   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2474   [(set_attr "type" "imovx")
2475    (set_attr "mode" "SI")])
2476
2477 (define_insn "*movqi_extv_1_rex64"
2478   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2479         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2480                          (const_int 8)
2481                          (const_int 8)))]
2482   "TARGET_64BIT"
2483 {
2484   switch (get_attr_type (insn))
2485     {
2486     case TYPE_IMOVX:
2487       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2488     default:
2489       return "mov{b}\t{%h1, %0|%0, %h1}";
2490     }
2491 }
2492   [(set (attr "type")
2493      (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2494                         (match_test "TARGET_MOVX"))
2495         (const_string "imovx")
2496         (const_string "imov")))
2497    (set (attr "mode")
2498      (if_then_else (eq_attr "type" "imovx")
2499         (const_string "SI")
2500         (const_string "QI")))])
2501
2502 (define_insn "*movqi_extv_1"
2503   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2504         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2505                          (const_int 8)
2506                          (const_int 8)))]
2507   "!TARGET_64BIT"
2508 {
2509   switch (get_attr_type (insn))
2510     {
2511     case TYPE_IMOVX:
2512       return "movs{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 (and (match_operand:QI 0 "register_operand" "")
2519                         (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2520                              (match_test "TARGET_MOVX")))
2521         (const_string "imovx")
2522         (const_string "imov")))
2523    (set (attr "mode")
2524      (if_then_else (eq_attr "type" "imovx")
2525         (const_string "SI")
2526         (const_string "QI")))])
2527
2528 (define_insn "*mov<mode>_extzv_1"
2529   [(set (match_operand:SWI48 0 "register_operand" "=R")
2530         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2531                             (const_int 8)
2532                             (const_int 8)))]
2533   ""
2534   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2535   [(set_attr "type" "imovx")
2536    (set_attr "mode" "SI")])
2537
2538 (define_insn "*movqi_extzv_2_rex64"
2539   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2540         (subreg:QI
2541           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2542                            (const_int 8)
2543                            (const_int 8)) 0))]
2544   "TARGET_64BIT"
2545 {
2546   switch (get_attr_type (insn))
2547     {
2548     case TYPE_IMOVX:
2549       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2550     default:
2551       return "mov{b}\t{%h1, %0|%0, %h1}";
2552     }
2553 }
2554   [(set (attr "type")
2555      (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2556                         (match_test "TARGET_MOVX"))
2557         (const_string "imovx")
2558         (const_string "imov")))
2559    (set (attr "mode")
2560      (if_then_else (eq_attr "type" "imovx")
2561         (const_string "SI")
2562         (const_string "QI")))])
2563
2564 (define_insn "*movqi_extzv_2"
2565   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2566         (subreg:QI
2567           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2568                            (const_int 8)
2569                            (const_int 8)) 0))]
2570   "!TARGET_64BIT"
2571 {
2572   switch (get_attr_type (insn))
2573     {
2574     case TYPE_IMOVX:
2575       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2576     default:
2577       return "mov{b}\t{%h1, %0|%0, %h1}";
2578     }
2579 }
2580   [(set (attr "type")
2581      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2582                         (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2583                              (match_test "TARGET_MOVX")))
2584         (const_string "imovx")
2585         (const_string "imov")))
2586    (set (attr "mode")
2587      (if_then_else (eq_attr "type" "imovx")
2588         (const_string "SI")
2589         (const_string "QI")))])
2590
2591 (define_expand "mov<mode>_insv_1"
2592   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2593                             (const_int 8)
2594                             (const_int 8))
2595         (match_operand:SWI48 1 "nonmemory_operand" ""))])
2596
2597 (define_insn "*mov<mode>_insv_1_rex64"
2598   [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2599                              (const_int 8)
2600                              (const_int 8))
2601         (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2602   "TARGET_64BIT"
2603   "mov{b}\t{%b1, %h0|%h0, %b1}"
2604   [(set_attr "type" "imov")
2605    (set_attr "mode" "QI")])
2606
2607 (define_insn "*movsi_insv_1"
2608   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2609                          (const_int 8)
2610                          (const_int 8))
2611         (match_operand:SI 1 "general_operand" "Qmn"))]
2612   "!TARGET_64BIT"
2613   "mov{b}\t{%b1, %h0|%h0, %b1}"
2614   [(set_attr "type" "imov")
2615    (set_attr "mode" "QI")])
2616
2617 (define_insn "*movqi_insv_2"
2618   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2619                          (const_int 8)
2620                          (const_int 8))
2621         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2622                      (const_int 8)))]
2623   ""
2624   "mov{b}\t{%h1, %h0|%h0, %h1}"
2625   [(set_attr "type" "imov")
2626    (set_attr "mode" "QI")])
2627 \f
2628 ;; Floating point push instructions.
2629
2630 (define_insn "*pushtf"
2631   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2632         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2633   "TARGET_SSE2"
2634 {
2635   /* This insn should be already split before reg-stack.  */
2636   gcc_unreachable ();
2637 }
2638   [(set_attr "type" "multi")
2639    (set_attr "unit" "sse,*,*")
2640    (set_attr "mode" "TF,SI,SI")])
2641
2642 ;; %%% Kill this when call knows how to work this out.
2643 (define_split
2644   [(set (match_operand:TF 0 "push_operand" "")
2645         (match_operand:TF 1 "sse_reg_operand" ""))]
2646   "TARGET_SSE2 && reload_completed"
2647   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2648    (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2649
2650 (define_insn "*pushxf"
2651   [(set (match_operand:XF 0 "push_operand" "=<,<")
2652         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2653   "optimize_function_for_speed_p (cfun)"
2654 {
2655   /* This insn should be already split before reg-stack.  */
2656   gcc_unreachable ();
2657 }
2658   [(set_attr "type" "multi")
2659    (set_attr "unit" "i387,*")
2660    (set_attr "mode" "XF,SI")])
2661
2662 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2663 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2664 ;; Pushing using integer instructions is longer except for constants
2665 ;; and direct memory references (assuming that any given constant is pushed
2666 ;; only once, but this ought to be handled elsewhere).
2667
2668 (define_insn "*pushxf_nointeger"
2669   [(set (match_operand:XF 0 "push_operand" "=<,<")
2670         (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2671   "optimize_function_for_size_p (cfun)"
2672 {
2673   /* This insn should be already split before reg-stack.  */
2674   gcc_unreachable ();
2675 }
2676   [(set_attr "type" "multi")
2677    (set_attr "unit" "i387,*")
2678    (set_attr "mode" "XF,SI")])
2679
2680 ;; %%% Kill this when call knows how to work this out.
2681 (define_split
2682   [(set (match_operand:XF 0 "push_operand" "")
2683         (match_operand:XF 1 "fp_register_operand" ""))]
2684   "reload_completed"
2685   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2686    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2687   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2688
2689 (define_insn "*pushdf_rex64"
2690   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2691         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2692   "TARGET_64BIT"
2693 {
2694   /* This insn should be already split before reg-stack.  */
2695   gcc_unreachable ();
2696 }
2697   [(set_attr "type" "multi")
2698    (set_attr "unit" "i387,*,*")
2699    (set_attr "mode" "DF,DI,DF")])
2700
2701 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2702 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2703 ;; On the average, pushdf using integers can be still shorter.
2704
2705 (define_insn "*pushdf"
2706   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2707         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2708   "!TARGET_64BIT"
2709 {
2710   /* This insn should be already split before reg-stack.  */
2711   gcc_unreachable ();
2712 }
2713   [(set_attr "isa" "*,*,sse2")
2714    (set_attr "type" "multi")
2715    (set_attr "unit" "i387,*,*")
2716    (set_attr "mode" "DF,DI,DF")])
2717
2718 ;; %%% Kill this when call knows how to work this out.
2719 (define_split
2720   [(set (match_operand:DF 0 "push_operand" "")
2721         (match_operand:DF 1 "any_fp_register_operand" ""))]
2722   "reload_completed"
2723   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2724    (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2725
2726 (define_insn "*pushsf_rex64"
2727   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2728         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2729   "TARGET_64BIT"
2730 {
2731   /* Anything else should be already split before reg-stack.  */
2732   gcc_assert (which_alternative == 1);
2733   return "push{q}\t%q1";
2734 }
2735   [(set_attr "type" "multi,push,multi")
2736    (set_attr "unit" "i387,*,*")
2737    (set_attr "mode" "SF,DI,SF")])
2738
2739 (define_insn "*pushsf"
2740   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2741         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2742   "!TARGET_64BIT"
2743 {
2744   /* Anything else should be already split before reg-stack.  */
2745   gcc_assert (which_alternative == 1);
2746   return "push{l}\t%1";
2747 }
2748   [(set_attr "type" "multi,push,multi")
2749    (set_attr "unit" "i387,*,*")
2750    (set_attr "mode" "SF,SI,SF")])
2751
2752 ;; %%% Kill this when call knows how to work this out.
2753 (define_split
2754   [(set (match_operand:SF 0 "push_operand" "")
2755         (match_operand:SF 1 "any_fp_register_operand" ""))]
2756   "reload_completed"
2757   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2758    (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2759   "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2760
2761 (define_split
2762   [(set (match_operand:SF 0 "push_operand" "")
2763         (match_operand:SF 1 "memory_operand" ""))]
2764   "reload_completed
2765    && (operands[2] = find_constant_src (insn))"
2766   [(set (match_dup 0) (match_dup 2))])
2767
2768 (define_split
2769   [(set (match_operand 0 "push_operand" "")
2770         (match_operand 1 "general_operand" ""))]
2771   "reload_completed
2772    && (GET_MODE (operands[0]) == TFmode
2773        || GET_MODE (operands[0]) == XFmode
2774        || GET_MODE (operands[0]) == DFmode)
2775    && !ANY_FP_REG_P (operands[1])"
2776   [(const_int 0)]
2777   "ix86_split_long_move (operands); DONE;")
2778 \f
2779 ;; Floating point move instructions.
2780
2781 (define_expand "movtf"
2782   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2783         (match_operand:TF 1 "nonimmediate_operand" ""))]
2784   "TARGET_SSE2"
2785 {
2786   ix86_expand_move (TFmode, operands);
2787   DONE;
2788 })
2789
2790 (define_expand "mov<mode>"
2791   [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2792         (match_operand:X87MODEF 1 "general_operand" ""))]
2793   ""
2794   "ix86_expand_move (<MODE>mode, operands); DONE;")
2795
2796 (define_insn "*movtf_internal"
2797   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2798         (match_operand:TF 1 "general_operand"      "xm,x,C,*roF,F*r"))]
2799   "TARGET_SSE2
2800    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2801    && (!can_create_pseudo_p ()
2802        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2803        || GET_CODE (operands[1]) != CONST_DOUBLE
2804        || (optimize_function_for_size_p (cfun)
2805            && standard_sse_constant_p (operands[1])
2806            && !memory_operand (operands[0], TFmode))
2807        || (!TARGET_MEMORY_MISMATCH_STALL
2808            && memory_operand (operands[0], TFmode)))"
2809 {
2810   switch (which_alternative)
2811     {
2812     case 0:
2813     case 1:
2814       /* Handle misaligned load/store since we
2815          don't have movmisaligntf pattern. */
2816       if (misaligned_operand (operands[0], TFmode)
2817           || misaligned_operand (operands[1], TFmode))
2818         {
2819           if (get_attr_mode (insn) == MODE_V4SF)
2820             return "%vmovups\t{%1, %0|%0, %1}";
2821           else
2822             return "%vmovdqu\t{%1, %0|%0, %1}";
2823         }
2824       else
2825         {
2826           if (get_attr_mode (insn) == MODE_V4SF)
2827             return "%vmovaps\t{%1, %0|%0, %1}";
2828           else
2829             return "%vmovdqa\t{%1, %0|%0, %1}";
2830         }
2831
2832     case 2:
2833       return standard_sse_constant_opcode (insn, operands[1]);
2834
2835     case 3:
2836     case 4:
2837         return "#";
2838
2839     default:
2840       gcc_unreachable ();
2841     }
2842 }
2843   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2844    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2845    (set (attr "mode")
2846         (cond [(eq_attr "alternative" "0,2")
2847                  (if_then_else
2848                    (match_test "optimize_function_for_size_p (cfun)")
2849                    (const_string "V4SF")
2850                    (const_string "TI"))
2851                (eq_attr "alternative" "1")
2852                  (if_then_else
2853                    (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2854                         (match_test "optimize_function_for_size_p (cfun)"))
2855                    (const_string "V4SF")
2856                    (const_string "TI"))]
2857                (const_string "DI")))])
2858
2859 ;; Possible store forwarding (partial memory) stall in alternative 4.
2860 (define_insn "*movxf_internal"
2861   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2862         (match_operand:XF 1 "general_operand"      "fm,f,G,Yx*roF,FYx*r"))]
2863   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2864    && (!can_create_pseudo_p ()
2865        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2866        || GET_CODE (operands[1]) != CONST_DOUBLE
2867        || (optimize_function_for_size_p (cfun)
2868            && standard_80387_constant_p (operands[1]) > 0
2869            && !memory_operand (operands[0], XFmode))
2870        || (!TARGET_MEMORY_MISMATCH_STALL
2871            && memory_operand (operands[0], XFmode)))"
2872 {
2873   switch (which_alternative)
2874     {
2875     case 0:
2876     case 1:
2877       return output_387_reg_move (insn, operands);
2878
2879     case 2:
2880       return standard_80387_constant_opcode (operands[1]);
2881
2882     case 3:
2883     case 4:
2884       return "#";
2885
2886     default:
2887       gcc_unreachable ();
2888     }
2889 }
2890   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2891    (set_attr "mode" "XF,XF,XF,SI,SI")])
2892
2893 (define_insn "*movdf_internal_rex64"
2894   [(set (match_operand:DF 0 "nonimmediate_operand"
2895                 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2896         (match_operand:DF 1 "general_operand"
2897                 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2898   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2899    && (!can_create_pseudo_p ()
2900        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2901        || GET_CODE (operands[1]) != CONST_DOUBLE
2902        || (optimize_function_for_size_p (cfun)
2903            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2904                 && standard_80387_constant_p (operands[1]) > 0)
2905                || (TARGET_SSE2 && TARGET_SSE_MATH
2906                    && standard_sse_constant_p (operands[1]))))
2907        || memory_operand (operands[0], DFmode))"
2908 {
2909   switch (which_alternative)
2910     {
2911     case 0:
2912     case 1:
2913       return output_387_reg_move (insn, operands);
2914
2915     case 2:
2916       return standard_80387_constant_opcode (operands[1]);
2917
2918     case 3:
2919     case 4:
2920       return "mov{q}\t{%1, %0|%0, %1}";
2921
2922     case 5:
2923       return "movabs{q}\t{%1, %0|%0, %1}";
2924
2925     case 6:
2926       return "#";
2927
2928     case 7:
2929       return standard_sse_constant_opcode (insn, operands[1]);
2930
2931     case 8:
2932     case 9:
2933     case 10:
2934       switch (get_attr_mode (insn))
2935         {
2936         case MODE_V2DF:
2937           if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2938             return "%vmovapd\t{%1, %0|%0, %1}";
2939         case MODE_V4SF:
2940           return "%vmovaps\t{%1, %0|%0, %1}";
2941
2942         case MODE_DI:
2943           return "%vmovq\t{%1, %0|%0, %1}";
2944         case MODE_DF:
2945           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2946             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2947           return "%vmovsd\t{%1, %0|%0, %1}";
2948         case MODE_V1DF:
2949           return "%vmovlpd\t{%1, %d0|%d0, %1}";
2950         case MODE_V2SF:
2951           return "%vmovlps\t{%1, %d0|%d0, %1}";
2952         default:
2953           gcc_unreachable ();
2954         }
2955
2956     case 11:
2957     case 12:
2958       /* Handle broken assemblers that require movd instead of movq.  */
2959       return "%vmovd\t{%1, %0|%0, %1}";
2960
2961     default:
2962       gcc_unreachable();
2963     }
2964 }
2965   [(set (attr "type")
2966         (cond [(eq_attr "alternative" "0,1,2")
2967                  (const_string "fmov")
2968                (eq_attr "alternative" "3,4,5")
2969                  (const_string "imov")
2970                (eq_attr "alternative" "6")
2971                  (const_string "multi")
2972                (eq_attr "alternative" "7")
2973                  (const_string "sselog1")
2974               ]
2975               (const_string "ssemov")))
2976    (set (attr "modrm")
2977      (if_then_else
2978        (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2979          (const_string "0")
2980          (const_string "*")))
2981    (set (attr "length_immediate")
2982      (if_then_else
2983        (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2984          (const_string "8")
2985          (const_string "*")))
2986    (set (attr "prefix")
2987      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
2988        (const_string "orig")
2989        (const_string "maybe_vex")))
2990    (set (attr "prefix_data16")
2991      (if_then_else (eq_attr "mode" "V1DF")
2992        (const_string "1")
2993        (const_string "*")))
2994    (set (attr "mode")
2995         (cond [(eq_attr "alternative" "0,1,2")
2996                  (const_string "DF")
2997                (eq_attr "alternative" "3,4,5,6,11,12")
2998                  (const_string "DI")
2999
3000                /* xorps is one byte shorter.  */
3001                (eq_attr "alternative" "7")
3002                  (cond [(match_test "optimize_function_for_size_p (cfun)")
3003                           (const_string "V4SF")
3004                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3005                           (const_string "TI")
3006                        ]
3007                        (const_string "V2DF"))
3008
3009                /* For architectures resolving dependencies on
3010                   whole SSE registers use APD move to break dependency
3011                   chains, otherwise use short move to avoid extra work.
3012
3013                   movaps encodes one byte shorter.  */
3014                (eq_attr "alternative" "8")
3015                  (cond
3016                    [(match_test "optimize_function_for_size_p (cfun)")
3017                       (const_string "V4SF")
3018                     (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3019                       (const_string "V2DF")
3020                    ]
3021                    (const_string "DF"))
3022                /* For architectures resolving dependencies on register
3023                   parts we may avoid extra work to zero out upper part
3024                   of register.  */
3025                (eq_attr "alternative" "9")
3026                  (if_then_else
3027                    (match_test "TARGET_SSE_SPLIT_REGS")
3028                    (const_string "V1DF")
3029                    (const_string "DF"))
3030               ]
3031               (const_string "DF")))])
3032
3033 ;; Possible store forwarding (partial memory) stall in alternative 4.
3034 (define_insn "*movdf_internal"
3035   [(set (match_operand:DF 0 "nonimmediate_operand"
3036                 "=f,m,f,?Yd*r ,!o   ,x,x,x,m,*x,*x,*x,m")
3037         (match_operand:DF 1 "general_operand"
3038                 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3039   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3040    && (!can_create_pseudo_p ()
3041        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3042        || GET_CODE (operands[1]) != CONST_DOUBLE
3043        || (optimize_function_for_size_p (cfun)
3044            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3045                 && standard_80387_constant_p (operands[1]) > 0)
3046                || (TARGET_SSE2 && TARGET_SSE_MATH
3047                    && standard_sse_constant_p (operands[1])))
3048            && !memory_operand (operands[0], DFmode))
3049        || (!TARGET_MEMORY_MISMATCH_STALL
3050            && memory_operand (operands[0], DFmode)))"
3051 {
3052   switch (which_alternative)
3053     {
3054     case 0:
3055     case 1:
3056       return output_387_reg_move (insn, operands);
3057
3058     case 2:
3059       return standard_80387_constant_opcode (operands[1]);
3060
3061     case 3:
3062     case 4:
3063       return "#";
3064
3065     case 5:
3066     case 9:
3067       return standard_sse_constant_opcode (insn, operands[1]);
3068
3069     case 6:
3070     case 7:
3071     case 8:
3072     case 10:
3073     case 11:
3074     case 12:
3075       switch (get_attr_mode (insn))
3076         {
3077         case MODE_V2DF:
3078           if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3079             return "%vmovapd\t{%1, %0|%0, %1}";
3080         case MODE_V4SF:
3081           return "%vmovaps\t{%1, %0|%0, %1}";
3082
3083         case MODE_DI:
3084           return "%vmovq\t{%1, %0|%0, %1}";
3085         case MODE_DF:
3086           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3087             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3088           return "%vmovsd\t{%1, %0|%0, %1}";
3089         case MODE_V1DF:
3090           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3091         case MODE_V2SF:
3092           return "%vmovlps\t{%1, %d0|%d0, %1}";
3093         default:
3094           gcc_unreachable ();
3095         }
3096
3097     default:
3098       gcc_unreachable ();
3099     }
3100 }
3101   [(set (attr "isa")
3102      (if_then_else (eq_attr "alternative" "5,6,7,8")
3103        (const_string "sse2")
3104        (const_string "*")))
3105    (set (attr "type")
3106         (cond [(eq_attr "alternative" "0,1,2")
3107                  (const_string "fmov")
3108                (eq_attr "alternative" "3,4")
3109                  (const_string "multi")
3110                (eq_attr "alternative" "5,9")
3111                  (const_string "sselog1")
3112               ]
3113               (const_string "ssemov")))
3114    (set (attr "prefix")
3115      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3116        (const_string "orig")
3117        (const_string "maybe_vex")))
3118    (set (attr "prefix_data16")
3119      (if_then_else (eq_attr "mode" "V1DF")
3120        (const_string "1")
3121        (const_string "*")))
3122    (set (attr "mode")
3123         (cond [(eq_attr "alternative" "0,1,2")
3124                  (const_string "DF")
3125                (eq_attr "alternative" "3,4")
3126                  (const_string "SI")
3127
3128                /* For SSE1, we have many fewer alternatives.  */
3129                (not (match_test "TARGET_SSE2"))
3130                  (if_then_else
3131                    (eq_attr "alternative" "5,6,9,10")
3132                    (const_string "V4SF")
3133                    (const_string "V2SF"))
3134
3135                /* xorps is one byte shorter.  */
3136                (eq_attr "alternative" "5,9")
3137                  (cond [(match_test "optimize_function_for_size_p (cfun)")
3138                           (const_string "V4SF")
3139                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3140                           (const_string "TI")
3141                        ]
3142                        (const_string "V2DF"))
3143
3144                /* For architectures resolving dependencies on
3145                   whole SSE registers use APD move to break dependency
3146                   chains, otherwise use short move to avoid extra work.
3147
3148                   movaps encodes one byte shorter.  */
3149                (eq_attr "alternative" "6,10")
3150                  (cond
3151                    [(match_test "optimize_function_for_size_p (cfun)")
3152                       (const_string "V4SF")
3153                     (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3154                       (const_string "V2DF")
3155                    ]
3156                    (const_string "DF"))
3157                /* For architectures resolving dependencies on register
3158                   parts we may avoid extra work to zero out upper part
3159                   of register.  */
3160                (eq_attr "alternative" "7,11")
3161                  (if_then_else
3162                    (match_test "TARGET_SSE_SPLIT_REGS")
3163                    (const_string "V1DF")
3164                    (const_string "DF"))
3165               ]
3166               (const_string "DF")))])
3167
3168 (define_insn "*movsf_internal"
3169   [(set (match_operand:SF 0 "nonimmediate_operand"
3170           "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3171         (match_operand:SF 1 "general_operand"
3172           "fm,f,G,rmF,Fr,C,x,m,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
3173   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3174    && (!can_create_pseudo_p ()
3175        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3176        || GET_CODE (operands[1]) != CONST_DOUBLE
3177        || (optimize_function_for_size_p (cfun)
3178            && ((!TARGET_SSE_MATH
3179                 && standard_80387_constant_p (operands[1]) > 0)
3180                || (TARGET_SSE_MATH
3181                    && standard_sse_constant_p (operands[1]))))
3182        || memory_operand (operands[0], SFmode))"
3183 {
3184   switch (which_alternative)
3185     {
3186     case 0:
3187     case 1:
3188       return output_387_reg_move (insn, operands);
3189
3190     case 2:
3191       return standard_80387_constant_opcode (operands[1]);
3192
3193     case 3:
3194     case 4:
3195       return "mov{l}\t{%1, %0|%0, %1}";
3196
3197     case 5:
3198       return standard_sse_constant_opcode (insn, operands[1]);
3199
3200     case 6:
3201       if (get_attr_mode (insn) == MODE_V4SF)
3202         return "%vmovaps\t{%1, %0|%0, %1}";
3203       if (TARGET_AVX)
3204         return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3205
3206     case 7:
3207     case 8:
3208       return "%vmovss\t{%1, %0|%0, %1}";
3209
3210     case 9:
3211     case 10:
3212     case 14:
3213     case 15:
3214       return "movd\t{%1, %0|%0, %1}";
3215
3216     case 11:
3217       return "movq\t{%1, %0|%0, %1}";
3218
3219     case 12:
3220     case 13:
3221       return "%vmovd\t{%1, %0|%0, %1}";
3222
3223     default:
3224       gcc_unreachable ();
3225     }
3226 }
3227   [(set (attr "type")
3228         (cond [(eq_attr "alternative" "0,1,2")
3229                  (const_string "fmov")
3230                (eq_attr "alternative" "3,4")
3231                  (const_string "multi")
3232                (eq_attr "alternative" "5")
3233                  (const_string "sselog1")
3234                (eq_attr "alternative" "9,10,11,14,15")
3235                  (const_string "mmxmov")
3236               ]
3237               (const_string "ssemov")))
3238    (set (attr "prefix")
3239      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3240        (const_string "maybe_vex")
3241        (const_string "orig")))
3242    (set (attr "mode")
3243         (cond [(eq_attr "alternative" "3,4,9,10")
3244                  (const_string "SI")
3245                (eq_attr "alternative" "5")
3246                  (if_then_else
3247                    (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3248                              (match_test "TARGET_SSE2"))
3249                         (not (match_test "optimize_function_for_size_p (cfun)")))
3250                    (const_string "TI")
3251                    (const_string "V4SF"))
3252                /* For architectures resolving dependencies on
3253                   whole SSE registers use APS move to break dependency
3254                   chains, otherwise use short move to avoid extra work.
3255
3256                   Do the same for architectures resolving dependencies on
3257                   the parts.  While in DF mode it is better to always handle
3258                   just register parts, the SF mode is different due to lack
3259                   of instructions to load just part of the register.  It is
3260                   better to maintain the whole registers in single format
3261                   to avoid problems on using packed logical operations.  */
3262                (eq_attr "alternative" "6")
3263                  (if_then_else
3264                    (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3265                         (match_test "TARGET_SSE_SPLIT_REGS"))
3266                    (const_string "V4SF")
3267                    (const_string "SF"))
3268                (eq_attr "alternative" "11")
3269                  (const_string "DI")]
3270                (const_string "SF")))])
3271
3272 (define_split
3273   [(set (match_operand 0 "any_fp_register_operand" "")
3274         (match_operand 1 "memory_operand" ""))]
3275   "reload_completed
3276    && (GET_MODE (operands[0]) == TFmode
3277        || GET_MODE (operands[0]) == XFmode
3278        || GET_MODE (operands[0]) == DFmode
3279        || GET_MODE (operands[0]) == SFmode)
3280    && (operands[2] = find_constant_src (insn))"
3281   [(set (match_dup 0) (match_dup 2))]
3282 {
3283   rtx c = operands[2];
3284   int r = REGNO (operands[0]);
3285
3286   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3287       || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3288     FAIL;
3289 })
3290
3291 (define_split
3292   [(set (match_operand 0 "any_fp_register_operand" "")
3293         (float_extend (match_operand 1 "memory_operand" "")))]
3294   "reload_completed
3295    && (GET_MODE (operands[0]) == TFmode
3296        || GET_MODE (operands[0]) == XFmode
3297        || GET_MODE (operands[0]) == DFmode)
3298    && (operands[2] = find_constant_src (insn))"
3299   [(set (match_dup 0) (match_dup 2))]
3300 {
3301   rtx c = operands[2];
3302   int r = REGNO (operands[0]);
3303
3304   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3305       || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3306     FAIL;
3307 })
3308
3309 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3310 (define_split
3311   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3312         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3313   "reload_completed
3314    && (standard_80387_constant_p (operands[1]) == 8
3315        || standard_80387_constant_p (operands[1]) == 9)"
3316   [(set (match_dup 0)(match_dup 1))
3317    (set (match_dup 0)
3318         (neg:X87MODEF (match_dup 0)))]
3319 {
3320   REAL_VALUE_TYPE r;
3321
3322   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3323   if (real_isnegzero (&r))
3324     operands[1] = CONST0_RTX (<MODE>mode);
3325   else
3326     operands[1] = CONST1_RTX (<MODE>mode);
3327 })
3328
3329 (define_split
3330   [(set (match_operand 0 "nonimmediate_operand" "")
3331         (match_operand 1 "general_operand" ""))]
3332   "reload_completed
3333    && (GET_MODE (operands[0]) == TFmode
3334        || GET_MODE (operands[0]) == XFmode
3335        || GET_MODE (operands[0]) == DFmode)
3336    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3337   [(const_int 0)]
3338   "ix86_split_long_move (operands); DONE;")
3339
3340 (define_insn "swapxf"
3341   [(set (match_operand:XF 0 "register_operand" "+f")
3342         (match_operand:XF 1 "register_operand" "+f"))
3343    (set (match_dup 1)
3344         (match_dup 0))]
3345   "TARGET_80387"
3346 {
3347   if (STACK_TOP_P (operands[0]))
3348     return "fxch\t%1";
3349   else
3350     return "fxch\t%0";
3351 }
3352   [(set_attr "type" "fxch")
3353    (set_attr "mode" "XF")])
3354
3355 (define_insn "*swap<mode>"
3356   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3357         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3358    (set (match_dup 1)
3359         (match_dup 0))]
3360   "TARGET_80387 || reload_completed"
3361 {
3362   if (STACK_TOP_P (operands[0]))
3363     return "fxch\t%1";
3364   else
3365     return "fxch\t%0";
3366 }
3367   [(set_attr "type" "fxch")
3368    (set_attr "mode" "<MODE>")])
3369 \f
3370 ;; Zero extension instructions
3371
3372 (define_expand "zero_extendsidi2"
3373   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3374         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3375   ""
3376 {
3377   if (!TARGET_64BIT)
3378     {
3379       emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3380       DONE;
3381     }
3382 })
3383
3384 (define_insn "*zero_extendsidi2_rex64"
3385   [(set (match_operand:DI 0 "nonimmediate_operand"  "=r,o,?*Ym,?*y,?*Yi,*x")
3386         (zero_extend:DI
3387          (match_operand:SI 1 "nonimmediate_operand" "rm,0,r   ,m  ,r   ,m")))]
3388   "TARGET_64BIT"
3389   "@
3390    mov{l}\t{%1, %k0|%k0, %1}
3391    #
3392    movd\t{%1, %0|%0, %1}
3393    movd\t{%1, %0|%0, %1}
3394    %vmovd\t{%1, %0|%0, %1}
3395    %vmovd\t{%1, %0|%0, %1}"
3396   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3397    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3398    (set_attr "prefix_0f" "0,*,*,*,*,*")
3399    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3400
3401 (define_split
3402   [(set (match_operand:DI 0 "memory_operand" "")
3403         (zero_extend:DI (match_dup 0)))]
3404   "TARGET_64BIT"
3405   [(set (match_dup 4) (const_int 0))]
3406   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3407
3408 ;; %%% Kill me once multi-word ops are sane.
3409 (define_insn "zero_extendsidi2_1"
3410   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*x")
3411         (zero_extend:DI
3412          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3413    (clobber (reg:CC FLAGS_REG))]
3414   "!TARGET_64BIT"
3415   "@
3416    #
3417    #
3418    #
3419    movd\t{%1, %0|%0, %1}
3420    movd\t{%1, %0|%0, %1}
3421    %vmovd\t{%1, %0|%0, %1}
3422    %vmovd\t{%1, %0|%0, %1}"
3423   [(set_attr "isa" "*,*,*,*,*,*,sse2")
3424    (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3425    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3426    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3427
3428 (define_split
3429   [(set (match_operand:DI 0 "register_operand" "")
3430         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3431    (clobber (reg:CC FLAGS_REG))]
3432   "!TARGET_64BIT && reload_completed
3433    && true_regnum (operands[0]) == true_regnum (operands[1])"
3434   [(set (match_dup 4) (const_int 0))]
3435   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3436
3437 (define_split
3438   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3439         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3440    (clobber (reg:CC FLAGS_REG))]
3441   "!TARGET_64BIT && reload_completed
3442    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3443   [(set (match_dup 3) (match_dup 1))
3444    (set (match_dup 4) (const_int 0))]
3445   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3446
3447 (define_insn "zero_extend<mode>di2"
3448   [(set (match_operand:DI 0 "register_operand" "=r")
3449         (zero_extend:DI
3450          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3451   "TARGET_64BIT"
3452   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3453   [(set_attr "type" "imovx")
3454    (set_attr "mode" "SI")])
3455
3456 (define_expand "zero_extendhisi2"
3457   [(set (match_operand:SI 0 "register_operand" "")
3458         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3459   ""
3460 {
3461   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3462     {
3463       operands[1] = force_reg (HImode, operands[1]);
3464       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3465       DONE;
3466     }
3467 })
3468
3469 (define_insn_and_split "zero_extendhisi2_and"
3470   [(set (match_operand:SI 0 "register_operand" "=r")
3471         (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3472    (clobber (reg:CC FLAGS_REG))]
3473   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3474   "#"
3475   "&& reload_completed"
3476   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3477               (clobber (reg:CC FLAGS_REG))])]
3478   ""
3479   [(set_attr "type" "alu1")
3480    (set_attr "mode" "SI")])
3481
3482 (define_insn "*zero_extendhisi2_movzwl"
3483   [(set (match_operand:SI 0 "register_operand" "=r")
3484         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3485   "!TARGET_ZERO_EXTEND_WITH_AND
3486    || optimize_function_for_size_p (cfun)"
3487   "movz{wl|x}\t{%1, %0|%0, %1}"
3488   [(set_attr "type" "imovx")
3489    (set_attr "mode" "SI")])
3490
3491 (define_expand "zero_extendqi<mode>2"
3492   [(parallel
3493     [(set (match_operand:SWI24 0 "register_operand" "")
3494           (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3495      (clobber (reg:CC FLAGS_REG))])])
3496
3497 (define_insn "*zero_extendqi<mode>2_and"
3498   [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3499         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3500    (clobber (reg:CC FLAGS_REG))]
3501   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3502   "#"
3503   [(set_attr "type" "alu1")
3504    (set_attr "mode" "<MODE>")])
3505
3506 ;; When source and destination does not overlap, clear destination
3507 ;; first and then do the movb
3508 (define_split
3509   [(set (match_operand:SWI24 0 "register_operand" "")
3510         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3511    (clobber (reg:CC FLAGS_REG))]
3512   "reload_completed
3513    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3514    && ANY_QI_REG_P (operands[0])
3515    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3516    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3517   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3518 {
3519   operands[2] = gen_lowpart (QImode, operands[0]);
3520   ix86_expand_clear (operands[0]);
3521 })
3522
3523 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3524   [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3525         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3526    (clobber (reg:CC FLAGS_REG))]
3527   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3528   "#"
3529   [(set_attr "type" "imovx,alu1")
3530    (set_attr "mode" "<MODE>")])
3531
3532 ;; For the movzbl case strip only the clobber
3533 (define_split
3534   [(set (match_operand:SWI24 0 "register_operand" "")
3535         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3536    (clobber (reg:CC FLAGS_REG))]
3537   "reload_completed
3538    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3539    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3540   [(set (match_dup 0)
3541         (zero_extend:SWI24 (match_dup 1)))])
3542
3543 ; zero extend to SImode to avoid partial register stalls
3544 (define_insn "*zero_extendqi<mode>2_movzbl"
3545   [(set (match_operand:SWI24 0 "register_operand" "=r")
3546         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3547   "reload_completed
3548    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3549   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3550   [(set_attr "type" "imovx")
3551    (set_attr "mode" "SI")])
3552
3553 ;; Rest is handled by single and.
3554 (define_split
3555   [(set (match_operand:SWI24 0 "register_operand" "")
3556         (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3557    (clobber (reg:CC FLAGS_REG))]
3558   "reload_completed
3559    && true_regnum (operands[0]) == true_regnum (operands[1])"
3560   [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3561               (clobber (reg:CC FLAGS_REG))])])
3562 \f
3563 ;; Sign extension instructions
3564
3565 (define_expand "extendsidi2"
3566   [(set (match_operand:DI 0 "register_operand" "")
3567         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3568   ""
3569 {
3570   if (!TARGET_64BIT)
3571     {
3572       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3573       DONE;
3574     }
3575 })
3576
3577 (define_insn "*extendsidi2_rex64"
3578   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3579         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3580   "TARGET_64BIT"
3581   "@
3582    {cltq|cdqe}
3583    movs{lq|x}\t{%1, %0|%0, %1}"
3584   [(set_attr "type" "imovx")
3585    (set_attr "mode" "DI")
3586    (set_attr "prefix_0f" "0")
3587    (set_attr "modrm" "0,1")])
3588
3589 (define_insn "extendsidi2_1"
3590   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3591         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3592    (clobber (reg:CC FLAGS_REG))
3593    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3594   "!TARGET_64BIT"
3595   "#")
3596
3597 ;; Extend to memory case when source register does die.
3598 (define_split
3599   [(set (match_operand:DI 0 "memory_operand" "")
3600         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3601    (clobber (reg:CC FLAGS_REG))
3602    (clobber (match_operand:SI 2 "register_operand" ""))]
3603   "(reload_completed
3604     && dead_or_set_p (insn, operands[1])
3605     && !reg_mentioned_p (operands[1], operands[0]))"
3606   [(set (match_dup 3) (match_dup 1))
3607    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3608               (clobber (reg:CC FLAGS_REG))])
3609    (set (match_dup 4) (match_dup 1))]
3610   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3611
3612 ;; Extend to memory case when source register does not die.
3613 (define_split
3614   [(set (match_operand:DI 0 "memory_operand" "")
3615         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3616    (clobber (reg:CC FLAGS_REG))
3617    (clobber (match_operand:SI 2 "register_operand" ""))]
3618   "reload_completed"
3619   [(const_int 0)]
3620 {
3621   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3622
3623   emit_move_insn (operands[3], operands[1]);
3624
3625   /* Generate a cltd if possible and doing so it profitable.  */
3626   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3627       && true_regnum (operands[1]) == AX_REG
3628       && true_regnum (operands[2]) == DX_REG)
3629     {
3630       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3631     }
3632   else
3633     {
3634       emit_move_insn (operands[2], operands[1]);
3635       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3636     }
3637   emit_move_insn (operands[4], operands[2]);
3638   DONE;
3639 })
3640
3641 ;; Extend to register case.  Optimize case where source and destination
3642 ;; registers match and cases where we can use cltd.
3643 (define_split
3644   [(set (match_operand:DI 0 "register_operand" "")
3645         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3646    (clobber (reg:CC FLAGS_REG))
3647    (clobber (match_scratch:SI 2 ""))]
3648   "reload_completed"
3649   [(const_int 0)]
3650 {
3651   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3652
3653   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3654     emit_move_insn (operands[3], operands[1]);
3655
3656   /* Generate a cltd if possible and doing so it profitable.  */
3657   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3658       && true_regnum (operands[3]) == AX_REG
3659       && true_regnum (operands[4]) == DX_REG)
3660     {
3661       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3662       DONE;
3663     }
3664
3665   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3666     emit_move_insn (operands[4], operands[1]);
3667
3668   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3669   DONE;
3670 })
3671
3672 (define_insn "extend<mode>di2"
3673   [(set (match_operand:DI 0 "register_operand" "=r")
3674         (sign_extend:DI
3675          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3676   "TARGET_64BIT"
3677   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3678   [(set_attr "type" "imovx")
3679    (set_attr "mode" "DI")])
3680
3681 (define_insn "extendhisi2"
3682   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3683         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3684   ""
3685 {
3686   switch (get_attr_prefix_0f (insn))
3687     {
3688     case 0:
3689       return "{cwtl|cwde}";
3690     default:
3691       return "movs{wl|x}\t{%1, %0|%0, %1}";
3692     }
3693 }
3694   [(set_attr "type" "imovx")
3695    (set_attr "mode" "SI")
3696    (set (attr "prefix_0f")
3697      ;; movsx is short decodable while cwtl is vector decoded.
3698      (if_then_else (and (eq_attr "cpu" "!k6")
3699                         (eq_attr "alternative" "0"))
3700         (const_string "0")
3701         (const_string "1")))
3702    (set (attr "modrm")
3703      (if_then_else (eq_attr "prefix_0f" "0")
3704         (const_string "0")
3705         (const_string "1")))])
3706
3707 (define_insn "*extendhisi2_zext"
3708   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3709         (zero_extend:DI
3710          (sign_extend:SI
3711           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3712   "TARGET_64BIT"
3713 {
3714   switch (get_attr_prefix_0f (insn))
3715     {
3716     case 0:
3717       return "{cwtl|cwde}";
3718     default:
3719       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3720     }
3721 }
3722   [(set_attr "type" "imovx")
3723    (set_attr "mode" "SI")
3724    (set (attr "prefix_0f")
3725      ;; movsx is short decodable while cwtl is vector decoded.
3726      (if_then_else (and (eq_attr "cpu" "!k6")
3727                         (eq_attr "alternative" "0"))
3728         (const_string "0")
3729         (const_string "1")))
3730    (set (attr "modrm")
3731      (if_then_else (eq_attr "prefix_0f" "0")
3732         (const_string "0")
3733         (const_string "1")))])
3734
3735 (define_insn "extendqisi2"
3736   [(set (match_operand:SI 0 "register_operand" "=r")
3737         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3738   ""
3739   "movs{bl|x}\t{%1, %0|%0, %1}"
3740    [(set_attr "type" "imovx")
3741     (set_attr "mode" "SI")])
3742
3743 (define_insn "*extendqisi2_zext"
3744   [(set (match_operand:DI 0 "register_operand" "=r")
3745         (zero_extend:DI
3746           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3747   "TARGET_64BIT"
3748   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3749    [(set_attr "type" "imovx")
3750     (set_attr "mode" "SI")])
3751
3752 (define_insn "extendqihi2"
3753   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3754         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3755   ""
3756 {
3757   switch (get_attr_prefix_0f (insn))
3758     {
3759     case 0:
3760       return "{cbtw|cbw}";
3761     default:
3762       return "movs{bw|x}\t{%1, %0|%0, %1}";
3763     }
3764 }
3765   [(set_attr "type" "imovx")
3766    (set_attr "mode" "HI")
3767    (set (attr "prefix_0f")
3768      ;; movsx is short decodable while cwtl is vector decoded.
3769      (if_then_else (and (eq_attr "cpu" "!k6")
3770                         (eq_attr "alternative" "0"))
3771         (const_string "0")
3772         (const_string "1")))
3773    (set (attr "modrm")
3774      (if_then_else (eq_attr "prefix_0f" "0")
3775         (const_string "0")
3776         (const_string "1")))])
3777 \f
3778 ;; Conversions between float and double.
3779
3780 ;; These are all no-ops in the model used for the 80387.
3781 ;; So just emit moves.
3782
3783 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3784 (define_split
3785   [(set (match_operand:DF 0 "push_operand" "")
3786         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3787   "reload_completed"
3788   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3789    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3790
3791 (define_split
3792   [(set (match_operand:XF 0 "push_operand" "")
3793         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3794   "reload_completed"
3795   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3796    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3797   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3798
3799 (define_expand "extendsfdf2"
3800   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3801         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3802   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3803 {
3804   /* ??? Needed for compress_float_constant since all fp constants
3805      are TARGET_LEGITIMATE_CONSTANT_P.  */
3806   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3807     {
3808       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3809           && standard_80387_constant_p (operands[1]) > 0)
3810         {
3811           operands[1] = simplify_const_unary_operation
3812             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3813           emit_move_insn_1 (operands[0], operands[1]);
3814           DONE;
3815         }
3816       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3817     }
3818 })
3819
3820 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3821    cvtss2sd:
3822       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3823       cvtps2pd xmm2,xmm1
3824    We do the conversion post reload to avoid producing of 128bit spills
3825    that might lead to ICE on 32bit target.  The sequence unlikely combine
3826    anyway.  */
3827 (define_split
3828   [(set (match_operand:DF 0 "register_operand" "")
3829         (float_extend:DF
3830           (match_operand:SF 1 "nonimmediate_operand" "")))]
3831   "TARGET_USE_VECTOR_FP_CONVERTS
3832    && optimize_insn_for_speed_p ()
3833    && reload_completed && SSE_REG_P (operands[0])"
3834    [(set (match_dup 2)
3835          (float_extend:V2DF
3836            (vec_select:V2SF
3837              (match_dup 3)
3838              (parallel [(const_int 0) (const_int 1)]))))]
3839 {
3840   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3841   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3842   /* Use movss for loading from memory, unpcklps reg, reg for registers.
3843      Try to avoid move when unpacking can be done in source.  */
3844   if (REG_P (operands[1]))
3845     {
3846       /* If it is unsafe to overwrite upper half of source, we need
3847          to move to destination and unpack there.  */
3848       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3849            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3850           && true_regnum (operands[0]) != true_regnum (operands[1]))
3851         {
3852           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3853           emit_move_insn (tmp, operands[1]);
3854         }
3855       else
3856         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3857       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3858                                              operands[3]));
3859     }
3860   else
3861     emit_insn (gen_vec_setv4sf_0 (operands[3],
3862                                   CONST0_RTX (V4SFmode), operands[1]));
3863 })
3864
3865 (define_insn "*extendsfdf2_mixed"
3866   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3867         (float_extend:DF
3868           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3869   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3870 {
3871   switch (which_alternative)
3872     {
3873     case 0:
3874     case 1:
3875       return output_387_reg_move (insn, operands);
3876
3877     case 2:
3878       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3879
3880     default:
3881       gcc_unreachable ();
3882     }
3883 }
3884   [(set_attr "type" "fmov,fmov,ssecvt")
3885    (set_attr "prefix" "orig,orig,maybe_vex")
3886    (set_attr "mode" "SF,XF,DF")])
3887
3888 (define_insn "*extendsfdf2_sse"
3889   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3890         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3891   "TARGET_SSE2 && TARGET_SSE_MATH"
3892   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3893   [(set_attr "type" "ssecvt")
3894    (set_attr "prefix" "maybe_vex")
3895    (set_attr "mode" "DF")])
3896
3897 (define_insn "*extendsfdf2_i387"
3898   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3899         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3900   "TARGET_80387"
3901   "* return output_387_reg_move (insn, operands);"
3902   [(set_attr "type" "fmov")
3903    (set_attr "mode" "SF,XF")])
3904
3905 (define_expand "extend<mode>xf2"
3906   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3907         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3908   "TARGET_80387"
3909 {
3910   /* ??? Needed for compress_float_constant since all fp constants
3911      are TARGET_LEGITIMATE_CONSTANT_P.  */
3912   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3913     {
3914       if (standard_80387_constant_p (operands[1]) > 0)
3915         {
3916           operands[1] = simplify_const_unary_operation
3917             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3918           emit_move_insn_1 (operands[0], operands[1]);
3919           DONE;
3920         }
3921       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3922     }
3923 })
3924
3925 (define_insn "*extend<mode>xf2_i387"
3926   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3927         (float_extend:XF
3928           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3929   "TARGET_80387"
3930   "* return output_387_reg_move (insn, operands);"
3931   [(set_attr "type" "fmov")
3932    (set_attr "mode" "<MODE>,XF")])
3933
3934 ;; %%% This seems bad bad news.
3935 ;; This cannot output into an f-reg because there is no way to be sure
3936 ;; of truncating in that case.  Otherwise this is just like a simple move
3937 ;; insn.  So we pretend we can output to a reg in order to get better
3938 ;; register preferencing, but we really use a stack slot.
3939
3940 ;; Conversion from DFmode to SFmode.
3941
3942 (define_expand "truncdfsf2"
3943   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3944         (float_truncate:SF
3945           (match_operand:DF 1 "nonimmediate_operand" "")))]
3946   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3947 {
3948   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3949     ;
3950   else if (flag_unsafe_math_optimizations)
3951     ;
3952   else
3953     {
3954       enum ix86_stack_slot slot = (virtuals_instantiated
3955                                    ? SLOT_TEMP
3956                                    : SLOT_VIRTUAL);
3957       rtx temp = assign_386_stack_local (SFmode, slot);
3958       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3959       DONE;
3960     }
3961 })
3962
3963 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3964    cvtsd2ss:
3965       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3966       cvtpd2ps xmm2,xmm1
3967    We do the conversion post reload to avoid producing of 128bit spills
3968    that might lead to ICE on 32bit target.  The sequence unlikely combine
3969    anyway.  */
3970 (define_split
3971   [(set (match_operand:SF 0 "register_operand" "")
3972         (float_truncate:SF
3973           (match_operand:DF 1 "nonimmediate_operand" "")))]
3974   "TARGET_USE_VECTOR_FP_CONVERTS
3975    && optimize_insn_for_speed_p ()
3976    && reload_completed && SSE_REG_P (operands[0])"
3977    [(set (match_dup 2)
3978          (vec_concat:V4SF
3979            (float_truncate:V2SF
3980              (match_dup 4))
3981            (match_dup 3)))]
3982 {
3983   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3984   operands[3] = CONST0_RTX (V2SFmode);
3985   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3986   /* Use movsd for loading from memory, unpcklpd for registers.
3987      Try to avoid move when unpacking can be done in source, or SSE3
3988      movddup is available.  */
3989   if (REG_P (operands[1]))
3990     {
3991       if (!TARGET_SSE3
3992           && true_regnum (operands[0]) != true_regnum (operands[1])
3993           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3994               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3995         {
3996           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3997           emit_move_insn (tmp, operands[1]);
3998           operands[1] = tmp;
3999         }
4000       else if (!TARGET_SSE3)
4001         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4002       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4003     }
4004   else
4005     emit_insn (gen_sse2_loadlpd (operands[4],
4006                                  CONST0_RTX (V2DFmode), operands[1]));
4007 })
4008
4009 (define_expand "truncdfsf2_with_temp"
4010   [(parallel [(set (match_operand:SF 0 "" "")
4011                    (float_truncate:SF (match_operand:DF 1 "" "")))
4012               (clobber (match_operand:SF 2 "" ""))])])
4013
4014 (define_insn "*truncdfsf_fast_mixed"
4015   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4016         (float_truncate:SF
4017           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4018   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4019 {
4020   switch (which_alternative)
4021     {
4022     case 0:
4023       return output_387_reg_move (insn, operands);
4024     case 1:
4025       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4026     default:
4027       gcc_unreachable ();
4028     }
4029 }
4030   [(set_attr "type" "fmov,ssecvt")
4031    (set_attr "prefix" "orig,maybe_vex")
4032    (set_attr "mode" "SF")])
4033
4034 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4035 ;; because nothing we do here is unsafe.
4036 (define_insn "*truncdfsf_fast_sse"
4037   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4038         (float_truncate:SF
4039           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4040   "TARGET_SSE2 && TARGET_SSE_MATH"
4041   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4042   [(set_attr "type" "ssecvt")
4043    (set_attr "prefix" "maybe_vex")
4044    (set_attr "mode" "SF")])
4045
4046 (define_insn "*truncdfsf_fast_i387"
4047   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4048         (float_truncate:SF
4049           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4050   "TARGET_80387 && flag_unsafe_math_optimizations"
4051   "* return output_387_reg_move (insn, operands);"
4052   [(set_attr "type" "fmov")
4053    (set_attr "mode" "SF")])
4054
4055 (define_insn "*truncdfsf_mixed"
4056   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,x ,?f,?x,?*r")
4057         (float_truncate:SF
4058           (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4059    (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
4060   "TARGET_MIX_SSE_I387"
4061 {
4062   switch (which_alternative)
4063     {
4064     case 0:
4065       return output_387_reg_move (insn, operands);
4066     case 1:
4067       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4068
4069     default:
4070       return "#";
4071     }
4072 }
4073   [(set_attr "isa" "*,sse2,*,*,*")
4074    (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4075    (set_attr "unit" "*,*,i387,i387,i387")
4076    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4077    (set_attr "mode" "SF")])
4078
4079 (define_insn "*truncdfsf_i387"
4080   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4081         (float_truncate:SF
4082           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4083    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4084   "TARGET_80387"
4085 {
4086   switch (which_alternative)
4087     {
4088     case 0:
4089       return output_387_reg_move (insn, operands);
4090
4091     default:
4092       return "#";
4093     }
4094 }
4095   [(set_attr "type" "fmov,multi,multi,multi")
4096    (set_attr "unit" "*,i387,i387,i387")
4097    (set_attr "mode" "SF")])
4098
4099 (define_insn "*truncdfsf2_i387_1"
4100   [(set (match_operand:SF 0 "memory_operand" "=m")
4101         (float_truncate:SF
4102           (match_operand:DF 1 "register_operand" "f")))]
4103   "TARGET_80387
4104    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4105    && !TARGET_MIX_SSE_I387"
4106   "* return output_387_reg_move (insn, operands);"
4107   [(set_attr "type" "fmov")
4108    (set_attr "mode" "SF")])
4109
4110 (define_split
4111   [(set (match_operand:SF 0 "register_operand" "")
4112         (float_truncate:SF
4113          (match_operand:DF 1 "fp_register_operand" "")))
4114    (clobber (match_operand 2 "" ""))]
4115   "reload_completed"
4116   [(set (match_dup 2) (match_dup 1))
4117    (set (match_dup 0) (match_dup 2))]
4118   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4119
4120 ;; Conversion from XFmode to {SF,DF}mode
4121
4122 (define_expand "truncxf<mode>2"
4123   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4124                    (float_truncate:MODEF
4125                      (match_operand:XF 1 "register_operand" "")))
4126               (clobber (match_dup 2))])]
4127   "TARGET_80387"
4128 {
4129   if (flag_unsafe_math_optimizations)
4130     {
4131       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4132       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4133       if (reg != operands[0])
4134         emit_move_insn (operands[0], reg);
4135       DONE;
4136     }
4137   else
4138     {
4139       enum ix86_stack_slot slot = (virtuals_instantiated
4140                                    ? SLOT_TEMP
4141                                    : SLOT_VIRTUAL);
4142       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4143     }
4144 })
4145
4146 (define_insn "*truncxfsf2_mixed"
4147   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4148         (float_truncate:SF
4149           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4150    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4151   "TARGET_80387"
4152 {
4153   gcc_assert (!which_alternative);
4154   return output_387_reg_move (insn, operands);
4155 }
4156   [(set_attr "type" "fmov,multi,multi,multi")
4157    (set_attr "unit" "*,i387,i387,i387")
4158    (set_attr "mode" "SF")])
4159
4160 (define_insn "*truncxfdf2_mixed"
4161   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4162         (float_truncate:DF
4163           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4164    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4165   "TARGET_80387"
4166 {
4167   gcc_assert (!which_alternative);
4168   return output_387_reg_move (insn, operands);
4169 }
4170   [(set_attr "isa" "*,*,sse2,*")
4171    (set_attr "type" "fmov,multi,multi,multi")
4172    (set_attr "unit" "*,i387,i387,i387")
4173    (set_attr "mode" "DF")])
4174
4175 (define_insn "truncxf<mode>2_i387_noop"
4176   [(set (match_operand:MODEF 0 "register_operand" "=f")
4177         (float_truncate:MODEF
4178           (match_operand:XF 1 "register_operand" "f")))]
4179   "TARGET_80387 && flag_unsafe_math_optimizations"
4180   "* return output_387_reg_move (insn, operands);"
4181   [(set_attr "type" "fmov")
4182    (set_attr "mode" "<MODE>")])
4183
4184 (define_insn "*truncxf<mode>2_i387"
4185   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4186         (float_truncate:MODEF
4187           (match_operand:XF 1 "register_operand" "f")))]
4188   "TARGET_80387"
4189   "* return output_387_reg_move (insn, operands);"
4190   [(set_attr "type" "fmov")
4191    (set_attr "mode" "<MODE>")])
4192
4193 (define_split
4194   [(set (match_operand:MODEF 0 "register_operand" "")
4195         (float_truncate:MODEF
4196           (match_operand:XF 1 "register_operand" "")))
4197    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4198   "TARGET_80387 && reload_completed"
4199   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4200    (set (match_dup 0) (match_dup 2))])
4201
4202 (define_split
4203   [(set (match_operand:MODEF 0 "memory_operand" "")
4204         (float_truncate:MODEF
4205           (match_operand:XF 1 "register_operand" "")))
4206    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4207   "TARGET_80387"
4208   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4209 \f
4210 ;; Signed conversion to DImode.
4211
4212 (define_expand "fix_truncxfdi2"
4213   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4214                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4215               (clobber (reg:CC FLAGS_REG))])]
4216   "TARGET_80387"
4217 {
4218   if (TARGET_FISTTP)
4219    {
4220      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4221      DONE;
4222    }
4223 })
4224
4225 (define_expand "fix_trunc<mode>di2"
4226   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4227                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4228               (clobber (reg:CC FLAGS_REG))])]
4229   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4230 {
4231   if (TARGET_FISTTP
4232       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4233    {
4234      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4235      DONE;
4236    }
4237   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4238    {
4239      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4240      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4241      if (out != operands[0])
4242         emit_move_insn (operands[0], out);
4243      DONE;
4244    }
4245 })
4246
4247 ;; Signed conversion to SImode.
4248
4249 (define_expand "fix_truncxfsi2"
4250   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4251                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4252               (clobber (reg:CC FLAGS_REG))])]
4253   "TARGET_80387"
4254 {
4255   if (TARGET_FISTTP)
4256    {
4257      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4258      DONE;
4259    }
4260 })
4261
4262 (define_expand "fix_trunc<mode>si2"
4263   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4264                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4265               (clobber (reg:CC FLAGS_REG))])]
4266   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4267 {
4268   if (TARGET_FISTTP
4269       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4270    {
4271      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4272      DONE;
4273    }
4274   if (SSE_FLOAT_MODE_P (<MODE>mode))
4275    {
4276      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4277      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4278      if (out != operands[0])
4279         emit_move_insn (operands[0], out);
4280      DONE;
4281    }
4282 })
4283
4284 ;; Signed conversion to HImode.
4285
4286 (define_expand "fix_trunc<mode>hi2"
4287   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4288                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4289               (clobber (reg:CC FLAGS_REG))])]
4290   "TARGET_80387
4291    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4292 {
4293   if (TARGET_FISTTP)
4294    {
4295      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4296      DONE;
4297    }
4298 })
4299
4300 ;; Unsigned conversion to SImode.
4301
4302 (define_expand "fixuns_trunc<mode>si2"
4303   [(parallel
4304     [(set (match_operand:SI 0 "register_operand" "")
4305           (unsigned_fix:SI
4306             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4307      (use (match_dup 2))
4308      (clobber (match_scratch:<ssevecmode> 3 ""))
4309      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4310   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4311 {
4312   enum machine_mode mode = <MODE>mode;
4313   enum machine_mode vecmode = <ssevecmode>mode;
4314   REAL_VALUE_TYPE TWO31r;
4315   rtx two31;
4316
4317   if (optimize_insn_for_size_p ())
4318     FAIL;
4319
4320   real_ldexp (&TWO31r, &dconst1, 31);
4321   two31 = const_double_from_real_value (TWO31r, mode);
4322   two31 = ix86_build_const_vector (vecmode, true, two31);
4323   operands[2] = force_reg (vecmode, two31);
4324 })
4325
4326 (define_insn_and_split "*fixuns_trunc<mode>_1"
4327   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4328         (unsigned_fix:SI
4329           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4330    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4331    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4332    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4333   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4334    && optimize_function_for_speed_p (cfun)"
4335   "#"
4336   "&& reload_completed"
4337   [(const_int 0)]
4338 {
4339   ix86_split_convert_uns_si_sse (operands);
4340   DONE;
4341 })
4342
4343 ;; Unsigned conversion to HImode.
4344 ;; Without these patterns, we'll try the unsigned SI conversion which
4345 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4346
4347 (define_expand "fixuns_trunc<mode>hi2"
4348   [(set (match_dup 2)
4349         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4350    (set (match_operand:HI 0 "nonimmediate_operand" "")
4351         (subreg:HI (match_dup 2) 0))]
4352   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4353   "operands[2] = gen_reg_rtx (SImode);")
4354
4355 ;; When SSE is available, it is always faster to use it!
4356 (define_insn "fix_trunc<mode>di_sse"
4357   [(set (match_operand:DI 0 "register_operand" "=r,r")
4358         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4359   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4360    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4361   "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4362   [(set_attr "type" "sseicvt")
4363    (set_attr "prefix" "maybe_vex")
4364    (set_attr "prefix_rex" "1")
4365    (set_attr "mode" "<MODE>")
4366    (set_attr "athlon_decode" "double,vector")
4367    (set_attr "amdfam10_decode" "double,double")
4368    (set_attr "bdver1_decode" "double,double")])
4369
4370 (define_insn "fix_trunc<mode>si_sse"
4371   [(set (match_operand:SI 0 "register_operand" "=r,r")
4372         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4373   "SSE_FLOAT_MODE_P (<MODE>mode)
4374    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4375   "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4376   [(set_attr "type" "sseicvt")
4377    (set_attr "prefix" "maybe_vex")
4378    (set_attr "mode" "<MODE>")
4379    (set_attr "athlon_decode" "double,vector")
4380    (set_attr "amdfam10_decode" "double,double")
4381    (set_attr "bdver1_decode" "double,double")])
4382
4383 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4384 (define_peephole2
4385   [(set (match_operand:MODEF 0 "register_operand" "")
4386         (match_operand:MODEF 1 "memory_operand" ""))
4387    (set (match_operand:SWI48x 2 "register_operand" "")
4388         (fix:SWI48x (match_dup 0)))]
4389   "TARGET_SHORTEN_X87_SSE
4390    && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4391    && peep2_reg_dead_p (2, operands[0])"
4392   [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4393
4394 ;; Avoid vector decoded forms of the instruction.
4395 (define_peephole2
4396   [(match_scratch:DF 2 "x")
4397    (set (match_operand:SWI48x 0 "register_operand" "")
4398         (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4399   "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4400   [(set (match_dup 2) (match_dup 1))
4401    (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4402
4403 (define_peephole2
4404   [(match_scratch:SF 2 "x")
4405    (set (match_operand:SWI48x 0 "register_operand" "")
4406         (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4407   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4408   [(set (match_dup 2) (match_dup 1))
4409    (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4410
4411 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4412   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4413         (fix:SWI248x (match_operand 1 "register_operand" "")))]
4414   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4415    && TARGET_FISTTP
4416    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4417          && (TARGET_64BIT || <MODE>mode != DImode))
4418         && TARGET_SSE_MATH)
4419    && can_create_pseudo_p ()"
4420   "#"
4421   "&& 1"
4422   [(const_int 0)]
4423 {
4424   if (memory_operand (operands[0], VOIDmode))
4425     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4426   else
4427     {
4428       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4429       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4430                                                             operands[1],
4431                                                             operands[2]));
4432     }
4433   DONE;
4434 }
4435   [(set_attr "type" "fisttp")
4436    (set_attr "mode" "<MODE>")])
4437
4438 (define_insn "fix_trunc<mode>_i387_fisttp"
4439   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4440         (fix:SWI248x (match_operand 1 "register_operand" "f")))
4441    (clobber (match_scratch:XF 2 "=&1f"))]
4442   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4443    && TARGET_FISTTP
4444    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4445          && (TARGET_64BIT || <MODE>mode != DImode))
4446         && TARGET_SSE_MATH)"
4447   "* return output_fix_trunc (insn, operands, true);"
4448   [(set_attr "type" "fisttp")
4449    (set_attr "mode" "<MODE>")])
4450
4451 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4452   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4453         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4454    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4455    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4456   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4457    && TARGET_FISTTP
4458    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4459         && (TARGET_64BIT || <MODE>mode != DImode))
4460         && TARGET_SSE_MATH)"
4461   "#"
4462   [(set_attr "type" "fisttp")
4463    (set_attr "mode" "<MODE>")])
4464
4465 (define_split
4466   [(set (match_operand:SWI248x 0 "register_operand" "")
4467         (fix:SWI248x (match_operand 1 "register_operand" "")))
4468    (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4469    (clobber (match_scratch 3 ""))]
4470   "reload_completed"
4471   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4472               (clobber (match_dup 3))])
4473    (set (match_dup 0) (match_dup 2))])
4474
4475 (define_split
4476   [(set (match_operand:SWI248x 0 "memory_operand" "")
4477         (fix:SWI248x (match_operand 1 "register_operand" "")))
4478    (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4479    (clobber (match_scratch 3 ""))]
4480   "reload_completed"
4481   [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4482               (clobber (match_dup 3))])])
4483
4484 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4485 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4486 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4487 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4488 ;; function in i386.c.
4489 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4490   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4491         (fix:SWI248x (match_operand 1 "register_operand" "")))
4492    (clobber (reg:CC FLAGS_REG))]
4493   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4494    && !TARGET_FISTTP
4495    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4496          && (TARGET_64BIT || <MODE>mode != DImode))
4497    && can_create_pseudo_p ()"
4498   "#"
4499   "&& 1"
4500   [(const_int 0)]
4501 {
4502   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4503
4504   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4505   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4506   if (memory_operand (operands[0], VOIDmode))
4507     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4508                                          operands[2], operands[3]));
4509   else
4510     {
4511       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4512       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4513                                                      operands[2], operands[3],
4514                                                      operands[4]));
4515     }
4516   DONE;
4517 }
4518   [(set_attr "type" "fistp")
4519    (set_attr "i387_cw" "trunc")
4520    (set_attr "mode" "<MODE>")])
4521
4522 (define_insn "fix_truncdi_i387"
4523   [(set (match_operand:DI 0 "memory_operand" "=m")
4524         (fix:DI (match_operand 1 "register_operand" "f")))
4525    (use (match_operand:HI 2 "memory_operand" "m"))
4526    (use (match_operand:HI 3 "memory_operand" "m"))
4527    (clobber (match_scratch:XF 4 "=&1f"))]
4528   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4529    && !TARGET_FISTTP
4530    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4531   "* return output_fix_trunc (insn, operands, false);"
4532   [(set_attr "type" "fistp")
4533    (set_attr "i387_cw" "trunc")
4534    (set_attr "mode" "DI")])
4535
4536 (define_insn "fix_truncdi_i387_with_temp"
4537   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4538         (fix:DI (match_operand 1 "register_operand" "f,f")))
4539    (use (match_operand:HI 2 "memory_operand" "m,m"))
4540    (use (match_operand:HI 3 "memory_operand" "m,m"))
4541    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4542    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4543   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4544    && !TARGET_FISTTP
4545    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4546   "#"
4547   [(set_attr "type" "fistp")
4548    (set_attr "i387_cw" "trunc")
4549    (set_attr "mode" "DI")])
4550
4551 (define_split
4552   [(set (match_operand:DI 0 "register_operand" "")
4553         (fix:DI (match_operand 1 "register_operand" "")))
4554    (use (match_operand:HI 2 "memory_operand" ""))
4555    (use (match_operand:HI 3 "memory_operand" ""))
4556    (clobber (match_operand:DI 4 "memory_operand" ""))
4557    (clobber (match_scratch 5 ""))]
4558   "reload_completed"
4559   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4560               (use (match_dup 2))
4561               (use (match_dup 3))
4562               (clobber (match_dup 5))])
4563    (set (match_dup 0) (match_dup 4))])
4564
4565 (define_split
4566   [(set (match_operand:DI 0 "memory_operand" "")
4567         (fix:DI (match_operand 1 "register_operand" "")))
4568    (use (match_operand:HI 2 "memory_operand" ""))
4569    (use (match_operand:HI 3 "memory_operand" ""))
4570    (clobber (match_operand:DI 4 "memory_operand" ""))
4571    (clobber (match_scratch 5 ""))]
4572   "reload_completed"
4573   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4574               (use (match_dup 2))
4575               (use (match_dup 3))
4576               (clobber (match_dup 5))])])
4577
4578 (define_insn "fix_trunc<mode>_i387"
4579   [(set (match_operand:SWI24 0 "memory_operand" "=m")
4580         (fix:SWI24 (match_operand 1 "register_operand" "f")))
4581    (use (match_operand:HI 2 "memory_operand" "m"))
4582    (use (match_operand:HI 3 "memory_operand" "m"))]
4583   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4584    && !TARGET_FISTTP
4585    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4586   "* return output_fix_trunc (insn, operands, false);"
4587   [(set_attr "type" "fistp")
4588    (set_attr "i387_cw" "trunc")
4589    (set_attr "mode" "<MODE>")])
4590
4591 (define_insn "fix_trunc<mode>_i387_with_temp"
4592   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4593         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4594    (use (match_operand:HI 2 "memory_operand" "m,m"))
4595    (use (match_operand:HI 3 "memory_operand" "m,m"))
4596    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4597   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4598    && !TARGET_FISTTP
4599    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4600   "#"
4601   [(set_attr "type" "fistp")
4602    (set_attr "i387_cw" "trunc")
4603    (set_attr "mode" "<MODE>")])
4604
4605 (define_split
4606   [(set (match_operand:SWI24 0 "register_operand" "")
4607         (fix:SWI24 (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:SWI24 4 "memory_operand" ""))]
4611   "reload_completed"
4612   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4613               (use (match_dup 2))
4614               (use (match_dup 3))])
4615    (set (match_dup 0) (match_dup 4))])
4616
4617 (define_split
4618   [(set (match_operand:SWI24 0 "memory_operand" "")
4619         (fix:SWI24 (match_operand 1 "register_operand" "")))
4620    (use (match_operand:HI 2 "memory_operand" ""))
4621    (use (match_operand:HI 3 "memory_operand" ""))
4622    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4623   "reload_completed"
4624   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4625               (use (match_dup 2))
4626               (use (match_dup 3))])])
4627
4628 (define_insn "x86_fnstcw_1"
4629   [(set (match_operand:HI 0 "memory_operand" "=m")
4630         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4631   "TARGET_80387"
4632   "fnstcw\t%0"
4633   [(set (attr "length")
4634         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4635    (set_attr "mode" "HI")
4636    (set_attr "unit" "i387")
4637    (set_attr "bdver1_decode" "vector")])
4638
4639 (define_insn "x86_fldcw_1"
4640   [(set (reg:HI FPCR_REG)
4641         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4642   "TARGET_80387"
4643   "fldcw\t%0"
4644   [(set (attr "length")
4645         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4646    (set_attr "mode" "HI")
4647    (set_attr "unit" "i387")
4648    (set_attr "athlon_decode" "vector")
4649    (set_attr "amdfam10_decode" "vector")
4650    (set_attr "bdver1_decode" "vector")])
4651 \f
4652 ;; Conversion between fixed point and floating point.
4653
4654 ;; Even though we only accept memory inputs, the backend _really_
4655 ;; wants to be able to do this between registers.
4656
4657 (define_expand "floathi<mode>2"
4658   [(set (match_operand:X87MODEF 0 "register_operand" "")
4659         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4660   "TARGET_80387
4661    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4662        || TARGET_MIX_SSE_I387)")
4663
4664 ;; Pre-reload splitter to add memory clobber to the pattern.
4665 (define_insn_and_split "*floathi<mode>2_1"
4666   [(set (match_operand:X87MODEF 0 "register_operand" "")
4667         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4668   "TARGET_80387
4669    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4670        || TARGET_MIX_SSE_I387)
4671    && can_create_pseudo_p ()"
4672   "#"
4673   "&& 1"
4674   [(parallel [(set (match_dup 0)
4675               (float:X87MODEF (match_dup 1)))
4676    (clobber (match_dup 2))])]
4677   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4678
4679 (define_insn "*floathi<mode>2_i387_with_temp"
4680   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4681         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4682   (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4683   "TARGET_80387
4684    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4685        || TARGET_MIX_SSE_I387)"
4686   "#"
4687   [(set_attr "type" "fmov,multi")
4688    (set_attr "mode" "<MODE>")
4689    (set_attr "unit" "*,i387")
4690    (set_attr "fp_int_src" "true")])
4691
4692 (define_insn "*floathi<mode>2_i387"
4693   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4694         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4695   "TARGET_80387
4696    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4697        || TARGET_MIX_SSE_I387)"
4698   "fild%Z1\t%1"
4699   [(set_attr "type" "fmov")
4700    (set_attr "mode" "<MODE>")
4701    (set_attr "fp_int_src" "true")])
4702
4703 (define_split
4704   [(set (match_operand:X87MODEF 0 "register_operand" "")
4705         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4706    (clobber (match_operand:HI 2 "memory_operand" ""))]
4707   "TARGET_80387
4708    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4709        || TARGET_MIX_SSE_I387)
4710    && reload_completed"
4711   [(set (match_dup 2) (match_dup 1))
4712    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4713
4714 (define_split
4715   [(set (match_operand:X87MODEF 0 "register_operand" "")
4716         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4717    (clobber (match_operand:HI 2 "memory_operand" ""))]
4718    "TARGET_80387
4719     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4720         || TARGET_MIX_SSE_I387)
4721     && reload_completed"
4722   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4723
4724 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4725   [(set (match_operand:X87MODEF 0 "register_operand" "")
4726         (float:X87MODEF
4727           (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4728   "TARGET_80387
4729    || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4730        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4731 {
4732   if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4733         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4734       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4735     {
4736       rtx reg = gen_reg_rtx (XFmode);
4737       rtx (*insn)(rtx, rtx);
4738
4739       emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4740
4741       if (<X87MODEF:MODE>mode == SFmode)
4742         insn = gen_truncxfsf2;
4743       else if (<X87MODEF:MODE>mode == DFmode)
4744         insn = gen_truncxfdf2;
4745       else
4746         gcc_unreachable ();
4747
4748       emit_insn (insn (operands[0], reg));
4749       DONE;
4750     }
4751 })
4752
4753 ;; Pre-reload splitter to add memory clobber to the pattern.
4754 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4755   [(set (match_operand:X87MODEF 0 "register_operand" "")
4756         (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4757   "((TARGET_80387
4758      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4759      && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4760            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4761          || TARGET_MIX_SSE_I387))
4762     || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4763         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4764         && ((<SWI48x:MODE>mode == SImode
4765              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4766              && optimize_function_for_speed_p (cfun)
4767              && flag_trapping_math)
4768             || !(TARGET_INTER_UNIT_CONVERSIONS
4769                  || optimize_function_for_size_p (cfun)))))
4770    && can_create_pseudo_p ()"
4771   "#"
4772   "&& 1"
4773   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4774               (clobber (match_dup 2))])]
4775 {
4776   operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4777
4778   /* Avoid store forwarding (partial memory) stall penalty
4779      by passing DImode value through XMM registers.  */
4780   if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4781       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4782       && optimize_function_for_speed_p (cfun))
4783     {
4784       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4785                                                             operands[1],
4786                                                             operands[2]));
4787       DONE;
4788     }
4789 })
4790
4791 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4792   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4793         (float:MODEF
4794           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4795    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4796   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4797    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4798   "#"
4799   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4800    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4801    (set_attr "unit" "*,i387,*,*,*")
4802    (set_attr "athlon_decode" "*,*,double,direct,double")
4803    (set_attr "amdfam10_decode" "*,*,vector,double,double")
4804    (set_attr "bdver1_decode" "*,*,double,direct,double")
4805    (set_attr "fp_int_src" "true")])
4806
4807 (define_insn "*floatsi<mode>2_vector_mixed"
4808   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4809         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4810   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4811    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4812   "@
4813    fild%Z1\t%1
4814    #"
4815   [(set_attr "type" "fmov,sseicvt")
4816    (set_attr "mode" "<MODE>,<ssevecmode>")
4817    (set_attr "unit" "i387,*")
4818    (set_attr "athlon_decode" "*,direct")
4819    (set_attr "amdfam10_decode" "*,double")
4820    (set_attr "bdver1_decode" "*,direct")
4821    (set_attr "fp_int_src" "true")])
4822
4823 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4824   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4825         (float:MODEF
4826           (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4827    (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4828   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4829    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4830   "#"
4831   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4832    (set_attr "mode" "<MODEF:MODE>")
4833    (set_attr "unit" "*,i387,*,*")
4834    (set_attr "athlon_decode" "*,*,double,direct")
4835    (set_attr "amdfam10_decode" "*,*,vector,double")
4836    (set_attr "bdver1_decode" "*,*,double,direct")
4837    (set_attr "fp_int_src" "true")])
4838
4839 (define_split
4840   [(set (match_operand:MODEF 0 "register_operand" "")
4841         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4842    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4843   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4844    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4845    && TARGET_INTER_UNIT_CONVERSIONS
4846    && reload_completed
4847    && (SSE_REG_P (operands[0])
4848        || (GET_CODE (operands[0]) == SUBREG
4849            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4850   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4851
4852 (define_split
4853   [(set (match_operand:MODEF 0 "register_operand" "")
4854         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4855    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4856   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4857    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4858    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4859    && reload_completed
4860    && (SSE_REG_P (operands[0])
4861        || (GET_CODE (operands[0]) == SUBREG
4862            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4863   [(set (match_dup 2) (match_dup 1))
4864    (set (match_dup 0) (float:MODEF (match_dup 2)))])
4865
4866 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4867   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4868         (float:MODEF
4869           (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4870   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4871    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4872    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4873   "@
4874    fild%Z1\t%1
4875    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4876    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4877   [(set_attr "type" "fmov,sseicvt,sseicvt")
4878    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4879    (set_attr "mode" "<MODEF:MODE>")
4880    (set (attr "prefix_rex")
4881      (if_then_else
4882        (and (eq_attr "prefix" "maybe_vex")
4883             (match_test "<SWI48x:MODE>mode == DImode"))
4884        (const_string "1")
4885        (const_string "*")))
4886    (set_attr "unit" "i387,*,*")
4887    (set_attr "athlon_decode" "*,double,direct")
4888    (set_attr "amdfam10_decode" "*,vector,double")
4889    (set_attr "bdver1_decode" "*,double,direct")
4890    (set_attr "fp_int_src" "true")])
4891
4892 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4893   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4894         (float:MODEF
4895           (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4896   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4897    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4898    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4899   "@
4900    fild%Z1\t%1
4901    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4902   [(set_attr "type" "fmov,sseicvt")
4903    (set_attr "prefix" "orig,maybe_vex")
4904    (set_attr "mode" "<MODEF:MODE>")
4905    (set (attr "prefix_rex")
4906      (if_then_else
4907        (and (eq_attr "prefix" "maybe_vex")
4908             (match_test "<SWI48x:MODE>mode == DImode"))
4909        (const_string "1")
4910        (const_string "*")))
4911    (set_attr "athlon_decode" "*,direct")
4912    (set_attr "amdfam10_decode" "*,double")
4913    (set_attr "bdver1_decode" "*,direct")
4914    (set_attr "fp_int_src" "true")])
4915
4916 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4917   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4918         (float:MODEF
4919           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4920    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4921   "TARGET_SSE2 && TARGET_SSE_MATH
4922    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4923   "#"
4924   [(set_attr "type" "sseicvt")
4925    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4926    (set_attr "athlon_decode" "double,direct,double")
4927    (set_attr "amdfam10_decode" "vector,double,double")
4928    (set_attr "bdver1_decode" "double,direct,double")
4929    (set_attr "fp_int_src" "true")])
4930
4931 (define_insn "*floatsi<mode>2_vector_sse"
4932   [(set (match_operand:MODEF 0 "register_operand" "=x")
4933         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4934   "TARGET_SSE2 && TARGET_SSE_MATH
4935    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4936   "#"
4937   [(set_attr "type" "sseicvt")
4938    (set_attr "mode" "<MODE>")
4939    (set_attr "athlon_decode" "direct")
4940    (set_attr "amdfam10_decode" "double")
4941    (set_attr "bdver1_decode" "direct")
4942    (set_attr "fp_int_src" "true")])
4943
4944 (define_split
4945   [(set (match_operand:MODEF 0 "register_operand" "")
4946         (float:MODEF (match_operand:SI 1 "register_operand" "")))
4947    (clobber (match_operand:SI 2 "memory_operand" ""))]
4948   "TARGET_SSE2 && TARGET_SSE_MATH
4949    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4950    && reload_completed
4951    && (SSE_REG_P (operands[0])
4952        || (GET_CODE (operands[0]) == SUBREG
4953            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4954   [(const_int 0)]
4955 {
4956   rtx op1 = operands[1];
4957
4958   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4959                                      <MODE>mode, 0);
4960   if (GET_CODE (op1) == SUBREG)
4961     op1 = SUBREG_REG (op1);
4962
4963   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4964     {
4965       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4966       emit_insn (gen_sse2_loadld (operands[4],
4967                                   CONST0_RTX (V4SImode), operands[1]));
4968     }
4969   /* We can ignore possible trapping value in the
4970      high part of SSE register for non-trapping math. */
4971   else if (SSE_REG_P (op1) && !flag_trapping_math)
4972     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4973   else
4974     {
4975       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4976       emit_move_insn (operands[2], operands[1]);
4977       emit_insn (gen_sse2_loadld (operands[4],
4978                                   CONST0_RTX (V4SImode), operands[2]));
4979     }
4980   if (<ssevecmode>mode == V4SFmode)
4981     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4982   else
4983     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4984   DONE;
4985 })
4986
4987 (define_split
4988   [(set (match_operand:MODEF 0 "register_operand" "")
4989         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
4990    (clobber (match_operand:SI 2 "memory_operand" ""))]
4991   "TARGET_SSE2 && TARGET_SSE_MATH
4992    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4993    && reload_completed
4994    && (SSE_REG_P (operands[0])
4995        || (GET_CODE (operands[0]) == SUBREG
4996            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4997   [(const_int 0)]
4998 {
4999   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5000                                      <MODE>mode, 0);
5001   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5002
5003   emit_insn (gen_sse2_loadld (operands[4],
5004                               CONST0_RTX (V4SImode), operands[1]));
5005   if (<ssevecmode>mode == V4SFmode)
5006     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5007   else
5008     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5009   DONE;
5010 })
5011
5012 (define_split
5013   [(set (match_operand:MODEF 0 "register_operand" "")
5014         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5015   "TARGET_SSE2 && TARGET_SSE_MATH
5016    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5017    && reload_completed
5018    && (SSE_REG_P (operands[0])
5019        || (GET_CODE (operands[0]) == SUBREG
5020            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5021   [(const_int 0)]
5022 {
5023   rtx op1 = operands[1];
5024
5025   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5026                                      <MODE>mode, 0);
5027   if (GET_CODE (op1) == SUBREG)
5028     op1 = SUBREG_REG (op1);
5029
5030   if (GENERAL_REG_P (op1))
5031     {
5032       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5033       if (TARGET_INTER_UNIT_MOVES)
5034         emit_insn (gen_sse2_loadld (operands[4],
5035                                     CONST0_RTX (V4SImode), operands[1]));
5036       else
5037         {
5038           operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5039                                               operands[1]);
5040           emit_insn (gen_sse2_loadld (operands[4],
5041                                       CONST0_RTX (V4SImode), operands[5]));
5042           ix86_free_from_memory (GET_MODE (operands[1]));
5043         }
5044     }
5045   /* We can ignore possible trapping value in the
5046      high part of SSE register for non-trapping math. */
5047   else if (SSE_REG_P (op1) && !flag_trapping_math)
5048     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5049   else
5050     gcc_unreachable ();
5051   if (<ssevecmode>mode == V4SFmode)
5052     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5053   else
5054     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5055   DONE;
5056 })
5057
5058 (define_split
5059   [(set (match_operand:MODEF 0 "register_operand" "")
5060         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5061   "TARGET_SSE2 && TARGET_SSE_MATH
5062    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5063    && reload_completed
5064    && (SSE_REG_P (operands[0])
5065        || (GET_CODE (operands[0]) == SUBREG
5066            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5067   [(const_int 0)]
5068 {
5069   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5070                                      <MODE>mode, 0);
5071   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5072
5073   emit_insn (gen_sse2_loadld (operands[4],
5074                               CONST0_RTX (V4SImode), operands[1]));
5075   if (<ssevecmode>mode == V4SFmode)
5076     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5077   else
5078     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5079   DONE;
5080 })
5081
5082 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5083   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5084         (float:MODEF
5085           (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5086   (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5087   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5088    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5089   "#"
5090   [(set_attr "type" "sseicvt")
5091    (set_attr "mode" "<MODEF:MODE>")
5092    (set_attr "athlon_decode" "double,direct")
5093    (set_attr "amdfam10_decode" "vector,double")
5094    (set_attr "bdver1_decode" "double,direct")
5095    (set_attr "fp_int_src" "true")])
5096
5097 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5098   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5099         (float:MODEF
5100           (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5101   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5102    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5103    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5104   "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5105   [(set_attr "type" "sseicvt")
5106    (set_attr "prefix" "maybe_vex")
5107    (set_attr "mode" "<MODEF:MODE>")
5108    (set (attr "prefix_rex")
5109      (if_then_else
5110        (and (eq_attr "prefix" "maybe_vex")
5111             (match_test "<SWI48x:MODE>mode == DImode"))
5112        (const_string "1")
5113        (const_string "*")))
5114    (set_attr "athlon_decode" "double,direct")
5115    (set_attr "amdfam10_decode" "vector,double")
5116    (set_attr "bdver1_decode" "double,direct")
5117    (set_attr "fp_int_src" "true")])
5118
5119 (define_split
5120   [(set (match_operand:MODEF 0 "register_operand" "")
5121         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5122    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5123   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5124    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5125    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5126    && reload_completed
5127    && (SSE_REG_P (operands[0])
5128        || (GET_CODE (operands[0]) == SUBREG
5129            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5130   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5131
5132 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5133   [(set (match_operand:MODEF 0 "register_operand" "=x")
5134         (float:MODEF
5135           (match_operand:SWI48x 1 "memory_operand" "m")))]
5136   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5137    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5138    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5139   "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5140   [(set_attr "type" "sseicvt")
5141    (set_attr "prefix" "maybe_vex")
5142    (set_attr "mode" "<MODEF:MODE>")
5143    (set (attr "prefix_rex")
5144      (if_then_else
5145        (and (eq_attr "prefix" "maybe_vex")
5146             (match_test "<SWI48x:MODE>mode == DImode"))
5147        (const_string "1")
5148        (const_string "*")))
5149    (set_attr "athlon_decode" "direct")
5150    (set_attr "amdfam10_decode" "double")
5151    (set_attr "bdver1_decode" "direct")
5152    (set_attr "fp_int_src" "true")])
5153
5154 (define_split
5155   [(set (match_operand:MODEF 0 "register_operand" "")
5156         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5157    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5158   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5159    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5160    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5161    && reload_completed
5162    && (SSE_REG_P (operands[0])
5163        || (GET_CODE (operands[0]) == SUBREG
5164            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5165   [(set (match_dup 2) (match_dup 1))
5166    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5167
5168 (define_split
5169   [(set (match_operand:MODEF 0 "register_operand" "")
5170         (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5171    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5172   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5173    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5174    && reload_completed
5175    && (SSE_REG_P (operands[0])
5176        || (GET_CODE (operands[0]) == SUBREG
5177            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5178   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5179
5180 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5181   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5182         (float:X87MODEF
5183           (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5184   (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5185   "TARGET_80387
5186    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5187   "@
5188    fild%Z1\t%1
5189    #"
5190   [(set_attr "type" "fmov,multi")
5191    (set_attr "mode" "<X87MODEF:MODE>")
5192    (set_attr "unit" "*,i387")
5193    (set_attr "fp_int_src" "true")])
5194
5195 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5196   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5197         (float:X87MODEF
5198           (match_operand:SWI48x 1 "memory_operand" "m")))]
5199   "TARGET_80387
5200    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5201   "fild%Z1\t%1"
5202   [(set_attr "type" "fmov")
5203    (set_attr "mode" "<X87MODEF:MODE>")
5204    (set_attr "fp_int_src" "true")])
5205
5206 (define_split
5207   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5208         (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5209    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5210   "TARGET_80387
5211    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5212    && reload_completed"
5213   [(set (match_dup 2) (match_dup 1))
5214    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5215
5216 (define_split
5217   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5218         (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5219    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5220   "TARGET_80387
5221    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5222    && reload_completed"
5223   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5224
5225 ;; Avoid store forwarding (partial memory) stall penalty
5226 ;; by passing DImode value through XMM registers.  */
5227
5228 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5229   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5230         (float:X87MODEF
5231           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5232    (clobber (match_scratch:V4SI 3 "=X,x"))
5233    (clobber (match_scratch:V4SI 4 "=X,x"))
5234    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5235   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5236    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5237    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5238   "#"
5239   [(set_attr "type" "multi")
5240    (set_attr "mode" "<X87MODEF:MODE>")
5241    (set_attr "unit" "i387")
5242    (set_attr "fp_int_src" "true")])
5243
5244 (define_split
5245   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5246         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5247    (clobber (match_scratch:V4SI 3 ""))
5248    (clobber (match_scratch:V4SI 4 ""))
5249    (clobber (match_operand:DI 2 "memory_operand" ""))]
5250   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5251    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5252    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5253    && reload_completed"
5254   [(set (match_dup 2) (match_dup 3))
5255    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5256 {
5257   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5258      Assemble the 64-bit DImode value in an xmm register.  */
5259   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5260                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5261   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5262                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5263   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5264                                          operands[4]));
5265
5266   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5267 })
5268
5269 (define_split
5270   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5271         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5272    (clobber (match_scratch:V4SI 3 ""))
5273    (clobber (match_scratch:V4SI 4 ""))
5274    (clobber (match_operand:DI 2 "memory_operand" ""))]
5275   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5276    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5277    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5278    && reload_completed"
5279   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5280
5281 ;; Avoid store forwarding (partial memory) stall penalty by extending
5282 ;; SImode value to DImode through XMM register instead of pushing two
5283 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5284 ;; targets benefit from this optimization. Also note that fild
5285 ;; loads from memory only.
5286
5287 (define_insn "*floatunssi<mode>2_1"
5288   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5289         (unsigned_float:X87MODEF
5290           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5291    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5292    (clobber (match_scratch:SI 3 "=X,x"))]
5293   "!TARGET_64BIT
5294    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5295    && TARGET_SSE"
5296   "#"
5297   [(set_attr "type" "multi")
5298    (set_attr "mode" "<MODE>")])
5299
5300 (define_split
5301   [(set (match_operand:X87MODEF 0 "register_operand" "")
5302         (unsigned_float:X87MODEF
5303           (match_operand:SI 1 "register_operand" "")))
5304    (clobber (match_operand:DI 2 "memory_operand" ""))
5305    (clobber (match_scratch:SI 3 ""))]
5306   "!TARGET_64BIT
5307    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5308    && TARGET_SSE
5309    && reload_completed"
5310   [(set (match_dup 2) (match_dup 1))
5311    (set (match_dup 0)
5312         (float:X87MODEF (match_dup 2)))]
5313   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5314
5315 (define_split
5316   [(set (match_operand:X87MODEF 0 "register_operand" "")
5317         (unsigned_float:X87MODEF
5318           (match_operand:SI 1 "memory_operand" "")))
5319    (clobber (match_operand:DI 2 "memory_operand" ""))
5320    (clobber (match_scratch:SI 3 ""))]
5321   "!TARGET_64BIT
5322    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5323    && TARGET_SSE
5324    && reload_completed"
5325   [(set (match_dup 2) (match_dup 3))
5326    (set (match_dup 0)
5327         (float:X87MODEF (match_dup 2)))]
5328 {
5329   emit_move_insn (operands[3], operands[1]);
5330   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5331 })
5332
5333 (define_expand "floatunssi<mode>2"
5334   [(parallel
5335      [(set (match_operand:X87MODEF 0 "register_operand" "")
5336            (unsigned_float:X87MODEF
5337              (match_operand:SI 1 "nonimmediate_operand" "")))
5338       (clobber (match_dup 2))
5339       (clobber (match_scratch:SI 3 ""))])]
5340   "!TARGET_64BIT
5341    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5342         && TARGET_SSE)
5343        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5344 {
5345   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5346     {
5347       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5348       DONE;
5349     }
5350   else
5351     {
5352       enum ix86_stack_slot slot = (virtuals_instantiated
5353                                    ? SLOT_TEMP
5354                                    : SLOT_VIRTUAL);
5355       operands[2] = assign_386_stack_local (DImode, slot);
5356     }
5357 })
5358
5359 (define_expand "floatunsdisf2"
5360   [(use (match_operand:SF 0 "register_operand" ""))
5361    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5362   "TARGET_64BIT && TARGET_SSE_MATH"
5363   "x86_emit_floatuns (operands); DONE;")
5364
5365 (define_expand "floatunsdidf2"
5366   [(use (match_operand:DF 0 "register_operand" ""))
5367    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5368   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5369    && TARGET_SSE2 && TARGET_SSE_MATH"
5370 {
5371   if (TARGET_64BIT)
5372     x86_emit_floatuns (operands);
5373   else
5374     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5375   DONE;
5376 })
5377 \f
5378 ;; Add instructions
5379
5380 (define_expand "add<mode>3"
5381   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5382         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5383                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5384   ""
5385   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5386
5387 (define_insn_and_split "*add<dwi>3_doubleword"
5388   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5389         (plus:<DWI>
5390           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5391           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5392    (clobber (reg:CC FLAGS_REG))]
5393   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5394   "#"
5395   "reload_completed"
5396   [(parallel [(set (reg:CC FLAGS_REG)
5397                    (unspec:CC [(match_dup 1) (match_dup 2)]
5398                               UNSPEC_ADD_CARRY))
5399               (set (match_dup 0)
5400                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5401    (parallel [(set (match_dup 3)
5402                    (plus:DWIH
5403                      (match_dup 4)
5404                      (plus:DWIH
5405                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5406                        (match_dup 5))))
5407               (clobber (reg:CC FLAGS_REG))])]
5408   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5409
5410 (define_insn "*add<mode>3_cc"
5411   [(set (reg:CC FLAGS_REG)
5412         (unspec:CC
5413           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5414            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5415           UNSPEC_ADD_CARRY))
5416    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5417         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5418   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5419   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5420   [(set_attr "type" "alu")
5421    (set_attr "mode" "<MODE>")])
5422
5423 (define_insn "addqi3_cc"
5424   [(set (reg:CC FLAGS_REG)
5425         (unspec:CC
5426           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5427            (match_operand:QI 2 "general_operand" "qn,qm")]
5428           UNSPEC_ADD_CARRY))
5429    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5430         (plus:QI (match_dup 1) (match_dup 2)))]
5431   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5432   "add{b}\t{%2, %0|%0, %2}"
5433   [(set_attr "type" "alu")
5434    (set_attr "mode" "QI")])
5435
5436 (define_insn_and_split "*lea_1"
5437   [(set (match_operand:SI 0 "register_operand" "=r")
5438         (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
5439   "TARGET_64BIT"
5440   "lea{l}\t{%a1, %0|%0, %a1}"
5441   "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5442   [(const_int 0)]
5443 {
5444   ix86_split_lea_for_addr (operands, SImode);
5445   DONE;
5446 }
5447   [(set_attr "type" "lea")
5448    (set_attr "mode" "SI")])
5449
5450 (define_insn_and_split "*lea<mode>_2"
5451   [(set (match_operand:SWI48 0 "register_operand" "=r")
5452         (match_operand:SWI48 1 "lea_address_operand" "p"))]
5453   ""
5454   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5455   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5456   [(const_int 0)]
5457 {
5458   ix86_split_lea_for_addr (operands, <MODE>mode);
5459   DONE;
5460 }
5461   [(set_attr "type" "lea")
5462    (set_attr "mode" "<MODE>")])
5463
5464 (define_insn "*lea_3_zext"
5465   [(set (match_operand:DI 0 "register_operand" "=r")
5466         (zero_extend:DI
5467           (subreg:SI (match_operand:DI 1 "lea_address_operand" "j") 0)))]
5468   "TARGET_64BIT"
5469   "lea{l}\t{%a1, %k0|%k0, %a1}"
5470   [(set_attr "type" "lea")
5471    (set_attr "mode" "SI")])
5472
5473 (define_insn "*lea_4_zext"
5474   [(set (match_operand:DI 0 "register_operand" "=r")
5475         (zero_extend:DI
5476           (match_operand:SI 1 "lea_address_operand" "j")))]
5477   "TARGET_64BIT"
5478   "lea{l}\t{%a1, %k0|%k0, %a1}"
5479   [(set_attr "type" "lea")
5480    (set_attr "mode" "SI")])
5481
5482 (define_insn "*lea_5_zext"
5483   [(set (match_operand:DI 0 "register_operand" "=r")
5484         (and:DI
5485           (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
5486           (match_operand:DI 2 "const_32bit_mask" "n")))]
5487   "TARGET_64BIT"
5488   "lea{l}\t{%a1, %k0|%k0, %a1}"
5489   [(set_attr "type" "lea")
5490    (set_attr "mode" "SI")])
5491
5492 (define_insn "*lea_6_zext"
5493   [(set (match_operand:DI 0 "register_operand" "=r")
5494         (and:DI
5495           (match_operand:DI 1 "lea_address_operand" "p")
5496           (match_operand:DI 2 "const_32bit_mask" "n")))]
5497   "TARGET_64BIT"
5498   "lea{l}\t{%a1, %k0|%k0, %a1}"
5499   [(set_attr "type" "lea")
5500    (set_attr "mode" "SI")])
5501
5502 (define_insn "*add<mode>_1"
5503   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5504         (plus:SWI48
5505           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5506           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5507    (clobber (reg:CC FLAGS_REG))]
5508   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5509 {
5510   switch (get_attr_type (insn))
5511     {
5512     case TYPE_LEA:
5513       return "#";
5514
5515     case TYPE_INCDEC:
5516       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5517       if (operands[2] == const1_rtx)
5518         return "inc{<imodesuffix>}\t%0";
5519       else
5520         {
5521           gcc_assert (operands[2] == constm1_rtx);
5522           return "dec{<imodesuffix>}\t%0";
5523         }
5524
5525     default:
5526       /* For most processors, ADD is faster than LEA.  This alternative
5527          was added to use ADD as much as possible.  */
5528       if (which_alternative == 2)
5529         {
5530           rtx tmp;
5531           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5532         }
5533         
5534       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5535       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5536         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5537
5538       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5539     }
5540 }
5541   [(set (attr "type")
5542      (cond [(eq_attr "alternative" "3")
5543               (const_string "lea")
5544             (match_operand:SWI48 2 "incdec_operand" "")
5545               (const_string "incdec")
5546            ]
5547            (const_string "alu")))
5548    (set (attr "length_immediate")
5549       (if_then_else
5550         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5551         (const_string "1")
5552         (const_string "*")))
5553    (set_attr "mode" "<MODE>")])
5554
5555 ;; It may seem that nonimmediate operand is proper one for operand 1.
5556 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5557 ;; we take care in ix86_binary_operator_ok to not allow two memory
5558 ;; operands so proper swapping will be done in reload.  This allow
5559 ;; patterns constructed from addsi_1 to match.
5560
5561 (define_insn "addsi_1_zext"
5562   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5563         (zero_extend:DI
5564           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5565                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5566    (clobber (reg:CC FLAGS_REG))]
5567   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5568 {
5569   switch (get_attr_type (insn))
5570     {
5571     case TYPE_LEA:
5572       return "#";
5573
5574     case TYPE_INCDEC:
5575       if (operands[2] == const1_rtx)
5576         return "inc{l}\t%k0";
5577       else
5578         {
5579           gcc_assert (operands[2] == constm1_rtx);
5580           return "dec{l}\t%k0";
5581         }
5582
5583     default:
5584       /* For most processors, ADD is faster than LEA.  This alternative
5585          was added to use ADD as much as possible.  */
5586       if (which_alternative == 1)
5587         {
5588           rtx tmp;
5589           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5590         }
5591
5592       if (x86_maybe_negate_const_int (&operands[2], SImode))
5593         return "sub{l}\t{%2, %k0|%k0, %2}";
5594
5595       return "add{l}\t{%2, %k0|%k0, %2}";
5596     }
5597 }
5598   [(set (attr "type")
5599      (cond [(eq_attr "alternative" "2")
5600               (const_string "lea")
5601             (match_operand:SI 2 "incdec_operand" "")
5602               (const_string "incdec")
5603            ]
5604            (const_string "alu")))
5605    (set (attr "length_immediate")
5606       (if_then_else
5607         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5608         (const_string "1")
5609         (const_string "*")))
5610    (set_attr "mode" "SI")])
5611
5612 (define_insn "*addhi_1"
5613   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5614         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5615                  (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5616    (clobber (reg:CC FLAGS_REG))]
5617   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5618 {
5619   switch (get_attr_type (insn))
5620     {
5621     case TYPE_LEA:
5622       return "#";
5623
5624     case TYPE_INCDEC:
5625       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5626       if (operands[2] == const1_rtx)
5627         return "inc{w}\t%0";
5628       else
5629         {
5630           gcc_assert (operands[2] == constm1_rtx);
5631           return "dec{w}\t%0";
5632         }
5633
5634     default:
5635       /* For most processors, ADD is faster than LEA.  This alternative
5636          was added to use ADD as much as possible.  */
5637       if (which_alternative == 2)
5638         {
5639           rtx tmp;
5640           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5641         }
5642
5643       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5644       if (x86_maybe_negate_const_int (&operands[2], HImode))
5645         return "sub{w}\t{%2, %0|%0, %2}";
5646
5647       return "add{w}\t{%2, %0|%0, %2}";
5648     }
5649 }
5650   [(set (attr "type")
5651      (cond [(eq_attr "alternative" "3")
5652               (const_string "lea")
5653             (match_operand:HI 2 "incdec_operand" "")
5654               (const_string "incdec")
5655            ]
5656            (const_string "alu")))
5657    (set (attr "length_immediate")
5658       (if_then_else
5659         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5660         (const_string "1")
5661         (const_string "*")))
5662    (set_attr "mode" "HI,HI,HI,SI")])
5663
5664 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5665 (define_insn "*addqi_1"
5666   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5667         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5668                  (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5669    (clobber (reg:CC FLAGS_REG))]
5670   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5671 {
5672   bool widen = (which_alternative == 3 || which_alternative == 4);
5673
5674   switch (get_attr_type (insn))
5675     {
5676     case TYPE_LEA:
5677       return "#";
5678
5679     case TYPE_INCDEC:
5680       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5681       if (operands[2] == const1_rtx)
5682         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5683       else
5684         {
5685           gcc_assert (operands[2] == constm1_rtx);
5686           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5687         }
5688
5689     default:
5690       /* For most processors, ADD is faster than LEA.  These alternatives
5691          were added to use ADD as much as possible.  */
5692       if (which_alternative == 2 || which_alternative == 4)
5693         {
5694           rtx tmp;
5695           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5696         }
5697
5698       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5699       if (x86_maybe_negate_const_int (&operands[2], QImode))
5700         {
5701           if (widen)
5702             return "sub{l}\t{%2, %k0|%k0, %2}";
5703           else
5704             return "sub{b}\t{%2, %0|%0, %2}";
5705         }
5706       if (widen)
5707         return "add{l}\t{%k2, %k0|%k0, %k2}";
5708       else
5709         return "add{b}\t{%2, %0|%0, %2}";
5710     }
5711 }
5712   [(set (attr "type")
5713      (cond [(eq_attr "alternative" "5")
5714               (const_string "lea")
5715             (match_operand:QI 2 "incdec_operand" "")
5716               (const_string "incdec")
5717            ]
5718            (const_string "alu")))
5719    (set (attr "length_immediate")
5720       (if_then_else
5721         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5722         (const_string "1")
5723         (const_string "*")))
5724    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5725
5726 (define_insn "*addqi_1_slp"
5727   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5728         (plus:QI (match_dup 0)
5729                  (match_operand:QI 1 "general_operand" "qn,qm")))
5730    (clobber (reg:CC FLAGS_REG))]
5731   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5732    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5733 {
5734   switch (get_attr_type (insn))
5735     {
5736     case TYPE_INCDEC:
5737       if (operands[1] == const1_rtx)
5738         return "inc{b}\t%0";
5739       else
5740         {
5741           gcc_assert (operands[1] == constm1_rtx);
5742           return "dec{b}\t%0";
5743         }
5744
5745     default:
5746       if (x86_maybe_negate_const_int (&operands[1], QImode))
5747         return "sub{b}\t{%1, %0|%0, %1}";
5748
5749       return "add{b}\t{%1, %0|%0, %1}";
5750     }
5751 }
5752   [(set (attr "type")
5753      (if_then_else (match_operand:QI 1 "incdec_operand" "")
5754         (const_string "incdec")
5755         (const_string "alu1")))
5756    (set (attr "memory")
5757      (if_then_else (match_operand 1 "memory_operand" "")
5758         (const_string "load")
5759         (const_string "none")))
5760    (set_attr "mode" "QI")])
5761
5762 ;; Split non destructive adds if we cannot use lea.
5763 (define_split
5764   [(set (match_operand:SWI48 0 "register_operand" "")
5765         (plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5766               (match_operand:SWI48 2 "nonmemory_operand" "")))
5767    (clobber (reg:CC FLAGS_REG))]
5768   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5769   [(set (match_dup 0) (match_dup 1))
5770    (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5771               (clobber (reg:CC FLAGS_REG))])])
5772
5773 ;; Convert add to the lea pattern to avoid flags dependency.
5774 (define_split
5775   [(set (match_operand:SWI 0 "register_operand" "")
5776         (plus:SWI (match_operand:SWI 1 "register_operand" "")
5777                   (match_operand:SWI 2 "<nonmemory_operand>" "")))
5778    (clobber (reg:CC FLAGS_REG))]
5779   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5780   [(const_int 0)]
5781 {
5782   enum machine_mode mode = <MODE>mode;
5783   rtx pat;
5784
5785   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5786     { 
5787       mode = SImode; 
5788       operands[0] = gen_lowpart (mode, operands[0]);
5789       operands[1] = gen_lowpart (mode, operands[1]);
5790       operands[2] = gen_lowpart (mode, operands[2]);
5791     }
5792
5793   pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5794
5795   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5796   DONE;
5797 })
5798
5799 ;; Convert add to the lea pattern to avoid flags dependency.
5800 (define_split
5801   [(set (match_operand:DI 0 "register_operand" "")
5802         (zero_extend:DI
5803           (plus:SI (match_operand:SI 1 "register_operand" "")
5804                    (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5805    (clobber (reg:CC FLAGS_REG))]
5806   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5807   [(set (match_dup 0)
5808         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5809
5810 (define_insn "*add<mode>_2"
5811   [(set (reg FLAGS_REG)
5812         (compare
5813           (plus:SWI
5814             (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5815             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5816           (const_int 0)))
5817    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5818         (plus:SWI (match_dup 1) (match_dup 2)))]
5819   "ix86_match_ccmode (insn, CCGOCmode)
5820    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5821 {
5822   switch (get_attr_type (insn))
5823     {
5824     case TYPE_INCDEC:
5825       if (operands[2] == const1_rtx)
5826         return "inc{<imodesuffix>}\t%0";
5827       else
5828         {
5829           gcc_assert (operands[2] == constm1_rtx);
5830           return "dec{<imodesuffix>}\t%0";
5831         }
5832
5833     default:
5834       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5835         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5836
5837       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5838     }
5839 }
5840   [(set (attr "type")
5841      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5842         (const_string "incdec")
5843         (const_string "alu")))
5844    (set (attr "length_immediate")
5845       (if_then_else
5846         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5847         (const_string "1")
5848         (const_string "*")))
5849    (set_attr "mode" "<MODE>")])
5850
5851 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5852 (define_insn "*addsi_2_zext"
5853   [(set (reg FLAGS_REG)
5854         (compare
5855           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5856                    (match_operand:SI 2 "x86_64_general_operand" "rme"))
5857           (const_int 0)))
5858    (set (match_operand:DI 0 "register_operand" "=r")
5859         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5860   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5861    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5862 {
5863   switch (get_attr_type (insn))
5864     {
5865     case TYPE_INCDEC:
5866       if (operands[2] == const1_rtx)
5867         return "inc{l}\t%k0";
5868       else
5869         {
5870           gcc_assert (operands[2] == constm1_rtx);
5871           return "dec{l}\t%k0";
5872         }
5873
5874     default:
5875       if (x86_maybe_negate_const_int (&operands[2], SImode))
5876         return "sub{l}\t{%2, %k0|%k0, %2}";
5877
5878       return "add{l}\t{%2, %k0|%k0, %2}";
5879     }
5880 }
5881   [(set (attr "type")
5882      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5883         (const_string "incdec")
5884         (const_string "alu")))
5885    (set (attr "length_immediate")
5886       (if_then_else
5887         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5888         (const_string "1")
5889         (const_string "*")))
5890    (set_attr "mode" "SI")])
5891
5892 (define_insn "*add<mode>_3"
5893   [(set (reg FLAGS_REG)
5894         (compare
5895           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5896           (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5897    (clobber (match_scratch:SWI 0 "=<r>"))]
5898   "ix86_match_ccmode (insn, CCZmode)
5899    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5900 {
5901   switch (get_attr_type (insn))
5902     {
5903     case TYPE_INCDEC:
5904       if (operands[2] == const1_rtx)
5905         return "inc{<imodesuffix>}\t%0";
5906       else
5907         {
5908           gcc_assert (operands[2] == constm1_rtx);
5909           return "dec{<imodesuffix>}\t%0";
5910         }
5911
5912     default:
5913       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5914         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5915
5916       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5917     }
5918 }
5919   [(set (attr "type")
5920      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5921         (const_string "incdec")
5922         (const_string "alu")))
5923    (set (attr "length_immediate")
5924       (if_then_else
5925         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5926         (const_string "1")
5927         (const_string "*")))
5928    (set_attr "mode" "<MODE>")])
5929
5930 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5931 (define_insn "*addsi_3_zext"
5932   [(set (reg FLAGS_REG)
5933         (compare
5934           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme"))
5935           (match_operand:SI 1 "nonimmediate_operand" "%0")))
5936    (set (match_operand:DI 0 "register_operand" "=r")
5937         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5938   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5939    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5940 {
5941   switch (get_attr_type (insn))
5942     {
5943     case TYPE_INCDEC:
5944       if (operands[2] == const1_rtx)
5945         return "inc{l}\t%k0";
5946       else
5947         {
5948           gcc_assert (operands[2] == constm1_rtx);
5949           return "dec{l}\t%k0";
5950         }
5951
5952     default:
5953       if (x86_maybe_negate_const_int (&operands[2], SImode))
5954         return "sub{l}\t{%2, %k0|%k0, %2}";
5955
5956       return "add{l}\t{%2, %k0|%k0, %2}";
5957     }
5958 }
5959   [(set (attr "type")
5960      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5961         (const_string "incdec")
5962         (const_string "alu")))
5963    (set (attr "length_immediate")
5964       (if_then_else
5965         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5966         (const_string "1")
5967         (const_string "*")))
5968    (set_attr "mode" "SI")])
5969
5970 ; For comparisons against 1, -1 and 128, we may generate better code
5971 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5972 ; is matched then.  We can't accept general immediate, because for
5973 ; case of overflows,  the result is messed up.
5974 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5975 ; only for comparisons not depending on it.
5976
5977 (define_insn "*adddi_4"
5978   [(set (reg FLAGS_REG)
5979         (compare
5980           (match_operand:DI 1 "nonimmediate_operand" "0")
5981           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5982    (clobber (match_scratch:DI 0 "=rm"))]
5983   "TARGET_64BIT
5984    && ix86_match_ccmode (insn, CCGCmode)"
5985 {
5986   switch (get_attr_type (insn))
5987     {
5988     case TYPE_INCDEC:
5989       if (operands[2] == constm1_rtx)
5990         return "inc{q}\t%0";
5991       else
5992         {
5993           gcc_assert (operands[2] == const1_rtx);
5994           return "dec{q}\t%0";
5995         }
5996
5997     default:
5998       if (x86_maybe_negate_const_int (&operands[2], DImode))
5999         return "add{q}\t{%2, %0|%0, %2}";
6000
6001       return "sub{q}\t{%2, %0|%0, %2}";
6002     }
6003 }
6004   [(set (attr "type")
6005      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6006         (const_string "incdec")
6007         (const_string "alu")))
6008    (set (attr "length_immediate")
6009       (if_then_else
6010         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6011         (const_string "1")
6012         (const_string "*")))
6013    (set_attr "mode" "DI")])
6014
6015 ; For comparisons against 1, -1 and 128, we may generate better code
6016 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6017 ; is matched then.  We can't accept general immediate, because for
6018 ; case of overflows,  the result is messed up.
6019 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6020 ; only for comparisons not depending on it.
6021
6022 (define_insn "*add<mode>_4"
6023   [(set (reg FLAGS_REG)
6024         (compare
6025           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6026           (match_operand:SWI124 2 "const_int_operand" "n")))
6027    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6028   "ix86_match_ccmode (insn, CCGCmode)"
6029 {
6030   switch (get_attr_type (insn))
6031     {
6032     case TYPE_INCDEC:
6033       if (operands[2] == constm1_rtx)
6034         return "inc{<imodesuffix>}\t%0";
6035       else
6036         {
6037           gcc_assert (operands[2] == const1_rtx);
6038           return "dec{<imodesuffix>}\t%0";
6039         }
6040
6041     default:
6042       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6043         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6044
6045       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6046     }
6047 }
6048   [(set (attr "type")
6049      (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6050         (const_string "incdec")
6051         (const_string "alu")))
6052    (set (attr "length_immediate")
6053       (if_then_else
6054         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6055         (const_string "1")
6056         (const_string "*")))
6057    (set_attr "mode" "<MODE>")])
6058
6059 (define_insn "*add<mode>_5"
6060   [(set (reg FLAGS_REG)
6061         (compare
6062           (plus:SWI
6063             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6064             (match_operand:SWI 2 "<general_operand>" "<g>"))
6065           (const_int 0)))
6066    (clobber (match_scratch:SWI 0 "=<r>"))]
6067   "ix86_match_ccmode (insn, CCGOCmode)
6068    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6069 {
6070   switch (get_attr_type (insn))
6071     {
6072     case TYPE_INCDEC:
6073       if (operands[2] == const1_rtx)
6074         return "inc{<imodesuffix>}\t%0";
6075       else
6076         {
6077           gcc_assert (operands[2] == constm1_rtx);
6078           return "dec{<imodesuffix>}\t%0";
6079         }
6080
6081     default:
6082       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6083         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6084
6085       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6086     }
6087 }
6088   [(set (attr "type")
6089      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6090         (const_string "incdec")
6091         (const_string "alu")))
6092    (set (attr "length_immediate")
6093       (if_then_else
6094         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6095         (const_string "1")
6096         (const_string "*")))
6097    (set_attr "mode" "<MODE>")])
6098
6099 (define_insn "*addqi_ext_1_rex64"
6100   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6101                          (const_int 8)
6102                          (const_int 8))
6103         (plus:SI
6104           (zero_extract:SI
6105             (match_operand 1 "ext_register_operand" "0")
6106             (const_int 8)
6107             (const_int 8))
6108           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6109    (clobber (reg:CC FLAGS_REG))]
6110   "TARGET_64BIT"
6111 {
6112   switch (get_attr_type (insn))
6113     {
6114     case TYPE_INCDEC:
6115       if (operands[2] == const1_rtx)
6116         return "inc{b}\t%h0";
6117       else
6118         {
6119           gcc_assert (operands[2] == constm1_rtx);
6120           return "dec{b}\t%h0";
6121         }
6122
6123     default:
6124       return "add{b}\t{%2, %h0|%h0, %2}";
6125     }
6126 }
6127   [(set (attr "type")
6128      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6129         (const_string "incdec")
6130         (const_string "alu")))
6131    (set_attr "modrm" "1")
6132    (set_attr "mode" "QI")])
6133
6134 (define_insn "addqi_ext_1"
6135   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6136                          (const_int 8)
6137                          (const_int 8))
6138         (plus:SI
6139           (zero_extract:SI
6140             (match_operand 1 "ext_register_operand" "0")
6141             (const_int 8)
6142             (const_int 8))
6143           (match_operand:QI 2 "general_operand" "Qmn")))
6144    (clobber (reg:CC FLAGS_REG))]
6145   "!TARGET_64BIT"
6146 {
6147   switch (get_attr_type (insn))
6148     {
6149     case TYPE_INCDEC:
6150       if (operands[2] == const1_rtx)
6151         return "inc{b}\t%h0";
6152       else
6153         {
6154           gcc_assert (operands[2] == constm1_rtx);
6155           return "dec{b}\t%h0";
6156         }
6157
6158     default:
6159       return "add{b}\t{%2, %h0|%h0, %2}";
6160     }
6161 }
6162   [(set (attr "type")
6163      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6164         (const_string "incdec")
6165         (const_string "alu")))
6166    (set_attr "modrm" "1")
6167    (set_attr "mode" "QI")])
6168
6169 (define_insn "*addqi_ext_2"
6170   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6171                          (const_int 8)
6172                          (const_int 8))
6173         (plus:SI
6174           (zero_extract:SI
6175             (match_operand 1 "ext_register_operand" "%0")
6176             (const_int 8)
6177             (const_int 8))
6178           (zero_extract:SI
6179             (match_operand 2 "ext_register_operand" "Q")
6180             (const_int 8)
6181             (const_int 8))))
6182    (clobber (reg:CC FLAGS_REG))]
6183   ""
6184   "add{b}\t{%h2, %h0|%h0, %h2}"
6185   [(set_attr "type" "alu")
6186    (set_attr "mode" "QI")])
6187
6188 ;; The lea patterns for modes less than 32 bits need to be matched by
6189 ;; several insns converted to real lea by splitters.
6190
6191 (define_insn_and_split "*lea_general_1"
6192   [(set (match_operand 0 "register_operand" "=r")
6193         (plus (plus (match_operand 1 "index_register_operand" "l")
6194                     (match_operand 2 "register_operand" "r"))
6195               (match_operand 3 "immediate_operand" "i")))]
6196   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6197    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6198    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6199    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6200    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6201        || GET_MODE (operands[3]) == VOIDmode)"
6202   "#"
6203   "&& reload_completed"
6204   [(const_int 0)]
6205 {
6206   enum machine_mode mode = SImode;
6207   rtx pat;
6208
6209   operands[0] = gen_lowpart (mode, operands[0]);
6210   operands[1] = gen_lowpart (mode, operands[1]);
6211   operands[2] = gen_lowpart (mode, operands[2]);
6212   operands[3] = gen_lowpart (mode, operands[3]);
6213
6214   pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6215                       operands[3]);
6216
6217   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6218   DONE;
6219 }
6220   [(set_attr "type" "lea")
6221    (set_attr "mode" "SI")])
6222
6223 (define_insn_and_split "*lea_general_2"
6224   [(set (match_operand 0 "register_operand" "=r")
6225         (plus (mult (match_operand 1 "index_register_operand" "l")
6226                     (match_operand 2 "const248_operand" "n"))
6227               (match_operand 3 "nonmemory_operand" "ri")))]
6228   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6229    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6230    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6231    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6232        || GET_MODE (operands[3]) == VOIDmode)"
6233   "#"
6234   "&& reload_completed"
6235   [(const_int 0)]
6236 {
6237   enum machine_mode mode = SImode;
6238   rtx pat;
6239
6240   operands[0] = gen_lowpart (mode, operands[0]);
6241   operands[1] = gen_lowpart (mode, operands[1]);
6242   operands[3] = gen_lowpart (mode, operands[3]);
6243
6244   pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6245                       operands[3]);
6246
6247   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6248   DONE;
6249 }
6250   [(set_attr "type" "lea")
6251    (set_attr "mode" "SI")])
6252
6253 (define_insn_and_split "*lea_general_3"
6254   [(set (match_operand 0 "register_operand" "=r")
6255         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6256                           (match_operand 2 "const248_operand" "n"))
6257                     (match_operand 3 "register_operand" "r"))
6258               (match_operand 4 "immediate_operand" "i")))]
6259   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6260    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6261    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6262    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6263   "#"
6264   "&& reload_completed"
6265   [(const_int 0)]
6266 {
6267   enum machine_mode mode = SImode;
6268   rtx pat;
6269
6270   operands[0] = gen_lowpart (mode, operands[0]);
6271   operands[1] = gen_lowpart (mode, operands[1]);
6272   operands[3] = gen_lowpart (mode, operands[3]);
6273   operands[4] = gen_lowpart (mode, operands[4]);
6274
6275   pat = gen_rtx_PLUS (mode,
6276                       gen_rtx_PLUS (mode,
6277                                     gen_rtx_MULT (mode, operands[1],
6278                                                         operands[2]),
6279                                     operands[3]),
6280                       operands[4]);
6281
6282   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6283   DONE;
6284 }
6285   [(set_attr "type" "lea")
6286    (set_attr "mode" "SI")])
6287
6288 (define_insn_and_split "*lea_general_4"
6289   [(set (match_operand 0 "register_operand" "=r")
6290         (any_or (ashift
6291                   (match_operand 1 "index_register_operand" "l")
6292                   (match_operand 2 "const_int_operand" "n"))
6293                 (match_operand 3 "const_int_operand" "n")))]
6294   "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6295       && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6296     || GET_MODE (operands[0]) == SImode
6297     || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6298    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6299    && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6300    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6301        < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6302   "#"
6303   "&& reload_completed"
6304   [(const_int 0)]
6305 {
6306   enum machine_mode mode = GET_MODE (operands[0]);
6307   rtx pat;
6308
6309   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6310     { 
6311       mode = SImode; 
6312       operands[0] = gen_lowpart (mode, operands[0]);
6313       operands[1] = gen_lowpart (mode, operands[1]);
6314     }
6315
6316   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6317
6318   pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6319                        INTVAL (operands[3]));
6320
6321   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6322   DONE;
6323 }
6324   [(set_attr "type" "lea")
6325    (set (attr "mode")
6326       (if_then_else (match_operand:DI 0 "" "")
6327         (const_string "DI")
6328         (const_string "SI")))])
6329 \f
6330 ;; Subtract instructions
6331
6332 (define_expand "sub<mode>3"
6333   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6334         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6335                      (match_operand:SDWIM 2 "<general_operand>" "")))]
6336   ""
6337   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6338
6339 (define_insn_and_split "*sub<dwi>3_doubleword"
6340   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6341         (minus:<DWI>
6342           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6343           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6344    (clobber (reg:CC FLAGS_REG))]
6345   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6346   "#"
6347   "reload_completed"
6348   [(parallel [(set (reg:CC FLAGS_REG)
6349                    (compare:CC (match_dup 1) (match_dup 2)))
6350               (set (match_dup 0)
6351                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6352    (parallel [(set (match_dup 3)
6353                    (minus:DWIH
6354                      (match_dup 4)
6355                      (plus:DWIH
6356                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6357                        (match_dup 5))))
6358               (clobber (reg:CC FLAGS_REG))])]
6359   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6360
6361 (define_insn "*sub<mode>_1"
6362   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6363         (minus:SWI
6364           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6365           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6366    (clobber (reg:CC FLAGS_REG))]
6367   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6368   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6369   [(set_attr "type" "alu")
6370    (set_attr "mode" "<MODE>")])
6371
6372 (define_insn "*subsi_1_zext"
6373   [(set (match_operand:DI 0 "register_operand" "=r")
6374         (zero_extend:DI
6375           (minus:SI (match_operand:SI 1 "register_operand" "0")
6376                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6377    (clobber (reg:CC FLAGS_REG))]
6378   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6379   "sub{l}\t{%2, %k0|%k0, %2}"
6380   [(set_attr "type" "alu")
6381    (set_attr "mode" "SI")])
6382
6383 (define_insn "*subqi_1_slp"
6384   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6385         (minus:QI (match_dup 0)
6386                   (match_operand:QI 1 "general_operand" "qn,qm")))
6387    (clobber (reg:CC FLAGS_REG))]
6388   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6389    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6390   "sub{b}\t{%1, %0|%0, %1}"
6391   [(set_attr "type" "alu1")
6392    (set_attr "mode" "QI")])
6393
6394 (define_insn "*sub<mode>_2"
6395   [(set (reg FLAGS_REG)
6396         (compare
6397           (minus:SWI
6398             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6399             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6400           (const_int 0)))
6401    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6402         (minus:SWI (match_dup 1) (match_dup 2)))]
6403   "ix86_match_ccmode (insn, CCGOCmode)
6404    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6405   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6406   [(set_attr "type" "alu")
6407    (set_attr "mode" "<MODE>")])
6408
6409 (define_insn "*subsi_2_zext"
6410   [(set (reg FLAGS_REG)
6411         (compare
6412           (minus:SI (match_operand:SI 1 "register_operand" "0")
6413                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6414           (const_int 0)))
6415    (set (match_operand:DI 0 "register_operand" "=r")
6416         (zero_extend:DI
6417           (minus:SI (match_dup 1)
6418                     (match_dup 2))))]
6419   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6420    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6421   "sub{l}\t{%2, %k0|%k0, %2}"
6422   [(set_attr "type" "alu")
6423    (set_attr "mode" "SI")])
6424
6425 (define_insn "*sub<mode>_3"
6426   [(set (reg FLAGS_REG)
6427         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6428                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6429    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6430         (minus:SWI (match_dup 1) (match_dup 2)))]
6431   "ix86_match_ccmode (insn, CCmode)
6432    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6433   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6434   [(set_attr "type" "alu")
6435    (set_attr "mode" "<MODE>")])
6436
6437 (define_insn "*subsi_3_zext"
6438   [(set (reg FLAGS_REG)
6439         (compare (match_operand:SI 1 "register_operand" "0")
6440                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6441    (set (match_operand:DI 0 "register_operand" "=r")
6442         (zero_extend:DI
6443           (minus:SI (match_dup 1)
6444                     (match_dup 2))))]
6445   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6446    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6447   "sub{l}\t{%2, %1|%1, %2}"
6448   [(set_attr "type" "alu")
6449    (set_attr "mode" "SI")])
6450 \f
6451 ;; Add with carry and subtract with borrow
6452
6453 (define_expand "<plusminus_insn><mode>3_carry"
6454   [(parallel
6455     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6456           (plusminus:SWI
6457             (match_operand:SWI 1 "nonimmediate_operand" "")
6458             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6459                        [(match_operand 3 "flags_reg_operand" "")
6460                         (const_int 0)])
6461                       (match_operand:SWI 2 "<general_operand>" ""))))
6462      (clobber (reg:CC FLAGS_REG))])]
6463   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6464
6465 (define_insn "*<plusminus_insn><mode>3_carry"
6466   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6467         (plusminus:SWI
6468           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6469           (plus:SWI
6470             (match_operator 3 "ix86_carry_flag_operator"
6471              [(reg FLAGS_REG) (const_int 0)])
6472             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6473    (clobber (reg:CC FLAGS_REG))]
6474   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6475   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6476   [(set_attr "type" "alu")
6477    (set_attr "use_carry" "1")
6478    (set_attr "pent_pair" "pu")
6479    (set_attr "mode" "<MODE>")])
6480
6481 (define_insn "*addsi3_carry_zext"
6482   [(set (match_operand:DI 0 "register_operand" "=r")
6483         (zero_extend:DI
6484           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6485                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6486                              [(reg FLAGS_REG) (const_int 0)])
6487                             (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6488    (clobber (reg:CC FLAGS_REG))]
6489   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6490   "adc{l}\t{%2, %k0|%k0, %2}"
6491   [(set_attr "type" "alu")
6492    (set_attr "use_carry" "1")
6493    (set_attr "pent_pair" "pu")
6494    (set_attr "mode" "SI")])
6495
6496 (define_insn "*subsi3_carry_zext"
6497   [(set (match_operand:DI 0 "register_operand" "=r")
6498         (zero_extend:DI
6499           (minus:SI (match_operand:SI 1 "register_operand" "0")
6500                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6501                               [(reg FLAGS_REG) (const_int 0)])
6502                              (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6503    (clobber (reg:CC FLAGS_REG))]
6504   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6505   "sbb{l}\t{%2, %k0|%k0, %2}"
6506   [(set_attr "type" "alu")
6507    (set_attr "pent_pair" "pu")
6508    (set_attr "mode" "SI")])
6509 \f
6510 ;; Overflow setting add and subtract instructions
6511
6512 (define_insn "*add<mode>3_cconly_overflow"
6513   [(set (reg:CCC FLAGS_REG)
6514         (compare:CCC
6515           (plus:SWI
6516             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6517             (match_operand:SWI 2 "<general_operand>" "<g>"))
6518           (match_dup 1)))
6519    (clobber (match_scratch:SWI 0 "=<r>"))]
6520   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6521   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6522   [(set_attr "type" "alu")
6523    (set_attr "mode" "<MODE>")])
6524
6525 (define_insn "*sub<mode>3_cconly_overflow"
6526   [(set (reg:CCC FLAGS_REG)
6527         (compare:CCC
6528           (minus:SWI
6529             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6530             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6531           (match_dup 0)))]
6532   ""
6533   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6534   [(set_attr "type" "icmp")
6535    (set_attr "mode" "<MODE>")])
6536
6537 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6538   [(set (reg:CCC FLAGS_REG)
6539         (compare:CCC
6540             (plusminus:SWI
6541                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6542                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6543             (match_dup 1)))
6544    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6545         (plusminus:SWI (match_dup 1) (match_dup 2)))]
6546   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6547   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6548   [(set_attr "type" "alu")
6549    (set_attr "mode" "<MODE>")])
6550
6551 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6552   [(set (reg:CCC FLAGS_REG)
6553         (compare:CCC
6554           (plusminus:SI
6555             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6556             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6557           (match_dup 1)))
6558    (set (match_operand:DI 0 "register_operand" "=r")
6559         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6560   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6561   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6562   [(set_attr "type" "alu")
6563    (set_attr "mode" "SI")])
6564
6565 ;; The patterns that match these are at the end of this file.
6566
6567 (define_expand "<plusminus_insn>xf3"
6568   [(set (match_operand:XF 0 "register_operand" "")
6569         (plusminus:XF
6570           (match_operand:XF 1 "register_operand" "")
6571           (match_operand:XF 2 "register_operand" "")))]
6572   "TARGET_80387")
6573
6574 (define_expand "<plusminus_insn><mode>3"
6575   [(set (match_operand:MODEF 0 "register_operand" "")
6576         (plusminus:MODEF
6577           (match_operand:MODEF 1 "register_operand" "")
6578           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6579   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6580     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6581 \f
6582 ;; Multiply instructions
6583
6584 (define_expand "mul<mode>3"
6585   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6586                    (mult:SWIM248
6587                      (match_operand:SWIM248 1 "register_operand" "")
6588                      (match_operand:SWIM248 2 "<general_operand>" "")))
6589               (clobber (reg:CC FLAGS_REG))])])
6590
6591 (define_expand "mulqi3"
6592   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6593                    (mult:QI
6594                      (match_operand:QI 1 "register_operand" "")
6595                      (match_operand:QI 2 "nonimmediate_operand" "")))
6596               (clobber (reg:CC FLAGS_REG))])]
6597   "TARGET_QIMODE_MATH")
6598
6599 ;; On AMDFAM10
6600 ;; IMUL reg32/64, reg32/64, imm8        Direct
6601 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6602 ;; IMUL reg32/64, reg32/64, imm32       Direct
6603 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6604 ;; IMUL reg32/64, reg32/64              Direct
6605 ;; IMUL reg32/64, mem32/64              Direct
6606 ;;
6607 ;; On BDVER1, all above IMULs use DirectPath
6608
6609 (define_insn "*mul<mode>3_1"
6610   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6611         (mult:SWI48
6612           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6613           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6614    (clobber (reg:CC FLAGS_REG))]
6615   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6616   "@
6617    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6618    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6619    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6620   [(set_attr "type" "imul")
6621    (set_attr "prefix_0f" "0,0,1")
6622    (set (attr "athlon_decode")
6623         (cond [(eq_attr "cpu" "athlon")
6624                   (const_string "vector")
6625                (eq_attr "alternative" "1")
6626                   (const_string "vector")
6627                (and (eq_attr "alternative" "2")
6628                     (match_operand 1 "memory_operand" ""))
6629                   (const_string "vector")]
6630               (const_string "direct")))
6631    (set (attr "amdfam10_decode")
6632         (cond [(and (eq_attr "alternative" "0,1")
6633                     (match_operand 1 "memory_operand" ""))
6634                   (const_string "vector")]
6635               (const_string "direct")))
6636    (set_attr "bdver1_decode" "direct")
6637    (set_attr "mode" "<MODE>")])
6638
6639 (define_insn "*mulsi3_1_zext"
6640   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6641         (zero_extend:DI
6642           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6643                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6644    (clobber (reg:CC FLAGS_REG))]
6645   "TARGET_64BIT
6646    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6647   "@
6648    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6649    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6650    imul{l}\t{%2, %k0|%k0, %2}"
6651   [(set_attr "type" "imul")
6652    (set_attr "prefix_0f" "0,0,1")
6653    (set (attr "athlon_decode")
6654         (cond [(eq_attr "cpu" "athlon")
6655                   (const_string "vector")
6656                (eq_attr "alternative" "1")
6657                   (const_string "vector")
6658                (and (eq_attr "alternative" "2")
6659                     (match_operand 1 "memory_operand" ""))
6660                   (const_string "vector")]
6661               (const_string "direct")))
6662    (set (attr "amdfam10_decode")
6663         (cond [(and (eq_attr "alternative" "0,1")
6664                     (match_operand 1 "memory_operand" ""))
6665                   (const_string "vector")]
6666               (const_string "direct")))
6667    (set_attr "bdver1_decode" "direct")
6668    (set_attr "mode" "SI")])
6669
6670 ;; On AMDFAM10
6671 ;; IMUL reg16, reg16, imm8      VectorPath
6672 ;; IMUL reg16, mem16, imm8      VectorPath
6673 ;; IMUL reg16, reg16, imm16     VectorPath
6674 ;; IMUL reg16, mem16, imm16     VectorPath
6675 ;; IMUL reg16, reg16            Direct
6676 ;; IMUL reg16, mem16            Direct
6677 ;;
6678 ;; On BDVER1, all HI MULs use DoublePath
6679
6680 (define_insn "*mulhi3_1"
6681   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6682         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6683                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6684    (clobber (reg:CC FLAGS_REG))]
6685   "TARGET_HIMODE_MATH
6686    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6687   "@
6688    imul{w}\t{%2, %1, %0|%0, %1, %2}
6689    imul{w}\t{%2, %1, %0|%0, %1, %2}
6690    imul{w}\t{%2, %0|%0, %2}"
6691   [(set_attr "type" "imul")
6692    (set_attr "prefix_0f" "0,0,1")
6693    (set (attr "athlon_decode")
6694         (cond [(eq_attr "cpu" "athlon")
6695                   (const_string "vector")
6696                (eq_attr "alternative" "1,2")
6697                   (const_string "vector")]
6698               (const_string "direct")))
6699    (set (attr "amdfam10_decode")
6700         (cond [(eq_attr "alternative" "0,1")
6701                   (const_string "vector")]
6702               (const_string "direct")))
6703    (set_attr "bdver1_decode" "double")
6704    (set_attr "mode" "HI")])
6705
6706 ;;On AMDFAM10 and BDVER1
6707 ;; MUL reg8     Direct
6708 ;; MUL mem8     Direct
6709
6710 (define_insn "*mulqi3_1"
6711   [(set (match_operand:QI 0 "register_operand" "=a")
6712         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6713                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6714    (clobber (reg:CC FLAGS_REG))]
6715   "TARGET_QIMODE_MATH
6716    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6717   "mul{b}\t%2"
6718   [(set_attr "type" "imul")
6719    (set_attr "length_immediate" "0")
6720    (set (attr "athlon_decode")
6721      (if_then_else (eq_attr "cpu" "athlon")
6722         (const_string "vector")
6723         (const_string "direct")))
6724    (set_attr "amdfam10_decode" "direct")
6725    (set_attr "bdver1_decode" "direct")
6726    (set_attr "mode" "QI")])
6727
6728 (define_expand "<u>mul<mode><dwi>3"
6729   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6730                    (mult:<DWI>
6731                      (any_extend:<DWI>
6732                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
6733                      (any_extend:<DWI>
6734                        (match_operand:DWIH 2 "register_operand" ""))))
6735               (clobber (reg:CC FLAGS_REG))])])
6736
6737 (define_expand "<u>mulqihi3"
6738   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6739                    (mult:HI
6740                      (any_extend:HI
6741                        (match_operand:QI 1 "nonimmediate_operand" ""))
6742                      (any_extend:HI
6743                        (match_operand:QI 2 "register_operand" ""))))
6744               (clobber (reg:CC FLAGS_REG))])]
6745   "TARGET_QIMODE_MATH")
6746
6747 (define_insn "*bmi2_umulditi3_1"
6748   [(set (match_operand:DI 0 "register_operand" "=r")
6749         (mult:DI
6750           (match_operand:DI 2 "nonimmediate_operand" "%d")
6751           (match_operand:DI 3 "nonimmediate_operand" "rm")))
6752    (set (match_operand:DI 1 "register_operand" "=r")
6753         (truncate:DI
6754           (lshiftrt:TI
6755             (mult:TI (zero_extend:TI (match_dup 2))
6756                      (zero_extend:TI (match_dup 3)))
6757             (const_int 64))))]
6758   "TARGET_64BIT && TARGET_BMI2
6759    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6760   "mulx\t{%3, %0, %1|%1, %0, %3}"
6761   [(set_attr "type" "imulx")
6762    (set_attr "prefix" "vex")
6763    (set_attr "mode" "DI")])
6764
6765 (define_insn "*bmi2_umulsidi3_1"
6766   [(set (match_operand:SI 0 "register_operand" "=r")
6767         (mult:SI
6768           (match_operand:SI 2 "nonimmediate_operand" "%d")
6769           (match_operand:SI 3 "nonimmediate_operand" "rm")))
6770    (set (match_operand:SI 1 "register_operand" "=r")
6771         (truncate:SI
6772           (lshiftrt:DI
6773             (mult:DI (zero_extend:DI (match_dup 2))
6774                      (zero_extend:DI (match_dup 3)))
6775             (const_int 32))))]
6776   "!TARGET_64BIT && TARGET_BMI2
6777    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6778   "mulx\t{%3, %0, %1|%1, %0, %3}"
6779   [(set_attr "type" "imulx")
6780    (set_attr "prefix" "vex")
6781    (set_attr "mode" "SI")])
6782
6783 (define_insn "*umul<mode><dwi>3_1"
6784   [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6785         (mult:<DWI>
6786           (zero_extend:<DWI>
6787             (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6788           (zero_extend:<DWI>
6789             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6790    (clobber (reg:CC FLAGS_REG))]
6791   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6792   "@
6793    mul{<imodesuffix>}\t%2
6794    #"
6795   [(set_attr "isa" "*,bmi2")
6796    (set_attr "type" "imul,imulx")
6797    (set_attr "length_immediate" "0,*")
6798    (set (attr "athlon_decode")
6799         (cond [(eq_attr "alternative" "0")
6800                  (if_then_else (eq_attr "cpu" "athlon")
6801                    (const_string "vector")
6802                    (const_string "double"))]
6803               (const_string "*")))
6804    (set_attr "amdfam10_decode" "double,*")
6805    (set_attr "bdver1_decode" "direct,*")
6806    (set_attr "prefix" "orig,vex")
6807    (set_attr "mode" "<MODE>")])
6808
6809 ;; Convert mul to the mulx pattern to avoid flags dependency.
6810 (define_split
6811  [(set (match_operand:<DWI> 0 "register_operand" "")
6812        (mult:<DWI>
6813          (zero_extend:<DWI>
6814            (match_operand:DWIH 1 "register_operand" ""))
6815          (zero_extend:<DWI>
6816            (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6817   (clobber (reg:CC FLAGS_REG))]
6818  "TARGET_BMI2 && reload_completed
6819   && true_regnum (operands[1]) == DX_REG"
6820   [(parallel [(set (match_dup 3)
6821                    (mult:DWIH (match_dup 1) (match_dup 2)))
6822               (set (match_dup 4)
6823                    (truncate:DWIH
6824                      (lshiftrt:<DWI>
6825                        (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6826                                    (zero_extend:<DWI> (match_dup 2)))
6827                        (match_dup 5))))])]
6828 {
6829   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6830
6831   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6832 })
6833
6834 (define_insn "*mul<mode><dwi>3_1"
6835   [(set (match_operand:<DWI> 0 "register_operand" "=A")
6836         (mult:<DWI>
6837           (sign_extend:<DWI>
6838             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6839           (sign_extend:<DWI>
6840             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6841    (clobber (reg:CC FLAGS_REG))]
6842   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6843   "imul{<imodesuffix>}\t%2"
6844   [(set_attr "type" "imul")
6845    (set_attr "length_immediate" "0")
6846    (set (attr "athlon_decode")
6847      (if_then_else (eq_attr "cpu" "athlon")
6848         (const_string "vector")
6849         (const_string "double")))
6850    (set_attr "amdfam10_decode" "double")
6851    (set_attr "bdver1_decode" "direct")
6852    (set_attr "mode" "<MODE>")])
6853
6854 (define_insn "*<u>mulqihi3_1"
6855   [(set (match_operand:HI 0 "register_operand" "=a")
6856         (mult:HI
6857           (any_extend:HI
6858             (match_operand:QI 1 "nonimmediate_operand" "%0"))
6859           (any_extend:HI
6860             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6861    (clobber (reg:CC FLAGS_REG))]
6862   "TARGET_QIMODE_MATH
6863    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6864   "<sgnprefix>mul{b}\t%2"
6865   [(set_attr "type" "imul")
6866    (set_attr "length_immediate" "0")
6867    (set (attr "athlon_decode")
6868      (if_then_else (eq_attr "cpu" "athlon")
6869         (const_string "vector")
6870         (const_string "direct")))
6871    (set_attr "amdfam10_decode" "direct")
6872    (set_attr "bdver1_decode" "direct")
6873    (set_attr "mode" "QI")])
6874
6875 (define_expand "<s>mul<mode>3_highpart"
6876   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6877                    (truncate:SWI48
6878                      (lshiftrt:<DWI>
6879                        (mult:<DWI>
6880                          (any_extend:<DWI>
6881                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
6882                          (any_extend:<DWI>
6883                            (match_operand:SWI48 2 "register_operand" "")))
6884                        (match_dup 4))))
6885               (clobber (match_scratch:SWI48 3 ""))
6886               (clobber (reg:CC FLAGS_REG))])]
6887   ""
6888   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6889
6890 (define_insn "*<s>muldi3_highpart_1"
6891   [(set (match_operand:DI 0 "register_operand" "=d")
6892         (truncate:DI
6893           (lshiftrt:TI
6894             (mult:TI
6895               (any_extend:TI
6896                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6897               (any_extend:TI
6898                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6899             (const_int 64))))
6900    (clobber (match_scratch:DI 3 "=1"))
6901    (clobber (reg:CC FLAGS_REG))]
6902   "TARGET_64BIT
6903    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6904   "<sgnprefix>mul{q}\t%2"
6905   [(set_attr "type" "imul")
6906    (set_attr "length_immediate" "0")
6907    (set (attr "athlon_decode")
6908      (if_then_else (eq_attr "cpu" "athlon")
6909         (const_string "vector")
6910         (const_string "double")))
6911    (set_attr "amdfam10_decode" "double")
6912    (set_attr "bdver1_decode" "direct")
6913    (set_attr "mode" "DI")])
6914
6915 (define_insn "*<s>mulsi3_highpart_1"
6916   [(set (match_operand:SI 0 "register_operand" "=d")
6917         (truncate:SI
6918           (lshiftrt:DI
6919             (mult:DI
6920               (any_extend:DI
6921                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6922               (any_extend:DI
6923                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6924             (const_int 32))))
6925    (clobber (match_scratch:SI 3 "=1"))
6926    (clobber (reg:CC FLAGS_REG))]
6927   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6928   "<sgnprefix>mul{l}\t%2"
6929   [(set_attr "type" "imul")
6930    (set_attr "length_immediate" "0")
6931    (set (attr "athlon_decode")
6932      (if_then_else (eq_attr "cpu" "athlon")
6933         (const_string "vector")
6934         (const_string "double")))
6935    (set_attr "amdfam10_decode" "double")
6936    (set_attr "bdver1_decode" "direct")
6937    (set_attr "mode" "SI")])
6938
6939 (define_insn "*<s>mulsi3_highpart_zext"
6940   [(set (match_operand:DI 0 "register_operand" "=d")
6941         (zero_extend:DI (truncate:SI
6942           (lshiftrt:DI
6943             (mult:DI (any_extend:DI
6944                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
6945                      (any_extend:DI
6946                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
6947             (const_int 32)))))
6948    (clobber (match_scratch:SI 3 "=1"))
6949    (clobber (reg:CC FLAGS_REG))]
6950   "TARGET_64BIT
6951    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6952   "<sgnprefix>mul{l}\t%2"
6953   [(set_attr "type" "imul")
6954    (set_attr "length_immediate" "0")
6955    (set (attr "athlon_decode")
6956      (if_then_else (eq_attr "cpu" "athlon")
6957         (const_string "vector")
6958         (const_string "double")))
6959    (set_attr "amdfam10_decode" "double")
6960    (set_attr "bdver1_decode" "direct")
6961    (set_attr "mode" "SI")])
6962
6963 ;; The patterns that match these are at the end of this file.
6964
6965 (define_expand "mulxf3"
6966   [(set (match_operand:XF 0 "register_operand" "")
6967         (mult:XF (match_operand:XF 1 "register_operand" "")
6968                  (match_operand:XF 2 "register_operand" "")))]
6969   "TARGET_80387")
6970
6971 (define_expand "mul<mode>3"
6972   [(set (match_operand:MODEF 0 "register_operand" "")
6973         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
6974                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6975   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6976     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6977 \f
6978 ;; Divide instructions
6979
6980 ;; The patterns that match these are at the end of this file.
6981
6982 (define_expand "divxf3"
6983   [(set (match_operand:XF 0 "register_operand" "")
6984         (div:XF (match_operand:XF 1 "register_operand" "")
6985                 (match_operand:XF 2 "register_operand" "")))]
6986   "TARGET_80387")
6987
6988 (define_expand "divdf3"
6989   [(set (match_operand:DF 0 "register_operand" "")
6990         (div:DF (match_operand:DF 1 "register_operand" "")
6991                 (match_operand:DF 2 "nonimmediate_operand" "")))]
6992    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6993     || (TARGET_SSE2 && TARGET_SSE_MATH)")
6994
6995 (define_expand "divsf3"
6996   [(set (match_operand:SF 0 "register_operand" "")
6997         (div:SF (match_operand:SF 1 "register_operand" "")
6998                 (match_operand:SF 2 "nonimmediate_operand" "")))]
6999   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7000     || TARGET_SSE_MATH"
7001 {
7002   if (TARGET_SSE_MATH
7003       && TARGET_RECIP_DIV
7004       && optimize_insn_for_speed_p ()
7005       && flag_finite_math_only && !flag_trapping_math
7006       && flag_unsafe_math_optimizations)
7007     {
7008       ix86_emit_swdivsf (operands[0], operands[1],
7009                          operands[2], SFmode);
7010       DONE;
7011     }
7012 })
7013 \f
7014 ;; Divmod instructions.
7015
7016 (define_expand "divmod<mode>4"
7017   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7018                    (div:SWIM248
7019                      (match_operand:SWIM248 1 "register_operand" "")
7020                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7021               (set (match_operand:SWIM248 3 "register_operand" "")
7022                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7023               (clobber (reg:CC FLAGS_REG))])])
7024
7025 ;; Split with 8bit unsigned divide:
7026 ;;      if (dividend an divisor are in [0-255])
7027 ;;         use 8bit unsigned integer divide
7028 ;;       else
7029 ;;         use original integer divide
7030 (define_split
7031   [(set (match_operand:SWI48 0 "register_operand" "")
7032         (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7033                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7034    (set (match_operand:SWI48 1 "register_operand" "")
7035         (mod:SWI48 (match_dup 2) (match_dup 3)))
7036    (clobber (reg:CC FLAGS_REG))]
7037   "TARGET_USE_8BIT_IDIV
7038    && TARGET_QIMODE_MATH
7039    && can_create_pseudo_p ()
7040    && !optimize_insn_for_size_p ()"
7041   [(const_int 0)]
7042   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7043
7044 (define_insn_and_split "divmod<mode>4_1"
7045   [(set (match_operand:SWI48 0 "register_operand" "=a")
7046         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7047                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7048    (set (match_operand:SWI48 1 "register_operand" "=&d")
7049         (mod:SWI48 (match_dup 2) (match_dup 3)))
7050    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7051    (clobber (reg:CC FLAGS_REG))]
7052   ""
7053   "#"
7054   "reload_completed"
7055   [(parallel [(set (match_dup 1)
7056                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7057               (clobber (reg:CC FLAGS_REG))])
7058    (parallel [(set (match_dup 0)
7059                    (div:SWI48 (match_dup 2) (match_dup 3)))
7060               (set (match_dup 1)
7061                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7062               (use (match_dup 1))
7063               (clobber (reg:CC FLAGS_REG))])]
7064 {
7065   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7066
7067   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7068     operands[4] = operands[2];
7069   else
7070     {
7071       /* Avoid use of cltd in favor of a mov+shift.  */
7072       emit_move_insn (operands[1], operands[2]);
7073       operands[4] = operands[1];
7074     }
7075 }
7076   [(set_attr "type" "multi")
7077    (set_attr "mode" "<MODE>")])
7078
7079 (define_insn_and_split "*divmod<mode>4"
7080   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7081         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7082                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7083    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7084         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7085    (clobber (reg:CC FLAGS_REG))]
7086   ""
7087   "#"
7088   "reload_completed"
7089   [(parallel [(set (match_dup 1)
7090                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7091               (clobber (reg:CC FLAGS_REG))])
7092    (parallel [(set (match_dup 0)
7093                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7094               (set (match_dup 1)
7095                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7096               (use (match_dup 1))
7097               (clobber (reg:CC FLAGS_REG))])]
7098 {
7099   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7100
7101   if (<MODE>mode != HImode
7102       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7103     operands[4] = operands[2];
7104   else
7105     {
7106       /* Avoid use of cltd in favor of a mov+shift.  */
7107       emit_move_insn (operands[1], operands[2]);
7108       operands[4] = operands[1];
7109     }
7110 }
7111   [(set_attr "type" "multi")
7112    (set_attr "mode" "<MODE>")])
7113
7114 (define_insn "*divmod<mode>4_noext"
7115   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7116         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7117                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7118    (set (match_operand:SWIM248 1 "register_operand" "=d")
7119         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7120    (use (match_operand:SWIM248 4 "register_operand" "1"))
7121    (clobber (reg:CC FLAGS_REG))]
7122   ""
7123   "idiv{<imodesuffix>}\t%3"
7124   [(set_attr "type" "idiv")
7125    (set_attr "mode" "<MODE>")])
7126
7127 (define_expand "divmodqi4"
7128   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7129                    (div:QI
7130                      (match_operand:QI 1 "register_operand" "")
7131                      (match_operand:QI 2 "nonimmediate_operand" "")))
7132               (set (match_operand:QI 3 "register_operand" "")
7133                    (mod:QI (match_dup 1) (match_dup 2)))
7134               (clobber (reg:CC FLAGS_REG))])]
7135   "TARGET_QIMODE_MATH"
7136 {
7137   rtx div, mod, insn;
7138   rtx tmp0, tmp1;
7139   
7140   tmp0 = gen_reg_rtx (HImode);
7141   tmp1 = gen_reg_rtx (HImode);
7142
7143   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7144      in AX.  */
7145   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7146   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7147
7148   /* Extract remainder from AH.  */
7149   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7150   insn = emit_move_insn (operands[3], tmp1);
7151
7152   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7153   set_unique_reg_note (insn, REG_EQUAL, mod);
7154
7155   /* Extract quotient from AL.  */
7156   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7157
7158   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7159   set_unique_reg_note (insn, REG_EQUAL, div);
7160
7161   DONE;
7162 })
7163
7164 ;; Divide AX by r/m8, with result stored in
7165 ;; AL <- Quotient
7166 ;; AH <- Remainder
7167 ;; Change div/mod to HImode and extend the second argument to HImode
7168 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7169 ;; combine may fail.
7170 (define_insn "divmodhiqi3"
7171   [(set (match_operand:HI 0 "register_operand" "=a")
7172         (ior:HI
7173           (ashift:HI
7174             (zero_extend:HI
7175               (truncate:QI
7176                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7177                         (sign_extend:HI
7178                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7179             (const_int 8))
7180           (zero_extend:HI
7181             (truncate:QI
7182               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7183    (clobber (reg:CC FLAGS_REG))]
7184   "TARGET_QIMODE_MATH"
7185   "idiv{b}\t%2"
7186   [(set_attr "type" "idiv")
7187    (set_attr "mode" "QI")])
7188
7189 (define_expand "udivmod<mode>4"
7190   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7191                    (udiv:SWIM248
7192                      (match_operand:SWIM248 1 "register_operand" "")
7193                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7194               (set (match_operand:SWIM248 3 "register_operand" "")
7195                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7196               (clobber (reg:CC FLAGS_REG))])])
7197
7198 ;; Split with 8bit unsigned divide:
7199 ;;      if (dividend an divisor are in [0-255])
7200 ;;         use 8bit unsigned integer divide
7201 ;;       else
7202 ;;         use original integer divide
7203 (define_split
7204   [(set (match_operand:SWI48 0 "register_operand" "")
7205         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7206                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7207    (set (match_operand:SWI48 1 "register_operand" "")
7208         (umod:SWI48 (match_dup 2) (match_dup 3)))
7209    (clobber (reg:CC FLAGS_REG))]
7210   "TARGET_USE_8BIT_IDIV
7211    && TARGET_QIMODE_MATH
7212    && can_create_pseudo_p ()
7213    && !optimize_insn_for_size_p ()"
7214   [(const_int 0)]
7215   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7216
7217 (define_insn_and_split "udivmod<mode>4_1"
7218   [(set (match_operand:SWI48 0 "register_operand" "=a")
7219         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7220                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7221    (set (match_operand:SWI48 1 "register_operand" "=&d")
7222         (umod:SWI48 (match_dup 2) (match_dup 3)))
7223    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7224    (clobber (reg:CC FLAGS_REG))]
7225   ""
7226   "#"
7227   "reload_completed"
7228   [(set (match_dup 1) (const_int 0))
7229    (parallel [(set (match_dup 0)
7230                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7231               (set (match_dup 1)
7232                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7233               (use (match_dup 1))
7234               (clobber (reg:CC FLAGS_REG))])]
7235   ""
7236   [(set_attr "type" "multi")
7237    (set_attr "mode" "<MODE>")])
7238
7239 (define_insn_and_split "*udivmod<mode>4"
7240   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7241         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7242                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7243    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7244         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7245    (clobber (reg:CC FLAGS_REG))]
7246   ""
7247   "#"
7248   "reload_completed"
7249   [(set (match_dup 1) (const_int 0))
7250    (parallel [(set (match_dup 0)
7251                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7252               (set (match_dup 1)
7253                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7254               (use (match_dup 1))
7255               (clobber (reg:CC FLAGS_REG))])]
7256   ""
7257   [(set_attr "type" "multi")
7258    (set_attr "mode" "<MODE>")])
7259
7260 (define_insn "*udivmod<mode>4_noext"
7261   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7262         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7263                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7264    (set (match_operand:SWIM248 1 "register_operand" "=d")
7265         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7266    (use (match_operand:SWIM248 4 "register_operand" "1"))
7267    (clobber (reg:CC FLAGS_REG))]
7268   ""
7269   "div{<imodesuffix>}\t%3"
7270   [(set_attr "type" "idiv")
7271    (set_attr "mode" "<MODE>")])
7272
7273 (define_expand "udivmodqi4"
7274   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7275                    (udiv:QI
7276                      (match_operand:QI 1 "register_operand" "")
7277                      (match_operand:QI 2 "nonimmediate_operand" "")))
7278               (set (match_operand:QI 3 "register_operand" "")
7279                    (umod:QI (match_dup 1) (match_dup 2)))
7280               (clobber (reg:CC FLAGS_REG))])]
7281   "TARGET_QIMODE_MATH"
7282 {
7283   rtx div, mod, insn;
7284   rtx tmp0, tmp1;
7285   
7286   tmp0 = gen_reg_rtx (HImode);
7287   tmp1 = gen_reg_rtx (HImode);
7288
7289   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7290      in AX.  */
7291   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7292   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7293
7294   /* Extract remainder from AH.  */
7295   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7296   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7297   insn = emit_move_insn (operands[3], tmp1);
7298
7299   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7300   set_unique_reg_note (insn, REG_EQUAL, mod);
7301
7302   /* Extract quotient from AL.  */
7303   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7304
7305   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7306   set_unique_reg_note (insn, REG_EQUAL, div);
7307
7308   DONE;
7309 })
7310
7311 (define_insn "udivmodhiqi3"
7312   [(set (match_operand:HI 0 "register_operand" "=a")
7313         (ior:HI
7314           (ashift:HI
7315             (zero_extend:HI
7316               (truncate:QI
7317                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7318                         (zero_extend:HI
7319                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7320             (const_int 8))
7321           (zero_extend:HI
7322             (truncate:QI
7323               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7324    (clobber (reg:CC FLAGS_REG))]
7325   "TARGET_QIMODE_MATH"
7326   "div{b}\t%2"
7327   [(set_attr "type" "idiv")
7328    (set_attr "mode" "QI")])
7329
7330 ;; We cannot use div/idiv for double division, because it causes
7331 ;; "division by zero" on the overflow and that's not what we expect
7332 ;; from truncate.  Because true (non truncating) double division is
7333 ;; never generated, we can't create this insn anyway.
7334 ;
7335 ;(define_insn ""
7336 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7337 ;       (truncate:SI
7338 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7339 ;                  (zero_extend:DI
7340 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7341 ;   (set (match_operand:SI 3 "register_operand" "=d")
7342 ;       (truncate:SI
7343 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7344 ;   (clobber (reg:CC FLAGS_REG))]
7345 ;  ""
7346 ;  "div{l}\t{%2, %0|%0, %2}"
7347 ;  [(set_attr "type" "idiv")])
7348 \f
7349 ;;- Logical AND instructions
7350
7351 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7352 ;; Note that this excludes ah.
7353
7354 (define_expand "testsi_ccno_1"
7355   [(set (reg:CCNO FLAGS_REG)
7356         (compare:CCNO
7357           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7358                   (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7359           (const_int 0)))])
7360
7361 (define_expand "testqi_ccz_1"
7362   [(set (reg:CCZ FLAGS_REG)
7363         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7364                              (match_operand:QI 1 "nonmemory_operand" ""))
7365                  (const_int 0)))])
7366
7367 (define_expand "testdi_ccno_1"
7368   [(set (reg:CCNO FLAGS_REG)
7369         (compare:CCNO
7370           (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7371                   (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7372           (const_int 0)))]
7373   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7374
7375 (define_insn "*testdi_1"
7376   [(set (reg FLAGS_REG)
7377         (compare
7378          (and:DI
7379           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7380           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7381          (const_int 0)))]
7382   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7383    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7384   "@
7385    test{l}\t{%k1, %k0|%k0, %k1}
7386    test{l}\t{%k1, %k0|%k0, %k1}
7387    test{q}\t{%1, %0|%0, %1}
7388    test{q}\t{%1, %0|%0, %1}
7389    test{q}\t{%1, %0|%0, %1}"
7390   [(set_attr "type" "test")
7391    (set_attr "modrm" "0,1,0,1,1")
7392    (set_attr "mode" "SI,SI,DI,DI,DI")])
7393
7394 (define_insn "*testqi_1_maybe_si"
7395   [(set (reg FLAGS_REG)
7396         (compare
7397           (and:QI
7398             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7399             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7400           (const_int 0)))]
7401    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7402     && ix86_match_ccmode (insn,
7403                          CONST_INT_P (operands[1])
7404                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7405 {
7406   if (which_alternative == 3)
7407     {
7408       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7409         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7410       return "test{l}\t{%1, %k0|%k0, %1}";
7411     }
7412   return "test{b}\t{%1, %0|%0, %1}";
7413 }
7414   [(set_attr "type" "test")
7415    (set_attr "modrm" "0,1,1,1")
7416    (set_attr "mode" "QI,QI,QI,SI")
7417    (set_attr "pent_pair" "uv,np,uv,np")])
7418
7419 (define_insn "*test<mode>_1"
7420   [(set (reg FLAGS_REG)
7421         (compare
7422          (and:SWI124
7423           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7424           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7425          (const_int 0)))]
7426   "ix86_match_ccmode (insn, CCNOmode)
7427    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7428   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7429   [(set_attr "type" "test")
7430    (set_attr "modrm" "0,1,1")
7431    (set_attr "mode" "<MODE>")
7432    (set_attr "pent_pair" "uv,np,uv")])
7433
7434 (define_expand "testqi_ext_ccno_0"
7435   [(set (reg:CCNO FLAGS_REG)
7436         (compare:CCNO
7437           (and:SI
7438             (zero_extract:SI
7439               (match_operand 0 "ext_register_operand" "")
7440               (const_int 8)
7441               (const_int 8))
7442             (match_operand 1 "const_int_operand" ""))
7443           (const_int 0)))])
7444
7445 (define_insn "*testqi_ext_0"
7446   [(set (reg FLAGS_REG)
7447         (compare
7448           (and:SI
7449             (zero_extract:SI
7450               (match_operand 0 "ext_register_operand" "Q")
7451               (const_int 8)
7452               (const_int 8))
7453             (match_operand 1 "const_int_operand" "n"))
7454           (const_int 0)))]
7455   "ix86_match_ccmode (insn, CCNOmode)"
7456   "test{b}\t{%1, %h0|%h0, %1}"
7457   [(set_attr "type" "test")
7458    (set_attr "mode" "QI")
7459    (set_attr "length_immediate" "1")
7460    (set_attr "modrm" "1")
7461    (set_attr "pent_pair" "np")])
7462
7463 (define_insn "*testqi_ext_1_rex64"
7464   [(set (reg FLAGS_REG)
7465         (compare
7466           (and:SI
7467             (zero_extract:SI
7468               (match_operand 0 "ext_register_operand" "Q")
7469               (const_int 8)
7470               (const_int 8))
7471             (zero_extend:SI
7472               (match_operand:QI 1 "register_operand" "Q")))
7473           (const_int 0)))]
7474   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7475   "test{b}\t{%1, %h0|%h0, %1}"
7476   [(set_attr "type" "test")
7477    (set_attr "mode" "QI")])
7478
7479 (define_insn "*testqi_ext_1"
7480   [(set (reg FLAGS_REG)
7481         (compare
7482           (and:SI
7483             (zero_extract:SI
7484               (match_operand 0 "ext_register_operand" "Q")
7485               (const_int 8)
7486               (const_int 8))
7487             (zero_extend:SI
7488               (match_operand:QI 1 "general_operand" "Qm")))
7489           (const_int 0)))]
7490   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7491   "test{b}\t{%1, %h0|%h0, %1}"
7492   [(set_attr "type" "test")
7493    (set_attr "mode" "QI")])
7494
7495 (define_insn "*testqi_ext_2"
7496   [(set (reg FLAGS_REG)
7497         (compare
7498           (and:SI
7499             (zero_extract:SI
7500               (match_operand 0 "ext_register_operand" "Q")
7501               (const_int 8)
7502               (const_int 8))
7503             (zero_extract:SI
7504               (match_operand 1 "ext_register_operand" "Q")
7505               (const_int 8)
7506               (const_int 8)))
7507           (const_int 0)))]
7508   "ix86_match_ccmode (insn, CCNOmode)"
7509   "test{b}\t{%h1, %h0|%h0, %h1}"
7510   [(set_attr "type" "test")
7511    (set_attr "mode" "QI")])
7512
7513 (define_insn "*testqi_ext_3_rex64"
7514   [(set (reg FLAGS_REG)
7515         (compare (zero_extract:DI
7516                    (match_operand 0 "nonimmediate_operand" "rm")
7517                    (match_operand:DI 1 "const_int_operand" "")
7518                    (match_operand:DI 2 "const_int_operand" ""))
7519                  (const_int 0)))]
7520   "TARGET_64BIT
7521    && ix86_match_ccmode (insn, CCNOmode)
7522    && INTVAL (operands[1]) > 0
7523    && INTVAL (operands[2]) >= 0
7524    /* Ensure that resulting mask is zero or sign extended operand.  */
7525    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7526        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7527            && INTVAL (operands[1]) > 32))
7528    && (GET_MODE (operands[0]) == SImode
7529        || GET_MODE (operands[0]) == DImode
7530        || GET_MODE (operands[0]) == HImode
7531        || GET_MODE (operands[0]) == QImode)"
7532   "#")
7533
7534 ;; Combine likes to form bit extractions for some tests.  Humor it.
7535 (define_insn "*testqi_ext_3"
7536   [(set (reg FLAGS_REG)
7537         (compare (zero_extract:SI
7538                    (match_operand 0 "nonimmediate_operand" "rm")
7539                    (match_operand:SI 1 "const_int_operand" "")
7540                    (match_operand:SI 2 "const_int_operand" ""))
7541                  (const_int 0)))]
7542   "ix86_match_ccmode (insn, CCNOmode)
7543    && INTVAL (operands[1]) > 0
7544    && INTVAL (operands[2]) >= 0
7545    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7546    && (GET_MODE (operands[0]) == SImode
7547        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7548        || GET_MODE (operands[0]) == HImode
7549        || GET_MODE (operands[0]) == QImode)"
7550   "#")
7551
7552 (define_split
7553   [(set (match_operand 0 "flags_reg_operand" "")
7554         (match_operator 1 "compare_operator"
7555           [(zero_extract
7556              (match_operand 2 "nonimmediate_operand" "")
7557              (match_operand 3 "const_int_operand" "")
7558              (match_operand 4 "const_int_operand" ""))
7559            (const_int 0)]))]
7560   "ix86_match_ccmode (insn, CCNOmode)"
7561   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7562 {
7563   rtx val = operands[2];
7564   HOST_WIDE_INT len = INTVAL (operands[3]);
7565   HOST_WIDE_INT pos = INTVAL (operands[4]);
7566   HOST_WIDE_INT mask;
7567   enum machine_mode mode, submode;
7568
7569   mode = GET_MODE (val);
7570   if (MEM_P (val))
7571     {
7572       /* ??? Combine likes to put non-volatile mem extractions in QImode
7573          no matter the size of the test.  So find a mode that works.  */
7574       if (! MEM_VOLATILE_P (val))
7575         {
7576           mode = smallest_mode_for_size (pos + len, MODE_INT);
7577           val = adjust_address (val, mode, 0);
7578         }
7579     }
7580   else if (GET_CODE (val) == SUBREG
7581            && (submode = GET_MODE (SUBREG_REG (val)),
7582                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7583            && pos + len <= GET_MODE_BITSIZE (submode)
7584            && GET_MODE_CLASS (submode) == MODE_INT)
7585     {
7586       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7587       mode = submode;
7588       val = SUBREG_REG (val);
7589     }
7590   else if (mode == HImode && pos + len <= 8)
7591     {
7592       /* Small HImode tests can be converted to QImode.  */
7593       mode = QImode;
7594       val = gen_lowpart (QImode, val);
7595     }
7596
7597   if (len == HOST_BITS_PER_WIDE_INT)
7598     mask = -1;
7599   else
7600     mask = ((HOST_WIDE_INT)1 << len) - 1;
7601   mask <<= pos;
7602
7603   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7604 })
7605
7606 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7607 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7608 ;; this is relatively important trick.
7609 ;; Do the conversion only post-reload to avoid limiting of the register class
7610 ;; to QI regs.
7611 (define_split
7612   [(set (match_operand 0 "flags_reg_operand" "")
7613         (match_operator 1 "compare_operator"
7614           [(and (match_operand 2 "register_operand" "")
7615                 (match_operand 3 "const_int_operand" ""))
7616            (const_int 0)]))]
7617    "reload_completed
7618     && QI_REG_P (operands[2])
7619     && GET_MODE (operands[2]) != QImode
7620     && ((ix86_match_ccmode (insn, CCZmode)
7621          && !(INTVAL (operands[3]) & ~(255 << 8)))
7622         || (ix86_match_ccmode (insn, CCNOmode)
7623             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7624   [(set (match_dup 0)
7625         (match_op_dup 1
7626           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7627                    (match_dup 3))
7628            (const_int 0)]))]
7629 {
7630   operands[2] = gen_lowpart (SImode, operands[2]);
7631   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7632 })
7633
7634 (define_split
7635   [(set (match_operand 0 "flags_reg_operand" "")
7636         (match_operator 1 "compare_operator"
7637           [(and (match_operand 2 "nonimmediate_operand" "")
7638                 (match_operand 3 "const_int_operand" ""))
7639            (const_int 0)]))]
7640    "reload_completed
7641     && GET_MODE (operands[2]) != QImode
7642     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7643     && ((ix86_match_ccmode (insn, CCZmode)
7644          && !(INTVAL (operands[3]) & ~255))
7645         || (ix86_match_ccmode (insn, CCNOmode)
7646             && !(INTVAL (operands[3]) & ~127)))"
7647   [(set (match_dup 0)
7648         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7649                          (const_int 0)]))]
7650 {
7651   operands[2] = gen_lowpart (QImode, operands[2]);
7652   operands[3] = gen_lowpart (QImode, operands[3]);
7653 })
7654
7655 ;; %%% This used to optimize known byte-wide and operations to memory,
7656 ;; and sometimes to QImode registers.  If this is considered useful,
7657 ;; it should be done with splitters.
7658
7659 (define_expand "and<mode>3"
7660   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7661         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7662                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7663   ""
7664   "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7665
7666 (define_insn "*anddi_1"
7667   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7668         (and:DI
7669          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7670          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7671    (clobber (reg:CC FLAGS_REG))]
7672   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7673 {
7674   switch (get_attr_type (insn))
7675     {
7676     case TYPE_IMOVX:
7677       {
7678         enum machine_mode mode;
7679
7680         gcc_assert (CONST_INT_P (operands[2]));
7681         if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff)
7682           mode = SImode;
7683         else if (INTVAL (operands[2]) == 0xffff)
7684           mode = HImode;
7685         else
7686           {
7687             gcc_assert (INTVAL (operands[2]) == 0xff);
7688             mode = QImode;
7689           }
7690
7691         operands[1] = gen_lowpart (mode, operands[1]);
7692         if (mode == SImode)
7693           return "mov{l}\t{%1, %k0|%k0, %1}";
7694         else if (mode == HImode)
7695           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7696         else
7697           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7698       }
7699
7700     default:
7701       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7702       if (get_attr_mode (insn) == MODE_SI)
7703         return "and{l}\t{%k2, %k0|%k0, %k2}";
7704       else
7705         return "and{q}\t{%2, %0|%0, %2}";
7706     }
7707 }
7708   [(set_attr "type" "alu,alu,alu,imovx")
7709    (set_attr "length_immediate" "*,*,*,0")
7710    (set (attr "prefix_rex")
7711      (if_then_else
7712        (and (eq_attr "type" "imovx")
7713             (and (match_test "INTVAL (operands[2]) == 0xff")
7714                  (match_operand 1 "ext_QIreg_operand" "")))
7715        (const_string "1")
7716        (const_string "*")))
7717    (set_attr "mode" "SI,DI,DI,SI")])
7718
7719 (define_insn "*andsi_1"
7720   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7721         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7722                 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7723    (clobber (reg:CC FLAGS_REG))]
7724   "ix86_binary_operator_ok (AND, SImode, operands)"
7725 {
7726   switch (get_attr_type (insn))
7727     {
7728     case TYPE_IMOVX:
7729       {
7730         enum machine_mode mode;
7731
7732         gcc_assert (CONST_INT_P (operands[2]));
7733         if (INTVAL (operands[2]) == 0xffff)
7734           mode = HImode;
7735         else
7736           {
7737             gcc_assert (INTVAL (operands[2]) == 0xff);
7738             mode = QImode;
7739           }
7740
7741         operands[1] = gen_lowpart (mode, operands[1]);
7742         if (mode == HImode)
7743           return "movz{wl|x}\t{%1, %0|%0, %1}";
7744         else
7745           return "movz{bl|x}\t{%1, %0|%0, %1}";
7746       }
7747
7748     default:
7749       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7750       return "and{l}\t{%2, %0|%0, %2}";
7751     }
7752 }
7753   [(set_attr "type" "alu,alu,imovx")
7754    (set (attr "prefix_rex")
7755      (if_then_else
7756        (and (eq_attr "type" "imovx")
7757             (and (match_test "INTVAL (operands[2]) == 0xff")
7758                  (match_operand 1 "ext_QIreg_operand" "")))
7759        (const_string "1")
7760        (const_string "*")))
7761    (set_attr "length_immediate" "*,*,0")
7762    (set_attr "mode" "SI")])
7763
7764 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7765 (define_insn "*andsi_1_zext"
7766   [(set (match_operand:DI 0 "register_operand" "=r")
7767         (zero_extend:DI
7768           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7769                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7770    (clobber (reg:CC FLAGS_REG))]
7771   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7772   "and{l}\t{%2, %k0|%k0, %2}"
7773   [(set_attr "type" "alu")
7774    (set_attr "mode" "SI")])
7775
7776 (define_insn "*andhi_1"
7777   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7778         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7779                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7780    (clobber (reg:CC FLAGS_REG))]
7781   "ix86_binary_operator_ok (AND, HImode, operands)"
7782 {
7783   switch (get_attr_type (insn))
7784     {
7785     case TYPE_IMOVX:
7786       gcc_assert (CONST_INT_P (operands[2]));
7787       gcc_assert (INTVAL (operands[2]) == 0xff);
7788       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7789
7790     default:
7791       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7792
7793       return "and{w}\t{%2, %0|%0, %2}";
7794     }
7795 }
7796   [(set_attr "type" "alu,alu,imovx")
7797    (set_attr "length_immediate" "*,*,0")
7798    (set (attr "prefix_rex")
7799      (if_then_else
7800        (and (eq_attr "type" "imovx")
7801             (match_operand 1 "ext_QIreg_operand" ""))
7802        (const_string "1")
7803        (const_string "*")))
7804    (set_attr "mode" "HI,HI,SI")])
7805
7806 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7807 (define_insn "*andqi_1"
7808   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7809         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7810                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7811    (clobber (reg:CC FLAGS_REG))]
7812   "ix86_binary_operator_ok (AND, QImode, operands)"
7813   "@
7814    and{b}\t{%2, %0|%0, %2}
7815    and{b}\t{%2, %0|%0, %2}
7816    and{l}\t{%k2, %k0|%k0, %k2}"
7817   [(set_attr "type" "alu")
7818    (set_attr "mode" "QI,QI,SI")])
7819
7820 (define_insn "*andqi_1_slp"
7821   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7822         (and:QI (match_dup 0)
7823                 (match_operand:QI 1 "general_operand" "qn,qmn")))
7824    (clobber (reg:CC FLAGS_REG))]
7825   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7826    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7827   "and{b}\t{%1, %0|%0, %1}"
7828   [(set_attr "type" "alu1")
7829    (set_attr "mode" "QI")])
7830
7831 (define_split
7832   [(set (match_operand 0 "register_operand" "")
7833         (and (match_dup 0)
7834              (const_int -65536)))
7835    (clobber (reg:CC FLAGS_REG))]
7836   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7837     || optimize_function_for_size_p (cfun)"
7838   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7839   "operands[1] = gen_lowpart (HImode, operands[0]);")
7840
7841 (define_split
7842   [(set (match_operand 0 "ext_register_operand" "")
7843         (and (match_dup 0)
7844              (const_int -256)))
7845    (clobber (reg:CC FLAGS_REG))]
7846   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7847    && reload_completed"
7848   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7849   "operands[1] = gen_lowpart (QImode, operands[0]);")
7850
7851 (define_split
7852   [(set (match_operand 0 "ext_register_operand" "")
7853         (and (match_dup 0)
7854              (const_int -65281)))
7855    (clobber (reg:CC FLAGS_REG))]
7856   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7857    && reload_completed"
7858   [(parallel [(set (zero_extract:SI (match_dup 0)
7859                                     (const_int 8)
7860                                     (const_int 8))
7861                    (xor:SI
7862                      (zero_extract:SI (match_dup 0)
7863                                       (const_int 8)
7864                                       (const_int 8))
7865                      (zero_extract:SI (match_dup 0)
7866                                       (const_int 8)
7867                                       (const_int 8))))
7868               (clobber (reg:CC FLAGS_REG))])]
7869   "operands[0] = gen_lowpart (SImode, operands[0]);")
7870
7871 (define_insn "*anddi_2"
7872   [(set (reg FLAGS_REG)
7873         (compare
7874          (and:DI
7875           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7876           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7877          (const_int 0)))
7878    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7879         (and:DI (match_dup 1) (match_dup 2)))]
7880   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7881    && ix86_binary_operator_ok (AND, DImode, operands)"
7882   "@
7883    and{l}\t{%k2, %k0|%k0, %k2}
7884    and{q}\t{%2, %0|%0, %2}
7885    and{q}\t{%2, %0|%0, %2}"
7886   [(set_attr "type" "alu")
7887    (set_attr "mode" "SI,DI,DI")])
7888
7889 (define_insn "*andqi_2_maybe_si"
7890   [(set (reg FLAGS_REG)
7891         (compare (and:QI
7892                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7893                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7894                  (const_int 0)))
7895    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7896         (and:QI (match_dup 1) (match_dup 2)))]
7897   "ix86_binary_operator_ok (AND, QImode, operands)
7898    && ix86_match_ccmode (insn,
7899                          CONST_INT_P (operands[2])
7900                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7901 {
7902   if (which_alternative == 2)
7903     {
7904       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7905         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7906       return "and{l}\t{%2, %k0|%k0, %2}";
7907     }
7908   return "and{b}\t{%2, %0|%0, %2}";
7909 }
7910   [(set_attr "type" "alu")
7911    (set_attr "mode" "QI,QI,SI")])
7912
7913 (define_insn "*and<mode>_2"
7914   [(set (reg FLAGS_REG)
7915         (compare (and:SWI124
7916                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7917                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7918                  (const_int 0)))
7919    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7920         (and:SWI124 (match_dup 1) (match_dup 2)))]
7921   "ix86_match_ccmode (insn, CCNOmode)
7922    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7923   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7924   [(set_attr "type" "alu")
7925    (set_attr "mode" "<MODE>")])
7926
7927 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7928 (define_insn "*andsi_2_zext"
7929   [(set (reg FLAGS_REG)
7930         (compare (and:SI
7931                   (match_operand:SI 1 "nonimmediate_operand" "%0")
7932                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
7933                  (const_int 0)))
7934    (set (match_operand:DI 0 "register_operand" "=r")
7935         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7936   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7937    && ix86_binary_operator_ok (AND, SImode, operands)"
7938   "and{l}\t{%2, %k0|%k0, %2}"
7939   [(set_attr "type" "alu")
7940    (set_attr "mode" "SI")])
7941
7942 (define_insn "*andqi_2_slp"
7943   [(set (reg FLAGS_REG)
7944         (compare (and:QI
7945                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7946                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7947                  (const_int 0)))
7948    (set (strict_low_part (match_dup 0))
7949         (and:QI (match_dup 0) (match_dup 1)))]
7950   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7951    && ix86_match_ccmode (insn, CCNOmode)
7952    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7953   "and{b}\t{%1, %0|%0, %1}"
7954   [(set_attr "type" "alu1")
7955    (set_attr "mode" "QI")])
7956
7957 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7958 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
7959 ;; for a QImode operand, which of course failed.
7960 (define_insn "andqi_ext_0"
7961   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7962                          (const_int 8)
7963                          (const_int 8))
7964         (and:SI
7965           (zero_extract:SI
7966             (match_operand 1 "ext_register_operand" "0")
7967             (const_int 8)
7968             (const_int 8))
7969           (match_operand 2 "const_int_operand" "n")))
7970    (clobber (reg:CC FLAGS_REG))]
7971   ""
7972   "and{b}\t{%2, %h0|%h0, %2}"
7973   [(set_attr "type" "alu")
7974    (set_attr "length_immediate" "1")
7975    (set_attr "modrm" "1")
7976    (set_attr "mode" "QI")])
7977
7978 ;; Generated by peephole translating test to and.  This shows up
7979 ;; often in fp comparisons.
7980 (define_insn "*andqi_ext_0_cc"
7981   [(set (reg FLAGS_REG)
7982         (compare
7983           (and:SI
7984             (zero_extract:SI
7985               (match_operand 1 "ext_register_operand" "0")
7986               (const_int 8)
7987               (const_int 8))
7988             (match_operand 2 "const_int_operand" "n"))
7989           (const_int 0)))
7990    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7991                          (const_int 8)
7992                          (const_int 8))
7993         (and:SI
7994           (zero_extract:SI
7995             (match_dup 1)
7996             (const_int 8)
7997             (const_int 8))
7998           (match_dup 2)))]
7999   "ix86_match_ccmode (insn, CCNOmode)"
8000   "and{b}\t{%2, %h0|%h0, %2}"
8001   [(set_attr "type" "alu")
8002    (set_attr "length_immediate" "1")
8003    (set_attr "modrm" "1")
8004    (set_attr "mode" "QI")])
8005
8006 (define_insn "*andqi_ext_1_rex64"
8007   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8008                          (const_int 8)
8009                          (const_int 8))
8010         (and:SI
8011           (zero_extract:SI
8012             (match_operand 1 "ext_register_operand" "0")
8013             (const_int 8)
8014             (const_int 8))
8015           (zero_extend:SI
8016             (match_operand 2 "ext_register_operand" "Q"))))
8017    (clobber (reg:CC FLAGS_REG))]
8018   "TARGET_64BIT"
8019   "and{b}\t{%2, %h0|%h0, %2}"
8020   [(set_attr "type" "alu")
8021    (set_attr "length_immediate" "0")
8022    (set_attr "mode" "QI")])
8023
8024 (define_insn "*andqi_ext_1"
8025   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8026                          (const_int 8)
8027                          (const_int 8))
8028         (and:SI
8029           (zero_extract:SI
8030             (match_operand 1 "ext_register_operand" "0")
8031             (const_int 8)
8032             (const_int 8))
8033           (zero_extend:SI
8034             (match_operand:QI 2 "general_operand" "Qm"))))
8035    (clobber (reg:CC FLAGS_REG))]
8036   "!TARGET_64BIT"
8037   "and{b}\t{%2, %h0|%h0, %2}"
8038   [(set_attr "type" "alu")
8039    (set_attr "length_immediate" "0")
8040    (set_attr "mode" "QI")])
8041
8042 (define_insn "*andqi_ext_2"
8043   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8044                          (const_int 8)
8045                          (const_int 8))
8046         (and:SI
8047           (zero_extract:SI
8048             (match_operand 1 "ext_register_operand" "%0")
8049             (const_int 8)
8050             (const_int 8))
8051           (zero_extract:SI
8052             (match_operand 2 "ext_register_operand" "Q")
8053             (const_int 8)
8054             (const_int 8))))
8055    (clobber (reg:CC FLAGS_REG))]
8056   ""
8057   "and{b}\t{%h2, %h0|%h0, %h2}"
8058   [(set_attr "type" "alu")
8059    (set_attr "length_immediate" "0")
8060    (set_attr "mode" "QI")])
8061
8062 ;; Convert wide AND instructions with immediate operand to shorter QImode
8063 ;; equivalents when possible.
8064 ;; Don't do the splitting with memory operands, since it introduces risk
8065 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8066 ;; for size, but that can (should?) be handled by generic code instead.
8067 (define_split
8068   [(set (match_operand 0 "register_operand" "")
8069         (and (match_operand 1 "register_operand" "")
8070              (match_operand 2 "const_int_operand" "")))
8071    (clobber (reg:CC FLAGS_REG))]
8072    "reload_completed
8073     && QI_REG_P (operands[0])
8074     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8075     && !(~INTVAL (operands[2]) & ~(255 << 8))
8076     && GET_MODE (operands[0]) != QImode"
8077   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8078                    (and:SI (zero_extract:SI (match_dup 1)
8079                                             (const_int 8) (const_int 8))
8080                            (match_dup 2)))
8081               (clobber (reg:CC FLAGS_REG))])]
8082 {
8083   operands[0] = gen_lowpart (SImode, operands[0]);
8084   operands[1] = gen_lowpart (SImode, operands[1]);
8085   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8086 })
8087
8088 ;; Since AND can be encoded with sign extended immediate, this is only
8089 ;; profitable when 7th bit is not set.
8090 (define_split
8091   [(set (match_operand 0 "register_operand" "")
8092         (and (match_operand 1 "general_operand" "")
8093              (match_operand 2 "const_int_operand" "")))
8094    (clobber (reg:CC FLAGS_REG))]
8095    "reload_completed
8096     && ANY_QI_REG_P (operands[0])
8097     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8098     && !(~INTVAL (operands[2]) & ~255)
8099     && !(INTVAL (operands[2]) & 128)
8100     && GET_MODE (operands[0]) != QImode"
8101   [(parallel [(set (strict_low_part (match_dup 0))
8102                    (and:QI (match_dup 1)
8103                            (match_dup 2)))
8104               (clobber (reg:CC FLAGS_REG))])]
8105 {
8106   operands[0] = gen_lowpart (QImode, operands[0]);
8107   operands[1] = gen_lowpart (QImode, operands[1]);
8108   operands[2] = gen_lowpart (QImode, operands[2]);
8109 })
8110 \f
8111 ;; Logical inclusive and exclusive OR instructions
8112
8113 ;; %%% This used to optimize known byte-wide and operations to memory.
8114 ;; If this is considered useful, it should be done with splitters.
8115
8116 (define_expand "<code><mode>3"
8117   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8118         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8119                      (match_operand:SWIM 2 "<general_operand>" "")))]
8120   ""
8121   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8122
8123 (define_insn "*<code><mode>_1"
8124   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8125         (any_or:SWI248
8126          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8127          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8128    (clobber (reg:CC FLAGS_REG))]
8129   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8130   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8131   [(set_attr "type" "alu")
8132    (set_attr "mode" "<MODE>")])
8133
8134 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8135 (define_insn "*<code>qi_1"
8136   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8137         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8138                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8139    (clobber (reg:CC FLAGS_REG))]
8140   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8141   "@
8142    <logic>{b}\t{%2, %0|%0, %2}
8143    <logic>{b}\t{%2, %0|%0, %2}
8144    <logic>{l}\t{%k2, %k0|%k0, %k2}"
8145   [(set_attr "type" "alu")
8146    (set_attr "mode" "QI,QI,SI")])
8147
8148 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8149 (define_insn "*<code>si_1_zext"
8150   [(set (match_operand:DI 0 "register_operand" "=r")
8151         (zero_extend:DI
8152          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8153                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8154    (clobber (reg:CC FLAGS_REG))]
8155   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8156   "<logic>{l}\t{%2, %k0|%k0, %2}"
8157   [(set_attr "type" "alu")
8158    (set_attr "mode" "SI")])
8159
8160 (define_insn "*<code>si_1_zext_imm"
8161   [(set (match_operand:DI 0 "register_operand" "=r")
8162         (any_or:DI
8163          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8164          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8165    (clobber (reg:CC FLAGS_REG))]
8166   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8167   "<logic>{l}\t{%2, %k0|%k0, %2}"
8168   [(set_attr "type" "alu")
8169    (set_attr "mode" "SI")])
8170
8171 (define_insn "*<code>qi_1_slp"
8172   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8173         (any_or:QI (match_dup 0)
8174                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8175    (clobber (reg:CC FLAGS_REG))]
8176   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8177    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8178   "<logic>{b}\t{%1, %0|%0, %1}"
8179   [(set_attr "type" "alu1")
8180    (set_attr "mode" "QI")])
8181
8182 (define_insn "*<code><mode>_2"
8183   [(set (reg FLAGS_REG)
8184         (compare (any_or:SWI
8185                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8186                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8187                  (const_int 0)))
8188    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8189         (any_or:SWI (match_dup 1) (match_dup 2)))]
8190   "ix86_match_ccmode (insn, CCNOmode)
8191    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8192   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8193   [(set_attr "type" "alu")
8194    (set_attr "mode" "<MODE>")])
8195
8196 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8197 ;; ??? Special case for immediate operand is missing - it is tricky.
8198 (define_insn "*<code>si_2_zext"
8199   [(set (reg FLAGS_REG)
8200         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8201                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
8202                  (const_int 0)))
8203    (set (match_operand:DI 0 "register_operand" "=r")
8204         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8205   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8206    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8207   "<logic>{l}\t{%2, %k0|%k0, %2}"
8208   [(set_attr "type" "alu")
8209    (set_attr "mode" "SI")])
8210
8211 (define_insn "*<code>si_2_zext_imm"
8212   [(set (reg FLAGS_REG)
8213         (compare (any_or:SI
8214                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8215                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8216                  (const_int 0)))
8217    (set (match_operand:DI 0 "register_operand" "=r")
8218         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8219   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8220    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8221   "<logic>{l}\t{%2, %k0|%k0, %2}"
8222   [(set_attr "type" "alu")
8223    (set_attr "mode" "SI")])
8224
8225 (define_insn "*<code>qi_2_slp"
8226   [(set (reg FLAGS_REG)
8227         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8228                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8229                  (const_int 0)))
8230    (set (strict_low_part (match_dup 0))
8231         (any_or:QI (match_dup 0) (match_dup 1)))]
8232   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8233    && ix86_match_ccmode (insn, CCNOmode)
8234    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8235   "<logic>{b}\t{%1, %0|%0, %1}"
8236   [(set_attr "type" "alu1")
8237    (set_attr "mode" "QI")])
8238
8239 (define_insn "*<code><mode>_3"
8240   [(set (reg FLAGS_REG)
8241         (compare (any_or:SWI
8242                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8243                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8244                  (const_int 0)))
8245    (clobber (match_scratch:SWI 0 "=<r>"))]
8246   "ix86_match_ccmode (insn, CCNOmode)
8247    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8248   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8249   [(set_attr "type" "alu")
8250    (set_attr "mode" "<MODE>")])
8251
8252 (define_insn "*<code>qi_ext_0"
8253   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8254                          (const_int 8)
8255                          (const_int 8))
8256         (any_or:SI
8257           (zero_extract:SI
8258             (match_operand 1 "ext_register_operand" "0")
8259             (const_int 8)
8260             (const_int 8))
8261           (match_operand 2 "const_int_operand" "n")))
8262    (clobber (reg:CC FLAGS_REG))]
8263   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8264   "<logic>{b}\t{%2, %h0|%h0, %2}"
8265   [(set_attr "type" "alu")
8266    (set_attr "length_immediate" "1")
8267    (set_attr "modrm" "1")
8268    (set_attr "mode" "QI")])
8269
8270 (define_insn "*<code>qi_ext_1_rex64"
8271   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8272                          (const_int 8)
8273                          (const_int 8))
8274         (any_or:SI
8275           (zero_extract:SI
8276             (match_operand 1 "ext_register_operand" "0")
8277             (const_int 8)
8278             (const_int 8))
8279           (zero_extend:SI
8280             (match_operand 2 "ext_register_operand" "Q"))))
8281    (clobber (reg:CC FLAGS_REG))]
8282   "TARGET_64BIT
8283    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8284   "<logic>{b}\t{%2, %h0|%h0, %2}"
8285   [(set_attr "type" "alu")
8286    (set_attr "length_immediate" "0")
8287    (set_attr "mode" "QI")])
8288
8289 (define_insn "*<code>qi_ext_1"
8290   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8291                          (const_int 8)
8292                          (const_int 8))
8293         (any_or:SI
8294           (zero_extract:SI
8295             (match_operand 1 "ext_register_operand" "0")
8296             (const_int 8)
8297             (const_int 8))
8298           (zero_extend:SI
8299             (match_operand:QI 2 "general_operand" "Qm"))))
8300    (clobber (reg:CC FLAGS_REG))]
8301   "!TARGET_64BIT
8302    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8303   "<logic>{b}\t{%2, %h0|%h0, %2}"
8304   [(set_attr "type" "alu")
8305    (set_attr "length_immediate" "0")
8306    (set_attr "mode" "QI")])
8307
8308 (define_insn "*<code>qi_ext_2"
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 (match_operand 1 "ext_register_operand" "0")
8314                            (const_int 8)
8315                            (const_int 8))
8316           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8317                            (const_int 8)
8318                            (const_int 8))))
8319    (clobber (reg:CC FLAGS_REG))]
8320   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8321   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8322   [(set_attr "type" "alu")
8323    (set_attr "length_immediate" "0")
8324    (set_attr "mode" "QI")])
8325
8326 (define_split
8327   [(set (match_operand 0 "register_operand" "")
8328         (any_or (match_operand 1 "register_operand" "")
8329                 (match_operand 2 "const_int_operand" "")))
8330    (clobber (reg:CC FLAGS_REG))]
8331    "reload_completed
8332     && QI_REG_P (operands[0])
8333     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8334     && !(INTVAL (operands[2]) & ~(255 << 8))
8335     && GET_MODE (operands[0]) != QImode"
8336   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8337                    (any_or:SI (zero_extract:SI (match_dup 1)
8338                                                (const_int 8) (const_int 8))
8339                               (match_dup 2)))
8340               (clobber (reg:CC FLAGS_REG))])]
8341 {
8342   operands[0] = gen_lowpart (SImode, operands[0]);
8343   operands[1] = gen_lowpart (SImode, operands[1]);
8344   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8345 })
8346
8347 ;; Since OR can be encoded with sign extended immediate, this is only
8348 ;; profitable when 7th bit is set.
8349 (define_split
8350   [(set (match_operand 0 "register_operand" "")
8351         (any_or (match_operand 1 "general_operand" "")
8352                 (match_operand 2 "const_int_operand" "")))
8353    (clobber (reg:CC FLAGS_REG))]
8354    "reload_completed
8355     && ANY_QI_REG_P (operands[0])
8356     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8357     && !(INTVAL (operands[2]) & ~255)
8358     && (INTVAL (operands[2]) & 128)
8359     && GET_MODE (operands[0]) != QImode"
8360   [(parallel [(set (strict_low_part (match_dup 0))
8361                    (any_or:QI (match_dup 1)
8362                               (match_dup 2)))
8363               (clobber (reg:CC FLAGS_REG))])]
8364 {
8365   operands[0] = gen_lowpart (QImode, operands[0]);
8366   operands[1] = gen_lowpart (QImode, operands[1]);
8367   operands[2] = gen_lowpart (QImode, operands[2]);
8368 })
8369
8370 (define_expand "xorqi_cc_ext_1"
8371   [(parallel [
8372      (set (reg:CCNO FLAGS_REG)
8373           (compare:CCNO
8374             (xor:SI
8375               (zero_extract:SI
8376                 (match_operand 1 "ext_register_operand" "")
8377                 (const_int 8)
8378                 (const_int 8))
8379               (match_operand:QI 2 "general_operand" ""))
8380             (const_int 0)))
8381      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8382                            (const_int 8)
8383                            (const_int 8))
8384           (xor:SI
8385             (zero_extract:SI
8386              (match_dup 1)
8387              (const_int 8)
8388              (const_int 8))
8389             (match_dup 2)))])])
8390
8391 (define_insn "*xorqi_cc_ext_1_rex64"
8392   [(set (reg FLAGS_REG)
8393         (compare
8394           (xor:SI
8395             (zero_extract:SI
8396               (match_operand 1 "ext_register_operand" "0")
8397               (const_int 8)
8398               (const_int 8))
8399             (match_operand:QI 2 "nonmemory_operand" "Qn"))
8400           (const_int 0)))
8401    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8402                          (const_int 8)
8403                          (const_int 8))
8404         (xor:SI
8405           (zero_extract:SI
8406            (match_dup 1)
8407            (const_int 8)
8408            (const_int 8))
8409           (match_dup 2)))]
8410   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8411   "xor{b}\t{%2, %h0|%h0, %2}"
8412   [(set_attr "type" "alu")
8413    (set_attr "modrm" "1")
8414    (set_attr "mode" "QI")])
8415
8416 (define_insn "*xorqi_cc_ext_1"
8417   [(set (reg FLAGS_REG)
8418         (compare
8419           (xor:SI
8420             (zero_extract:SI
8421               (match_operand 1 "ext_register_operand" "0")
8422               (const_int 8)
8423               (const_int 8))
8424             (match_operand:QI 2 "general_operand" "qmn"))
8425           (const_int 0)))
8426    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8427                          (const_int 8)
8428                          (const_int 8))
8429         (xor:SI
8430           (zero_extract:SI
8431            (match_dup 1)
8432            (const_int 8)
8433            (const_int 8))
8434           (match_dup 2)))]
8435   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8436   "xor{b}\t{%2, %h0|%h0, %2}"
8437   [(set_attr "type" "alu")
8438    (set_attr "modrm" "1")
8439    (set_attr "mode" "QI")])
8440 \f
8441 ;; Negation instructions
8442
8443 (define_expand "neg<mode>2"
8444   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8445         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8446   ""
8447   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8448
8449 (define_insn_and_split "*neg<dwi>2_doubleword"
8450   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8451         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8452    (clobber (reg:CC FLAGS_REG))]
8453   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8454   "#"
8455   "reload_completed"
8456   [(parallel
8457     [(set (reg:CCZ FLAGS_REG)
8458           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8459      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8460    (parallel
8461     [(set (match_dup 2)
8462           (plus:DWIH (match_dup 3)
8463                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8464                                 (const_int 0))))
8465      (clobber (reg:CC FLAGS_REG))])
8466    (parallel
8467     [(set (match_dup 2)
8468           (neg:DWIH (match_dup 2)))
8469      (clobber (reg:CC FLAGS_REG))])]
8470   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8471
8472 (define_insn "*neg<mode>2_1"
8473   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8474         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8475    (clobber (reg:CC FLAGS_REG))]
8476   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8477   "neg{<imodesuffix>}\t%0"
8478   [(set_attr "type" "negnot")
8479    (set_attr "mode" "<MODE>")])
8480
8481 ;; Combine is quite creative about this pattern.
8482 (define_insn "*negsi2_1_zext"
8483   [(set (match_operand:DI 0 "register_operand" "=r")
8484         (lshiftrt:DI
8485           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8486                              (const_int 32)))
8487         (const_int 32)))
8488    (clobber (reg:CC FLAGS_REG))]
8489   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8490   "neg{l}\t%k0"
8491   [(set_attr "type" "negnot")
8492    (set_attr "mode" "SI")])
8493
8494 ;; The problem with neg is that it does not perform (compare x 0),
8495 ;; it really performs (compare 0 x), which leaves us with the zero
8496 ;; flag being the only useful item.
8497
8498 (define_insn "*neg<mode>2_cmpz"
8499   [(set (reg:CCZ FLAGS_REG)
8500         (compare:CCZ
8501           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8502                    (const_int 0)))
8503    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8504         (neg:SWI (match_dup 1)))]
8505   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8506   "neg{<imodesuffix>}\t%0"
8507   [(set_attr "type" "negnot")
8508    (set_attr "mode" "<MODE>")])
8509
8510 (define_insn "*negsi2_cmpz_zext"
8511   [(set (reg:CCZ FLAGS_REG)
8512         (compare:CCZ
8513           (lshiftrt:DI
8514             (neg:DI (ashift:DI
8515                       (match_operand:DI 1 "register_operand" "0")
8516                       (const_int 32)))
8517             (const_int 32))
8518           (const_int 0)))
8519    (set (match_operand:DI 0 "register_operand" "=r")
8520         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8521                                         (const_int 32)))
8522                      (const_int 32)))]
8523   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8524   "neg{l}\t%k0"
8525   [(set_attr "type" "negnot")
8526    (set_attr "mode" "SI")])
8527
8528 ;; Changing of sign for FP values is doable using integer unit too.
8529
8530 (define_expand "<code><mode>2"
8531   [(set (match_operand:X87MODEF 0 "register_operand" "")
8532         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8533   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8534   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8535
8536 (define_insn "*absneg<mode>2_mixed"
8537   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8538         (match_operator:MODEF 3 "absneg_operator"
8539           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8540    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8541    (clobber (reg:CC FLAGS_REG))]
8542   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8543   "#")
8544
8545 (define_insn "*absneg<mode>2_sse"
8546   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8547         (match_operator:MODEF 3 "absneg_operator"
8548           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8549    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8550    (clobber (reg:CC FLAGS_REG))]
8551   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8552   "#")
8553
8554 (define_insn "*absneg<mode>2_i387"
8555   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8556         (match_operator:X87MODEF 3 "absneg_operator"
8557           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8558    (use (match_operand 2 "" ""))
8559    (clobber (reg:CC FLAGS_REG))]
8560   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8561   "#")
8562
8563 (define_expand "<code>tf2"
8564   [(set (match_operand:TF 0 "register_operand" "")
8565         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8566   "TARGET_SSE2"
8567   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8568
8569 (define_insn "*absnegtf2_sse"
8570   [(set (match_operand:TF 0 "register_operand" "=x,x")
8571         (match_operator:TF 3 "absneg_operator"
8572           [(match_operand:TF 1 "register_operand" "0,x")]))
8573    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8574    (clobber (reg:CC FLAGS_REG))]
8575   "TARGET_SSE2"
8576   "#")
8577
8578 ;; Splitters for fp abs and neg.
8579
8580 (define_split
8581   [(set (match_operand 0 "fp_register_operand" "")
8582         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8583    (use (match_operand 2 "" ""))
8584    (clobber (reg:CC FLAGS_REG))]
8585   "reload_completed"
8586   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8587
8588 (define_split
8589   [(set (match_operand 0 "register_operand" "")
8590         (match_operator 3 "absneg_operator"
8591           [(match_operand 1 "register_operand" "")]))
8592    (use (match_operand 2 "nonimmediate_operand" ""))
8593    (clobber (reg:CC FLAGS_REG))]
8594   "reload_completed && SSE_REG_P (operands[0])"
8595   [(set (match_dup 0) (match_dup 3))]
8596 {
8597   enum machine_mode mode = GET_MODE (operands[0]);
8598   enum machine_mode vmode = GET_MODE (operands[2]);
8599   rtx tmp;
8600
8601   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8602   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8603   if (operands_match_p (operands[0], operands[2]))
8604     {
8605       tmp = operands[1];
8606       operands[1] = operands[2];
8607       operands[2] = tmp;
8608     }
8609   if (GET_CODE (operands[3]) == ABS)
8610     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8611   else
8612     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8613   operands[3] = tmp;
8614 })
8615
8616 (define_split
8617   [(set (match_operand:SF 0 "register_operand" "")
8618         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8619    (use (match_operand:V4SF 2 "" ""))
8620    (clobber (reg:CC FLAGS_REG))]
8621   "reload_completed"
8622   [(parallel [(set (match_dup 0) (match_dup 1))
8623               (clobber (reg:CC FLAGS_REG))])]
8624 {
8625   rtx tmp;
8626   operands[0] = gen_lowpart (SImode, operands[0]);
8627   if (GET_CODE (operands[1]) == ABS)
8628     {
8629       tmp = gen_int_mode (0x7fffffff, SImode);
8630       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8631     }
8632   else
8633     {
8634       tmp = gen_int_mode (0x80000000, SImode);
8635       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8636     }
8637   operands[1] = tmp;
8638 })
8639
8640 (define_split
8641   [(set (match_operand:DF 0 "register_operand" "")
8642         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8643    (use (match_operand 2 "" ""))
8644    (clobber (reg:CC FLAGS_REG))]
8645   "reload_completed"
8646   [(parallel [(set (match_dup 0) (match_dup 1))
8647               (clobber (reg:CC FLAGS_REG))])]
8648 {
8649   rtx tmp;
8650   if (TARGET_64BIT)
8651     {
8652       tmp = gen_lowpart (DImode, operands[0]);
8653       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8654       operands[0] = tmp;
8655
8656       if (GET_CODE (operands[1]) == ABS)
8657         tmp = const0_rtx;
8658       else
8659         tmp = gen_rtx_NOT (DImode, tmp);
8660     }
8661   else
8662     {
8663       operands[0] = gen_highpart (SImode, operands[0]);
8664       if (GET_CODE (operands[1]) == ABS)
8665         {
8666           tmp = gen_int_mode (0x7fffffff, SImode);
8667           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8668         }
8669       else
8670         {
8671           tmp = gen_int_mode (0x80000000, SImode);
8672           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8673         }
8674     }
8675   operands[1] = tmp;
8676 })
8677
8678 (define_split
8679   [(set (match_operand:XF 0 "register_operand" "")
8680         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8681    (use (match_operand 2 "" ""))
8682    (clobber (reg:CC FLAGS_REG))]
8683   "reload_completed"
8684   [(parallel [(set (match_dup 0) (match_dup 1))
8685               (clobber (reg:CC FLAGS_REG))])]
8686 {
8687   rtx tmp;
8688   operands[0] = gen_rtx_REG (SImode,
8689                              true_regnum (operands[0])
8690                              + (TARGET_64BIT ? 1 : 2));
8691   if (GET_CODE (operands[1]) == ABS)
8692     {
8693       tmp = GEN_INT (0x7fff);
8694       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8695     }
8696   else
8697     {
8698       tmp = GEN_INT (0x8000);
8699       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8700     }
8701   operands[1] = tmp;
8702 })
8703
8704 ;; Conditionalize these after reload. If they match before reload, we
8705 ;; lose the clobber and ability to use integer instructions.
8706
8707 (define_insn "*<code><mode>2_1"
8708   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8709         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8710   "TARGET_80387
8711    && (reload_completed
8712        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8713   "f<absneg_mnemonic>"
8714   [(set_attr "type" "fsgn")
8715    (set_attr "mode" "<MODE>")])
8716
8717 (define_insn "*<code>extendsfdf2"
8718   [(set (match_operand:DF 0 "register_operand" "=f")
8719         (absneg:DF (float_extend:DF
8720                      (match_operand:SF 1 "register_operand" "0"))))]
8721   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8722   "f<absneg_mnemonic>"
8723   [(set_attr "type" "fsgn")
8724    (set_attr "mode" "DF")])
8725
8726 (define_insn "*<code>extendsfxf2"
8727   [(set (match_operand:XF 0 "register_operand" "=f")
8728         (absneg:XF (float_extend:XF
8729                      (match_operand:SF 1 "register_operand" "0"))))]
8730   "TARGET_80387"
8731   "f<absneg_mnemonic>"
8732   [(set_attr "type" "fsgn")
8733    (set_attr "mode" "XF")])
8734
8735 (define_insn "*<code>extenddfxf2"
8736   [(set (match_operand:XF 0 "register_operand" "=f")
8737         (absneg:XF (float_extend:XF
8738                      (match_operand:DF 1 "register_operand" "0"))))]
8739   "TARGET_80387"
8740   "f<absneg_mnemonic>"
8741   [(set_attr "type" "fsgn")
8742    (set_attr "mode" "XF")])
8743
8744 ;; Copysign instructions
8745
8746 (define_mode_iterator CSGNMODE [SF DF TF])
8747 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8748
8749 (define_expand "copysign<mode>3"
8750   [(match_operand:CSGNMODE 0 "register_operand" "")
8751    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8752    (match_operand:CSGNMODE 2 "register_operand" "")]
8753   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8754    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8755   "ix86_expand_copysign (operands); DONE;")
8756
8757 (define_insn_and_split "copysign<mode>3_const"
8758   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8759         (unspec:CSGNMODE
8760           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8761            (match_operand:CSGNMODE 2 "register_operand" "0")
8762            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8763           UNSPEC_COPYSIGN))]
8764   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8765    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8766   "#"
8767   "&& reload_completed"
8768   [(const_int 0)]
8769   "ix86_split_copysign_const (operands); DONE;")
8770
8771 (define_insn "copysign<mode>3_var"
8772   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8773         (unspec:CSGNMODE
8774           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8775            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8776            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8777            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8778           UNSPEC_COPYSIGN))
8779    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8780   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8781    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8782   "#")
8783
8784 (define_split
8785   [(set (match_operand:CSGNMODE 0 "register_operand" "")
8786         (unspec:CSGNMODE
8787           [(match_operand:CSGNMODE 2 "register_operand" "")
8788            (match_operand:CSGNMODE 3 "register_operand" "")
8789            (match_operand:<CSGNVMODE> 4 "" "")
8790            (match_operand:<CSGNVMODE> 5 "" "")]
8791           UNSPEC_COPYSIGN))
8792    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8793   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8794     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8795    && reload_completed"
8796   [(const_int 0)]
8797   "ix86_split_copysign_var (operands); DONE;")
8798 \f
8799 ;; One complement instructions
8800
8801 (define_expand "one_cmpl<mode>2"
8802   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8803         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8804   ""
8805   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8806
8807 (define_insn "*one_cmpl<mode>2_1"
8808   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8809         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8810   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8811   "not{<imodesuffix>}\t%0"
8812   [(set_attr "type" "negnot")
8813    (set_attr "mode" "<MODE>")])
8814
8815 ;; %%% Potential partial reg stall on alternative 1.  What to do?
8816 (define_insn "*one_cmplqi2_1"
8817   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8818         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8819   "ix86_unary_operator_ok (NOT, QImode, operands)"
8820   "@
8821    not{b}\t%0
8822    not{l}\t%k0"
8823   [(set_attr "type" "negnot")
8824    (set_attr "mode" "QI,SI")])
8825
8826 ;; ??? Currently never generated - xor is used instead.
8827 (define_insn "*one_cmplsi2_1_zext"
8828   [(set (match_operand:DI 0 "register_operand" "=r")
8829         (zero_extend:DI
8830           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8831   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8832   "not{l}\t%k0"
8833   [(set_attr "type" "negnot")
8834    (set_attr "mode" "SI")])
8835
8836 (define_insn "*one_cmpl<mode>2_2"
8837   [(set (reg FLAGS_REG)
8838         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8839                  (const_int 0)))
8840    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8841         (not:SWI (match_dup 1)))]
8842   "ix86_match_ccmode (insn, CCNOmode)
8843    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8844   "#"
8845   [(set_attr "type" "alu1")
8846    (set_attr "mode" "<MODE>")])
8847
8848 (define_split
8849   [(set (match_operand 0 "flags_reg_operand" "")
8850         (match_operator 2 "compare_operator"
8851           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8852            (const_int 0)]))
8853    (set (match_operand:SWI 1 "nonimmediate_operand" "")
8854         (not:SWI (match_dup 3)))]
8855   "ix86_match_ccmode (insn, CCNOmode)"
8856   [(parallel [(set (match_dup 0)
8857                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8858                                     (const_int 0)]))
8859               (set (match_dup 1)
8860                    (xor:SWI (match_dup 3) (const_int -1)))])])
8861
8862 ;; ??? Currently never generated - xor is used instead.
8863 (define_insn "*one_cmplsi2_2_zext"
8864   [(set (reg FLAGS_REG)
8865         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8866                  (const_int 0)))
8867    (set (match_operand:DI 0 "register_operand" "=r")
8868         (zero_extend:DI (not:SI (match_dup 1))))]
8869   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8870    && ix86_unary_operator_ok (NOT, SImode, operands)"
8871   "#"
8872   [(set_attr "type" "alu1")
8873    (set_attr "mode" "SI")])
8874
8875 (define_split
8876   [(set (match_operand 0 "flags_reg_operand" "")
8877         (match_operator 2 "compare_operator"
8878           [(not:SI (match_operand:SI 3 "register_operand" ""))
8879            (const_int 0)]))
8880    (set (match_operand:DI 1 "register_operand" "")
8881         (zero_extend:DI (not:SI (match_dup 3))))]
8882   "ix86_match_ccmode (insn, CCNOmode)"
8883   [(parallel [(set (match_dup 0)
8884                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8885                                     (const_int 0)]))
8886               (set (match_dup 1)
8887                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8888 \f
8889 ;; Shift instructions
8890
8891 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8892 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
8893 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8894 ;; from the assembler input.
8895 ;;
8896 ;; This instruction shifts the target reg/mem as usual, but instead of
8897 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
8898 ;; is a left shift double, bits are taken from the high order bits of
8899 ;; reg, else if the insn is a shift right double, bits are taken from the
8900 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
8901 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8902 ;;
8903 ;; Since sh[lr]d does not change the `reg' operand, that is done
8904 ;; separately, making all shifts emit pairs of shift double and normal
8905 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
8906 ;; support a 63 bit shift, each shift where the count is in a reg expands
8907 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8908 ;;
8909 ;; If the shift count is a constant, we need never emit more than one
8910 ;; shift pair, instead using moves and sign extension for counts greater
8911 ;; than 31.
8912
8913 (define_expand "ashl<mode>3"
8914   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8915         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8916                       (match_operand:QI 2 "nonmemory_operand" "")))]
8917   ""
8918   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8919
8920 (define_insn "*ashl<mode>3_doubleword"
8921   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8922         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8923                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8924    (clobber (reg:CC FLAGS_REG))]
8925   ""
8926   "#"
8927   [(set_attr "type" "multi")])
8928
8929 (define_split
8930   [(set (match_operand:DWI 0 "register_operand" "")
8931         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8932                     (match_operand:QI 2 "nonmemory_operand" "")))
8933    (clobber (reg:CC FLAGS_REG))]
8934   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8935   [(const_int 0)]
8936   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8937
8938 ;; By default we don't ask for a scratch register, because when DWImode
8939 ;; values are manipulated, registers are already at a premium.  But if
8940 ;; we have one handy, we won't turn it away.
8941
8942 (define_peephole2
8943   [(match_scratch:DWIH 3 "r")
8944    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8945                    (ashift:<DWI>
8946                      (match_operand:<DWI> 1 "nonmemory_operand" "")
8947                      (match_operand:QI 2 "nonmemory_operand" "")))
8948               (clobber (reg:CC FLAGS_REG))])
8949    (match_dup 3)]
8950   "TARGET_CMOVE"
8951   [(const_int 0)]
8952   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8953
8954 (define_insn "x86_64_shld"
8955   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8956         (ior:DI (ashift:DI (match_dup 0)
8957                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
8958                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8959                   (minus:QI (const_int 64) (match_dup 2)))))
8960    (clobber (reg:CC FLAGS_REG))]
8961   "TARGET_64BIT"
8962   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8963   [(set_attr "type" "ishift")
8964    (set_attr "prefix_0f" "1")
8965    (set_attr "mode" "DI")
8966    (set_attr "athlon_decode" "vector")
8967    (set_attr "amdfam10_decode" "vector")
8968    (set_attr "bdver1_decode" "vector")])
8969
8970 (define_insn "x86_shld"
8971   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8972         (ior:SI (ashift:SI (match_dup 0)
8973                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
8974                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8975                   (minus:QI (const_int 32) (match_dup 2)))))
8976    (clobber (reg:CC FLAGS_REG))]
8977   ""
8978   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8979   [(set_attr "type" "ishift")
8980    (set_attr "prefix_0f" "1")
8981    (set_attr "mode" "SI")
8982    (set_attr "pent_pair" "np")
8983    (set_attr "athlon_decode" "vector")
8984    (set_attr "amdfam10_decode" "vector")
8985    (set_attr "bdver1_decode" "vector")])
8986
8987 (define_expand "x86_shift<mode>_adj_1"
8988   [(set (reg:CCZ FLAGS_REG)
8989         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
8990                              (match_dup 4))
8991                      (const_int 0)))
8992    (set (match_operand:SWI48 0 "register_operand" "")
8993         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8994                             (match_operand:SWI48 1 "register_operand" "")
8995                             (match_dup 0)))
8996    (set (match_dup 1)
8997         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8998                             (match_operand:SWI48 3 "register_operand" "")
8999                             (match_dup 1)))]
9000   "TARGET_CMOVE"
9001   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9002
9003 (define_expand "x86_shift<mode>_adj_2"
9004   [(use (match_operand:SWI48 0 "register_operand" ""))
9005    (use (match_operand:SWI48 1 "register_operand" ""))
9006    (use (match_operand:QI 2 "register_operand" ""))]
9007   ""
9008 {
9009   rtx label = gen_label_rtx ();
9010   rtx tmp;
9011
9012   emit_insn (gen_testqi_ccz_1 (operands[2],
9013                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9014
9015   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9016   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9017   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9018                               gen_rtx_LABEL_REF (VOIDmode, label),
9019                               pc_rtx);
9020   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9021   JUMP_LABEL (tmp) = label;
9022
9023   emit_move_insn (operands[0], operands[1]);
9024   ix86_expand_clear (operands[1]);
9025
9026   emit_label (label);
9027   LABEL_NUSES (label) = 1;
9028
9029   DONE;
9030 })
9031
9032 ;; Avoid useless masking of count operand.
9033 (define_insn_and_split "*ashl<mode>3_mask"
9034   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9035         (ashift:SWI48
9036           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9037           (subreg:QI
9038             (and:SI
9039               (match_operand:SI 2 "nonimmediate_operand" "c")
9040               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9041    (clobber (reg:CC FLAGS_REG))]
9042   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9043    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9044       == GET_MODE_BITSIZE (<MODE>mode)-1"
9045   "#"
9046   "&& 1"
9047   [(parallel [(set (match_dup 0)
9048                    (ashift:SWI48 (match_dup 1) (match_dup 2)))
9049               (clobber (reg:CC FLAGS_REG))])]
9050 {
9051   if (can_create_pseudo_p ())
9052     operands [2] = force_reg (SImode, operands[2]);
9053
9054   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9055 }
9056   [(set_attr "type" "ishift")
9057    (set_attr "mode" "<MODE>")])
9058
9059 (define_insn "*bmi2_ashl<mode>3_1"
9060   [(set (match_operand:SWI48 0 "register_operand" "=r")
9061         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9062                       (match_operand:SWI48 2 "register_operand" "r")))]
9063   "TARGET_BMI2"
9064   "shlx\t{%2, %1, %0|%0, %1, %2}"
9065   [(set_attr "type" "ishiftx")
9066    (set_attr "mode" "<MODE>")])
9067
9068 (define_insn "*ashl<mode>3_1"
9069   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9070         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9071                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9072    (clobber (reg:CC FLAGS_REG))]
9073   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9074 {
9075   switch (get_attr_type (insn))
9076     {
9077     case TYPE_LEA:
9078     case TYPE_ISHIFTX:
9079       return "#";
9080
9081     case TYPE_ALU:
9082       gcc_assert (operands[2] == const1_rtx);
9083       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9084       return "add{<imodesuffix>}\t%0, %0";
9085
9086     default:
9087       if (operands[2] == const1_rtx
9088           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9089         return "sal{<imodesuffix>}\t%0";
9090       else
9091         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9092     }
9093 }
9094   [(set_attr "isa" "*,*,bmi2")
9095    (set (attr "type")
9096      (cond [(eq_attr "alternative" "1")
9097               (const_string "lea")
9098             (eq_attr "alternative" "2")
9099               (const_string "ishiftx")
9100             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9101                       (match_operand 0 "register_operand" ""))
9102                  (match_operand 2 "const1_operand" ""))
9103               (const_string "alu")
9104            ]
9105            (const_string "ishift")))
9106    (set (attr "length_immediate")
9107      (if_then_else
9108        (ior (eq_attr "type" "alu")
9109             (and (eq_attr "type" "ishift")
9110                  (and (match_operand 2 "const1_operand" "")
9111                       (ior (match_test "TARGET_SHIFT1")
9112                            (match_test "optimize_function_for_size_p (cfun)")))))
9113        (const_string "0")
9114        (const_string "*")))
9115    (set_attr "mode" "<MODE>")])
9116
9117 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9118 (define_split
9119   [(set (match_operand:SWI48 0 "register_operand" "")
9120         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9121                       (match_operand:QI 2 "register_operand" "")))
9122    (clobber (reg:CC FLAGS_REG))]
9123   "TARGET_BMI2 && reload_completed"
9124   [(set (match_dup 0)
9125         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9126   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9127
9128 (define_insn "*bmi2_ashlsi3_1_zext"
9129   [(set (match_operand:DI 0 "register_operand" "=r")
9130         (zero_extend:DI
9131           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9132                      (match_operand:SI 2 "register_operand" "r"))))]
9133   "TARGET_64BIT && TARGET_BMI2"
9134   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9135   [(set_attr "type" "ishiftx")
9136    (set_attr "mode" "SI")])
9137
9138 (define_insn "*ashlsi3_1_zext"
9139   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9140         (zero_extend:DI
9141           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9142                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9143    (clobber (reg:CC FLAGS_REG))]
9144   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9145 {
9146   switch (get_attr_type (insn))
9147     {
9148     case TYPE_LEA:
9149     case TYPE_ISHIFTX:
9150       return "#";
9151
9152     case TYPE_ALU:
9153       gcc_assert (operands[2] == const1_rtx);
9154       return "add{l}\t%k0, %k0";
9155
9156     default:
9157       if (operands[2] == const1_rtx
9158           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9159         return "sal{l}\t%k0";
9160       else
9161         return "sal{l}\t{%2, %k0|%k0, %2}";
9162     }
9163 }
9164   [(set_attr "isa" "*,*,bmi2")
9165    (set (attr "type")
9166      (cond [(eq_attr "alternative" "1")
9167               (const_string "lea")
9168             (eq_attr "alternative" "2")
9169               (const_string "ishiftx")
9170             (and (match_test "TARGET_DOUBLE_WITH_ADD")
9171                  (match_operand 2 "const1_operand" ""))
9172               (const_string "alu")
9173            ]
9174            (const_string "ishift")))
9175    (set (attr "length_immediate")
9176      (if_then_else
9177        (ior (eq_attr "type" "alu")
9178             (and (eq_attr "type" "ishift")
9179                  (and (match_operand 2 "const1_operand" "")
9180                       (ior (match_test "TARGET_SHIFT1")
9181                            (match_test "optimize_function_for_size_p (cfun)")))))
9182        (const_string "0")
9183        (const_string "*")))
9184    (set_attr "mode" "SI")])
9185
9186 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9187 (define_split
9188   [(set (match_operand:DI 0 "register_operand" "")
9189         (zero_extend:DI
9190           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9191                      (match_operand:QI 2 "register_operand" ""))))
9192    (clobber (reg:CC FLAGS_REG))]
9193   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9194   [(set (match_dup 0)
9195         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9196   "operands[2] = gen_lowpart (SImode, operands[2]);")
9197
9198 (define_insn "*ashlhi3_1"
9199   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9200         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9201                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9202    (clobber (reg:CC FLAGS_REG))]
9203   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9204 {
9205   switch (get_attr_type (insn))
9206     {
9207     case TYPE_LEA:
9208       return "#";
9209
9210     case TYPE_ALU:
9211       gcc_assert (operands[2] == const1_rtx);
9212       return "add{w}\t%0, %0";
9213
9214     default:
9215       if (operands[2] == const1_rtx
9216           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9217         return "sal{w}\t%0";
9218       else
9219         return "sal{w}\t{%2, %0|%0, %2}";
9220     }
9221 }
9222   [(set (attr "type")
9223      (cond [(eq_attr "alternative" "1")
9224               (const_string "lea")
9225             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9226                       (match_operand 0 "register_operand" ""))
9227                  (match_operand 2 "const1_operand" ""))
9228               (const_string "alu")
9229            ]
9230            (const_string "ishift")))
9231    (set (attr "length_immediate")
9232      (if_then_else
9233        (ior (eq_attr "type" "alu")
9234             (and (eq_attr "type" "ishift")
9235                  (and (match_operand 2 "const1_operand" "")
9236                       (ior (match_test "TARGET_SHIFT1")
9237                            (match_test "optimize_function_for_size_p (cfun)")))))
9238        (const_string "0")
9239        (const_string "*")))
9240    (set_attr "mode" "HI,SI")])
9241
9242 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9243 (define_insn "*ashlqi3_1"
9244   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9245         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9246                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9247    (clobber (reg:CC FLAGS_REG))]
9248   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9249 {
9250   switch (get_attr_type (insn))
9251     {
9252     case TYPE_LEA:
9253       return "#";
9254
9255     case TYPE_ALU:
9256       gcc_assert (operands[2] == const1_rtx);
9257       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9258         return "add{l}\t%k0, %k0";
9259       else
9260         return "add{b}\t%0, %0";
9261
9262     default:
9263       if (operands[2] == const1_rtx
9264           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9265         {
9266           if (get_attr_mode (insn) == MODE_SI)
9267             return "sal{l}\t%k0";
9268           else
9269             return "sal{b}\t%0";
9270         }
9271       else
9272         {
9273           if (get_attr_mode (insn) == MODE_SI)
9274             return "sal{l}\t{%2, %k0|%k0, %2}";
9275           else
9276             return "sal{b}\t{%2, %0|%0, %2}";
9277         }
9278     }
9279 }
9280   [(set (attr "type")
9281      (cond [(eq_attr "alternative" "2")
9282               (const_string "lea")
9283             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9284                       (match_operand 0 "register_operand" ""))
9285                  (match_operand 2 "const1_operand" ""))
9286               (const_string "alu")
9287            ]
9288            (const_string "ishift")))
9289    (set (attr "length_immediate")
9290      (if_then_else
9291        (ior (eq_attr "type" "alu")
9292             (and (eq_attr "type" "ishift")
9293                  (and (match_operand 2 "const1_operand" "")
9294                       (ior (match_test "TARGET_SHIFT1")
9295                            (match_test "optimize_function_for_size_p (cfun)")))))
9296        (const_string "0")
9297        (const_string "*")))
9298    (set_attr "mode" "QI,SI,SI")])
9299
9300 (define_insn "*ashlqi3_1_slp"
9301   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9302         (ashift:QI (match_dup 0)
9303                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9304    (clobber (reg:CC FLAGS_REG))]
9305   "(optimize_function_for_size_p (cfun)
9306     || !TARGET_PARTIAL_FLAG_REG_STALL
9307     || (operands[1] == const1_rtx
9308         && (TARGET_SHIFT1
9309             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9310 {
9311   switch (get_attr_type (insn))
9312     {
9313     case TYPE_ALU:
9314       gcc_assert (operands[1] == const1_rtx);
9315       return "add{b}\t%0, %0";
9316
9317     default:
9318       if (operands[1] == const1_rtx
9319           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9320         return "sal{b}\t%0";
9321       else
9322         return "sal{b}\t{%1, %0|%0, %1}";
9323     }
9324 }
9325   [(set (attr "type")
9326      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9327                       (match_operand 0 "register_operand" ""))
9328                  (match_operand 1 "const1_operand" ""))
9329               (const_string "alu")
9330            ]
9331            (const_string "ishift1")))
9332    (set (attr "length_immediate")
9333      (if_then_else
9334        (ior (eq_attr "type" "alu")
9335             (and (eq_attr "type" "ishift1")
9336                  (and (match_operand 1 "const1_operand" "")
9337                       (ior (match_test "TARGET_SHIFT1")
9338                            (match_test "optimize_function_for_size_p (cfun)")))))
9339        (const_string "0")
9340        (const_string "*")))
9341    (set_attr "mode" "QI")])
9342
9343 ;; Convert ashift to the lea pattern to avoid flags dependency.
9344 (define_split
9345   [(set (match_operand 0 "register_operand" "")
9346         (ashift (match_operand 1 "index_register_operand" "")
9347                 (match_operand:QI 2 "const_int_operand" "")))
9348    (clobber (reg:CC FLAGS_REG))]
9349   "GET_MODE (operands[0]) == GET_MODE (operands[1])
9350    && reload_completed
9351    && true_regnum (operands[0]) != true_regnum (operands[1])"
9352   [(const_int 0)]
9353 {
9354   enum machine_mode mode = GET_MODE (operands[0]);
9355   rtx pat;
9356
9357   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9358     { 
9359       mode = SImode; 
9360       operands[0] = gen_lowpart (mode, operands[0]);
9361       operands[1] = gen_lowpart (mode, operands[1]);
9362     }
9363
9364   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9365
9366   pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9367
9368   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9369   DONE;
9370 })
9371
9372 ;; Convert ashift to the lea pattern to avoid flags dependency.
9373 (define_split
9374   [(set (match_operand:DI 0 "register_operand" "")
9375         (zero_extend:DI
9376           (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9377                      (match_operand:QI 2 "const_int_operand" ""))))
9378    (clobber (reg:CC FLAGS_REG))]
9379   "TARGET_64BIT && reload_completed
9380    && true_regnum (operands[0]) != true_regnum (operands[1])"
9381   [(set (match_dup 0)
9382         (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9383 {
9384   operands[1] = gen_lowpart (DImode, operands[1]);
9385   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9386 })
9387
9388 ;; This pattern can't accept a variable shift count, since shifts by
9389 ;; zero don't affect the flags.  We assume that shifts by constant
9390 ;; zero are optimized away.
9391 (define_insn "*ashl<mode>3_cmp"
9392   [(set (reg FLAGS_REG)
9393         (compare
9394           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9395                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9396           (const_int 0)))
9397    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9398         (ashift:SWI (match_dup 1) (match_dup 2)))]
9399   "(optimize_function_for_size_p (cfun)
9400     || !TARGET_PARTIAL_FLAG_REG_STALL
9401     || (operands[2] == const1_rtx
9402         && (TARGET_SHIFT1
9403             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9404    && ix86_match_ccmode (insn, CCGOCmode)
9405    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9406 {
9407   switch (get_attr_type (insn))
9408     {
9409     case TYPE_ALU:
9410       gcc_assert (operands[2] == const1_rtx);
9411       return "add{<imodesuffix>}\t%0, %0";
9412
9413     default:
9414       if (operands[2] == const1_rtx
9415           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9416         return "sal{<imodesuffix>}\t%0";
9417       else
9418         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9419     }
9420 }
9421   [(set (attr "type")
9422      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9423                       (match_operand 0 "register_operand" ""))
9424                  (match_operand 2 "const1_operand" ""))
9425               (const_string "alu")
9426            ]
9427            (const_string "ishift")))
9428    (set (attr "length_immediate")
9429      (if_then_else
9430        (ior (eq_attr "type" "alu")
9431             (and (eq_attr "type" "ishift")
9432                  (and (match_operand 2 "const1_operand" "")
9433                       (ior (match_test "TARGET_SHIFT1")
9434                            (match_test "optimize_function_for_size_p (cfun)")))))
9435        (const_string "0")
9436        (const_string "*")))
9437    (set_attr "mode" "<MODE>")])
9438
9439 (define_insn "*ashlsi3_cmp_zext"
9440   [(set (reg FLAGS_REG)
9441         (compare
9442           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9443                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9444           (const_int 0)))
9445    (set (match_operand:DI 0 "register_operand" "=r")
9446         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9447   "TARGET_64BIT
9448    && (optimize_function_for_size_p (cfun)
9449        || !TARGET_PARTIAL_FLAG_REG_STALL
9450        || (operands[2] == const1_rtx
9451            && (TARGET_SHIFT1
9452                || TARGET_DOUBLE_WITH_ADD)))
9453    && ix86_match_ccmode (insn, CCGOCmode)
9454    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9455 {
9456   switch (get_attr_type (insn))
9457     {
9458     case TYPE_ALU:
9459       gcc_assert (operands[2] == const1_rtx);
9460       return "add{l}\t%k0, %k0";
9461
9462     default:
9463       if (operands[2] == const1_rtx
9464           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9465         return "sal{l}\t%k0";
9466       else
9467         return "sal{l}\t{%2, %k0|%k0, %2}";
9468     }
9469 }
9470   [(set (attr "type")
9471      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
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" "SI")])
9486
9487 (define_insn "*ashl<mode>3_cconly"
9488   [(set (reg FLAGS_REG)
9489         (compare
9490           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9491                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9492           (const_int 0)))
9493    (clobber (match_scratch:SWI 0 "=<r>"))]
9494   "(optimize_function_for_size_p (cfun)
9495     || !TARGET_PARTIAL_FLAG_REG_STALL
9496     || (operands[2] == const1_rtx
9497         && (TARGET_SHIFT1
9498             || TARGET_DOUBLE_WITH_ADD)))
9499    && ix86_match_ccmode (insn, CCGOCmode)"
9500 {
9501   switch (get_attr_type (insn))
9502     {
9503     case TYPE_ALU:
9504       gcc_assert (operands[2] == const1_rtx);
9505       return "add{<imodesuffix>}\t%0, %0";
9506
9507     default:
9508       if (operands[2] == const1_rtx
9509           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9510         return "sal{<imodesuffix>}\t%0";
9511       else
9512         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9513     }
9514 }
9515   [(set (attr "type")
9516      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9517                       (match_operand 0 "register_operand" ""))
9518                  (match_operand 2 "const1_operand" ""))
9519               (const_string "alu")
9520            ]
9521            (const_string "ishift")))
9522    (set (attr "length_immediate")
9523      (if_then_else
9524        (ior (eq_attr "type" "alu")
9525             (and (eq_attr "type" "ishift")
9526                  (and (match_operand 2 "const1_operand" "")
9527                       (ior (match_test "TARGET_SHIFT1")
9528                            (match_test "optimize_function_for_size_p (cfun)")))))
9529        (const_string "0")
9530        (const_string "*")))
9531    (set_attr "mode" "<MODE>")])
9532
9533 ;; See comment above `ashl<mode>3' about how this works.
9534
9535 (define_expand "<shift_insn><mode>3"
9536   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9537         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9538                            (match_operand:QI 2 "nonmemory_operand" "")))]
9539   ""
9540   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9541
9542 ;; Avoid useless masking of count operand.
9543 (define_insn_and_split "*<shift_insn><mode>3_mask"
9544   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9545         (any_shiftrt:SWI48
9546           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9547           (subreg:QI
9548             (and:SI
9549               (match_operand:SI 2 "nonimmediate_operand" "c")
9550               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9551    (clobber (reg:CC FLAGS_REG))]
9552   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9553    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9554       == GET_MODE_BITSIZE (<MODE>mode)-1"
9555   "#"
9556   "&& 1"
9557   [(parallel [(set (match_dup 0)
9558                    (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9559               (clobber (reg:CC FLAGS_REG))])]
9560 {
9561   if (can_create_pseudo_p ())
9562     operands [2] = force_reg (SImode, operands[2]);
9563
9564   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9565 }
9566   [(set_attr "type" "ishift")
9567    (set_attr "mode" "<MODE>")])
9568
9569 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9570   [(set (match_operand:DWI 0 "register_operand" "=r")
9571         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9572                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9573    (clobber (reg:CC FLAGS_REG))]
9574   ""
9575   "#"
9576   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9577   [(const_int 0)]
9578   "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9579   [(set_attr "type" "multi")])
9580
9581 ;; By default we don't ask for a scratch register, because when DWImode
9582 ;; values are manipulated, registers are already at a premium.  But if
9583 ;; we have one handy, we won't turn it away.
9584
9585 (define_peephole2
9586   [(match_scratch:DWIH 3 "r")
9587    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9588                    (any_shiftrt:<DWI>
9589                      (match_operand:<DWI> 1 "register_operand" "")
9590                      (match_operand:QI 2 "nonmemory_operand" "")))
9591               (clobber (reg:CC FLAGS_REG))])
9592    (match_dup 3)]
9593   "TARGET_CMOVE"
9594   [(const_int 0)]
9595   "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9596
9597 (define_insn "x86_64_shrd"
9598   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9599         (ior:DI (ashiftrt:DI (match_dup 0)
9600                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9601                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9602                   (minus:QI (const_int 64) (match_dup 2)))))
9603    (clobber (reg:CC FLAGS_REG))]
9604   "TARGET_64BIT"
9605   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9606   [(set_attr "type" "ishift")
9607    (set_attr "prefix_0f" "1")
9608    (set_attr "mode" "DI")
9609    (set_attr "athlon_decode" "vector")
9610    (set_attr "amdfam10_decode" "vector")
9611    (set_attr "bdver1_decode" "vector")])
9612
9613 (define_insn "x86_shrd"
9614   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9615         (ior:SI (ashiftrt:SI (match_dup 0)
9616                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9617                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9618                   (minus:QI (const_int 32) (match_dup 2)))))
9619    (clobber (reg:CC FLAGS_REG))]
9620   ""
9621   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9622   [(set_attr "type" "ishift")
9623    (set_attr "prefix_0f" "1")
9624    (set_attr "mode" "SI")
9625    (set_attr "pent_pair" "np")
9626    (set_attr "athlon_decode" "vector")
9627    (set_attr "amdfam10_decode" "vector")
9628    (set_attr "bdver1_decode" "vector")])
9629
9630 (define_insn "ashrdi3_cvt"
9631   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9632         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9633                      (match_operand:QI 2 "const_int_operand" "")))
9634    (clobber (reg:CC FLAGS_REG))]
9635   "TARGET_64BIT && INTVAL (operands[2]) == 63
9636    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9637    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9638   "@
9639    {cqto|cqo}
9640    sar{q}\t{%2, %0|%0, %2}"
9641   [(set_attr "type" "imovx,ishift")
9642    (set_attr "prefix_0f" "0,*")
9643    (set_attr "length_immediate" "0,*")
9644    (set_attr "modrm" "0,1")
9645    (set_attr "mode" "DI")])
9646
9647 (define_insn "ashrsi3_cvt"
9648   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9649         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9650                      (match_operand:QI 2 "const_int_operand" "")))
9651    (clobber (reg:CC FLAGS_REG))]
9652   "INTVAL (operands[2]) == 31
9653    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9654    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9655   "@
9656    {cltd|cdq}
9657    sar{l}\t{%2, %0|%0, %2}"
9658   [(set_attr "type" "imovx,ishift")
9659    (set_attr "prefix_0f" "0,*")
9660    (set_attr "length_immediate" "0,*")
9661    (set_attr "modrm" "0,1")
9662    (set_attr "mode" "SI")])
9663
9664 (define_insn "*ashrsi3_cvt_zext"
9665   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9666         (zero_extend:DI
9667           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9668                        (match_operand:QI 2 "const_int_operand" ""))))
9669    (clobber (reg:CC FLAGS_REG))]
9670   "TARGET_64BIT && INTVAL (operands[2]) == 31
9671    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9672    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9673   "@
9674    {cltd|cdq}
9675    sar{l}\t{%2, %k0|%k0, %2}"
9676   [(set_attr "type" "imovx,ishift")
9677    (set_attr "prefix_0f" "0,*")
9678    (set_attr "length_immediate" "0,*")
9679    (set_attr "modrm" "0,1")
9680    (set_attr "mode" "SI")])
9681
9682 (define_expand "x86_shift<mode>_adj_3"
9683   [(use (match_operand:SWI48 0 "register_operand" ""))
9684    (use (match_operand:SWI48 1 "register_operand" ""))
9685    (use (match_operand:QI 2 "register_operand" ""))]
9686   ""
9687 {
9688   rtx label = gen_label_rtx ();
9689   rtx tmp;
9690
9691   emit_insn (gen_testqi_ccz_1 (operands[2],
9692                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9693
9694   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9695   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9696   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9697                               gen_rtx_LABEL_REF (VOIDmode, label),
9698                               pc_rtx);
9699   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9700   JUMP_LABEL (tmp) = label;
9701
9702   emit_move_insn (operands[0], operands[1]);
9703   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9704                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9705   emit_label (label);
9706   LABEL_NUSES (label) = 1;
9707
9708   DONE;
9709 })
9710
9711 (define_insn "*bmi2_<shift_insn><mode>3_1"
9712   [(set (match_operand:SWI48 0 "register_operand" "=r")
9713         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9714                            (match_operand:SWI48 2 "register_operand" "r")))]
9715   "TARGET_BMI2"
9716   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9717   [(set_attr "type" "ishiftx")
9718    (set_attr "mode" "<MODE>")])
9719
9720 (define_insn "*<shift_insn><mode>3_1"
9721   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9722         (any_shiftrt:SWI48
9723           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9724           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9725    (clobber (reg:CC FLAGS_REG))]
9726   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9727 {
9728   switch (get_attr_type (insn))
9729     {
9730     case TYPE_ISHIFTX:
9731       return "#";
9732
9733     default:
9734       if (operands[2] == const1_rtx
9735           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9736         return "<shift>{<imodesuffix>}\t%0";
9737       else
9738         return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9739     }
9740 }
9741   [(set_attr "isa" "*,bmi2")
9742    (set_attr "type" "ishift,ishiftx")
9743    (set (attr "length_immediate")
9744      (if_then_else
9745        (and (match_operand 2 "const1_operand" "")
9746             (ior (match_test "TARGET_SHIFT1")
9747                  (match_test "optimize_function_for_size_p (cfun)")))
9748        (const_string "0")
9749        (const_string "*")))
9750    (set_attr "mode" "<MODE>")])
9751
9752 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9753 (define_split
9754   [(set (match_operand:SWI48 0 "register_operand" "")
9755         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9756                            (match_operand:QI 2 "register_operand" "")))
9757    (clobber (reg:CC FLAGS_REG))]
9758   "TARGET_BMI2 && reload_completed"
9759   [(set (match_dup 0)
9760         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9761   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9762
9763 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9764   [(set (match_operand:DI 0 "register_operand" "=r")
9765         (zero_extend:DI
9766           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9767                           (match_operand:SI 2 "register_operand" "r"))))]
9768   "TARGET_64BIT && TARGET_BMI2"
9769   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9770   [(set_attr "type" "ishiftx")
9771    (set_attr "mode" "SI")])
9772
9773 (define_insn "*<shift_insn>si3_1_zext"
9774   [(set (match_operand:DI 0 "register_operand" "=r,r")
9775         (zero_extend:DI
9776           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9777                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9778    (clobber (reg:CC FLAGS_REG))]
9779   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9780 {
9781   switch (get_attr_type (insn))
9782     {
9783     case TYPE_ISHIFTX:
9784       return "#";
9785
9786     default:
9787       if (operands[2] == const1_rtx
9788           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9789         return "<shift>{l}\t%k0";
9790       else
9791         return "<shift>{l}\t{%2, %k0|%k0, %2}";
9792     }
9793 }
9794   [(set_attr "isa" "*,bmi2")
9795    (set_attr "type" "ishift,ishiftx")
9796    (set (attr "length_immediate")
9797      (if_then_else
9798        (and (match_operand 2 "const1_operand" "")
9799             (ior (match_test "TARGET_SHIFT1")
9800                  (match_test "optimize_function_for_size_p (cfun)")))
9801        (const_string "0")
9802        (const_string "*")))
9803    (set_attr "mode" "SI")])
9804
9805 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9806 (define_split
9807   [(set (match_operand:DI 0 "register_operand" "")
9808         (zero_extend:DI
9809           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9810                           (match_operand:QI 2 "register_operand" ""))))
9811    (clobber (reg:CC FLAGS_REG))]
9812   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9813   [(set (match_dup 0)
9814         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9815   "operands[2] = gen_lowpart (SImode, operands[2]);")
9816
9817 (define_insn "*<shift_insn><mode>3_1"
9818   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9819         (any_shiftrt:SWI12
9820           (match_operand:SWI12 1 "nonimmediate_operand" "0")
9821           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9822    (clobber (reg:CC FLAGS_REG))]
9823   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9824 {
9825   if (operands[2] == const1_rtx
9826       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9827     return "<shift>{<imodesuffix>}\t%0";
9828   else
9829     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9830 }
9831   [(set_attr "type" "ishift")
9832    (set (attr "length_immediate")
9833      (if_then_else
9834        (and (match_operand 2 "const1_operand" "")
9835             (ior (match_test "TARGET_SHIFT1")
9836                  (match_test "optimize_function_for_size_p (cfun)")))
9837        (const_string "0")
9838        (const_string "*")))
9839    (set_attr "mode" "<MODE>")])
9840
9841 (define_insn "*<shift_insn>qi3_1_slp"
9842   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9843         (any_shiftrt:QI (match_dup 0)
9844                         (match_operand:QI 1 "nonmemory_operand" "cI")))
9845    (clobber (reg:CC FLAGS_REG))]
9846   "(optimize_function_for_size_p (cfun)
9847     || !TARGET_PARTIAL_REG_STALL
9848     || (operands[1] == const1_rtx
9849         && TARGET_SHIFT1))"
9850 {
9851   if (operands[1] == const1_rtx
9852       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9853     return "<shift>{b}\t%0";
9854   else
9855     return "<shift>{b}\t{%1, %0|%0, %1}";
9856 }
9857   [(set_attr "type" "ishift1")
9858    (set (attr "length_immediate")
9859      (if_then_else
9860        (and (match_operand 1 "const1_operand" "")
9861             (ior (match_test "TARGET_SHIFT1")
9862                  (match_test "optimize_function_for_size_p (cfun)")))
9863        (const_string "0")
9864        (const_string "*")))
9865    (set_attr "mode" "QI")])
9866
9867 ;; This pattern can't accept a variable shift count, since shifts by
9868 ;; zero don't affect the flags.  We assume that shifts by constant
9869 ;; zero are optimized away.
9870 (define_insn "*<shift_insn><mode>3_cmp"
9871   [(set (reg FLAGS_REG)
9872         (compare
9873           (any_shiftrt:SWI
9874             (match_operand:SWI 1 "nonimmediate_operand" "0")
9875             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9876           (const_int 0)))
9877    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9878         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9879   "(optimize_function_for_size_p (cfun)
9880     || !TARGET_PARTIAL_FLAG_REG_STALL
9881     || (operands[2] == const1_rtx
9882         && TARGET_SHIFT1))
9883    && ix86_match_ccmode (insn, CCGOCmode)
9884    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9885 {
9886   if (operands[2] == const1_rtx
9887       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9888     return "<shift>{<imodesuffix>}\t%0";
9889   else
9890     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9891 }
9892   [(set_attr "type" "ishift")
9893    (set (attr "length_immediate")
9894      (if_then_else
9895        (and (match_operand 2 "const1_operand" "")
9896             (ior (match_test "TARGET_SHIFT1")
9897                  (match_test "optimize_function_for_size_p (cfun)")))
9898        (const_string "0")
9899        (const_string "*")))
9900    (set_attr "mode" "<MODE>")])
9901
9902 (define_insn "*<shift_insn>si3_cmp_zext"
9903   [(set (reg FLAGS_REG)
9904         (compare
9905           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9906                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
9907           (const_int 0)))
9908    (set (match_operand:DI 0 "register_operand" "=r")
9909         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9910   "TARGET_64BIT
9911    && (optimize_function_for_size_p (cfun)
9912        || !TARGET_PARTIAL_FLAG_REG_STALL
9913        || (operands[2] == const1_rtx
9914            && TARGET_SHIFT1))
9915    && ix86_match_ccmode (insn, CCGOCmode)
9916    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9917 {
9918   if (operands[2] == const1_rtx
9919       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9920     return "<shift>{l}\t%k0";
9921   else
9922     return "<shift>{l}\t{%2, %k0|%k0, %2}";
9923 }
9924   [(set_attr "type" "ishift")
9925    (set (attr "length_immediate")
9926      (if_then_else
9927        (and (match_operand 2 "const1_operand" "")
9928             (ior (match_test "TARGET_SHIFT1")
9929                  (match_test "optimize_function_for_size_p (cfun)")))
9930        (const_string "0")
9931        (const_string "*")))
9932    (set_attr "mode" "SI")])
9933
9934 (define_insn "*<shift_insn><mode>3_cconly"
9935   [(set (reg FLAGS_REG)
9936         (compare
9937           (any_shiftrt:SWI
9938             (match_operand:SWI 1 "register_operand" "0")
9939             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9940           (const_int 0)))
9941    (clobber (match_scratch:SWI 0 "=<r>"))]
9942   "(optimize_function_for_size_p (cfun)
9943     || !TARGET_PARTIAL_FLAG_REG_STALL
9944     || (operands[2] == const1_rtx
9945         && TARGET_SHIFT1))
9946    && ix86_match_ccmode (insn, CCGOCmode)"
9947 {
9948   if (operands[2] == const1_rtx
9949       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9950     return "<shift>{<imodesuffix>}\t%0";
9951   else
9952     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9953 }
9954   [(set_attr "type" "ishift")
9955    (set (attr "length_immediate")
9956      (if_then_else
9957        (and (match_operand 2 "const1_operand" "")
9958             (ior (match_test "TARGET_SHIFT1")
9959                  (match_test "optimize_function_for_size_p (cfun)")))
9960        (const_string "0")
9961        (const_string "*")))
9962    (set_attr "mode" "<MODE>")])
9963 \f
9964 ;; Rotate instructions
9965
9966 (define_expand "<rotate_insn>ti3"
9967   [(set (match_operand:TI 0 "register_operand" "")
9968         (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9969                        (match_operand:QI 2 "nonmemory_operand" "")))]
9970   "TARGET_64BIT"
9971 {
9972   if (const_1_to_63_operand (operands[2], VOIDmode))
9973     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9974                 (operands[0], operands[1], operands[2]));
9975   else
9976     FAIL;
9977
9978   DONE;
9979 })
9980
9981 (define_expand "<rotate_insn>di3"
9982   [(set (match_operand:DI 0 "shiftdi_operand" "")
9983         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9984                        (match_operand:QI 2 "nonmemory_operand" "")))]
9985  ""
9986 {
9987   if (TARGET_64BIT)
9988     ix86_expand_binary_operator (<CODE>, DImode, operands);
9989   else if (const_1_to_31_operand (operands[2], VOIDmode))
9990     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9991                 (operands[0], operands[1], operands[2]));
9992   else
9993     FAIL;
9994
9995   DONE;
9996 })
9997
9998 (define_expand "<rotate_insn><mode>3"
9999   [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10000         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10001                             (match_operand:QI 2 "nonmemory_operand" "")))]
10002   ""
10003   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10004
10005 ;; Avoid useless masking of count operand.
10006 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10007   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10008         (any_rotate:SWI48
10009           (match_operand:SWI48 1 "nonimmediate_operand" "0")
10010           (subreg:QI
10011             (and:SI
10012               (match_operand:SI 2 "nonimmediate_operand" "c")
10013               (match_operand:SI 3 "const_int_operand" "n")) 0)))
10014    (clobber (reg:CC FLAGS_REG))]
10015   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10016    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10017       == GET_MODE_BITSIZE (<MODE>mode)-1"
10018   "#"
10019   "&& 1"
10020   [(parallel [(set (match_dup 0)
10021                    (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10022               (clobber (reg:CC FLAGS_REG))])]
10023 {
10024   if (can_create_pseudo_p ())
10025     operands [2] = force_reg (SImode, operands[2]);
10026
10027   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10028 }
10029   [(set_attr "type" "rotate")
10030    (set_attr "mode" "<MODE>")])
10031
10032 ;; Implement rotation using two double-precision
10033 ;; shift instructions and a scratch register.
10034
10035 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10036  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10037        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10038                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10039   (clobber (reg:CC FLAGS_REG))
10040   (clobber (match_scratch:DWIH 3 "=&r"))]
10041  ""
10042  "#"
10043  "reload_completed"
10044  [(set (match_dup 3) (match_dup 4))
10045   (parallel
10046    [(set (match_dup 4)
10047          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10048                    (lshiftrt:DWIH (match_dup 5)
10049                                   (minus:QI (match_dup 6) (match_dup 2)))))
10050     (clobber (reg:CC FLAGS_REG))])
10051   (parallel
10052    [(set (match_dup 5)
10053          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10054                    (lshiftrt:DWIH (match_dup 3)
10055                                   (minus:QI (match_dup 6) (match_dup 2)))))
10056     (clobber (reg:CC FLAGS_REG))])]
10057 {
10058   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10059
10060   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10061 })
10062
10063 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10064  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10065        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10066                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10067   (clobber (reg:CC FLAGS_REG))
10068   (clobber (match_scratch:DWIH 3 "=&r"))]
10069  ""
10070  "#"
10071  "reload_completed"
10072  [(set (match_dup 3) (match_dup 4))
10073   (parallel
10074    [(set (match_dup 4)
10075          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10076                    (ashift:DWIH (match_dup 5)
10077                                 (minus:QI (match_dup 6) (match_dup 2)))))
10078     (clobber (reg:CC FLAGS_REG))])
10079   (parallel
10080    [(set (match_dup 5)
10081          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10082                    (ashift:DWIH (match_dup 3)
10083                                 (minus:QI (match_dup 6) (match_dup 2)))))
10084     (clobber (reg:CC FLAGS_REG))])]
10085 {
10086   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10087
10088   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10089 })
10090
10091 (define_insn "*bmi2_rorx<mode>3_1"
10092   [(set (match_operand:SWI48 0 "register_operand" "=r")
10093         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10094                         (match_operand:QI 2 "immediate_operand" "<S>")))]
10095   "TARGET_BMI2"
10096   "rorx\t{%2, %1, %0|%0, %1, %2}"
10097   [(set_attr "type" "rotatex")
10098    (set_attr "mode" "<MODE>")])
10099
10100 (define_insn "*<rotate_insn><mode>3_1"
10101   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10102         (any_rotate:SWI48
10103           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10104           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10105    (clobber (reg:CC FLAGS_REG))]
10106   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10107 {
10108   switch (get_attr_type (insn))
10109     {
10110     case TYPE_ROTATEX:
10111       return "#";
10112
10113     default:
10114       if (operands[2] == const1_rtx
10115           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10116         return "<rotate>{<imodesuffix>}\t%0";
10117       else
10118         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10119     }
10120 }
10121   [(set_attr "isa" "*,bmi2")
10122    (set_attr "type" "rotate,rotatex")
10123    (set (attr "length_immediate")
10124      (if_then_else
10125        (and (eq_attr "type" "rotate")
10126             (and (match_operand 2 "const1_operand" "")
10127                  (ior (match_test "TARGET_SHIFT1")
10128                       (match_test "optimize_function_for_size_p (cfun)"))))
10129        (const_string "0")
10130        (const_string "*")))
10131    (set_attr "mode" "<MODE>")])
10132
10133 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10134 (define_split
10135   [(set (match_operand:SWI48 0 "register_operand" "")
10136         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10137                       (match_operand:QI 2 "immediate_operand" "")))
10138    (clobber (reg:CC FLAGS_REG))]
10139   "TARGET_BMI2 && reload_completed"
10140   [(set (match_dup 0)
10141         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10142 {
10143   operands[2]
10144     = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10145 })
10146
10147 (define_split
10148   [(set (match_operand:SWI48 0 "register_operand" "")
10149         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10150                         (match_operand:QI 2 "immediate_operand" "")))
10151    (clobber (reg:CC FLAGS_REG))]
10152   "TARGET_BMI2 && reload_completed"
10153   [(set (match_dup 0)
10154         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10155
10156 (define_insn "*bmi2_rorxsi3_1_zext"
10157   [(set (match_operand:DI 0 "register_operand" "=r")
10158         (zero_extend:DI
10159           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10160                        (match_operand:QI 2 "immediate_operand" "I"))))]
10161   "TARGET_64BIT && TARGET_BMI2"
10162   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10163   [(set_attr "type" "rotatex")
10164    (set_attr "mode" "SI")])
10165
10166 (define_insn "*<rotate_insn>si3_1_zext"
10167   [(set (match_operand:DI 0 "register_operand" "=r,r")
10168         (zero_extend:DI
10169           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10170                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10171    (clobber (reg:CC FLAGS_REG))]
10172   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10173 {
10174   switch (get_attr_type (insn))
10175     {
10176     case TYPE_ROTATEX:
10177       return "#";
10178
10179     default:
10180       if (operands[2] == const1_rtx
10181           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10182         return "<rotate>{l}\t%k0";
10183       else
10184         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10185     }
10186 }
10187   [(set_attr "isa" "*,bmi2")
10188    (set_attr "type" "rotate,rotatex")
10189    (set (attr "length_immediate")
10190      (if_then_else
10191        (and (eq_attr "type" "rotate")
10192             (and (match_operand 2 "const1_operand" "")
10193                  (ior (match_test "TARGET_SHIFT1")
10194                       (match_test "optimize_function_for_size_p (cfun)"))))
10195        (const_string "0")
10196        (const_string "*")))
10197    (set_attr "mode" "SI")])
10198
10199 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10200 (define_split
10201   [(set (match_operand:DI 0 "register_operand" "")
10202         (zero_extend:DI
10203           (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10204                      (match_operand:QI 2 "immediate_operand" ""))))
10205    (clobber (reg:CC FLAGS_REG))]
10206   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10207   [(set (match_dup 0)
10208         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10209 {
10210   operands[2]
10211     = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10212 })
10213
10214 (define_split
10215   [(set (match_operand:DI 0 "register_operand" "")
10216         (zero_extend:DI
10217           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10218                        (match_operand:QI 2 "immediate_operand" ""))))
10219    (clobber (reg:CC FLAGS_REG))]
10220   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10221   [(set (match_dup 0)
10222         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10223
10224 (define_insn "*<rotate_insn><mode>3_1"
10225   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10226         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10227                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10228    (clobber (reg:CC FLAGS_REG))]
10229   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10230 {
10231   if (operands[2] == const1_rtx
10232       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10233     return "<rotate>{<imodesuffix>}\t%0";
10234   else
10235     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10236 }
10237   [(set_attr "type" "rotate")
10238    (set (attr "length_immediate")
10239      (if_then_else
10240        (and (match_operand 2 "const1_operand" "")
10241             (ior (match_test "TARGET_SHIFT1")
10242                  (match_test "optimize_function_for_size_p (cfun)")))
10243        (const_string "0")
10244        (const_string "*")))
10245    (set_attr "mode" "<MODE>")])
10246
10247 (define_insn "*<rotate_insn>qi3_1_slp"
10248   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10249         (any_rotate:QI (match_dup 0)
10250                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10251    (clobber (reg:CC FLAGS_REG))]
10252   "(optimize_function_for_size_p (cfun)
10253     || !TARGET_PARTIAL_REG_STALL
10254     || (operands[1] == const1_rtx
10255         && TARGET_SHIFT1))"
10256 {
10257   if (operands[1] == const1_rtx
10258       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10259     return "<rotate>{b}\t%0";
10260   else
10261     return "<rotate>{b}\t{%1, %0|%0, %1}";
10262 }
10263   [(set_attr "type" "rotate1")
10264    (set (attr "length_immediate")
10265      (if_then_else
10266        (and (match_operand 1 "const1_operand" "")
10267             (ior (match_test "TARGET_SHIFT1")
10268                  (match_test "optimize_function_for_size_p (cfun)")))
10269        (const_string "0")
10270        (const_string "*")))
10271    (set_attr "mode" "QI")])
10272
10273 (define_split
10274  [(set (match_operand:HI 0 "register_operand" "")
10275        (any_rotate:HI (match_dup 0) (const_int 8)))
10276   (clobber (reg:CC FLAGS_REG))]
10277  "reload_completed
10278   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10279  [(parallel [(set (strict_low_part (match_dup 0))
10280                   (bswap:HI (match_dup 0)))
10281              (clobber (reg:CC FLAGS_REG))])])
10282 \f
10283 ;; Bit set / bit test instructions
10284
10285 (define_expand "extv"
10286   [(set (match_operand:SI 0 "register_operand" "")
10287         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10288                          (match_operand:SI 2 "const8_operand" "")
10289                          (match_operand:SI 3 "const8_operand" "")))]
10290   ""
10291 {
10292   /* Handle extractions from %ah et al.  */
10293   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10294     FAIL;
10295
10296   /* From mips.md: extract_bit_field doesn't verify that our source
10297      matches the predicate, so check it again here.  */
10298   if (! ext_register_operand (operands[1], VOIDmode))
10299     FAIL;
10300 })
10301
10302 (define_expand "extzv"
10303   [(set (match_operand:SI 0 "register_operand" "")
10304         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10305                          (match_operand:SI 2 "const8_operand" "")
10306                          (match_operand:SI 3 "const8_operand" "")))]
10307   ""
10308 {
10309   /* Handle extractions from %ah et al.  */
10310   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10311     FAIL;
10312
10313   /* From mips.md: extract_bit_field doesn't verify that our source
10314      matches the predicate, so check it again here.  */
10315   if (! ext_register_operand (operands[1], VOIDmode))
10316     FAIL;
10317 })
10318
10319 (define_expand "insv"
10320   [(set (zero_extract (match_operand 0 "register_operand" "")
10321                       (match_operand 1 "const_int_operand" "")
10322                       (match_operand 2 "const_int_operand" ""))
10323         (match_operand 3 "register_operand" ""))]
10324   ""
10325 {
10326   rtx (*gen_mov_insv_1) (rtx, rtx);
10327
10328   if (ix86_expand_pinsr (operands))
10329     DONE;
10330
10331   /* Handle insertions to %ah et al.  */
10332   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10333     FAIL;
10334
10335   /* From mips.md: insert_bit_field doesn't verify that our source
10336      matches the predicate, so check it again here.  */
10337   if (! ext_register_operand (operands[0], VOIDmode))
10338     FAIL;
10339
10340   gen_mov_insv_1 = (TARGET_64BIT
10341                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10342
10343   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10344   DONE;
10345 })
10346
10347 ;; %%% bts, btr, btc, bt.
10348 ;; In general these instructions are *slow* when applied to memory,
10349 ;; since they enforce atomic operation.  When applied to registers,
10350 ;; it depends on the cpu implementation.  They're never faster than
10351 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10352 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10353 ;; within the instruction itself, so operating on bits in the high
10354 ;; 32-bits of a register becomes easier.
10355 ;;
10356 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10357 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10358 ;; negdf respectively, so they can never be disabled entirely.
10359
10360 (define_insn "*btsq"
10361   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10362                          (const_int 1)
10363                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10364         (const_int 1))
10365    (clobber (reg:CC FLAGS_REG))]
10366   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10367   "bts{q}\t{%1, %0|%0, %1}"
10368   [(set_attr "type" "alu1")
10369    (set_attr "prefix_0f" "1")
10370    (set_attr "mode" "DI")])
10371
10372 (define_insn "*btrq"
10373   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10374                          (const_int 1)
10375                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10376         (const_int 0))
10377    (clobber (reg:CC FLAGS_REG))]
10378   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10379   "btr{q}\t{%1, %0|%0, %1}"
10380   [(set_attr "type" "alu1")
10381    (set_attr "prefix_0f" "1")
10382    (set_attr "mode" "DI")])
10383
10384 (define_insn "*btcq"
10385   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10386                          (const_int 1)
10387                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10388         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10389    (clobber (reg:CC FLAGS_REG))]
10390   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10391   "btc{q}\t{%1, %0|%0, %1}"
10392   [(set_attr "type" "alu1")
10393    (set_attr "prefix_0f" "1")
10394    (set_attr "mode" "DI")])
10395
10396 ;; Allow Nocona to avoid these instructions if a register is available.
10397
10398 (define_peephole2
10399   [(match_scratch:DI 2 "r")
10400    (parallel [(set (zero_extract:DI
10401                      (match_operand:DI 0 "register_operand" "")
10402                      (const_int 1)
10403                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10404                    (const_int 1))
10405               (clobber (reg:CC FLAGS_REG))])]
10406   "TARGET_64BIT && !TARGET_USE_BT"
10407   [(const_int 0)]
10408 {
10409   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10410   rtx op1;
10411
10412   if (HOST_BITS_PER_WIDE_INT >= 64)
10413     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10414   else if (i < HOST_BITS_PER_WIDE_INT)
10415     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10416   else
10417     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10418
10419   op1 = immed_double_const (lo, hi, DImode);
10420   if (i >= 31)
10421     {
10422       emit_move_insn (operands[2], op1);
10423       op1 = operands[2];
10424     }
10425
10426   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10427   DONE;
10428 })
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 0))
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 >= 32)
10453     {
10454       emit_move_insn (operands[2], op1);
10455       op1 = operands[2];
10456     }
10457
10458   emit_insn (gen_anddi3 (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               (not:DI (zero_extract:DI
10469                         (match_dup 0) (const_int 1) (match_dup 1))))
10470               (clobber (reg:CC FLAGS_REG))])]
10471   "TARGET_64BIT && !TARGET_USE_BT"
10472   [(const_int 0)]
10473 {
10474   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10475   rtx op1;
10476
10477   if (HOST_BITS_PER_WIDE_INT >= 64)
10478     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10479   else if (i < HOST_BITS_PER_WIDE_INT)
10480     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10481   else
10482     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10483
10484   op1 = immed_double_const (lo, hi, DImode);
10485   if (i >= 31)
10486     {
10487       emit_move_insn (operands[2], op1);
10488       op1 = operands[2];
10489     }
10490
10491   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10492   DONE;
10493 })
10494
10495 (define_insn "*bt<mode>"
10496   [(set (reg:CCC FLAGS_REG)
10497         (compare:CCC
10498           (zero_extract:SWI48
10499             (match_operand:SWI48 0 "register_operand" "r")
10500             (const_int 1)
10501             (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10502           (const_int 0)))]
10503   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10504   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10505   [(set_attr "type" "alu1")
10506    (set_attr "prefix_0f" "1")
10507    (set_attr "mode" "<MODE>")])
10508 \f
10509 ;; Store-flag instructions.
10510
10511 ;; For all sCOND expanders, also expand the compare or test insn that
10512 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10513
10514 (define_insn_and_split "*setcc_di_1"
10515   [(set (match_operand:DI 0 "register_operand" "=q")
10516         (match_operator:DI 1 "ix86_comparison_operator"
10517           [(reg FLAGS_REG) (const_int 0)]))]
10518   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10519   "#"
10520   "&& reload_completed"
10521   [(set (match_dup 2) (match_dup 1))
10522    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10523 {
10524   PUT_MODE (operands[1], QImode);
10525   operands[2] = gen_lowpart (QImode, operands[0]);
10526 })
10527
10528 (define_insn_and_split "*setcc_si_1_and"
10529   [(set (match_operand:SI 0 "register_operand" "=q")
10530         (match_operator:SI 1 "ix86_comparison_operator"
10531           [(reg FLAGS_REG) (const_int 0)]))
10532    (clobber (reg:CC FLAGS_REG))]
10533   "!TARGET_PARTIAL_REG_STALL
10534    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10535   "#"
10536   "&& reload_completed"
10537   [(set (match_dup 2) (match_dup 1))
10538    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10539               (clobber (reg:CC FLAGS_REG))])]
10540 {
10541   PUT_MODE (operands[1], QImode);
10542   operands[2] = gen_lowpart (QImode, operands[0]);
10543 })
10544
10545 (define_insn_and_split "*setcc_si_1_movzbl"
10546   [(set (match_operand:SI 0 "register_operand" "=q")
10547         (match_operator:SI 1 "ix86_comparison_operator"
10548           [(reg FLAGS_REG) (const_int 0)]))]
10549   "!TARGET_PARTIAL_REG_STALL
10550    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10551   "#"
10552   "&& reload_completed"
10553   [(set (match_dup 2) (match_dup 1))
10554    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10555 {
10556   PUT_MODE (operands[1], QImode);
10557   operands[2] = gen_lowpart (QImode, operands[0]);
10558 })
10559
10560 (define_insn "*setcc_qi"
10561   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10562         (match_operator:QI 1 "ix86_comparison_operator"
10563           [(reg FLAGS_REG) (const_int 0)]))]
10564   ""
10565   "set%C1\t%0"
10566   [(set_attr "type" "setcc")
10567    (set_attr "mode" "QI")])
10568
10569 (define_insn "*setcc_qi_slp"
10570   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10571         (match_operator:QI 1 "ix86_comparison_operator"
10572           [(reg FLAGS_REG) (const_int 0)]))]
10573   ""
10574   "set%C1\t%0"
10575   [(set_attr "type" "setcc")
10576    (set_attr "mode" "QI")])
10577
10578 ;; In general it is not safe to assume too much about CCmode registers,
10579 ;; so simplify-rtx stops when it sees a second one.  Under certain
10580 ;; conditions this is safe on x86, so help combine not create
10581 ;;
10582 ;;      seta    %al
10583 ;;      testb   %al, %al
10584 ;;      sete    %al
10585
10586 (define_split
10587   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10588         (ne:QI (match_operator 1 "ix86_comparison_operator"
10589                  [(reg FLAGS_REG) (const_int 0)])
10590             (const_int 0)))]
10591   ""
10592   [(set (match_dup 0) (match_dup 1))]
10593   "PUT_MODE (operands[1], QImode);")
10594
10595 (define_split
10596   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10597         (ne:QI (match_operator 1 "ix86_comparison_operator"
10598                  [(reg FLAGS_REG) (const_int 0)])
10599             (const_int 0)))]
10600   ""
10601   [(set (match_dup 0) (match_dup 1))]
10602   "PUT_MODE (operands[1], QImode);")
10603
10604 (define_split
10605   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10606         (eq:QI (match_operator 1 "ix86_comparison_operator"
10607                  [(reg FLAGS_REG) (const_int 0)])
10608             (const_int 0)))]
10609   ""
10610   [(set (match_dup 0) (match_dup 1))]
10611 {
10612   rtx new_op1 = copy_rtx (operands[1]);
10613   operands[1] = new_op1;
10614   PUT_MODE (new_op1, QImode);
10615   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10616                                              GET_MODE (XEXP (new_op1, 0))));
10617
10618   /* Make sure that (a) the CCmode we have for the flags is strong
10619      enough for the reversed compare or (b) we have a valid FP compare.  */
10620   if (! ix86_comparison_operator (new_op1, VOIDmode))
10621     FAIL;
10622 })
10623
10624 (define_split
10625   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10626         (eq:QI (match_operator 1 "ix86_comparison_operator"
10627                  [(reg FLAGS_REG) (const_int 0)])
10628             (const_int 0)))]
10629   ""
10630   [(set (match_dup 0) (match_dup 1))]
10631 {
10632   rtx new_op1 = copy_rtx (operands[1]);
10633   operands[1] = new_op1;
10634   PUT_MODE (new_op1, QImode);
10635   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10636                                              GET_MODE (XEXP (new_op1, 0))));
10637
10638   /* Make sure that (a) the CCmode we have for the flags is strong
10639      enough for the reversed compare or (b) we have a valid FP compare.  */
10640   if (! ix86_comparison_operator (new_op1, VOIDmode))
10641     FAIL;
10642 })
10643
10644 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10645 ;; subsequent logical operations are used to imitate conditional moves.
10646 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10647 ;; it directly.
10648
10649 (define_insn "setcc_<mode>_sse"
10650   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10651         (match_operator:MODEF 3 "sse_comparison_operator"
10652           [(match_operand:MODEF 1 "register_operand" "0,x")
10653            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10654   "SSE_FLOAT_MODE_P (<MODE>mode)"
10655   "@
10656    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10657    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10658   [(set_attr "isa" "noavx,avx")
10659    (set_attr "type" "ssecmp")
10660    (set_attr "length_immediate" "1")
10661    (set_attr "prefix" "orig,vex")
10662    (set_attr "mode" "<MODE>")])
10663 \f
10664 ;; Basic conditional jump instructions.
10665 ;; We ignore the overflow flag for signed branch instructions.
10666
10667 (define_insn "*jcc_1"
10668   [(set (pc)
10669         (if_then_else (match_operator 1 "ix86_comparison_operator"
10670                                       [(reg FLAGS_REG) (const_int 0)])
10671                       (label_ref (match_operand 0 "" ""))
10672                       (pc)))]
10673   ""
10674   "%+j%C1\t%l0"
10675   [(set_attr "type" "ibr")
10676    (set_attr "modrm" "0")
10677    (set (attr "length")
10678            (if_then_else (and (ge (minus (match_dup 0) (pc))
10679                                   (const_int -126))
10680                               (lt (minus (match_dup 0) (pc))
10681                                   (const_int 128)))
10682              (const_int 2)
10683              (const_int 6)))])
10684
10685 (define_insn "*jcc_2"
10686   [(set (pc)
10687         (if_then_else (match_operator 1 "ix86_comparison_operator"
10688                                       [(reg FLAGS_REG) (const_int 0)])
10689                       (pc)
10690                       (label_ref (match_operand 0 "" ""))))]
10691   ""
10692   "%+j%c1\t%l0"
10693   [(set_attr "type" "ibr")
10694    (set_attr "modrm" "0")
10695    (set (attr "length")
10696            (if_then_else (and (ge (minus (match_dup 0) (pc))
10697                                   (const_int -126))
10698                               (lt (minus (match_dup 0) (pc))
10699                                   (const_int 128)))
10700              (const_int 2)
10701              (const_int 6)))])
10702
10703 ;; In general it is not safe to assume too much about CCmode registers,
10704 ;; so simplify-rtx stops when it sees a second one.  Under certain
10705 ;; conditions this is safe on x86, so help combine not create
10706 ;;
10707 ;;      seta    %al
10708 ;;      testb   %al, %al
10709 ;;      je      Lfoo
10710
10711 (define_split
10712   [(set (pc)
10713         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10714                                       [(reg FLAGS_REG) (const_int 0)])
10715                           (const_int 0))
10716                       (label_ref (match_operand 1 "" ""))
10717                       (pc)))]
10718   ""
10719   [(set (pc)
10720         (if_then_else (match_dup 0)
10721                       (label_ref (match_dup 1))
10722                       (pc)))]
10723   "PUT_MODE (operands[0], VOIDmode);")
10724
10725 (define_split
10726   [(set (pc)
10727         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10728                                       [(reg FLAGS_REG) (const_int 0)])
10729                           (const_int 0))
10730                       (label_ref (match_operand 1 "" ""))
10731                       (pc)))]
10732   ""
10733   [(set (pc)
10734         (if_then_else (match_dup 0)
10735                       (label_ref (match_dup 1))
10736                       (pc)))]
10737 {
10738   rtx new_op0 = copy_rtx (operands[0]);
10739   operands[0] = new_op0;
10740   PUT_MODE (new_op0, VOIDmode);
10741   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10742                                              GET_MODE (XEXP (new_op0, 0))));
10743
10744   /* Make sure that (a) the CCmode we have for the flags is strong
10745      enough for the reversed compare or (b) we have a valid FP compare.  */
10746   if (! ix86_comparison_operator (new_op0, VOIDmode))
10747     FAIL;
10748 })
10749
10750 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10751 ;; pass generates from shift insn with QImode operand.  Actually, the mode
10752 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10753 ;; appropriate modulo of the bit offset value.
10754
10755 (define_insn_and_split "*jcc_bt<mode>"
10756   [(set (pc)
10757         (if_then_else (match_operator 0 "bt_comparison_operator"
10758                         [(zero_extract:SWI48
10759                            (match_operand:SWI48 1 "register_operand" "r")
10760                            (const_int 1)
10761                            (zero_extend:SI
10762                              (match_operand:QI 2 "register_operand" "r")))
10763                          (const_int 0)])
10764                       (label_ref (match_operand 3 "" ""))
10765                       (pc)))
10766    (clobber (reg:CC FLAGS_REG))]
10767   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10768   "#"
10769   "&& 1"
10770   [(set (reg:CCC FLAGS_REG)
10771         (compare:CCC
10772           (zero_extract:SWI48
10773             (match_dup 1)
10774             (const_int 1)
10775             (match_dup 2))
10776           (const_int 0)))
10777    (set (pc)
10778         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10779                       (label_ref (match_dup 3))
10780                       (pc)))]
10781 {
10782   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10783
10784   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10785 })
10786
10787 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10788 ;; also for DImode, this is what combine produces.
10789 (define_insn_and_split "*jcc_bt<mode>_mask"
10790   [(set (pc)
10791         (if_then_else (match_operator 0 "bt_comparison_operator"
10792                         [(zero_extract:SWI48
10793                            (match_operand:SWI48 1 "register_operand" "r")
10794                            (const_int 1)
10795                            (and:SI
10796                              (match_operand:SI 2 "register_operand" "r")
10797                              (match_operand:SI 3 "const_int_operand" "n")))])
10798                       (label_ref (match_operand 4 "" ""))
10799                       (pc)))
10800    (clobber (reg:CC FLAGS_REG))]
10801   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10802    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10803       == GET_MODE_BITSIZE (<MODE>mode)-1"
10804   "#"
10805   "&& 1"
10806   [(set (reg:CCC FLAGS_REG)
10807         (compare:CCC
10808           (zero_extract:SWI48
10809             (match_dup 1)
10810             (const_int 1)
10811             (match_dup 2))
10812           (const_int 0)))
10813    (set (pc)
10814         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10815                       (label_ref (match_dup 4))
10816                       (pc)))]
10817 {
10818   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10819
10820   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10821 })
10822
10823 (define_insn_and_split "*jcc_btsi_1"
10824   [(set (pc)
10825         (if_then_else (match_operator 0 "bt_comparison_operator"
10826                         [(and:SI
10827                            (lshiftrt:SI
10828                              (match_operand:SI 1 "register_operand" "r")
10829                              (match_operand:QI 2 "register_operand" "r"))
10830                            (const_int 1))
10831                          (const_int 0)])
10832                       (label_ref (match_operand 3 "" ""))
10833                       (pc)))
10834    (clobber (reg:CC FLAGS_REG))]
10835   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10836   "#"
10837   "&& 1"
10838   [(set (reg:CCC FLAGS_REG)
10839         (compare:CCC
10840           (zero_extract:SI
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 3))
10848                       (pc)))]
10849 {
10850   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10851
10852   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10853 })
10854
10855 ;; avoid useless masking of bit offset operand
10856 (define_insn_and_split "*jcc_btsi_mask_1"
10857   [(set (pc)
10858         (if_then_else
10859           (match_operator 0 "bt_comparison_operator"
10860             [(and:SI
10861                (lshiftrt:SI
10862                  (match_operand:SI 1 "register_operand" "r")
10863                  (subreg:QI
10864                    (and:SI
10865                      (match_operand:SI 2 "register_operand" "r")
10866                      (match_operand:SI 3 "const_int_operand" "n")) 0))
10867                (const_int 1))
10868              (const_int 0)])
10869           (label_ref (match_operand 4 "" ""))
10870           (pc)))
10871    (clobber (reg:CC FLAGS_REG))]
10872   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10873    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10874   "#"
10875   "&& 1"
10876   [(set (reg:CCC FLAGS_REG)
10877         (compare:CCC
10878           (zero_extract:SI
10879             (match_dup 1)
10880             (const_int 1)
10881             (match_dup 2))
10882           (const_int 0)))
10883    (set (pc)
10884         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10885                       (label_ref (match_dup 4))
10886                       (pc)))]
10887   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10888
10889 ;; Define combination compare-and-branch fp compare instructions to help
10890 ;; combine.
10891
10892 (define_insn "*fp_jcc_1_387"
10893   [(set (pc)
10894         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10895                         [(match_operand 1 "register_operand" "f")
10896                          (match_operand 2 "nonimmediate_operand" "fm")])
10897           (label_ref (match_operand 3 "" ""))
10898           (pc)))
10899    (clobber (reg:CCFP FPSR_REG))
10900    (clobber (reg:CCFP FLAGS_REG))
10901    (clobber (match_scratch:HI 4 "=a"))]
10902   "TARGET_80387
10903    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10904    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10905    && SELECT_CC_MODE (GET_CODE (operands[0]),
10906                       operands[1], operands[2]) == CCFPmode
10907    && !TARGET_CMOVE"
10908   "#")
10909
10910 (define_insn "*fp_jcc_1r_387"
10911   [(set (pc)
10912         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10913                         [(match_operand 1 "register_operand" "f")
10914                          (match_operand 2 "nonimmediate_operand" "fm")])
10915           (pc)
10916           (label_ref (match_operand 3 "" ""))))
10917    (clobber (reg:CCFP FPSR_REG))
10918    (clobber (reg:CCFP FLAGS_REG))
10919    (clobber (match_scratch:HI 4 "=a"))]
10920   "TARGET_80387
10921    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10922    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10923    && SELECT_CC_MODE (GET_CODE (operands[0]),
10924                       operands[1], operands[2]) == CCFPmode
10925    && !TARGET_CMOVE"
10926   "#")
10927
10928 (define_insn "*fp_jcc_2_387"
10929   [(set (pc)
10930         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10931                         [(match_operand 1 "register_operand" "f")
10932                          (match_operand 2 "register_operand" "f")])
10933           (label_ref (match_operand 3 "" ""))
10934           (pc)))
10935    (clobber (reg:CCFP FPSR_REG))
10936    (clobber (reg:CCFP FLAGS_REG))
10937    (clobber (match_scratch:HI 4 "=a"))]
10938   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10939    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10940    && !TARGET_CMOVE"
10941   "#")
10942
10943 (define_insn "*fp_jcc_2r_387"
10944   [(set (pc)
10945         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10946                         [(match_operand 1 "register_operand" "f")
10947                          (match_operand 2 "register_operand" "f")])
10948           (pc)
10949           (label_ref (match_operand 3 "" ""))))
10950    (clobber (reg:CCFP FPSR_REG))
10951    (clobber (reg:CCFP FLAGS_REG))
10952    (clobber (match_scratch:HI 4 "=a"))]
10953   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10954    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10955    && !TARGET_CMOVE"
10956   "#")
10957
10958 (define_insn "*fp_jcc_3_387"
10959   [(set (pc)
10960         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10961                         [(match_operand 1 "register_operand" "f")
10962                          (match_operand 2 "const0_operand" "")])
10963           (label_ref (match_operand 3 "" ""))
10964           (pc)))
10965    (clobber (reg:CCFP FPSR_REG))
10966    (clobber (reg:CCFP FLAGS_REG))
10967    (clobber (match_scratch:HI 4 "=a"))]
10968   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10969    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10970    && SELECT_CC_MODE (GET_CODE (operands[0]),
10971                       operands[1], operands[2]) == CCFPmode
10972    && !TARGET_CMOVE"
10973   "#")
10974
10975 (define_split
10976   [(set (pc)
10977         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10978                         [(match_operand 1 "register_operand" "")
10979                          (match_operand 2 "nonimmediate_operand" "")])
10980           (match_operand 3 "" "")
10981           (match_operand 4 "" "")))
10982    (clobber (reg:CCFP FPSR_REG))
10983    (clobber (reg:CCFP FLAGS_REG))]
10984   "reload_completed"
10985   [(const_int 0)]
10986 {
10987   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10988                         operands[3], operands[4], NULL_RTX, NULL_RTX);
10989   DONE;
10990 })
10991
10992 (define_split
10993   [(set (pc)
10994         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10995                         [(match_operand 1 "register_operand" "")
10996                          (match_operand 2 "general_operand" "")])
10997           (match_operand 3 "" "")
10998           (match_operand 4 "" "")))
10999    (clobber (reg:CCFP FPSR_REG))
11000    (clobber (reg:CCFP FLAGS_REG))
11001    (clobber (match_scratch:HI 5 "=a"))]
11002   "reload_completed"
11003   [(const_int 0)]
11004 {
11005   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11006                         operands[3], operands[4], operands[5], NULL_RTX);
11007   DONE;
11008 })
11009
11010 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11011 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11012 ;; with a precedence over other operators and is always put in the first
11013 ;; place. Swap condition and operands to match ficom instruction.
11014
11015 (define_insn "*fp_jcc_4_<mode>_387"
11016   [(set (pc)
11017         (if_then_else
11018           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11019             [(match_operator 1 "float_operator"
11020               [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11021              (match_operand 3 "register_operand" "f,f")])
11022           (label_ref (match_operand 4 "" ""))
11023           (pc)))
11024    (clobber (reg:CCFP FPSR_REG))
11025    (clobber (reg:CCFP FLAGS_REG))
11026    (clobber (match_scratch:HI 5 "=a,a"))]
11027   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11028    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11029    && GET_MODE (operands[1]) == GET_MODE (operands[3])
11030    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11031    && !TARGET_CMOVE"
11032   "#")
11033
11034 (define_split
11035   [(set (pc)
11036         (if_then_else
11037           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11038             [(match_operator 1 "float_operator"
11039               [(match_operand:SWI24 2 "memory_operand" "")])
11040              (match_operand 3 "register_operand" "")])
11041           (match_operand 4 "" "")
11042           (match_operand 5 "" "")))
11043    (clobber (reg:CCFP FPSR_REG))
11044    (clobber (reg:CCFP FLAGS_REG))
11045    (clobber (match_scratch:HI 6 "=a"))]
11046   "reload_completed"
11047   [(const_int 0)]
11048 {
11049   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11050
11051   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11052                         operands[3], operands[7],
11053                         operands[4], operands[5], operands[6], NULL_RTX);
11054   DONE;
11055 })
11056
11057 ;; %%% Kill this when reload knows how to do it.
11058 (define_split
11059   [(set (pc)
11060         (if_then_else
11061           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11062             [(match_operator 1 "float_operator"
11063               [(match_operand:SWI24 2 "register_operand" "")])
11064              (match_operand 3 "register_operand" "")])
11065           (match_operand 4 "" "")
11066           (match_operand 5 "" "")))
11067    (clobber (reg:CCFP FPSR_REG))
11068    (clobber (reg:CCFP FLAGS_REG))
11069    (clobber (match_scratch:HI 6 "=a"))]
11070   "reload_completed"
11071   [(const_int 0)]
11072 {
11073   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11074   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11075
11076   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11077                         operands[3], operands[7],
11078                         operands[4], operands[5], operands[6], operands[2]);
11079   DONE;
11080 })
11081 \f
11082 ;; Unconditional and other jump instructions
11083
11084 (define_insn "jump"
11085   [(set (pc)
11086         (label_ref (match_operand 0 "" "")))]
11087   ""
11088   "jmp\t%l0"
11089   [(set_attr "type" "ibr")
11090    (set (attr "length")
11091            (if_then_else (and (ge (minus (match_dup 0) (pc))
11092                                   (const_int -126))
11093                               (lt (minus (match_dup 0) (pc))
11094                                   (const_int 128)))
11095              (const_int 2)
11096              (const_int 5)))
11097    (set_attr "modrm" "0")])
11098
11099 (define_expand "indirect_jump"
11100   [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11101
11102 (define_insn "*indirect_jump"
11103   [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11104   ""
11105   "jmp\t%A0"
11106   [(set_attr "type" "ibr")
11107    (set_attr "length_immediate" "0")])
11108
11109 (define_expand "tablejump"
11110   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11111               (use (label_ref (match_operand 1 "" "")))])]
11112   ""
11113 {
11114   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11115      relative.  Convert the relative address to an absolute address.  */
11116   if (flag_pic)
11117     {
11118       rtx op0, op1;
11119       enum rtx_code code;
11120
11121       /* We can't use @GOTOFF for text labels on VxWorks;
11122          see gotoff_operand.  */
11123       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11124         {
11125           code = PLUS;
11126           op0 = operands[0];
11127           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11128         }
11129       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11130         {
11131           code = PLUS;
11132           op0 = operands[0];
11133           op1 = pic_offset_table_rtx;
11134         }
11135       else
11136         {
11137           code = MINUS;
11138           op0 = pic_offset_table_rtx;
11139           op1 = operands[0];
11140         }
11141
11142       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11143                                          OPTAB_DIRECT);
11144     }
11145   else if (TARGET_X32)
11146     operands[0] = convert_memory_address (Pmode, operands[0]);
11147 })
11148
11149 (define_insn "*tablejump_1"
11150   [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11151    (use (label_ref (match_operand 1 "" "")))]
11152   ""
11153   "jmp\t%A0"
11154   [(set_attr "type" "ibr")
11155    (set_attr "length_immediate" "0")])
11156 \f
11157 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11158
11159 (define_peephole2
11160   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11161    (set (match_operand:QI 1 "register_operand" "")
11162         (match_operator:QI 2 "ix86_comparison_operator"
11163           [(reg FLAGS_REG) (const_int 0)]))
11164    (set (match_operand 3 "q_regs_operand" "")
11165         (zero_extend (match_dup 1)))]
11166   "(peep2_reg_dead_p (3, operands[1])
11167     || operands_match_p (operands[1], operands[3]))
11168    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11169   [(set (match_dup 4) (match_dup 0))
11170    (set (strict_low_part (match_dup 5))
11171         (match_dup 2))]
11172 {
11173   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11174   operands[5] = gen_lowpart (QImode, operands[3]);
11175   ix86_expand_clear (operands[3]);
11176 })
11177
11178 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11179
11180 (define_peephole2
11181   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11182    (set (match_operand:QI 1 "register_operand" "")
11183         (match_operator:QI 2 "ix86_comparison_operator"
11184           [(reg FLAGS_REG) (const_int 0)]))
11185    (parallel [(set (match_operand 3 "q_regs_operand" "")
11186                    (zero_extend (match_dup 1)))
11187               (clobber (reg:CC FLAGS_REG))])]
11188   "(peep2_reg_dead_p (3, operands[1])
11189     || operands_match_p (operands[1], operands[3]))
11190    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11191   [(set (match_dup 4) (match_dup 0))
11192    (set (strict_low_part (match_dup 5))
11193         (match_dup 2))]
11194 {
11195   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11196   operands[5] = gen_lowpart (QImode, operands[3]);
11197   ix86_expand_clear (operands[3]);
11198 })
11199 \f
11200 ;; Call instructions.
11201
11202 ;; The predicates normally associated with named expanders are not properly
11203 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11204 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11205
11206 ;; P6 processors will jump to the address after the decrement when %esp
11207 ;; is used as a call operand, so they will execute return address as a code.
11208 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11209
11210 ;; Register constraint for call instruction.
11211 (define_mode_attr c [(SI "l") (DI "r")])
11212
11213 ;; Call subroutine returning no value.
11214
11215 (define_expand "call"
11216   [(call (match_operand:QI 0 "" "")
11217          (match_operand 1 "" ""))
11218    (use (match_operand 2 "" ""))]
11219   ""
11220 {
11221   ix86_expand_call (NULL, operands[0], operands[1],
11222                     operands[2], NULL, false);
11223   DONE;
11224 })
11225
11226 (define_expand "sibcall"
11227   [(call (match_operand:QI 0 "" "")
11228          (match_operand 1 "" ""))
11229    (use (match_operand 2 "" ""))]
11230   ""
11231 {
11232   ix86_expand_call (NULL, operands[0], operands[1],
11233                     operands[2], NULL, true);
11234   DONE;
11235 })
11236
11237 (define_insn_and_split "*call_vzeroupper"
11238   [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11239          (match_operand 1 "" ""))
11240    (unspec [(match_operand 2 "const_int_operand" "")]
11241            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11242   "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11243   "#"
11244   "&& reload_completed"
11245   [(const_int 0)]
11246   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11247   [(set_attr "type" "call")])
11248
11249 (define_insn "*call"
11250   [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11251          (match_operand 1 "" ""))]
11252   "!SIBLING_CALL_P (insn)"
11253   "* return ix86_output_call_insn (insn, operands[0]);"
11254   [(set_attr "type" "call")])
11255
11256 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11257   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11258          (match_operand 1 "" ""))
11259    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11260    (clobber (reg:TI XMM6_REG))
11261    (clobber (reg:TI XMM7_REG))
11262    (clobber (reg:TI XMM8_REG))
11263    (clobber (reg:TI XMM9_REG))
11264    (clobber (reg:TI XMM10_REG))
11265    (clobber (reg:TI XMM11_REG))
11266    (clobber (reg:TI XMM12_REG))
11267    (clobber (reg:TI XMM13_REG))
11268    (clobber (reg:TI XMM14_REG))
11269    (clobber (reg:TI XMM15_REG))
11270    (clobber (reg:DI SI_REG))
11271    (clobber (reg:DI DI_REG))
11272    (unspec [(match_operand 2 "const_int_operand" "")]
11273            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11274   "TARGET_VZEROUPPER && TARGET_64BIT && !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_rex64_ms_sysv"
11282   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11283          (match_operand 1 "" ""))
11284    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11285    (clobber (reg:TI XMM6_REG))
11286    (clobber (reg:TI XMM7_REG))
11287    (clobber (reg:TI XMM8_REG))
11288    (clobber (reg:TI XMM9_REG))
11289    (clobber (reg:TI XMM10_REG))
11290    (clobber (reg:TI XMM11_REG))
11291    (clobber (reg:TI XMM12_REG))
11292    (clobber (reg:TI XMM13_REG))
11293    (clobber (reg:TI XMM14_REG))
11294    (clobber (reg:TI XMM15_REG))
11295    (clobber (reg:DI SI_REG))
11296    (clobber (reg:DI DI_REG))]
11297   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11298   "* return ix86_output_call_insn (insn, operands[0]);"
11299   [(set_attr "type" "call")])
11300
11301 (define_insn_and_split "*sibcall_vzeroupper"
11302   [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11303          (match_operand 1 "" ""))
11304    (unspec [(match_operand 2 "const_int_operand" "")]
11305            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11306   "TARGET_VZEROUPPER && 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 "*sibcall"
11314   [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11315          (match_operand 1 "" ""))]
11316   "SIBLING_CALL_P (insn)"
11317   "* return ix86_output_call_insn (insn, operands[0]);"
11318   [(set_attr "type" "call")])
11319
11320 (define_expand "call_pop"
11321   [(parallel [(call (match_operand:QI 0 "" "")
11322                     (match_operand:SI 1 "" ""))
11323               (set (reg:SI SP_REG)
11324                    (plus:SI (reg:SI SP_REG)
11325                             (match_operand:SI 3 "" "")))])]
11326   "!TARGET_64BIT"
11327 {
11328   ix86_expand_call (NULL, operands[0], operands[1],
11329                     operands[2], operands[3], false);
11330   DONE;
11331 })
11332
11333 (define_insn_and_split "*call_pop_vzeroupper"
11334   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11335          (match_operand:SI 1 "" ""))
11336    (set (reg:SI SP_REG)
11337         (plus:SI (reg:SI SP_REG)
11338                  (match_operand:SI 2 "immediate_operand" "i")))
11339    (unspec [(match_operand 3 "const_int_operand" "")]
11340            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11341   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11342   "#"
11343   "&& reload_completed"
11344   [(const_int 0)]
11345   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11346   [(set_attr "type" "call")])
11347
11348 (define_insn "*call_pop"
11349   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11350          (match_operand 1 "" ""))
11351    (set (reg:SI SP_REG)
11352         (plus:SI (reg:SI SP_REG)
11353                  (match_operand:SI 2 "immediate_operand" "i")))]
11354   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11355   "* return ix86_output_call_insn (insn, operands[0]);"
11356   [(set_attr "type" "call")])
11357
11358 (define_insn_and_split "*sibcall_pop_vzeroupper"
11359   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11360          (match_operand 1 "" ""))
11361    (set (reg:SI SP_REG)
11362         (plus:SI (reg:SI SP_REG)
11363                  (match_operand:SI 2 "immediate_operand" "i")))
11364    (unspec [(match_operand 3 "const_int_operand" "")]
11365            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11366   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11367   "#"
11368   "&& reload_completed"
11369   [(const_int 0)]
11370   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11371   [(set_attr "type" "call")])
11372
11373 (define_insn "*sibcall_pop"
11374   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11375          (match_operand 1 "" ""))
11376    (set (reg:SI SP_REG)
11377         (plus:SI (reg:SI SP_REG)
11378                  (match_operand:SI 2 "immediate_operand" "i")))]
11379   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11380   "* return ix86_output_call_insn (insn, operands[0]);"
11381   [(set_attr "type" "call")])
11382
11383 ;; Call subroutine, returning value in operand 0
11384
11385 (define_expand "call_value"
11386   [(set (match_operand 0 "" "")
11387         (call (match_operand:QI 1 "" "")
11388               (match_operand 2 "" "")))
11389    (use (match_operand 3 "" ""))]
11390   ""
11391 {
11392   ix86_expand_call (operands[0], operands[1], operands[2],
11393                     operands[3], NULL, false);
11394   DONE;
11395 })
11396
11397 (define_expand "sibcall_value"
11398   [(set (match_operand 0 "" "")
11399         (call (match_operand:QI 1 "" "")
11400               (match_operand 2 "" "")))
11401    (use (match_operand 3 "" ""))]
11402   ""
11403 {
11404   ix86_expand_call (operands[0], operands[1], operands[2],
11405                     operands[3], NULL, true);
11406   DONE;
11407 })
11408
11409 (define_insn_and_split "*call_value_vzeroupper"
11410   [(set (match_operand 0 "" "")
11411         (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11412               (match_operand 2 "" "")))
11413    (unspec [(match_operand 3 "const_int_operand" "")]
11414            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11415   "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11416   "#"
11417   "&& reload_completed"
11418   [(const_int 0)]
11419   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11420   [(set_attr "type" "callv")])
11421
11422 (define_insn "*call_value"
11423   [(set (match_operand 0 "" "")
11424         (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11425               (match_operand 2 "" "")))]
11426   "!SIBLING_CALL_P (insn)"
11427   "* return ix86_output_call_insn (insn, operands[1]);"
11428   [(set_attr "type" "callv")])
11429
11430 (define_insn_and_split "*sibcall_value_vzeroupper"
11431   [(set (match_operand 0 "" "")
11432         (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11433               (match_operand 2 "" "")))
11434    (unspec [(match_operand 3 "const_int_operand" "")]
11435            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11436   "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11437   "#"
11438   "&& reload_completed"
11439   [(const_int 0)]
11440   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11441   [(set_attr "type" "callv")])
11442
11443 (define_insn "*sibcall_value"
11444   [(set (match_operand 0 "" "")
11445         (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11446               (match_operand 2 "" "")))]
11447   "SIBLING_CALL_P (insn)"
11448   "* return ix86_output_call_insn (insn, operands[1]);"
11449   [(set_attr "type" "callv")])
11450
11451 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11452   [(set (match_operand 0 "" "")
11453         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11454               (match_operand 2 "" "")))
11455    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11456    (clobber (reg:TI XMM6_REG))
11457    (clobber (reg:TI XMM7_REG))
11458    (clobber (reg:TI XMM8_REG))
11459    (clobber (reg:TI XMM9_REG))
11460    (clobber (reg:TI XMM10_REG))
11461    (clobber (reg:TI XMM11_REG))
11462    (clobber (reg:TI XMM12_REG))
11463    (clobber (reg:TI XMM13_REG))
11464    (clobber (reg:TI XMM14_REG))
11465    (clobber (reg:TI XMM15_REG))
11466    (clobber (reg:DI SI_REG))
11467    (clobber (reg:DI DI_REG))
11468    (unspec [(match_operand 3 "const_int_operand" "")]
11469            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11470   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11471   "#"
11472   "&& reload_completed"
11473   [(const_int 0)]
11474   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11475   [(set_attr "type" "callv")])
11476
11477 (define_insn "*call_value_rex64_ms_sysv"
11478   [(set (match_operand 0 "" "")
11479         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11480               (match_operand 2 "" "")))
11481    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11482    (clobber (reg:TI XMM6_REG))
11483    (clobber (reg:TI XMM7_REG))
11484    (clobber (reg:TI XMM8_REG))
11485    (clobber (reg:TI XMM9_REG))
11486    (clobber (reg:TI XMM10_REG))
11487    (clobber (reg:TI XMM11_REG))
11488    (clobber (reg:TI XMM12_REG))
11489    (clobber (reg:TI XMM13_REG))
11490    (clobber (reg:TI XMM14_REG))
11491    (clobber (reg:TI XMM15_REG))
11492    (clobber (reg:DI SI_REG))
11493    (clobber (reg:DI DI_REG))]
11494   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11495   "* return ix86_output_call_insn (insn, operands[1]);"
11496   [(set_attr "type" "callv")])
11497
11498 (define_expand "call_value_pop"
11499   [(parallel [(set (match_operand 0 "" "")
11500                    (call (match_operand:QI 1 "" "")
11501                          (match_operand:SI 2 "" "")))
11502               (set (reg:SI SP_REG)
11503                    (plus:SI (reg:SI SP_REG)
11504                             (match_operand:SI 4 "" "")))])]
11505   "!TARGET_64BIT"
11506 {
11507   ix86_expand_call (operands[0], operands[1], operands[2],
11508                     operands[3], operands[4], false);
11509   DONE;
11510 })
11511
11512 (define_insn_and_split "*call_value_pop_vzeroupper"
11513   [(set (match_operand 0 "" "")
11514         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11515               (match_operand 2 "" "")))
11516    (set (reg:SI SP_REG)
11517         (plus:SI (reg:SI SP_REG)
11518                  (match_operand:SI 3 "immediate_operand" "i")))
11519    (unspec [(match_operand 4 "const_int_operand" "")]
11520            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11521   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11522   "#"
11523   "&& reload_completed"
11524   [(const_int 0)]
11525   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11526   [(set_attr "type" "callv")])
11527
11528 (define_insn "*call_value_pop"
11529   [(set (match_operand 0 "" "")
11530         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11531               (match_operand 2 "" "")))
11532    (set (reg:SI SP_REG)
11533         (plus:SI (reg:SI SP_REG)
11534                  (match_operand:SI 3 "immediate_operand" "i")))]
11535   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11536   "* return ix86_output_call_insn (insn, operands[1]);"
11537   [(set_attr "type" "callv")])
11538
11539 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11540   [(set (match_operand 0 "" "")
11541         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11542               (match_operand 2 "" "")))
11543    (set (reg:SI SP_REG)
11544         (plus:SI (reg:SI SP_REG)
11545                  (match_operand:SI 3 "immediate_operand" "i")))
11546    (unspec [(match_operand 4 "const_int_operand" "")]
11547            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11548   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11549   "#"
11550   "&& reload_completed"
11551   [(const_int 0)]
11552   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11553   [(set_attr "type" "callv")])
11554
11555 (define_insn "*sibcall_value_pop"
11556   [(set (match_operand 0 "" "")
11557         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11558               (match_operand 2 "" "")))
11559    (set (reg:SI SP_REG)
11560         (plus:SI (reg:SI SP_REG)
11561                  (match_operand:SI 3 "immediate_operand" "i")))]
11562   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11563   "* return ix86_output_call_insn (insn, operands[1]);"
11564   [(set_attr "type" "callv")])
11565
11566 ;; Call subroutine returning any type.
11567
11568 (define_expand "untyped_call"
11569   [(parallel [(call (match_operand 0 "" "")
11570                     (const_int 0))
11571               (match_operand 1 "" "")
11572               (match_operand 2 "" "")])]
11573   ""
11574 {
11575   int i;
11576
11577   /* In order to give reg-stack an easier job in validating two
11578      coprocessor registers as containing a possible return value,
11579      simply pretend the untyped call returns a complex long double
11580      value. 
11581
11582      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11583      and should have the default ABI.  */
11584
11585   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11586                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11587                     operands[0], const0_rtx,
11588                     GEN_INT ((TARGET_64BIT
11589                               ? (ix86_abi == SYSV_ABI
11590                                  ? X86_64_SSE_REGPARM_MAX
11591                                  : X86_64_MS_SSE_REGPARM_MAX)
11592                               : X86_32_SSE_REGPARM_MAX)
11593                              - 1),
11594                     NULL, false);
11595
11596   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11597     {
11598       rtx set = XVECEXP (operands[2], 0, i);
11599       emit_move_insn (SET_DEST (set), SET_SRC (set));
11600     }
11601
11602   /* The optimizer does not know that the call sets the function value
11603      registers we stored in the result block.  We avoid problems by
11604      claiming that all hard registers are used and clobbered at this
11605      point.  */
11606   emit_insn (gen_blockage ());
11607
11608   DONE;
11609 })
11610 \f
11611 ;; Prologue and epilogue instructions
11612
11613 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11614 ;; all of memory.  This blocks insns from being moved across this point.
11615
11616 (define_insn "blockage"
11617   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11618   ""
11619   ""
11620   [(set_attr "length" "0")])
11621
11622 ;; Do not schedule instructions accessing memory across this point.
11623
11624 (define_expand "memory_blockage"
11625   [(set (match_dup 0)
11626         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11627   ""
11628 {
11629   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11630   MEM_VOLATILE_P (operands[0]) = 1;
11631 })
11632
11633 (define_insn "*memory_blockage"
11634   [(set (match_operand:BLK 0 "" "")
11635         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11636   ""
11637   ""
11638   [(set_attr "length" "0")])
11639
11640 ;; As USE insns aren't meaningful after reload, this is used instead
11641 ;; to prevent deleting instructions setting registers for PIC code
11642 (define_insn "prologue_use"
11643   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11644   ""
11645   ""
11646   [(set_attr "length" "0")])
11647
11648 ;; Insn emitted into the body of a function to return from a function.
11649 ;; This is only done if the function's epilogue is known to be simple.
11650 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11651
11652 (define_expand "return"
11653   [(simple_return)]
11654   "ix86_can_use_return_insn_p ()"
11655 {
11656   ix86_maybe_emit_epilogue_vzeroupper ();
11657   if (crtl->args.pops_args)
11658     {
11659       rtx popc = GEN_INT (crtl->args.pops_args);
11660       emit_jump_insn (gen_simple_return_pop_internal (popc));
11661       DONE;
11662     }
11663 })
11664
11665 ;; We need to disable this for TARGET_SEH, as otherwise
11666 ;; shrink-wrapped prologue gets enabled too.  This might exceed
11667 ;; the maximum size of prologue in unwind information.
11668
11669 (define_expand "simple_return"
11670   [(simple_return)]
11671   "!TARGET_SEH"
11672 {
11673   ix86_maybe_emit_epilogue_vzeroupper ();
11674   if (crtl->args.pops_args)
11675     {
11676       rtx popc = GEN_INT (crtl->args.pops_args);
11677       emit_jump_insn (gen_simple_return_pop_internal (popc));
11678       DONE;
11679     }
11680 })
11681
11682 (define_insn "simple_return_internal"
11683   [(simple_return)]
11684   "reload_completed"
11685   "ret"
11686   [(set_attr "length" "1")
11687    (set_attr "atom_unit" "jeu")
11688    (set_attr "length_immediate" "0")
11689    (set_attr "modrm" "0")])
11690
11691 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11692 ;; instruction Athlon and K8 have.
11693
11694 (define_insn "simple_return_internal_long"
11695   [(simple_return)
11696    (unspec [(const_int 0)] UNSPEC_REP)]
11697   "reload_completed"
11698   "rep\;ret"
11699   [(set_attr "length" "2")
11700    (set_attr "atom_unit" "jeu")
11701    (set_attr "length_immediate" "0")
11702    (set_attr "prefix_rep" "1")
11703    (set_attr "modrm" "0")])
11704
11705 (define_insn "simple_return_pop_internal"
11706   [(simple_return)
11707    (use (match_operand:SI 0 "const_int_operand" ""))]
11708   "reload_completed"
11709   "ret\t%0"
11710   [(set_attr "length" "3")
11711    (set_attr "atom_unit" "jeu")
11712    (set_attr "length_immediate" "2")
11713    (set_attr "modrm" "0")])
11714
11715 (define_insn "simple_return_indirect_internal"
11716   [(simple_return)
11717    (use (match_operand:SI 0 "register_operand" "r"))]
11718   "reload_completed"
11719   "jmp\t%A0"
11720   [(set_attr "type" "ibr")
11721    (set_attr "length_immediate" "0")])
11722
11723 (define_insn "nop"
11724   [(const_int 0)]
11725   ""
11726   "nop"
11727   [(set_attr "length" "1")
11728    (set_attr "length_immediate" "0")
11729    (set_attr "modrm" "0")])
11730
11731 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
11732 (define_insn "nops"
11733   [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11734                     UNSPECV_NOPS)]
11735   "reload_completed"
11736 {
11737   int num = INTVAL (operands[0]);
11738
11739   gcc_assert (num >= 1 && num <= 8);
11740
11741   while (num--)
11742     fputs ("\tnop\n", asm_out_file);
11743
11744   return "";
11745 }
11746   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11747    (set_attr "length_immediate" "0")
11748    (set_attr "modrm" "0")])
11749
11750 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11751 ;; branch prediction penalty for the third jump in a 16-byte
11752 ;; block on K8.
11753
11754 (define_insn "pad"
11755   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11756   ""
11757 {
11758 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11759   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11760 #else
11761   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11762      The align insn is used to avoid 3 jump instructions in the row to improve
11763      branch prediction and the benefits hardly outweigh the cost of extra 8
11764      nops on the average inserted by full alignment pseudo operation.  */
11765 #endif
11766   return "";
11767 }
11768   [(set_attr "length" "16")])
11769
11770 (define_expand "prologue"
11771   [(const_int 0)]
11772   ""
11773   "ix86_expand_prologue (); DONE;")
11774
11775 (define_insn "set_got"
11776   [(set (match_operand:SI 0 "register_operand" "=r")
11777         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11778    (clobber (reg:CC FLAGS_REG))]
11779   "!TARGET_64BIT"
11780   "* return output_set_got (operands[0], NULL_RTX);"
11781   [(set_attr "type" "multi")
11782    (set_attr "length" "12")])
11783
11784 (define_insn "set_got_labelled"
11785   [(set (match_operand:SI 0 "register_operand" "=r")
11786         (unspec:SI [(label_ref (match_operand 1 "" ""))]
11787          UNSPEC_SET_GOT))
11788    (clobber (reg:CC FLAGS_REG))]
11789   "!TARGET_64BIT"
11790   "* return output_set_got (operands[0], operands[1]);"
11791   [(set_attr "type" "multi")
11792    (set_attr "length" "12")])
11793
11794 (define_insn "set_got_rex64"
11795   [(set (match_operand:DI 0 "register_operand" "=r")
11796         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11797   "TARGET_64BIT"
11798   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11799   [(set_attr "type" "lea")
11800    (set_attr "length_address" "4")
11801    (set_attr "mode" "DI")])
11802
11803 (define_insn "set_rip_rex64"
11804   [(set (match_operand:DI 0 "register_operand" "=r")
11805         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11806   "TARGET_64BIT"
11807   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11808   [(set_attr "type" "lea")
11809    (set_attr "length_address" "4")
11810    (set_attr "mode" "DI")])
11811
11812 (define_insn "set_got_offset_rex64"
11813   [(set (match_operand:DI 0 "register_operand" "=r")
11814         (unspec:DI
11815           [(label_ref (match_operand 1 "" ""))]
11816           UNSPEC_SET_GOT_OFFSET))]
11817   "TARGET_LP64"
11818   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11819   [(set_attr "type" "imov")
11820    (set_attr "length_immediate" "0")
11821    (set_attr "length_address" "8")
11822    (set_attr "mode" "DI")])
11823
11824 (define_expand "epilogue"
11825   [(const_int 0)]
11826   ""
11827   "ix86_expand_epilogue (1); DONE;")
11828
11829 (define_expand "sibcall_epilogue"
11830   [(const_int 0)]
11831   ""
11832   "ix86_expand_epilogue (0); DONE;")
11833
11834 (define_expand "eh_return"
11835   [(use (match_operand 0 "register_operand" ""))]
11836   ""
11837 {
11838   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11839
11840   /* Tricky bit: we write the address of the handler to which we will
11841      be returning into someone else's stack frame, one word below the
11842      stack address we wish to restore.  */
11843   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11844   tmp = plus_constant (tmp, -UNITS_PER_WORD);
11845   tmp = gen_rtx_MEM (Pmode, tmp);
11846   emit_move_insn (tmp, ra);
11847
11848   emit_jump_insn (gen_eh_return_internal ());
11849   emit_barrier ();
11850   DONE;
11851 })
11852
11853 (define_insn_and_split "eh_return_internal"
11854   [(eh_return)]
11855   ""
11856   "#"
11857   "epilogue_completed"
11858   [(const_int 0)]
11859   "ix86_expand_epilogue (2); DONE;")
11860
11861 (define_insn "leave"
11862   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11863    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11864    (clobber (mem:BLK (scratch)))]
11865   "!TARGET_64BIT"
11866   "leave"
11867   [(set_attr "type" "leave")])
11868
11869 (define_insn "leave_rex64"
11870   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11871    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11872    (clobber (mem:BLK (scratch)))]
11873   "TARGET_64BIT"
11874   "leave"
11875   [(set_attr "type" "leave")])
11876 \f
11877 ;; Handle -fsplit-stack.
11878
11879 (define_expand "split_stack_prologue"
11880   [(const_int 0)]
11881   ""
11882 {
11883   ix86_expand_split_stack_prologue ();
11884   DONE;
11885 })
11886
11887 ;; In order to support the call/return predictor, we use a return
11888 ;; instruction which the middle-end doesn't see.
11889 (define_insn "split_stack_return"
11890   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11891                      UNSPECV_SPLIT_STACK_RETURN)]
11892   ""
11893 {
11894   if (operands[0] == const0_rtx)
11895     return "ret";
11896   else
11897     return "ret\t%0";
11898 }
11899   [(set_attr "atom_unit" "jeu")
11900    (set_attr "modrm" "0")
11901    (set (attr "length")
11902         (if_then_else (match_operand:SI 0 "const0_operand" "")
11903                       (const_int 1)
11904                       (const_int 3)))
11905    (set (attr "length_immediate")
11906         (if_then_else (match_operand:SI 0 "const0_operand" "")
11907                       (const_int 0)
11908                       (const_int 2)))])
11909
11910 ;; If there are operand 0 bytes available on the stack, jump to
11911 ;; operand 1.
11912
11913 (define_expand "split_stack_space_check"
11914   [(set (pc) (if_then_else
11915               (ltu (minus (reg SP_REG)
11916                           (match_operand 0 "register_operand" ""))
11917                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11918               (label_ref (match_operand 1 "" ""))
11919               (pc)))]
11920   ""
11921 {
11922   rtx reg, size, limit;
11923
11924   reg = gen_reg_rtx (Pmode);
11925   size = force_reg (Pmode, operands[0]);
11926   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11927   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11928                           UNSPEC_STACK_CHECK);
11929   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11930   ix86_expand_branch (GEU, reg, limit, operands[1]);
11931
11932   DONE;
11933 })
11934 \f
11935 ;; Bit manipulation instructions.
11936
11937 (define_expand "ffs<mode>2"
11938   [(set (match_dup 2) (const_int -1))
11939    (parallel [(set (reg:CCZ FLAGS_REG)
11940                    (compare:CCZ
11941                      (match_operand:SWI48 1 "nonimmediate_operand" "")
11942                      (const_int 0)))
11943               (set (match_operand:SWI48 0 "register_operand" "")
11944                    (ctz:SWI48 (match_dup 1)))])
11945    (set (match_dup 0) (if_then_else:SWI48
11946                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
11947                         (match_dup 2)
11948                         (match_dup 0)))
11949    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11950               (clobber (reg:CC FLAGS_REG))])]
11951   ""
11952 {
11953   if (<MODE>mode == SImode && !TARGET_CMOVE)
11954     {
11955       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11956       DONE;
11957     }
11958   operands[2] = gen_reg_rtx (<MODE>mode);
11959 })
11960
11961 (define_insn_and_split "ffssi2_no_cmove"
11962   [(set (match_operand:SI 0 "register_operand" "=r")
11963         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11964    (clobber (match_scratch:SI 2 "=&q"))
11965    (clobber (reg:CC FLAGS_REG))]
11966   "!TARGET_CMOVE"
11967   "#"
11968   "&& reload_completed"
11969   [(parallel [(set (reg:CCZ FLAGS_REG)
11970                    (compare:CCZ (match_dup 1) (const_int 0)))
11971               (set (match_dup 0) (ctz:SI (match_dup 1)))])
11972    (set (strict_low_part (match_dup 3))
11973         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11974    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11975               (clobber (reg:CC FLAGS_REG))])
11976    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11977               (clobber (reg:CC FLAGS_REG))])
11978    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11979               (clobber (reg:CC FLAGS_REG))])]
11980 {
11981   operands[3] = gen_lowpart (QImode, operands[2]);
11982   ix86_expand_clear (operands[2]);
11983 })
11984
11985 (define_insn "*ffs<mode>_1"
11986   [(set (reg:CCZ FLAGS_REG)
11987         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11988                      (const_int 0)))
11989    (set (match_operand:SWI48 0 "register_operand" "=r")
11990         (ctz:SWI48 (match_dup 1)))]
11991   ""
11992   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11993   [(set_attr "type" "alu1")
11994    (set_attr "prefix_0f" "1")
11995    (set_attr "mode" "<MODE>")])
11996
11997 (define_insn "ctz<mode>2"
11998   [(set (match_operand:SWI248 0 "register_operand" "=r")
11999         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12000    (clobber (reg:CC FLAGS_REG))]
12001   ""
12002 {
12003   if (TARGET_BMI)
12004     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12005   else
12006     return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12007 }
12008   [(set_attr "type" "alu1")
12009    (set_attr "prefix_0f" "1")
12010    (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12011    (set_attr "mode" "<MODE>")])
12012
12013 (define_expand "clz<mode>2"
12014   [(parallel
12015      [(set (match_operand:SWI248 0 "register_operand" "")
12016            (minus:SWI248
12017              (match_dup 2)
12018              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12019       (clobber (reg:CC FLAGS_REG))])
12020    (parallel
12021      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12022       (clobber (reg:CC FLAGS_REG))])]
12023   ""
12024 {
12025   if (TARGET_LZCNT)
12026     {
12027       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12028       DONE;
12029     }
12030   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12031 })
12032
12033 (define_insn "clz<mode>2_lzcnt"
12034   [(set (match_operand:SWI248 0 "register_operand" "=r")
12035         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12036    (clobber (reg:CC FLAGS_REG))]
12037   "TARGET_LZCNT"
12038   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12039   [(set_attr "prefix_rep" "1")
12040    (set_attr "type" "bitmanip")
12041    (set_attr "mode" "<MODE>")])
12042
12043 ;; BMI instructions.
12044 (define_insn "*bmi_andn_<mode>"
12045   [(set (match_operand:SWI48 0 "register_operand" "=r")
12046         (and:SWI48
12047           (not:SWI48
12048             (match_operand:SWI48 1 "register_operand" "r"))
12049             (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12050    (clobber (reg:CC FLAGS_REG))]
12051   "TARGET_BMI"
12052   "andn\t{%2, %1, %0|%0, %1, %2}"
12053   [(set_attr "type" "bitmanip")
12054    (set_attr "mode" "<MODE>")])
12055
12056 (define_insn "bmi_bextr_<mode>"
12057   [(set (match_operand:SWI48 0 "register_operand" "=r")
12058         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12059                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12060                        UNSPEC_BEXTR))
12061    (clobber (reg:CC FLAGS_REG))]
12062   "TARGET_BMI"
12063   "bextr\t{%2, %1, %0|%0, %1, %2}"
12064   [(set_attr "type" "bitmanip")
12065    (set_attr "mode" "<MODE>")])
12066
12067 (define_insn "*bmi_blsi_<mode>"
12068   [(set (match_operand:SWI48 0 "register_operand" "=r")
12069         (and:SWI48
12070           (neg:SWI48
12071             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12072           (match_dup 1)))
12073    (clobber (reg:CC FLAGS_REG))]
12074   "TARGET_BMI"
12075   "blsi\t{%1, %0|%0, %1}"
12076   [(set_attr "type" "bitmanip")
12077    (set_attr "mode" "<MODE>")])
12078
12079 (define_insn "*bmi_blsmsk_<mode>"
12080   [(set (match_operand:SWI48 0 "register_operand" "=r")
12081         (xor:SWI48
12082           (plus:SWI48
12083             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12084             (const_int -1))
12085           (match_dup 1)))
12086    (clobber (reg:CC FLAGS_REG))]
12087   "TARGET_BMI"
12088   "blsmsk\t{%1, %0|%0, %1}"
12089   [(set_attr "type" "bitmanip")
12090    (set_attr "mode" "<MODE>")])
12091
12092 (define_insn "*bmi_blsr_<mode>"
12093   [(set (match_operand:SWI48 0 "register_operand" "=r")
12094         (and:SWI48
12095           (plus:SWI48
12096             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12097             (const_int -1))
12098           (match_dup 1)))
12099    (clobber (reg:CC FLAGS_REG))]
12100    "TARGET_BMI"
12101    "blsr\t{%1, %0|%0, %1}"
12102   [(set_attr "type" "bitmanip")
12103    (set_attr "mode" "<MODE>")])
12104
12105 ;; BMI2 instructions.
12106 (define_insn "bmi2_bzhi_<mode>3"
12107   [(set (match_operand:SWI48 0 "register_operand" "=r")
12108         (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12109                    (lshiftrt:SWI48 (const_int -1)
12110                                    (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12111    (clobber (reg:CC FLAGS_REG))]
12112   "TARGET_BMI2"
12113   "bzhi\t{%2, %1, %0|%0, %1, %2}"
12114   [(set_attr "type" "bitmanip")
12115    (set_attr "prefix" "vex")
12116    (set_attr "mode" "<MODE>")])
12117
12118 (define_insn "bmi2_pdep_<mode>3"
12119   [(set (match_operand:SWI48 0 "register_operand" "=r")
12120         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12121                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12122                        UNSPEC_PDEP))]
12123   "TARGET_BMI2"
12124   "pdep\t{%2, %1, %0|%0, %1, %2}"
12125   [(set_attr "type" "bitmanip")
12126    (set_attr "prefix" "vex")
12127    (set_attr "mode" "<MODE>")])
12128
12129 (define_insn "bmi2_pext_<mode>3"
12130   [(set (match_operand:SWI48 0 "register_operand" "=r")
12131         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12132                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12133                        UNSPEC_PEXT))]
12134   "TARGET_BMI2"
12135   "pext\t{%2, %1, %0|%0, %1, %2}"
12136   [(set_attr "type" "bitmanip")
12137    (set_attr "prefix" "vex")
12138    (set_attr "mode" "<MODE>")])
12139
12140 ;; TBM instructions.
12141 (define_insn "tbm_bextri_<mode>"
12142   [(set (match_operand:SWI48 0 "register_operand" "=r")
12143         (zero_extract:SWI48
12144           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12145           (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12146           (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12147    (clobber (reg:CC FLAGS_REG))]
12148    "TARGET_TBM"
12149 {
12150   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12151   return "bextr\t{%2, %1, %0|%0, %1, %2}";
12152 }
12153   [(set_attr "type" "bitmanip")
12154    (set_attr "mode" "<MODE>")])
12155
12156 (define_insn "*tbm_blcfill_<mode>"
12157   [(set (match_operand:SWI48 0 "register_operand" "=r")
12158         (and:SWI48
12159           (plus:SWI48
12160             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12161             (const_int 1))
12162           (match_dup 1)))
12163    (clobber (reg:CC FLAGS_REG))]
12164    "TARGET_TBM"
12165    "blcfill\t{%1, %0|%0, %1}"
12166   [(set_attr "type" "bitmanip")
12167    (set_attr "mode" "<MODE>")])
12168
12169 (define_insn "*tbm_blci_<mode>"
12170   [(set (match_operand:SWI48 0 "register_operand" "=r")
12171         (ior:SWI48
12172           (not:SWI48
12173             (plus:SWI48
12174               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12175               (const_int 1)))
12176           (match_dup 1)))
12177    (clobber (reg:CC FLAGS_REG))]
12178    "TARGET_TBM"
12179    "blci\t{%1, %0|%0, %1}"
12180   [(set_attr "type" "bitmanip")
12181    (set_attr "mode" "<MODE>")])
12182
12183 (define_insn "*tbm_blcic_<mode>"
12184   [(set (match_operand:SWI48 0 "register_operand" "=r")
12185         (and:SWI48
12186           (plus:SWI48
12187             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12188             (const_int 1))
12189           (not:SWI48
12190             (match_dup 1))))
12191    (clobber (reg:CC FLAGS_REG))]
12192    "TARGET_TBM"
12193    "blcic\t{%1, %0|%0, %1}"
12194   [(set_attr "type" "bitmanip")
12195    (set_attr "mode" "<MODE>")])
12196
12197 (define_insn "*tbm_blcmsk_<mode>"
12198   [(set (match_operand:SWI48 0 "register_operand" "=r")
12199         (xor:SWI48
12200           (plus:SWI48
12201             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12202             (const_int 1))
12203           (match_dup 1)))
12204    (clobber (reg:CC FLAGS_REG))]
12205    "TARGET_TBM"
12206    "blcmsk\t{%1, %0|%0, %1}"
12207   [(set_attr "type" "bitmanip")
12208    (set_attr "mode" "<MODE>")])
12209
12210 (define_insn "*tbm_blcs_<mode>"
12211   [(set (match_operand:SWI48 0 "register_operand" "=r")
12212         (ior:SWI48
12213           (plus:SWI48
12214             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12215             (const_int 1))
12216           (match_dup 1)))
12217    (clobber (reg:CC FLAGS_REG))]
12218    "TARGET_TBM"
12219    "blcs\t{%1, %0|%0, %1}"
12220   [(set_attr "type" "bitmanip")
12221    (set_attr "mode" "<MODE>")])
12222
12223 (define_insn "*tbm_blsfill_<mode>"
12224   [(set (match_operand:SWI48 0 "register_operand" "=r")
12225         (ior:SWI48
12226           (plus:SWI48
12227             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12228             (const_int -1))
12229           (match_dup 1)))
12230    (clobber (reg:CC FLAGS_REG))]
12231    "TARGET_TBM"
12232    "blsfill\t{%1, %0|%0, %1}"
12233   [(set_attr "type" "bitmanip")
12234    (set_attr "mode" "<MODE>")])
12235
12236 (define_insn "*tbm_blsic_<mode>"
12237   [(set (match_operand:SWI48 0 "register_operand" "=r")
12238         (ior:SWI48
12239           (plus:SWI48
12240             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12241             (const_int -1))
12242           (not:SWI48
12243             (match_dup 1))))
12244    (clobber (reg:CC FLAGS_REG))]
12245    "TARGET_TBM"
12246    "blsic\t{%1, %0|%0, %1}"
12247   [(set_attr "type" "bitmanip")
12248    (set_attr "mode" "<MODE>")])
12249
12250 (define_insn "*tbm_t1mskc_<mode>"
12251   [(set (match_operand:SWI48 0 "register_operand" "=r")
12252         (ior:SWI48
12253           (plus:SWI48
12254             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12255             (const_int 1))
12256           (not:SWI48
12257             (match_dup 1))))
12258    (clobber (reg:CC FLAGS_REG))]
12259    "TARGET_TBM"
12260    "t1mskc\t{%1, %0|%0, %1}"
12261   [(set_attr "type" "bitmanip")
12262    (set_attr "mode" "<MODE>")])
12263
12264 (define_insn "*tbm_tzmsk_<mode>"
12265   [(set (match_operand:SWI48 0 "register_operand" "=r")
12266         (and:SWI48
12267           (plus:SWI48
12268             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12269             (const_int -1))
12270           (not:SWI48
12271             (match_dup 1))))
12272    (clobber (reg:CC FLAGS_REG))]
12273    "TARGET_TBM"
12274    "tzmsk\t{%1, %0|%0, %1}"
12275   [(set_attr "type" "bitmanip")
12276    (set_attr "mode" "<MODE>")])
12277
12278 (define_insn "bsr_rex64"
12279   [(set (match_operand:DI 0 "register_operand" "=r")
12280         (minus:DI (const_int 63)
12281                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12282    (clobber (reg:CC FLAGS_REG))]
12283   "TARGET_64BIT"
12284   "bsr{q}\t{%1, %0|%0, %1}"
12285   [(set_attr "type" "alu1")
12286    (set_attr "prefix_0f" "1")
12287    (set_attr "mode" "DI")])
12288
12289 (define_insn "bsr"
12290   [(set (match_operand:SI 0 "register_operand" "=r")
12291         (minus:SI (const_int 31)
12292                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12293    (clobber (reg:CC FLAGS_REG))]
12294   ""
12295   "bsr{l}\t{%1, %0|%0, %1}"
12296   [(set_attr "type" "alu1")
12297    (set_attr "prefix_0f" "1")
12298    (set_attr "mode" "SI")])
12299
12300 (define_insn "*bsrhi"
12301   [(set (match_operand:HI 0 "register_operand" "=r")
12302         (minus:HI (const_int 15)
12303                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12304    (clobber (reg:CC FLAGS_REG))]
12305   ""
12306   "bsr{w}\t{%1, %0|%0, %1}"
12307   [(set_attr "type" "alu1")
12308    (set_attr "prefix_0f" "1")
12309    (set_attr "mode" "HI")])
12310
12311 (define_insn "popcount<mode>2"
12312   [(set (match_operand:SWI248 0 "register_operand" "=r")
12313         (popcount:SWI248
12314           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12315    (clobber (reg:CC FLAGS_REG))]
12316   "TARGET_POPCNT"
12317 {
12318 #if TARGET_MACHO
12319   return "popcnt\t{%1, %0|%0, %1}";
12320 #else
12321   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12322 #endif
12323 }
12324   [(set_attr "prefix_rep" "1")
12325    (set_attr "type" "bitmanip")
12326    (set_attr "mode" "<MODE>")])
12327
12328 (define_insn "*popcount<mode>2_cmp"
12329   [(set (reg FLAGS_REG)
12330         (compare
12331           (popcount:SWI248
12332             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12333           (const_int 0)))
12334    (set (match_operand:SWI248 0 "register_operand" "=r")
12335         (popcount:SWI248 (match_dup 1)))]
12336   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12337 {
12338 #if TARGET_MACHO
12339   return "popcnt\t{%1, %0|%0, %1}";
12340 #else
12341   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12342 #endif
12343 }
12344   [(set_attr "prefix_rep" "1")
12345    (set_attr "type" "bitmanip")
12346    (set_attr "mode" "<MODE>")])
12347
12348 (define_insn "*popcountsi2_cmp_zext"
12349   [(set (reg FLAGS_REG)
12350         (compare
12351           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12352           (const_int 0)))
12353    (set (match_operand:DI 0 "register_operand" "=r")
12354         (zero_extend:DI(popcount:SI (match_dup 1))))]
12355   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12356 {
12357 #if TARGET_MACHO
12358   return "popcnt\t{%1, %0|%0, %1}";
12359 #else
12360   return "popcnt{l}\t{%1, %0|%0, %1}";
12361 #endif
12362 }
12363   [(set_attr "prefix_rep" "1")
12364    (set_attr "type" "bitmanip")
12365    (set_attr "mode" "SI")])
12366
12367 (define_expand "bswap<mode>2"
12368   [(set (match_operand:SWI48 0 "register_operand" "")
12369         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12370   ""
12371 {
12372   if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12373     {
12374       rtx x = operands[0];
12375
12376       emit_move_insn (x, operands[1]);
12377       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12378       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12379       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12380       DONE;
12381     }
12382 })
12383
12384 (define_insn "*bswap<mode>2_movbe"
12385   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12386         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12387   "TARGET_MOVBE
12388    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12389   "@
12390     bswap\t%0
12391     movbe\t{%1, %0|%0, %1}
12392     movbe\t{%1, %0|%0, %1}"
12393   [(set_attr "type" "bitmanip,imov,imov")
12394    (set_attr "modrm" "0,1,1")
12395    (set_attr "prefix_0f" "*,1,1")
12396    (set_attr "prefix_extra" "*,1,1")
12397    (set_attr "mode" "<MODE>")])
12398
12399 (define_insn "*bswap<mode>2_1"
12400   [(set (match_operand:SWI48 0 "register_operand" "=r")
12401         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12402   "TARGET_BSWAP"
12403   "bswap\t%0"
12404   [(set_attr "type" "bitmanip")
12405    (set_attr "modrm" "0")
12406    (set_attr "mode" "<MODE>")])
12407
12408 (define_insn "*bswaphi_lowpart_1"
12409   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12410         (bswap:HI (match_dup 0)))
12411    (clobber (reg:CC FLAGS_REG))]
12412   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12413   "@
12414     xchg{b}\t{%h0, %b0|%b0, %h0}
12415     rol{w}\t{$8, %0|%0, 8}"
12416   [(set_attr "length" "2,4")
12417    (set_attr "mode" "QI,HI")])
12418
12419 (define_insn "bswaphi_lowpart"
12420   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12421         (bswap:HI (match_dup 0)))
12422    (clobber (reg:CC FLAGS_REG))]
12423   ""
12424   "rol{w}\t{$8, %0|%0, 8}"
12425   [(set_attr "length" "4")
12426    (set_attr "mode" "HI")])
12427
12428 (define_expand "paritydi2"
12429   [(set (match_operand:DI 0 "register_operand" "")
12430         (parity:DI (match_operand:DI 1 "register_operand" "")))]
12431   "! TARGET_POPCNT"
12432 {
12433   rtx scratch = gen_reg_rtx (QImode);
12434   rtx cond;
12435
12436   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12437                                 NULL_RTX, operands[1]));
12438
12439   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12440                          gen_rtx_REG (CCmode, FLAGS_REG),
12441                          const0_rtx);
12442   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12443
12444   if (TARGET_64BIT)
12445     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12446   else
12447     {
12448       rtx tmp = gen_reg_rtx (SImode);
12449
12450       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12451       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12452     }
12453   DONE;
12454 })
12455
12456 (define_expand "paritysi2"
12457   [(set (match_operand:SI 0 "register_operand" "")
12458         (parity:SI (match_operand:SI 1 "register_operand" "")))]
12459   "! TARGET_POPCNT"
12460 {
12461   rtx scratch = gen_reg_rtx (QImode);
12462   rtx cond;
12463
12464   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12465
12466   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12467                          gen_rtx_REG (CCmode, FLAGS_REG),
12468                          const0_rtx);
12469   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12470
12471   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12472   DONE;
12473 })
12474
12475 (define_insn_and_split "paritydi2_cmp"
12476   [(set (reg:CC FLAGS_REG)
12477         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12478                    UNSPEC_PARITY))
12479    (clobber (match_scratch:DI 0 "=r"))
12480    (clobber (match_scratch:SI 1 "=&r"))
12481    (clobber (match_scratch:HI 2 "=Q"))]
12482   "! TARGET_POPCNT"
12483   "#"
12484   "&& reload_completed"
12485   [(parallel
12486      [(set (match_dup 1)
12487            (xor:SI (match_dup 1) (match_dup 4)))
12488       (clobber (reg:CC FLAGS_REG))])
12489    (parallel
12490      [(set (reg:CC FLAGS_REG)
12491            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12492       (clobber (match_dup 1))
12493       (clobber (match_dup 2))])]
12494 {
12495   operands[4] = gen_lowpart (SImode, operands[3]);
12496
12497   if (TARGET_64BIT)
12498     {
12499       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12500       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12501     }
12502   else
12503     operands[1] = gen_highpart (SImode, operands[3]);
12504 })
12505
12506 (define_insn_and_split "paritysi2_cmp"
12507   [(set (reg:CC FLAGS_REG)
12508         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12509                    UNSPEC_PARITY))
12510    (clobber (match_scratch:SI 0 "=r"))
12511    (clobber (match_scratch:HI 1 "=&Q"))]
12512   "! TARGET_POPCNT"
12513   "#"
12514   "&& reload_completed"
12515   [(parallel
12516      [(set (match_dup 1)
12517            (xor:HI (match_dup 1) (match_dup 3)))
12518       (clobber (reg:CC FLAGS_REG))])
12519    (parallel
12520      [(set (reg:CC FLAGS_REG)
12521            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12522       (clobber (match_dup 1))])]
12523 {
12524   operands[3] = gen_lowpart (HImode, operands[2]);
12525
12526   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12527   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12528 })
12529
12530 (define_insn "*parityhi2_cmp"
12531   [(set (reg:CC FLAGS_REG)
12532         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12533                    UNSPEC_PARITY))
12534    (clobber (match_scratch:HI 0 "=Q"))]
12535   "! TARGET_POPCNT"
12536   "xor{b}\t{%h0, %b0|%b0, %h0}"
12537   [(set_attr "length" "2")
12538    (set_attr "mode" "HI")])
12539
12540 \f
12541 ;; Thread-local storage patterns for ELF.
12542 ;;
12543 ;; Note that these code sequences must appear exactly as shown
12544 ;; in order to allow linker relaxation.
12545
12546 (define_insn "*tls_global_dynamic_32_gnu"
12547   [(set (match_operand:SI 0 "register_operand" "=a")
12548         (unspec:SI
12549          [(match_operand:SI 1 "register_operand" "b")
12550           (match_operand:SI 2 "tls_symbolic_operand" "")
12551           (match_operand:SI 3 "constant_call_address_operand" "z")]
12552          UNSPEC_TLS_GD))
12553    (clobber (match_scratch:SI 4 "=d"))
12554    (clobber (match_scratch:SI 5 "=c"))
12555    (clobber (reg:CC FLAGS_REG))]
12556   "!TARGET_64BIT && TARGET_GNU_TLS"
12557 {
12558   output_asm_insn
12559     ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12560   if (TARGET_SUN_TLS)
12561 #ifdef HAVE_AS_IX86_TLSGDPLT
12562     return "call\t%a2@tlsgdplt";
12563 #else
12564     return "call\t%p3@plt";
12565 #endif
12566   return "call\t%P3";
12567 }
12568   [(set_attr "type" "multi")
12569    (set_attr "length" "12")])
12570
12571 (define_expand "tls_global_dynamic_32"
12572   [(parallel
12573     [(set (match_operand:SI 0 "register_operand" "")
12574           (unspec:SI [(match_operand:SI 2 "register_operand" "")
12575                       (match_operand:SI 1 "tls_symbolic_operand" "")
12576                       (match_operand:SI 3 "constant_call_address_operand" "")]
12577                      UNSPEC_TLS_GD))
12578      (clobber (match_scratch:SI 4 ""))
12579      (clobber (match_scratch:SI 5 ""))
12580      (clobber (reg:CC FLAGS_REG))])])
12581
12582 (define_insn "*tls_global_dynamic_64"
12583   [(set (match_operand:DI 0 "register_operand" "=a")
12584         (call:DI
12585          (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12586          (match_operand:DI 3 "" "")))
12587    (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12588               UNSPEC_TLS_GD)]
12589   "TARGET_64BIT"
12590 {
12591   if (!TARGET_X32)
12592     fputs (ASM_BYTE "0x66\n", asm_out_file);
12593   output_asm_insn
12594     ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12595   fputs (ASM_SHORT "0x6666\n", asm_out_file);
12596   fputs ("\trex64\n", asm_out_file);
12597   if (TARGET_SUN_TLS)
12598     return "call\t%p2@plt";
12599   return "call\t%P2";
12600 }
12601   [(set_attr "type" "multi")
12602    (set (attr "length")
12603         (symbol_ref "TARGET_X32 ? 15 : 16"))])
12604
12605 (define_expand "tls_global_dynamic_64"
12606   [(parallel
12607     [(set (match_operand:DI 0 "register_operand" "")
12608           (call:DI
12609            (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12610            (const_int 0)))
12611      (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12612                 UNSPEC_TLS_GD)])])
12613
12614 (define_insn "*tls_local_dynamic_base_32_gnu"
12615   [(set (match_operand:SI 0 "register_operand" "=a")
12616         (unspec:SI
12617          [(match_operand:SI 1 "register_operand" "b")
12618           (match_operand:SI 2 "constant_call_address_operand" "z")]
12619          UNSPEC_TLS_LD_BASE))
12620    (clobber (match_scratch:SI 3 "=d"))
12621    (clobber (match_scratch:SI 4 "=c"))
12622    (clobber (reg:CC FLAGS_REG))]
12623   "!TARGET_64BIT && TARGET_GNU_TLS"
12624 {
12625   output_asm_insn
12626     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12627   if (TARGET_SUN_TLS)
12628 #ifdef HAVE_AS_IX86_TLSLDMPLT
12629     return "call\t%&@tlsldmplt";
12630 #else
12631     return "call\t%p2@plt";
12632 #endif
12633   return "call\t%P2";
12634 }
12635   [(set_attr "type" "multi")
12636    (set_attr "length" "11")])
12637
12638 (define_expand "tls_local_dynamic_base_32"
12639   [(parallel
12640      [(set (match_operand:SI 0 "register_operand" "")
12641            (unspec:SI
12642             [(match_operand:SI 1 "register_operand" "")
12643              (match_operand:SI 2 "constant_call_address_operand" "")]
12644             UNSPEC_TLS_LD_BASE))
12645       (clobber (match_scratch:SI 3 ""))
12646       (clobber (match_scratch:SI 4 ""))
12647       (clobber (reg:CC FLAGS_REG))])])
12648
12649 (define_insn "*tls_local_dynamic_base_64"
12650   [(set (match_operand:DI 0 "register_operand" "=a")
12651         (call:DI
12652          (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12653          (match_operand:DI 2 "" "")))
12654    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12655   "TARGET_64BIT"
12656 {
12657   output_asm_insn
12658     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12659   if (TARGET_SUN_TLS)
12660     return "call\t%p1@plt";
12661   return "call\t%P1";
12662 }
12663   [(set_attr "type" "multi")
12664    (set_attr "length" "12")])
12665
12666 (define_expand "tls_local_dynamic_base_64"
12667   [(parallel
12668      [(set (match_operand:DI 0 "register_operand" "")
12669            (call:DI
12670             (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12671             (const_int 0)))
12672       (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12673
12674 ;; Local dynamic of a single variable is a lose.  Show combine how
12675 ;; to convert that back to global dynamic.
12676
12677 (define_insn_and_split "*tls_local_dynamic_32_once"
12678   [(set (match_operand:SI 0 "register_operand" "=a")
12679         (plus:SI
12680          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12681                      (match_operand:SI 2 "constant_call_address_operand" "z")]
12682                     UNSPEC_TLS_LD_BASE)
12683          (const:SI (unspec:SI
12684                     [(match_operand:SI 3 "tls_symbolic_operand" "")]
12685                     UNSPEC_DTPOFF))))
12686    (clobber (match_scratch:SI 4 "=d"))
12687    (clobber (match_scratch:SI 5 "=c"))
12688    (clobber (reg:CC FLAGS_REG))]
12689   ""
12690   "#"
12691   ""
12692   [(parallel
12693      [(set (match_dup 0)
12694            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12695                       UNSPEC_TLS_GD))
12696       (clobber (match_dup 4))
12697       (clobber (match_dup 5))
12698       (clobber (reg:CC FLAGS_REG))])])
12699
12700 ;; Segment register for the thread base ptr load
12701 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12702
12703 ;; Load and add the thread base pointer from %<tp_seg>:0.
12704 (define_insn "*load_tp_x32"
12705   [(set (match_operand:SI 0 "register_operand" "=r")
12706         (unspec:SI [(const_int 0)] UNSPEC_TP))]
12707   "TARGET_X32"
12708   "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12709   [(set_attr "type" "imov")
12710    (set_attr "modrm" "0")
12711    (set_attr "length" "7")
12712    (set_attr "memory" "load")
12713    (set_attr "imm_disp" "false")])
12714
12715 (define_insn "*load_tp_x32_zext"
12716   [(set (match_operand:DI 0 "register_operand" "=r")
12717         (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12718   "TARGET_X32"
12719   "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12720   [(set_attr "type" "imov")
12721    (set_attr "modrm" "0")
12722    (set_attr "length" "7")
12723    (set_attr "memory" "load")
12724    (set_attr "imm_disp" "false")])
12725
12726 (define_insn "*load_tp_<mode>"
12727   [(set (match_operand:P 0 "register_operand" "=r")
12728         (unspec:P [(const_int 0)] UNSPEC_TP))]
12729   "!TARGET_X32"
12730   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12731   [(set_attr "type" "imov")
12732    (set_attr "modrm" "0")
12733    (set_attr "length" "7")
12734    (set_attr "memory" "load")
12735    (set_attr "imm_disp" "false")])
12736
12737 (define_insn "*add_tp_x32"
12738   [(set (match_operand:SI 0 "register_operand" "=r")
12739         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12740                  (match_operand:SI 1 "register_operand" "0")))
12741    (clobber (reg:CC FLAGS_REG))]
12742   "TARGET_X32"
12743   "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12744   [(set_attr "type" "alu")
12745    (set_attr "modrm" "0")
12746    (set_attr "length" "7")
12747    (set_attr "memory" "load")
12748    (set_attr "imm_disp" "false")])
12749
12750 (define_insn "*add_tp_x32_zext"
12751   [(set (match_operand:DI 0 "register_operand" "=r")
12752         (zero_extend:DI
12753           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12754                    (match_operand:SI 1 "register_operand" "0"))))
12755    (clobber (reg:CC FLAGS_REG))]
12756   "TARGET_X32"
12757   "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12758   [(set_attr "type" "alu")
12759    (set_attr "modrm" "0")
12760    (set_attr "length" "7")
12761    (set_attr "memory" "load")
12762    (set_attr "imm_disp" "false")])
12763
12764 (define_insn "*add_tp_<mode>"
12765   [(set (match_operand:P 0 "register_operand" "=r")
12766         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12767                 (match_operand:P 1 "register_operand" "0")))
12768    (clobber (reg:CC FLAGS_REG))]
12769   "!TARGET_X32"
12770   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12771   [(set_attr "type" "alu")
12772    (set_attr "modrm" "0")
12773    (set_attr "length" "7")
12774    (set_attr "memory" "load")
12775    (set_attr "imm_disp" "false")])
12776
12777 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12778 ;; %rax as destination of the initial executable code sequence.
12779 (define_insn "tls_initial_exec_64_sun"
12780   [(set (match_operand:DI 0 "register_operand" "=a")
12781         (unspec:DI
12782          [(match_operand:DI 1 "tls_symbolic_operand" "")]
12783          UNSPEC_TLS_IE_SUN))
12784    (clobber (reg:CC FLAGS_REG))]
12785   "TARGET_64BIT && TARGET_SUN_TLS"
12786 {
12787   output_asm_insn
12788     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12789   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12790 }
12791   [(set_attr "type" "multi")])
12792
12793 ;; GNU2 TLS patterns can be split.
12794
12795 (define_expand "tls_dynamic_gnu2_32"
12796   [(set (match_dup 3)
12797         (plus:SI (match_operand:SI 2 "register_operand" "")
12798                  (const:SI
12799                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12800                              UNSPEC_TLSDESC))))
12801    (parallel
12802     [(set (match_operand:SI 0 "register_operand" "")
12803           (unspec:SI [(match_dup 1) (match_dup 3)
12804                       (match_dup 2) (reg:SI SP_REG)]
12805                       UNSPEC_TLSDESC))
12806      (clobber (reg:CC FLAGS_REG))])]
12807   "!TARGET_64BIT && TARGET_GNU2_TLS"
12808 {
12809   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12810   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12811 })
12812
12813 (define_insn "*tls_dynamic_gnu2_lea_32"
12814   [(set (match_operand:SI 0 "register_operand" "=r")
12815         (plus:SI (match_operand:SI 1 "register_operand" "b")
12816                  (const:SI
12817                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12818                               UNSPEC_TLSDESC))))]
12819   "!TARGET_64BIT && TARGET_GNU2_TLS"
12820   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12821   [(set_attr "type" "lea")
12822    (set_attr "mode" "SI")
12823    (set_attr "length" "6")
12824    (set_attr "length_address" "4")])
12825
12826 (define_insn "*tls_dynamic_gnu2_call_32"
12827   [(set (match_operand:SI 0 "register_operand" "=a")
12828         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12829                     (match_operand:SI 2 "register_operand" "0")
12830                     ;; we have to make sure %ebx still points to the GOT
12831                     (match_operand:SI 3 "register_operand" "b")
12832                     (reg:SI SP_REG)]
12833                    UNSPEC_TLSDESC))
12834    (clobber (reg:CC FLAGS_REG))]
12835   "!TARGET_64BIT && TARGET_GNU2_TLS"
12836   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12837   [(set_attr "type" "call")
12838    (set_attr "length" "2")
12839    (set_attr "length_address" "0")])
12840
12841 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12842   [(set (match_operand:SI 0 "register_operand" "=&a")
12843         (plus:SI
12844          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12845                      (match_operand:SI 4 "" "")
12846                      (match_operand:SI 2 "register_operand" "b")
12847                      (reg:SI SP_REG)]
12848                     UNSPEC_TLSDESC)
12849          (const:SI (unspec:SI
12850                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
12851                     UNSPEC_DTPOFF))))
12852    (clobber (reg:CC FLAGS_REG))]
12853   "!TARGET_64BIT && TARGET_GNU2_TLS"
12854   "#"
12855   ""
12856   [(set (match_dup 0) (match_dup 5))]
12857 {
12858   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12859   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12860 })
12861
12862 (define_expand "tls_dynamic_gnu2_64"
12863   [(set (match_dup 2)
12864         (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12865                    UNSPEC_TLSDESC))
12866    (parallel
12867     [(set (match_operand:DI 0 "register_operand" "")
12868           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12869                      UNSPEC_TLSDESC))
12870      (clobber (reg:CC FLAGS_REG))])]
12871   "TARGET_64BIT && TARGET_GNU2_TLS"
12872 {
12873   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12874   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12875 })
12876
12877 (define_insn "*tls_dynamic_gnu2_lea_64"
12878   [(set (match_operand:DI 0 "register_operand" "=r")
12879         (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12880                    UNSPEC_TLSDESC))]
12881   "TARGET_64BIT && TARGET_GNU2_TLS"
12882   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12883   [(set_attr "type" "lea")
12884    (set_attr "mode" "DI")
12885    (set_attr "length" "7")
12886    (set_attr "length_address" "4")])
12887
12888 (define_insn "*tls_dynamic_gnu2_call_64"
12889   [(set (match_operand:DI 0 "register_operand" "=a")
12890         (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12891                     (match_operand:DI 2 "register_operand" "0")
12892                     (reg:DI SP_REG)]
12893                    UNSPEC_TLSDESC))
12894    (clobber (reg:CC FLAGS_REG))]
12895   "TARGET_64BIT && TARGET_GNU2_TLS"
12896   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12897   [(set_attr "type" "call")
12898    (set_attr "length" "2")
12899    (set_attr "length_address" "0")])
12900
12901 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12902   [(set (match_operand:DI 0 "register_operand" "=&a")
12903         (plus:DI
12904          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12905                      (match_operand:DI 3 "" "")
12906                      (reg:DI SP_REG)]
12907                     UNSPEC_TLSDESC)
12908          (const:DI (unspec:DI
12909                     [(match_operand 1 "tls_symbolic_operand" "")]
12910                     UNSPEC_DTPOFF))))
12911    (clobber (reg:CC FLAGS_REG))]
12912   "TARGET_64BIT && TARGET_GNU2_TLS"
12913   "#"
12914   ""
12915   [(set (match_dup 0) (match_dup 4))]
12916 {
12917   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12918   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12919 })
12920 \f
12921 ;; These patterns match the binary 387 instructions for addM3, subM3,
12922 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
12923 ;; SFmode.  The first is the normal insn, the second the same insn but
12924 ;; with one operand a conversion, and the third the same insn but with
12925 ;; the other operand a conversion.  The conversion may be SFmode or
12926 ;; SImode if the target mode DFmode, but only SImode if the target mode
12927 ;; is SFmode.
12928
12929 ;; Gcc is slightly more smart about handling normal two address instructions
12930 ;; so use special patterns for add and mull.
12931
12932 (define_insn "*fop_<mode>_comm_mixed"
12933   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12934         (match_operator:MODEF 3 "binary_fp_operator"
12935           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12936            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12937   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12938    && COMMUTATIVE_ARITH_P (operands[3])
12939    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12940   "* return output_387_binary_op (insn, operands);"
12941   [(set (attr "type")
12942         (if_then_else (eq_attr "alternative" "1,2")
12943            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12944               (const_string "ssemul")
12945               (const_string "sseadd"))
12946            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12947               (const_string "fmul")
12948               (const_string "fop"))))
12949    (set_attr "isa" "*,noavx,avx")
12950    (set_attr "prefix" "orig,orig,vex")
12951    (set_attr "mode" "<MODE>")])
12952
12953 (define_insn "*fop_<mode>_comm_sse"
12954   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12955         (match_operator:MODEF 3 "binary_fp_operator"
12956           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12957            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12958   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12959    && COMMUTATIVE_ARITH_P (operands[3])
12960    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12961   "* return output_387_binary_op (insn, operands);"
12962   [(set (attr "type")
12963         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12964            (const_string "ssemul")
12965            (const_string "sseadd")))
12966    (set_attr "isa" "noavx,avx")
12967    (set_attr "prefix" "orig,vex")
12968    (set_attr "mode" "<MODE>")])
12969
12970 (define_insn "*fop_<mode>_comm_i387"
12971   [(set (match_operand:MODEF 0 "register_operand" "=f")
12972         (match_operator:MODEF 3 "binary_fp_operator"
12973           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12974            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12975   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12976    && COMMUTATIVE_ARITH_P (operands[3])
12977    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12978   "* return output_387_binary_op (insn, operands);"
12979   [(set (attr "type")
12980         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12981            (const_string "fmul")
12982            (const_string "fop")))
12983    (set_attr "mode" "<MODE>")])
12984
12985 (define_insn "*fop_<mode>_1_mixed"
12986   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12987         (match_operator:MODEF 3 "binary_fp_operator"
12988           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12989            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12990   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
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         (cond [(and (eq_attr "alternative" "2,3")
12996                     (match_operand:MODEF 3 "mult_operator" ""))
12997                  (const_string "ssemul")
12998                (and (eq_attr "alternative" "2,3")
12999                     (match_operand:MODEF 3 "div_operator" ""))
13000                  (const_string "ssediv")
13001                (eq_attr "alternative" "2,3")
13002                  (const_string "sseadd")
13003                (match_operand:MODEF 3 "mult_operator" "")
13004                  (const_string "fmul")
13005                (match_operand:MODEF 3 "div_operator" "")
13006                  (const_string "fdiv")
13007               ]
13008               (const_string "fop")))
13009    (set_attr "isa" "*,*,noavx,avx")
13010    (set_attr "prefix" "orig,orig,orig,vex")
13011    (set_attr "mode" "<MODE>")])
13012
13013 (define_insn "*rcpsf2_sse"
13014   [(set (match_operand:SF 0 "register_operand" "=x")
13015         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13016                    UNSPEC_RCP))]
13017   "TARGET_SSE_MATH"
13018   "%vrcpss\t{%1, %d0|%d0, %1}"
13019   [(set_attr "type" "sse")
13020    (set_attr "atom_sse_attr" "rcp")
13021    (set_attr "prefix" "maybe_vex")
13022    (set_attr "mode" "SF")])
13023
13024 (define_insn "*fop_<mode>_1_sse"
13025   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13026         (match_operator:MODEF 3 "binary_fp_operator"
13027           [(match_operand:MODEF 1 "register_operand" "0,x")
13028            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13029   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13030    && !COMMUTATIVE_ARITH_P (operands[3])"
13031   "* return output_387_binary_op (insn, operands);"
13032   [(set (attr "type")
13033         (cond [(match_operand:MODEF 3 "mult_operator" "")
13034                  (const_string "ssemul")
13035                (match_operand:MODEF 3 "div_operator" "")
13036                  (const_string "ssediv")
13037               ]
13038               (const_string "sseadd")))
13039    (set_attr "isa" "noavx,avx")
13040    (set_attr "prefix" "orig,vex")
13041    (set_attr "mode" "<MODE>")])
13042
13043 ;; This pattern is not fully shadowed by the pattern above.
13044 (define_insn "*fop_<mode>_1_i387"
13045   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13046         (match_operator:MODEF 3 "binary_fp_operator"
13047           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13048            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13049   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13050    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13051    && !COMMUTATIVE_ARITH_P (operands[3])
13052    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13053   "* return output_387_binary_op (insn, operands);"
13054   [(set (attr "type")
13055         (cond [(match_operand:MODEF 3 "mult_operator" "")
13056                  (const_string "fmul")
13057                (match_operand:MODEF 3 "div_operator" "")
13058                  (const_string "fdiv")
13059               ]
13060               (const_string "fop")))
13061    (set_attr "mode" "<MODE>")])
13062
13063 ;; ??? Add SSE splitters for these!
13064 (define_insn "*fop_<MODEF:mode>_2_i387"
13065   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13066         (match_operator:MODEF 3 "binary_fp_operator"
13067           [(float:MODEF
13068              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13069            (match_operand:MODEF 2 "register_operand" "0,0")]))]
13070   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13071    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13072    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13073   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13074   [(set (attr "type")
13075         (cond [(match_operand:MODEF 3 "mult_operator" "")
13076                  (const_string "fmul")
13077                (match_operand:MODEF 3 "div_operator" "")
13078                  (const_string "fdiv")
13079               ]
13080               (const_string "fop")))
13081    (set_attr "fp_int_src" "true")
13082    (set_attr "mode" "<SWI24:MODE>")])
13083
13084 (define_insn "*fop_<MODEF:mode>_3_i387"
13085   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13086         (match_operator:MODEF 3 "binary_fp_operator"
13087           [(match_operand:MODEF 1 "register_operand" "0,0")
13088            (float:MODEF
13089              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13090   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13091    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13092    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13093   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13094   [(set (attr "type")
13095         (cond [(match_operand:MODEF 3 "mult_operator" "")
13096                  (const_string "fmul")
13097                (match_operand:MODEF 3 "div_operator" "")
13098                  (const_string "fdiv")
13099               ]
13100               (const_string "fop")))
13101    (set_attr "fp_int_src" "true")
13102    (set_attr "mode" "<MODE>")])
13103
13104 (define_insn "*fop_df_4_i387"
13105   [(set (match_operand:DF 0 "register_operand" "=f,f")
13106         (match_operator:DF 3 "binary_fp_operator"
13107            [(float_extend:DF
13108              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13109             (match_operand:DF 2 "register_operand" "0,f")]))]
13110   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13111    && !(TARGET_SSE2 && TARGET_SSE_MATH)
13112    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13113   "* return output_387_binary_op (insn, operands);"
13114   [(set (attr "type")
13115         (cond [(match_operand:DF 3 "mult_operator" "")
13116                  (const_string "fmul")
13117                (match_operand:DF 3 "div_operator" "")
13118                  (const_string "fdiv")
13119               ]
13120               (const_string "fop")))
13121    (set_attr "mode" "SF")])
13122
13123 (define_insn "*fop_df_5_i387"
13124   [(set (match_operand:DF 0 "register_operand" "=f,f")
13125         (match_operator:DF 3 "binary_fp_operator"
13126           [(match_operand:DF 1 "register_operand" "0,f")
13127            (float_extend:DF
13128             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13129   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13130    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13131   "* return output_387_binary_op (insn, operands);"
13132   [(set (attr "type")
13133         (cond [(match_operand:DF 3 "mult_operator" "")
13134                  (const_string "fmul")
13135                (match_operand:DF 3 "div_operator" "")
13136                  (const_string "fdiv")
13137               ]
13138               (const_string "fop")))
13139    (set_attr "mode" "SF")])
13140
13141 (define_insn "*fop_df_6_i387"
13142   [(set (match_operand:DF 0 "register_operand" "=f,f")
13143         (match_operator:DF 3 "binary_fp_operator"
13144           [(float_extend:DF
13145             (match_operand:SF 1 "register_operand" "0,f"))
13146            (float_extend:DF
13147             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13148   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13149    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13150   "* return output_387_binary_op (insn, operands);"
13151   [(set (attr "type")
13152         (cond [(match_operand:DF 3 "mult_operator" "")
13153                  (const_string "fmul")
13154                (match_operand:DF 3 "div_operator" "")
13155                  (const_string "fdiv")
13156               ]
13157               (const_string "fop")))
13158    (set_attr "mode" "SF")])
13159
13160 (define_insn "*fop_xf_comm_i387"
13161   [(set (match_operand:XF 0 "register_operand" "=f")
13162         (match_operator:XF 3 "binary_fp_operator"
13163                         [(match_operand:XF 1 "register_operand" "%0")
13164                          (match_operand:XF 2 "register_operand" "f")]))]
13165   "TARGET_80387
13166    && COMMUTATIVE_ARITH_P (operands[3])"
13167   "* return output_387_binary_op (insn, operands);"
13168   [(set (attr "type")
13169         (if_then_else (match_operand:XF 3 "mult_operator" "")
13170            (const_string "fmul")
13171            (const_string "fop")))
13172    (set_attr "mode" "XF")])
13173
13174 (define_insn "*fop_xf_1_i387"
13175   [(set (match_operand:XF 0 "register_operand" "=f,f")
13176         (match_operator:XF 3 "binary_fp_operator"
13177                         [(match_operand:XF 1 "register_operand" "0,f")
13178                          (match_operand:XF 2 "register_operand" "f,0")]))]
13179   "TARGET_80387
13180    && !COMMUTATIVE_ARITH_P (operands[3])"
13181   "* return output_387_binary_op (insn, operands);"
13182   [(set (attr "type")
13183         (cond [(match_operand:XF 3 "mult_operator" "")
13184                  (const_string "fmul")
13185                (match_operand:XF 3 "div_operator" "")
13186                  (const_string "fdiv")
13187               ]
13188               (const_string "fop")))
13189    (set_attr "mode" "XF")])
13190
13191 (define_insn "*fop_xf_2_i387"
13192   [(set (match_operand:XF 0 "register_operand" "=f,f")
13193         (match_operator:XF 3 "binary_fp_operator"
13194           [(float:XF
13195              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13196            (match_operand:XF 2 "register_operand" "0,0")]))]
13197   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13198   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13199   [(set (attr "type")
13200         (cond [(match_operand:XF 3 "mult_operator" "")
13201                  (const_string "fmul")
13202                (match_operand:XF 3 "div_operator" "")
13203                  (const_string "fdiv")
13204               ]
13205               (const_string "fop")))
13206    (set_attr "fp_int_src" "true")
13207    (set_attr "mode" "<MODE>")])
13208
13209 (define_insn "*fop_xf_3_i387"
13210   [(set (match_operand:XF 0 "register_operand" "=f,f")
13211         (match_operator:XF 3 "binary_fp_operator"
13212           [(match_operand:XF 1 "register_operand" "0,0")
13213            (float:XF
13214              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13215   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13216   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13217   [(set (attr "type")
13218         (cond [(match_operand:XF 3 "mult_operator" "")
13219                  (const_string "fmul")
13220                (match_operand:XF 3 "div_operator" "")
13221                  (const_string "fdiv")
13222               ]
13223               (const_string "fop")))
13224    (set_attr "fp_int_src" "true")
13225    (set_attr "mode" "<MODE>")])
13226
13227 (define_insn "*fop_xf_4_i387"
13228   [(set (match_operand:XF 0 "register_operand" "=f,f")
13229         (match_operator:XF 3 "binary_fp_operator"
13230            [(float_extend:XF
13231               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13232             (match_operand:XF 2 "register_operand" "0,f")]))]
13233   "TARGET_80387"
13234   "* return output_387_binary_op (insn, operands);"
13235   [(set (attr "type")
13236         (cond [(match_operand:XF 3 "mult_operator" "")
13237                  (const_string "fmul")
13238                (match_operand:XF 3 "div_operator" "")
13239                  (const_string "fdiv")
13240               ]
13241               (const_string "fop")))
13242    (set_attr "mode" "<MODE>")])
13243
13244 (define_insn "*fop_xf_5_i387"
13245   [(set (match_operand:XF 0 "register_operand" "=f,f")
13246         (match_operator:XF 3 "binary_fp_operator"
13247           [(match_operand:XF 1 "register_operand" "0,f")
13248            (float_extend:XF
13249              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13250   "TARGET_80387"
13251   "* return output_387_binary_op (insn, operands);"
13252   [(set (attr "type")
13253         (cond [(match_operand:XF 3 "mult_operator" "")
13254                  (const_string "fmul")
13255                (match_operand:XF 3 "div_operator" "")
13256                  (const_string "fdiv")
13257               ]
13258               (const_string "fop")))
13259    (set_attr "mode" "<MODE>")])
13260
13261 (define_insn "*fop_xf_6_i387"
13262   [(set (match_operand:XF 0 "register_operand" "=f,f")
13263         (match_operator:XF 3 "binary_fp_operator"
13264           [(float_extend:XF
13265              (match_operand:MODEF 1 "register_operand" "0,f"))
13266            (float_extend:XF
13267              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13268   "TARGET_80387"
13269   "* return output_387_binary_op (insn, operands);"
13270   [(set (attr "type")
13271         (cond [(match_operand:XF 3 "mult_operator" "")
13272                  (const_string "fmul")
13273                (match_operand:XF 3 "div_operator" "")
13274                  (const_string "fdiv")
13275               ]
13276               (const_string "fop")))
13277    (set_attr "mode" "<MODE>")])
13278
13279 (define_split
13280   [(set (match_operand 0 "register_operand" "")
13281         (match_operator 3 "binary_fp_operator"
13282            [(float (match_operand:SWI24 1 "register_operand" ""))
13283             (match_operand 2 "register_operand" "")]))]
13284   "reload_completed
13285    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13286    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13287   [(const_int 0)]
13288 {
13289   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13290   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13291   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13292                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13293                                           GET_MODE (operands[3]),
13294                                           operands[4],
13295                                           operands[2])));
13296   ix86_free_from_memory (GET_MODE (operands[1]));
13297   DONE;
13298 })
13299
13300 (define_split
13301   [(set (match_operand 0 "register_operand" "")
13302         (match_operator 3 "binary_fp_operator"
13303            [(match_operand 1 "register_operand" "")
13304             (float (match_operand:SWI24 2 "register_operand" ""))]))]
13305   "reload_completed
13306    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13307    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13308   [(const_int 0)]
13309 {
13310   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13311   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13312   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13313                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13314                                           GET_MODE (operands[3]),
13315                                           operands[1],
13316                                           operands[4])));
13317   ix86_free_from_memory (GET_MODE (operands[2]));
13318   DONE;
13319 })
13320 \f
13321 ;; FPU special functions.
13322
13323 ;; This pattern implements a no-op XFmode truncation for
13324 ;; all fancy i386 XFmode math functions.
13325
13326 (define_insn "truncxf<mode>2_i387_noop_unspec"
13327   [(set (match_operand:MODEF 0 "register_operand" "=f")
13328         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13329         UNSPEC_TRUNC_NOOP))]
13330   "TARGET_USE_FANCY_MATH_387"
13331   "* return output_387_reg_move (insn, operands);"
13332   [(set_attr "type" "fmov")
13333    (set_attr "mode" "<MODE>")])
13334
13335 (define_insn "sqrtxf2"
13336   [(set (match_operand:XF 0 "register_operand" "=f")
13337         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13338   "TARGET_USE_FANCY_MATH_387"
13339   "fsqrt"
13340   [(set_attr "type" "fpspc")
13341    (set_attr "mode" "XF")
13342    (set_attr "athlon_decode" "direct")
13343    (set_attr "amdfam10_decode" "direct")
13344    (set_attr "bdver1_decode" "direct")])
13345
13346 (define_insn "sqrt_extend<mode>xf2_i387"
13347   [(set (match_operand:XF 0 "register_operand" "=f")
13348         (sqrt:XF
13349           (float_extend:XF
13350             (match_operand:MODEF 1 "register_operand" "0"))))]
13351   "TARGET_USE_FANCY_MATH_387"
13352   "fsqrt"
13353   [(set_attr "type" "fpspc")
13354    (set_attr "mode" "XF")
13355    (set_attr "athlon_decode" "direct")
13356    (set_attr "amdfam10_decode" "direct")
13357    (set_attr "bdver1_decode" "direct")])
13358
13359 (define_insn "*rsqrtsf2_sse"
13360   [(set (match_operand:SF 0 "register_operand" "=x")
13361         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13362                    UNSPEC_RSQRT))]
13363   "TARGET_SSE_MATH"
13364   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13365   [(set_attr "type" "sse")
13366    (set_attr "atom_sse_attr" "rcp")
13367    (set_attr "prefix" "maybe_vex")
13368    (set_attr "mode" "SF")])
13369
13370 (define_expand "rsqrtsf2"
13371   [(set (match_operand:SF 0 "register_operand" "")
13372         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13373                    UNSPEC_RSQRT))]
13374   "TARGET_SSE_MATH"
13375 {
13376   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13377   DONE;
13378 })
13379
13380 (define_insn "*sqrt<mode>2_sse"
13381   [(set (match_operand:MODEF 0 "register_operand" "=x")
13382         (sqrt:MODEF
13383           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13384   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13385   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13386   [(set_attr "type" "sse")
13387    (set_attr "atom_sse_attr" "sqrt")
13388    (set_attr "prefix" "maybe_vex")
13389    (set_attr "mode" "<MODE>")
13390    (set_attr "athlon_decode" "*")
13391    (set_attr "amdfam10_decode" "*")
13392    (set_attr "bdver1_decode" "*")])
13393
13394 (define_expand "sqrt<mode>2"
13395   [(set (match_operand:MODEF 0 "register_operand" "")
13396         (sqrt:MODEF
13397           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13398   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13399    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13400 {
13401   if (<MODE>mode == SFmode
13402       && TARGET_SSE_MATH
13403       && TARGET_RECIP_SQRT
13404       && !optimize_function_for_size_p (cfun)
13405       && flag_finite_math_only && !flag_trapping_math
13406       && flag_unsafe_math_optimizations)
13407     {
13408       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13409       DONE;
13410     }
13411
13412   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13413     {
13414       rtx op0 = gen_reg_rtx (XFmode);
13415       rtx op1 = force_reg (<MODE>mode, operands[1]);
13416
13417       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13418       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13419       DONE;
13420    }
13421 })
13422
13423 (define_insn "fpremxf4_i387"
13424   [(set (match_operand:XF 0 "register_operand" "=f")
13425         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13426                     (match_operand:XF 3 "register_operand" "1")]
13427                    UNSPEC_FPREM_F))
13428    (set (match_operand:XF 1 "register_operand" "=u")
13429         (unspec:XF [(match_dup 2) (match_dup 3)]
13430                    UNSPEC_FPREM_U))
13431    (set (reg:CCFP FPSR_REG)
13432         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13433                      UNSPEC_C2_FLAG))]
13434   "TARGET_USE_FANCY_MATH_387"
13435   "fprem"
13436   [(set_attr "type" "fpspc")
13437    (set_attr "mode" "XF")])
13438
13439 (define_expand "fmodxf3"
13440   [(use (match_operand:XF 0 "register_operand" ""))
13441    (use (match_operand:XF 1 "general_operand" ""))
13442    (use (match_operand:XF 2 "general_operand" ""))]
13443   "TARGET_USE_FANCY_MATH_387"
13444 {
13445   rtx label = gen_label_rtx ();
13446
13447   rtx op1 = gen_reg_rtx (XFmode);
13448   rtx op2 = gen_reg_rtx (XFmode);
13449
13450   emit_move_insn (op2, operands[2]);
13451   emit_move_insn (op1, operands[1]);
13452
13453   emit_label (label);
13454   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13455   ix86_emit_fp_unordered_jump (label);
13456   LABEL_NUSES (label) = 1;
13457
13458   emit_move_insn (operands[0], op1);
13459   DONE;
13460 })
13461
13462 (define_expand "fmod<mode>3"
13463   [(use (match_operand:MODEF 0 "register_operand" ""))
13464    (use (match_operand:MODEF 1 "general_operand" ""))
13465    (use (match_operand:MODEF 2 "general_operand" ""))]
13466   "TARGET_USE_FANCY_MATH_387"
13467 {
13468   rtx (*gen_truncxf) (rtx, rtx);
13469
13470   rtx label = gen_label_rtx ();
13471
13472   rtx op1 = gen_reg_rtx (XFmode);
13473   rtx op2 = gen_reg_rtx (XFmode);
13474
13475   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13476   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13477
13478   emit_label (label);
13479   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13480   ix86_emit_fp_unordered_jump (label);
13481   LABEL_NUSES (label) = 1;
13482
13483   /* Truncate the result properly for strict SSE math.  */
13484   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13485       && !TARGET_MIX_SSE_I387)
13486     gen_truncxf = gen_truncxf<mode>2;
13487   else
13488     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13489
13490   emit_insn (gen_truncxf (operands[0], op1));
13491   DONE;
13492 })
13493
13494 (define_insn "fprem1xf4_i387"
13495   [(set (match_operand:XF 0 "register_operand" "=f")
13496         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13497                     (match_operand:XF 3 "register_operand" "1")]
13498                    UNSPEC_FPREM1_F))
13499    (set (match_operand:XF 1 "register_operand" "=u")
13500         (unspec:XF [(match_dup 2) (match_dup 3)]
13501                    UNSPEC_FPREM1_U))
13502    (set (reg:CCFP FPSR_REG)
13503         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13504                      UNSPEC_C2_FLAG))]
13505   "TARGET_USE_FANCY_MATH_387"
13506   "fprem1"
13507   [(set_attr "type" "fpspc")
13508    (set_attr "mode" "XF")])
13509
13510 (define_expand "remainderxf3"
13511   [(use (match_operand:XF 0 "register_operand" ""))
13512    (use (match_operand:XF 1 "general_operand" ""))
13513    (use (match_operand:XF 2 "general_operand" ""))]
13514   "TARGET_USE_FANCY_MATH_387"
13515 {
13516   rtx label = gen_label_rtx ();
13517
13518   rtx op1 = gen_reg_rtx (XFmode);
13519   rtx op2 = gen_reg_rtx (XFmode);
13520
13521   emit_move_insn (op2, operands[2]);
13522   emit_move_insn (op1, operands[1]);
13523
13524   emit_label (label);
13525   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13526   ix86_emit_fp_unordered_jump (label);
13527   LABEL_NUSES (label) = 1;
13528
13529   emit_move_insn (operands[0], op1);
13530   DONE;
13531 })
13532
13533 (define_expand "remainder<mode>3"
13534   [(use (match_operand:MODEF 0 "register_operand" ""))
13535    (use (match_operand:MODEF 1 "general_operand" ""))
13536    (use (match_operand:MODEF 2 "general_operand" ""))]
13537   "TARGET_USE_FANCY_MATH_387"
13538 {
13539   rtx (*gen_truncxf) (rtx, rtx);
13540
13541   rtx label = gen_label_rtx ();
13542
13543   rtx op1 = gen_reg_rtx (XFmode);
13544   rtx op2 = gen_reg_rtx (XFmode);
13545
13546   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13547   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13548
13549   emit_label (label);
13550
13551   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13552   ix86_emit_fp_unordered_jump (label);
13553   LABEL_NUSES (label) = 1;
13554
13555   /* Truncate the result properly for strict SSE math.  */
13556   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13557       && !TARGET_MIX_SSE_I387)
13558     gen_truncxf = gen_truncxf<mode>2;
13559   else
13560     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13561
13562   emit_insn (gen_truncxf (operands[0], op1));
13563   DONE;
13564 })
13565
13566 (define_insn "*sinxf2_i387"
13567   [(set (match_operand:XF 0 "register_operand" "=f")
13568         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13569   "TARGET_USE_FANCY_MATH_387
13570    && flag_unsafe_math_optimizations"
13571   "fsin"
13572   [(set_attr "type" "fpspc")
13573    (set_attr "mode" "XF")])
13574
13575 (define_insn "*sin_extend<mode>xf2_i387"
13576   [(set (match_operand:XF 0 "register_operand" "=f")
13577         (unspec:XF [(float_extend:XF
13578                       (match_operand:MODEF 1 "register_operand" "0"))]
13579                    UNSPEC_SIN))]
13580   "TARGET_USE_FANCY_MATH_387
13581    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13582        || TARGET_MIX_SSE_I387)
13583    && flag_unsafe_math_optimizations"
13584   "fsin"
13585   [(set_attr "type" "fpspc")
13586    (set_attr "mode" "XF")])
13587
13588 (define_insn "*cosxf2_i387"
13589   [(set (match_operand:XF 0 "register_operand" "=f")
13590         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13591   "TARGET_USE_FANCY_MATH_387
13592    && flag_unsafe_math_optimizations"
13593   "fcos"
13594   [(set_attr "type" "fpspc")
13595    (set_attr "mode" "XF")])
13596
13597 (define_insn "*cos_extend<mode>xf2_i387"
13598   [(set (match_operand:XF 0 "register_operand" "=f")
13599         (unspec:XF [(float_extend:XF
13600                       (match_operand:MODEF 1 "register_operand" "0"))]
13601                    UNSPEC_COS))]
13602   "TARGET_USE_FANCY_MATH_387
13603    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13604        || TARGET_MIX_SSE_I387)
13605    && flag_unsafe_math_optimizations"
13606   "fcos"
13607   [(set_attr "type" "fpspc")
13608    (set_attr "mode" "XF")])
13609
13610 ;; When sincos pattern is defined, sin and cos builtin functions will be
13611 ;; expanded to sincos pattern with one of its outputs left unused.
13612 ;; CSE pass will figure out if two sincos patterns can be combined,
13613 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13614 ;; depending on the unused output.
13615
13616 (define_insn "sincosxf3"
13617   [(set (match_operand:XF 0 "register_operand" "=f")
13618         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13619                    UNSPEC_SINCOS_COS))
13620    (set (match_operand:XF 1 "register_operand" "=u")
13621         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13622   "TARGET_USE_FANCY_MATH_387
13623    && flag_unsafe_math_optimizations"
13624   "fsincos"
13625   [(set_attr "type" "fpspc")
13626    (set_attr "mode" "XF")])
13627
13628 (define_split
13629   [(set (match_operand:XF 0 "register_operand" "")
13630         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13631                    UNSPEC_SINCOS_COS))
13632    (set (match_operand:XF 1 "register_operand" "")
13633         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13634   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13635    && can_create_pseudo_p ()"
13636   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13637
13638 (define_split
13639   [(set (match_operand:XF 0 "register_operand" "")
13640         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13641                    UNSPEC_SINCOS_COS))
13642    (set (match_operand:XF 1 "register_operand" "")
13643         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13644   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13645    && can_create_pseudo_p ()"
13646   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13647
13648 (define_insn "sincos_extend<mode>xf3_i387"
13649   [(set (match_operand:XF 0 "register_operand" "=f")
13650         (unspec:XF [(float_extend:XF
13651                       (match_operand:MODEF 2 "register_operand" "0"))]
13652                    UNSPEC_SINCOS_COS))
13653    (set (match_operand:XF 1 "register_operand" "=u")
13654         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13655   "TARGET_USE_FANCY_MATH_387
13656    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13657        || TARGET_MIX_SSE_I387)
13658    && flag_unsafe_math_optimizations"
13659   "fsincos"
13660   [(set_attr "type" "fpspc")
13661    (set_attr "mode" "XF")])
13662
13663 (define_split
13664   [(set (match_operand:XF 0 "register_operand" "")
13665         (unspec:XF [(float_extend:XF
13666                       (match_operand:MODEF 2 "register_operand" ""))]
13667                    UNSPEC_SINCOS_COS))
13668    (set (match_operand:XF 1 "register_operand" "")
13669         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13670   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13671    && can_create_pseudo_p ()"
13672   [(set (match_dup 1)
13673         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13674
13675 (define_split
13676   [(set (match_operand:XF 0 "register_operand" "")
13677         (unspec:XF [(float_extend:XF
13678                       (match_operand:MODEF 2 "register_operand" ""))]
13679                    UNSPEC_SINCOS_COS))
13680    (set (match_operand:XF 1 "register_operand" "")
13681         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13682   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13683    && can_create_pseudo_p ()"
13684   [(set (match_dup 0)
13685         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13686
13687 (define_expand "sincos<mode>3"
13688   [(use (match_operand:MODEF 0 "register_operand" ""))
13689    (use (match_operand:MODEF 1 "register_operand" ""))
13690    (use (match_operand:MODEF 2 "register_operand" ""))]
13691   "TARGET_USE_FANCY_MATH_387
13692    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13693        || TARGET_MIX_SSE_I387)
13694    && flag_unsafe_math_optimizations"
13695 {
13696   rtx op0 = gen_reg_rtx (XFmode);
13697   rtx op1 = gen_reg_rtx (XFmode);
13698
13699   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13700   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13701   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13702   DONE;
13703 })
13704
13705 (define_insn "fptanxf4_i387"
13706   [(set (match_operand:XF 0 "register_operand" "=f")
13707         (match_operand:XF 3 "const_double_operand" "F"))
13708    (set (match_operand:XF 1 "register_operand" "=u")
13709         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13710                    UNSPEC_TAN))]
13711   "TARGET_USE_FANCY_MATH_387
13712    && flag_unsafe_math_optimizations
13713    && standard_80387_constant_p (operands[3]) == 2"
13714   "fptan"
13715   [(set_attr "type" "fpspc")
13716    (set_attr "mode" "XF")])
13717
13718 (define_insn "fptan_extend<mode>xf4_i387"
13719   [(set (match_operand:MODEF 0 "register_operand" "=f")
13720         (match_operand:MODEF 3 "const_double_operand" "F"))
13721    (set (match_operand:XF 1 "register_operand" "=u")
13722         (unspec:XF [(float_extend:XF
13723                       (match_operand:MODEF 2 "register_operand" "0"))]
13724                    UNSPEC_TAN))]
13725   "TARGET_USE_FANCY_MATH_387
13726    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13727        || TARGET_MIX_SSE_I387)
13728    && flag_unsafe_math_optimizations
13729    && standard_80387_constant_p (operands[3]) == 2"
13730   "fptan"
13731   [(set_attr "type" "fpspc")
13732    (set_attr "mode" "XF")])
13733
13734 (define_expand "tanxf2"
13735   [(use (match_operand:XF 0 "register_operand" ""))
13736    (use (match_operand:XF 1 "register_operand" ""))]
13737   "TARGET_USE_FANCY_MATH_387
13738    && flag_unsafe_math_optimizations"
13739 {
13740   rtx one = gen_reg_rtx (XFmode);
13741   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13742
13743   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13744   DONE;
13745 })
13746
13747 (define_expand "tan<mode>2"
13748   [(use (match_operand:MODEF 0 "register_operand" ""))
13749    (use (match_operand:MODEF 1 "register_operand" ""))]
13750   "TARGET_USE_FANCY_MATH_387
13751    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13752        || TARGET_MIX_SSE_I387)
13753    && flag_unsafe_math_optimizations"
13754 {
13755   rtx op0 = gen_reg_rtx (XFmode);
13756
13757   rtx one = gen_reg_rtx (<MODE>mode);
13758   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13759
13760   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13761                                              operands[1], op2));
13762   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13763   DONE;
13764 })
13765
13766 (define_insn "*fpatanxf3_i387"
13767   [(set (match_operand:XF 0 "register_operand" "=f")
13768         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13769                     (match_operand:XF 2 "register_operand" "u")]
13770                    UNSPEC_FPATAN))
13771    (clobber (match_scratch:XF 3 "=2"))]
13772   "TARGET_USE_FANCY_MATH_387
13773    && flag_unsafe_math_optimizations"
13774   "fpatan"
13775   [(set_attr "type" "fpspc")
13776    (set_attr "mode" "XF")])
13777
13778 (define_insn "fpatan_extend<mode>xf3_i387"
13779   [(set (match_operand:XF 0 "register_operand" "=f")
13780         (unspec:XF [(float_extend:XF
13781                       (match_operand:MODEF 1 "register_operand" "0"))
13782                     (float_extend:XF
13783                       (match_operand:MODEF 2 "register_operand" "u"))]
13784                    UNSPEC_FPATAN))
13785    (clobber (match_scratch:XF 3 "=2"))]
13786   "TARGET_USE_FANCY_MATH_387
13787    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13788        || TARGET_MIX_SSE_I387)
13789    && flag_unsafe_math_optimizations"
13790   "fpatan"
13791   [(set_attr "type" "fpspc")
13792    (set_attr "mode" "XF")])
13793
13794 (define_expand "atan2xf3"
13795   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13796                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
13797                                (match_operand:XF 1 "register_operand" "")]
13798                               UNSPEC_FPATAN))
13799               (clobber (match_scratch:XF 3 ""))])]
13800   "TARGET_USE_FANCY_MATH_387
13801    && flag_unsafe_math_optimizations")
13802
13803 (define_expand "atan2<mode>3"
13804   [(use (match_operand:MODEF 0 "register_operand" ""))
13805    (use (match_operand:MODEF 1 "register_operand" ""))
13806    (use (match_operand:MODEF 2 "register_operand" ""))]
13807   "TARGET_USE_FANCY_MATH_387
13808    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13809        || TARGET_MIX_SSE_I387)
13810    && flag_unsafe_math_optimizations"
13811 {
13812   rtx op0 = gen_reg_rtx (XFmode);
13813
13814   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13815   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13816   DONE;
13817 })
13818
13819 (define_expand "atanxf2"
13820   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13821                    (unspec:XF [(match_dup 2)
13822                                (match_operand:XF 1 "register_operand" "")]
13823                               UNSPEC_FPATAN))
13824               (clobber (match_scratch:XF 3 ""))])]
13825   "TARGET_USE_FANCY_MATH_387
13826    && flag_unsafe_math_optimizations"
13827 {
13828   operands[2] = gen_reg_rtx (XFmode);
13829   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13830 })
13831
13832 (define_expand "atan<mode>2"
13833   [(use (match_operand:MODEF 0 "register_operand" ""))
13834    (use (match_operand:MODEF 1 "register_operand" ""))]
13835   "TARGET_USE_FANCY_MATH_387
13836    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13837        || TARGET_MIX_SSE_I387)
13838    && flag_unsafe_math_optimizations"
13839 {
13840   rtx op0 = gen_reg_rtx (XFmode);
13841
13842   rtx op2 = gen_reg_rtx (<MODE>mode);
13843   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13844
13845   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13846   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13847   DONE;
13848 })
13849
13850 (define_expand "asinxf2"
13851   [(set (match_dup 2)
13852         (mult:XF (match_operand:XF 1 "register_operand" "")
13853                  (match_dup 1)))
13854    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13855    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13856    (parallel [(set (match_operand:XF 0 "register_operand" "")
13857                    (unspec:XF [(match_dup 5) (match_dup 1)]
13858                               UNSPEC_FPATAN))
13859               (clobber (match_scratch:XF 6 ""))])]
13860   "TARGET_USE_FANCY_MATH_387
13861    && flag_unsafe_math_optimizations"
13862 {
13863   int i;
13864
13865   if (optimize_insn_for_size_p ())
13866     FAIL;
13867
13868   for (i = 2; i < 6; i++)
13869     operands[i] = gen_reg_rtx (XFmode);
13870
13871   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13872 })
13873
13874 (define_expand "asin<mode>2"
13875   [(use (match_operand:MODEF 0 "register_operand" ""))
13876    (use (match_operand:MODEF 1 "general_operand" ""))]
13877  "TARGET_USE_FANCY_MATH_387
13878    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13879        || TARGET_MIX_SSE_I387)
13880    && flag_unsafe_math_optimizations"
13881 {
13882   rtx op0 = gen_reg_rtx (XFmode);
13883   rtx op1 = gen_reg_rtx (XFmode);
13884
13885   if (optimize_insn_for_size_p ())
13886     FAIL;
13887
13888   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13889   emit_insn (gen_asinxf2 (op0, op1));
13890   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13891   DONE;
13892 })
13893
13894 (define_expand "acosxf2"
13895   [(set (match_dup 2)
13896         (mult:XF (match_operand:XF 1 "register_operand" "")
13897                  (match_dup 1)))
13898    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13899    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13900    (parallel [(set (match_operand:XF 0 "register_operand" "")
13901                    (unspec:XF [(match_dup 1) (match_dup 5)]
13902                               UNSPEC_FPATAN))
13903               (clobber (match_scratch:XF 6 ""))])]
13904   "TARGET_USE_FANCY_MATH_387
13905    && flag_unsafe_math_optimizations"
13906 {
13907   int i;
13908
13909   if (optimize_insn_for_size_p ())
13910     FAIL;
13911
13912   for (i = 2; i < 6; i++)
13913     operands[i] = gen_reg_rtx (XFmode);
13914
13915   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13916 })
13917
13918 (define_expand "acos<mode>2"
13919   [(use (match_operand:MODEF 0 "register_operand" ""))
13920    (use (match_operand:MODEF 1 "general_operand" ""))]
13921  "TARGET_USE_FANCY_MATH_387
13922    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13923        || TARGET_MIX_SSE_I387)
13924    && flag_unsafe_math_optimizations"
13925 {
13926   rtx op0 = gen_reg_rtx (XFmode);
13927   rtx op1 = gen_reg_rtx (XFmode);
13928
13929   if (optimize_insn_for_size_p ())
13930     FAIL;
13931
13932   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13933   emit_insn (gen_acosxf2 (op0, op1));
13934   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13935   DONE;
13936 })
13937
13938 (define_insn "fyl2xxf3_i387"
13939   [(set (match_operand:XF 0 "register_operand" "=f")
13940         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13941                     (match_operand:XF 2 "register_operand" "u")]
13942                    UNSPEC_FYL2X))
13943    (clobber (match_scratch:XF 3 "=2"))]
13944   "TARGET_USE_FANCY_MATH_387
13945    && flag_unsafe_math_optimizations"
13946   "fyl2x"
13947   [(set_attr "type" "fpspc")
13948    (set_attr "mode" "XF")])
13949
13950 (define_insn "fyl2x_extend<mode>xf3_i387"
13951   [(set (match_operand:XF 0 "register_operand" "=f")
13952         (unspec:XF [(float_extend:XF
13953                       (match_operand:MODEF 1 "register_operand" "0"))
13954                     (match_operand:XF 2 "register_operand" "u")]
13955                    UNSPEC_FYL2X))
13956    (clobber (match_scratch:XF 3 "=2"))]
13957   "TARGET_USE_FANCY_MATH_387
13958    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13959        || TARGET_MIX_SSE_I387)
13960    && flag_unsafe_math_optimizations"
13961   "fyl2x"
13962   [(set_attr "type" "fpspc")
13963    (set_attr "mode" "XF")])
13964
13965 (define_expand "logxf2"
13966   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13967                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13968                                (match_dup 2)] UNSPEC_FYL2X))
13969               (clobber (match_scratch:XF 3 ""))])]
13970   "TARGET_USE_FANCY_MATH_387
13971    && flag_unsafe_math_optimizations"
13972 {
13973   operands[2] = gen_reg_rtx (XFmode);
13974   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13975 })
13976
13977 (define_expand "log<mode>2"
13978   [(use (match_operand:MODEF 0 "register_operand" ""))
13979    (use (match_operand:MODEF 1 "register_operand" ""))]
13980   "TARGET_USE_FANCY_MATH_387
13981    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13982        || TARGET_MIX_SSE_I387)
13983    && flag_unsafe_math_optimizations"
13984 {
13985   rtx op0 = gen_reg_rtx (XFmode);
13986
13987   rtx op2 = gen_reg_rtx (XFmode);
13988   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13989
13990   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13991   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13992   DONE;
13993 })
13994
13995 (define_expand "log10xf2"
13996   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13997                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13998                                (match_dup 2)] UNSPEC_FYL2X))
13999               (clobber (match_scratch:XF 3 ""))])]
14000   "TARGET_USE_FANCY_MATH_387
14001    && flag_unsafe_math_optimizations"
14002 {
14003   operands[2] = gen_reg_rtx (XFmode);
14004   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14005 })
14006
14007 (define_expand "log10<mode>2"
14008   [(use (match_operand:MODEF 0 "register_operand" ""))
14009    (use (match_operand:MODEF 1 "register_operand" ""))]
14010   "TARGET_USE_FANCY_MATH_387
14011    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14012        || TARGET_MIX_SSE_I387)
14013    && flag_unsafe_math_optimizations"
14014 {
14015   rtx op0 = gen_reg_rtx (XFmode);
14016
14017   rtx op2 = gen_reg_rtx (XFmode);
14018   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14019
14020   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14021   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14022   DONE;
14023 })
14024
14025 (define_expand "log2xf2"
14026   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14027                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14028                                (match_dup 2)] UNSPEC_FYL2X))
14029               (clobber (match_scratch:XF 3 ""))])]
14030   "TARGET_USE_FANCY_MATH_387
14031    && flag_unsafe_math_optimizations"
14032 {
14033   operands[2] = gen_reg_rtx (XFmode);
14034   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14035 })
14036
14037 (define_expand "log2<mode>2"
14038   [(use (match_operand:MODEF 0 "register_operand" ""))
14039    (use (match_operand:MODEF 1 "register_operand" ""))]
14040   "TARGET_USE_FANCY_MATH_387
14041    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14042        || TARGET_MIX_SSE_I387)
14043    && flag_unsafe_math_optimizations"
14044 {
14045   rtx op0 = gen_reg_rtx (XFmode);
14046
14047   rtx op2 = gen_reg_rtx (XFmode);
14048   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14049
14050   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14051   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14052   DONE;
14053 })
14054
14055 (define_insn "fyl2xp1xf3_i387"
14056   [(set (match_operand:XF 0 "register_operand" "=f")
14057         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14058                     (match_operand:XF 2 "register_operand" "u")]
14059                    UNSPEC_FYL2XP1))
14060    (clobber (match_scratch:XF 3 "=2"))]
14061   "TARGET_USE_FANCY_MATH_387
14062    && flag_unsafe_math_optimizations"
14063   "fyl2xp1"
14064   [(set_attr "type" "fpspc")
14065    (set_attr "mode" "XF")])
14066
14067 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14068   [(set (match_operand:XF 0 "register_operand" "=f")
14069         (unspec:XF [(float_extend:XF
14070                       (match_operand:MODEF 1 "register_operand" "0"))
14071                     (match_operand:XF 2 "register_operand" "u")]
14072                    UNSPEC_FYL2XP1))
14073    (clobber (match_scratch:XF 3 "=2"))]
14074   "TARGET_USE_FANCY_MATH_387
14075    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14076        || TARGET_MIX_SSE_I387)
14077    && flag_unsafe_math_optimizations"
14078   "fyl2xp1"
14079   [(set_attr "type" "fpspc")
14080    (set_attr "mode" "XF")])
14081
14082 (define_expand "log1pxf2"
14083   [(use (match_operand:XF 0 "register_operand" ""))
14084    (use (match_operand:XF 1 "register_operand" ""))]
14085   "TARGET_USE_FANCY_MATH_387
14086    && flag_unsafe_math_optimizations"
14087 {
14088   if (optimize_insn_for_size_p ())
14089     FAIL;
14090
14091   ix86_emit_i387_log1p (operands[0], operands[1]);
14092   DONE;
14093 })
14094
14095 (define_expand "log1p<mode>2"
14096   [(use (match_operand:MODEF 0 "register_operand" ""))
14097    (use (match_operand:MODEF 1 "register_operand" ""))]
14098   "TARGET_USE_FANCY_MATH_387
14099    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14100        || TARGET_MIX_SSE_I387)
14101    && flag_unsafe_math_optimizations"
14102 {
14103   rtx op0;
14104
14105   if (optimize_insn_for_size_p ())
14106     FAIL;
14107
14108   op0 = gen_reg_rtx (XFmode);
14109
14110   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14111
14112   ix86_emit_i387_log1p (op0, operands[1]);
14113   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14114   DONE;
14115 })
14116
14117 (define_insn "fxtractxf3_i387"
14118   [(set (match_operand:XF 0 "register_operand" "=f")
14119         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14120                    UNSPEC_XTRACT_FRACT))
14121    (set (match_operand:XF 1 "register_operand" "=u")
14122         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14123   "TARGET_USE_FANCY_MATH_387
14124    && flag_unsafe_math_optimizations"
14125   "fxtract"
14126   [(set_attr "type" "fpspc")
14127    (set_attr "mode" "XF")])
14128
14129 (define_insn "fxtract_extend<mode>xf3_i387"
14130   [(set (match_operand:XF 0 "register_operand" "=f")
14131         (unspec:XF [(float_extend:XF
14132                       (match_operand:MODEF 2 "register_operand" "0"))]
14133                    UNSPEC_XTRACT_FRACT))
14134    (set (match_operand:XF 1 "register_operand" "=u")
14135         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14136   "TARGET_USE_FANCY_MATH_387
14137    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14138        || TARGET_MIX_SSE_I387)
14139    && flag_unsafe_math_optimizations"
14140   "fxtract"
14141   [(set_attr "type" "fpspc")
14142    (set_attr "mode" "XF")])
14143
14144 (define_expand "logbxf2"
14145   [(parallel [(set (match_dup 2)
14146                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14147                               UNSPEC_XTRACT_FRACT))
14148               (set (match_operand:XF 0 "register_operand" "")
14149                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14150   "TARGET_USE_FANCY_MATH_387
14151    && flag_unsafe_math_optimizations"
14152   "operands[2] = gen_reg_rtx (XFmode);")
14153
14154 (define_expand "logb<mode>2"
14155   [(use (match_operand:MODEF 0 "register_operand" ""))
14156    (use (match_operand:MODEF 1 "register_operand" ""))]
14157   "TARGET_USE_FANCY_MATH_387
14158    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14159        || TARGET_MIX_SSE_I387)
14160    && flag_unsafe_math_optimizations"
14161 {
14162   rtx op0 = gen_reg_rtx (XFmode);
14163   rtx op1 = gen_reg_rtx (XFmode);
14164
14165   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14166   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14167   DONE;
14168 })
14169
14170 (define_expand "ilogbxf2"
14171   [(use (match_operand:SI 0 "register_operand" ""))
14172    (use (match_operand:XF 1 "register_operand" ""))]
14173   "TARGET_USE_FANCY_MATH_387
14174    && flag_unsafe_math_optimizations"
14175 {
14176   rtx op0, op1;
14177
14178   if (optimize_insn_for_size_p ())
14179     FAIL;
14180
14181   op0 = gen_reg_rtx (XFmode);
14182   op1 = gen_reg_rtx (XFmode);
14183
14184   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14185   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14186   DONE;
14187 })
14188
14189 (define_expand "ilogb<mode>2"
14190   [(use (match_operand:SI 0 "register_operand" ""))
14191    (use (match_operand:MODEF 1 "register_operand" ""))]
14192   "TARGET_USE_FANCY_MATH_387
14193    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14194        || TARGET_MIX_SSE_I387)
14195    && flag_unsafe_math_optimizations"
14196 {
14197   rtx op0, op1;
14198
14199   if (optimize_insn_for_size_p ())
14200     FAIL;
14201
14202   op0 = gen_reg_rtx (XFmode);
14203   op1 = gen_reg_rtx (XFmode);
14204
14205   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14206   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14207   DONE;
14208 })
14209
14210 (define_insn "*f2xm1xf2_i387"
14211   [(set (match_operand:XF 0 "register_operand" "=f")
14212         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14213                    UNSPEC_F2XM1))]
14214   "TARGET_USE_FANCY_MATH_387
14215    && flag_unsafe_math_optimizations"
14216   "f2xm1"
14217   [(set_attr "type" "fpspc")
14218    (set_attr "mode" "XF")])
14219
14220 (define_insn "*fscalexf4_i387"
14221   [(set (match_operand:XF 0 "register_operand" "=f")
14222         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14223                     (match_operand:XF 3 "register_operand" "1")]
14224                    UNSPEC_FSCALE_FRACT))
14225    (set (match_operand:XF 1 "register_operand" "=u")
14226         (unspec:XF [(match_dup 2) (match_dup 3)]
14227                    UNSPEC_FSCALE_EXP))]
14228   "TARGET_USE_FANCY_MATH_387
14229    && flag_unsafe_math_optimizations"
14230   "fscale"
14231   [(set_attr "type" "fpspc")
14232    (set_attr "mode" "XF")])
14233
14234 (define_expand "expNcorexf3"
14235   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14236                                (match_operand:XF 2 "register_operand" "")))
14237    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14238    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14239    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14240    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14241    (parallel [(set (match_operand:XF 0 "register_operand" "")
14242                    (unspec:XF [(match_dup 8) (match_dup 4)]
14243                               UNSPEC_FSCALE_FRACT))
14244               (set (match_dup 9)
14245                    (unspec:XF [(match_dup 8) (match_dup 4)]
14246                               UNSPEC_FSCALE_EXP))])]
14247   "TARGET_USE_FANCY_MATH_387
14248    && flag_unsafe_math_optimizations"
14249 {
14250   int i;
14251
14252   if (optimize_insn_for_size_p ())
14253     FAIL;
14254
14255   for (i = 3; i < 10; i++)
14256     operands[i] = gen_reg_rtx (XFmode);
14257
14258   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14259 })
14260
14261 (define_expand "expxf2"
14262   [(use (match_operand:XF 0 "register_operand" ""))
14263    (use (match_operand:XF 1 "register_operand" ""))]
14264   "TARGET_USE_FANCY_MATH_387
14265    && flag_unsafe_math_optimizations"
14266 {
14267   rtx op2;
14268
14269   if (optimize_insn_for_size_p ())
14270     FAIL;
14271
14272   op2 = gen_reg_rtx (XFmode);
14273   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14274
14275   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14276   DONE;
14277 })
14278
14279 (define_expand "exp<mode>2"
14280   [(use (match_operand:MODEF 0 "register_operand" ""))
14281    (use (match_operand:MODEF 1 "general_operand" ""))]
14282  "TARGET_USE_FANCY_MATH_387
14283    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14284        || TARGET_MIX_SSE_I387)
14285    && flag_unsafe_math_optimizations"
14286 {
14287   rtx op0, op1;
14288
14289   if (optimize_insn_for_size_p ())
14290     FAIL;
14291
14292   op0 = gen_reg_rtx (XFmode);
14293   op1 = gen_reg_rtx (XFmode);
14294
14295   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14296   emit_insn (gen_expxf2 (op0, op1));
14297   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14298   DONE;
14299 })
14300
14301 (define_expand "exp10xf2"
14302   [(use (match_operand:XF 0 "register_operand" ""))
14303    (use (match_operand:XF 1 "register_operand" ""))]
14304   "TARGET_USE_FANCY_MATH_387
14305    && flag_unsafe_math_optimizations"
14306 {
14307   rtx op2;
14308
14309   if (optimize_insn_for_size_p ())
14310     FAIL;
14311
14312   op2 = gen_reg_rtx (XFmode);
14313   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14314
14315   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14316   DONE;
14317 })
14318
14319 (define_expand "exp10<mode>2"
14320   [(use (match_operand:MODEF 0 "register_operand" ""))
14321    (use (match_operand:MODEF 1 "general_operand" ""))]
14322  "TARGET_USE_FANCY_MATH_387
14323    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14324        || TARGET_MIX_SSE_I387)
14325    && flag_unsafe_math_optimizations"
14326 {
14327   rtx op0, op1;
14328
14329   if (optimize_insn_for_size_p ())
14330     FAIL;
14331
14332   op0 = gen_reg_rtx (XFmode);
14333   op1 = gen_reg_rtx (XFmode);
14334
14335   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14336   emit_insn (gen_exp10xf2 (op0, op1));
14337   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14338   DONE;
14339 })
14340
14341 (define_expand "exp2xf2"
14342   [(use (match_operand:XF 0 "register_operand" ""))
14343    (use (match_operand:XF 1 "register_operand" ""))]
14344   "TARGET_USE_FANCY_MATH_387
14345    && flag_unsafe_math_optimizations"
14346 {
14347   rtx op2;
14348
14349   if (optimize_insn_for_size_p ())
14350     FAIL;
14351
14352   op2 = gen_reg_rtx (XFmode);
14353   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14354
14355   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14356   DONE;
14357 })
14358
14359 (define_expand "exp2<mode>2"
14360   [(use (match_operand:MODEF 0 "register_operand" ""))
14361    (use (match_operand:MODEF 1 "general_operand" ""))]
14362  "TARGET_USE_FANCY_MATH_387
14363    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14364        || TARGET_MIX_SSE_I387)
14365    && flag_unsafe_math_optimizations"
14366 {
14367   rtx op0, op1;
14368
14369   if (optimize_insn_for_size_p ())
14370     FAIL;
14371
14372   op0 = gen_reg_rtx (XFmode);
14373   op1 = gen_reg_rtx (XFmode);
14374
14375   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14376   emit_insn (gen_exp2xf2 (op0, op1));
14377   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14378   DONE;
14379 })
14380
14381 (define_expand "expm1xf2"
14382   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14383                                (match_dup 2)))
14384    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14385    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14386    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14387    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14388    (parallel [(set (match_dup 7)
14389                    (unspec:XF [(match_dup 6) (match_dup 4)]
14390                               UNSPEC_FSCALE_FRACT))
14391               (set (match_dup 8)
14392                    (unspec:XF [(match_dup 6) (match_dup 4)]
14393                               UNSPEC_FSCALE_EXP))])
14394    (parallel [(set (match_dup 10)
14395                    (unspec:XF [(match_dup 9) (match_dup 8)]
14396                               UNSPEC_FSCALE_FRACT))
14397               (set (match_dup 11)
14398                    (unspec:XF [(match_dup 9) (match_dup 8)]
14399                               UNSPEC_FSCALE_EXP))])
14400    (set (match_dup 12) (minus:XF (match_dup 10)
14401                                  (float_extend:XF (match_dup 13))))
14402    (set (match_operand:XF 0 "register_operand" "")
14403         (plus:XF (match_dup 12) (match_dup 7)))]
14404   "TARGET_USE_FANCY_MATH_387
14405    && flag_unsafe_math_optimizations"
14406 {
14407   int i;
14408
14409   if (optimize_insn_for_size_p ())
14410     FAIL;
14411
14412   for (i = 2; i < 13; i++)
14413     operands[i] = gen_reg_rtx (XFmode);
14414
14415   operands[13]
14416     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14417
14418   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14419 })
14420
14421 (define_expand "expm1<mode>2"
14422   [(use (match_operand:MODEF 0 "register_operand" ""))
14423    (use (match_operand:MODEF 1 "general_operand" ""))]
14424  "TARGET_USE_FANCY_MATH_387
14425    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14426        || TARGET_MIX_SSE_I387)
14427    && flag_unsafe_math_optimizations"
14428 {
14429   rtx op0, op1;
14430
14431   if (optimize_insn_for_size_p ())
14432     FAIL;
14433
14434   op0 = gen_reg_rtx (XFmode);
14435   op1 = gen_reg_rtx (XFmode);
14436
14437   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14438   emit_insn (gen_expm1xf2 (op0, op1));
14439   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14440   DONE;
14441 })
14442
14443 (define_expand "ldexpxf3"
14444   [(set (match_dup 3)
14445         (float:XF (match_operand:SI 2 "register_operand" "")))
14446    (parallel [(set (match_operand:XF 0 " register_operand" "")
14447                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14448                                (match_dup 3)]
14449                               UNSPEC_FSCALE_FRACT))
14450               (set (match_dup 4)
14451                    (unspec:XF [(match_dup 1) (match_dup 3)]
14452                               UNSPEC_FSCALE_EXP))])]
14453   "TARGET_USE_FANCY_MATH_387
14454    && flag_unsafe_math_optimizations"
14455 {
14456   if (optimize_insn_for_size_p ())
14457     FAIL;
14458
14459   operands[3] = gen_reg_rtx (XFmode);
14460   operands[4] = gen_reg_rtx (XFmode);
14461 })
14462
14463 (define_expand "ldexp<mode>3"
14464   [(use (match_operand:MODEF 0 "register_operand" ""))
14465    (use (match_operand:MODEF 1 "general_operand" ""))
14466    (use (match_operand:SI 2 "register_operand" ""))]
14467  "TARGET_USE_FANCY_MATH_387
14468    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14469        || TARGET_MIX_SSE_I387)
14470    && flag_unsafe_math_optimizations"
14471 {
14472   rtx op0, op1;
14473
14474   if (optimize_insn_for_size_p ())
14475     FAIL;
14476
14477   op0 = gen_reg_rtx (XFmode);
14478   op1 = gen_reg_rtx (XFmode);
14479
14480   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14481   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14482   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14483   DONE;
14484 })
14485
14486 (define_expand "scalbxf3"
14487   [(parallel [(set (match_operand:XF 0 " register_operand" "")
14488                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14489                                (match_operand:XF 2 "register_operand" "")]
14490                               UNSPEC_FSCALE_FRACT))
14491               (set (match_dup 3)
14492                    (unspec:XF [(match_dup 1) (match_dup 2)]
14493                               UNSPEC_FSCALE_EXP))])]
14494   "TARGET_USE_FANCY_MATH_387
14495    && flag_unsafe_math_optimizations"
14496 {
14497   if (optimize_insn_for_size_p ())
14498     FAIL;
14499
14500   operands[3] = gen_reg_rtx (XFmode);
14501 })
14502
14503 (define_expand "scalb<mode>3"
14504   [(use (match_operand:MODEF 0 "register_operand" ""))
14505    (use (match_operand:MODEF 1 "general_operand" ""))
14506    (use (match_operand:MODEF 2 "general_operand" ""))]
14507  "TARGET_USE_FANCY_MATH_387
14508    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14509        || TARGET_MIX_SSE_I387)
14510    && flag_unsafe_math_optimizations"
14511 {
14512   rtx op0, op1, op2;
14513
14514   if (optimize_insn_for_size_p ())
14515     FAIL;
14516
14517   op0 = gen_reg_rtx (XFmode);
14518   op1 = gen_reg_rtx (XFmode);
14519   op2 = gen_reg_rtx (XFmode);
14520
14521   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14522   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14523   emit_insn (gen_scalbxf3 (op0, op1, op2));
14524   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14525   DONE;
14526 })
14527
14528 (define_expand "significandxf2"
14529   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14530                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14531                               UNSPEC_XTRACT_FRACT))
14532               (set (match_dup 2)
14533                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14534   "TARGET_USE_FANCY_MATH_387
14535    && flag_unsafe_math_optimizations"
14536   "operands[2] = gen_reg_rtx (XFmode);")
14537
14538 (define_expand "significand<mode>2"
14539   [(use (match_operand:MODEF 0 "register_operand" ""))
14540    (use (match_operand:MODEF 1 "register_operand" ""))]
14541   "TARGET_USE_FANCY_MATH_387
14542    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14543        || TARGET_MIX_SSE_I387)
14544    && flag_unsafe_math_optimizations"
14545 {
14546   rtx op0 = gen_reg_rtx (XFmode);
14547   rtx op1 = gen_reg_rtx (XFmode);
14548
14549   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14550   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14551   DONE;
14552 })
14553 \f
14554
14555 (define_insn "sse4_1_round<mode>2"
14556   [(set (match_operand:MODEF 0 "register_operand" "=x")
14557         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14558                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14559                       UNSPEC_ROUND))]
14560   "TARGET_ROUND"
14561   "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14562   [(set_attr "type" "ssecvt")
14563    (set_attr "prefix_extra" "1")
14564    (set_attr "prefix" "maybe_vex")
14565    (set_attr "mode" "<MODE>")])
14566
14567 (define_insn "rintxf2"
14568   [(set (match_operand:XF 0 "register_operand" "=f")
14569         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14570                    UNSPEC_FRNDINT))]
14571   "TARGET_USE_FANCY_MATH_387
14572    && flag_unsafe_math_optimizations"
14573   "frndint"
14574   [(set_attr "type" "fpspc")
14575    (set_attr "mode" "XF")])
14576
14577 (define_expand "rint<mode>2"
14578   [(use (match_operand:MODEF 0 "register_operand" ""))
14579    (use (match_operand:MODEF 1 "register_operand" ""))]
14580   "(TARGET_USE_FANCY_MATH_387
14581     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14582         || TARGET_MIX_SSE_I387)
14583     && flag_unsafe_math_optimizations)
14584    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14585        && !flag_trapping_math)"
14586 {
14587   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14588       && !flag_trapping_math)
14589     {
14590       if (TARGET_ROUND)
14591         emit_insn (gen_sse4_1_round<mode>2
14592                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14593       else if (optimize_insn_for_size_p ())
14594         FAIL;
14595       else
14596         ix86_expand_rint (operands[0], operands[1]);
14597     }
14598   else
14599     {
14600       rtx op0 = gen_reg_rtx (XFmode);
14601       rtx op1 = gen_reg_rtx (XFmode);
14602
14603       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14604       emit_insn (gen_rintxf2 (op0, op1));
14605
14606       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14607     }
14608   DONE;
14609 })
14610
14611 (define_expand "round<mode>2"
14612   [(match_operand:X87MODEF 0 "register_operand" "")
14613    (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14614   "(TARGET_USE_FANCY_MATH_387
14615     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14616         || TARGET_MIX_SSE_I387)
14617     && flag_unsafe_math_optimizations)
14618    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14619        && !flag_trapping_math && !flag_rounding_math)"
14620 {
14621   if (optimize_insn_for_size_p ())
14622     FAIL;
14623
14624   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14625       && !flag_trapping_math && !flag_rounding_math)
14626     {
14627       if (TARGET_ROUND)
14628         {
14629           operands[1] = force_reg (<MODE>mode, operands[1]);
14630           ix86_expand_round_sse4 (operands[0], operands[1]);
14631         }
14632       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14633         ix86_expand_round (operands[0], operands[1]);
14634       else
14635         ix86_expand_rounddf_32 (operands[0], operands[1]);
14636     }
14637   else
14638     {
14639       operands[1] = force_reg (<MODE>mode, operands[1]);
14640       ix86_emit_i387_round (operands[0], operands[1]);
14641     }
14642   DONE;
14643 })
14644
14645 (define_insn_and_split "*fistdi2_1"
14646   [(set (match_operand:DI 0 "nonimmediate_operand" "")
14647         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14648                    UNSPEC_FIST))]
14649   "TARGET_USE_FANCY_MATH_387
14650    && can_create_pseudo_p ()"
14651   "#"
14652   "&& 1"
14653   [(const_int 0)]
14654 {
14655   if (memory_operand (operands[0], VOIDmode))
14656     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14657   else
14658     {
14659       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14660       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14661                                          operands[2]));
14662     }
14663   DONE;
14664 }
14665   [(set_attr "type" "fpspc")
14666    (set_attr "mode" "DI")])
14667
14668 (define_insn "fistdi2"
14669   [(set (match_operand:DI 0 "memory_operand" "=m")
14670         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14671                    UNSPEC_FIST))
14672    (clobber (match_scratch:XF 2 "=&1f"))]
14673   "TARGET_USE_FANCY_MATH_387"
14674   "* return output_fix_trunc (insn, operands, false);"
14675   [(set_attr "type" "fpspc")
14676    (set_attr "mode" "DI")])
14677
14678 (define_insn "fistdi2_with_temp"
14679   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14680         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14681                    UNSPEC_FIST))
14682    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14683    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14684   "TARGET_USE_FANCY_MATH_387"
14685   "#"
14686   [(set_attr "type" "fpspc")
14687    (set_attr "mode" "DI")])
14688
14689 (define_split
14690   [(set (match_operand:DI 0 "register_operand" "")
14691         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14692                    UNSPEC_FIST))
14693    (clobber (match_operand:DI 2 "memory_operand" ""))
14694    (clobber (match_scratch 3 ""))]
14695   "reload_completed"
14696   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14697               (clobber (match_dup 3))])
14698    (set (match_dup 0) (match_dup 2))])
14699
14700 (define_split
14701   [(set (match_operand:DI 0 "memory_operand" "")
14702         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14703                    UNSPEC_FIST))
14704    (clobber (match_operand:DI 2 "memory_operand" ""))
14705    (clobber (match_scratch 3 ""))]
14706   "reload_completed"
14707   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14708               (clobber (match_dup 3))])])
14709
14710 (define_insn_and_split "*fist<mode>2_1"
14711   [(set (match_operand:SWI24 0 "register_operand" "")
14712         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14713                       UNSPEC_FIST))]
14714   "TARGET_USE_FANCY_MATH_387
14715    && can_create_pseudo_p ()"
14716   "#"
14717   "&& 1"
14718   [(const_int 0)]
14719 {
14720   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14721   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14722                                         operands[2]));
14723   DONE;
14724 }
14725   [(set_attr "type" "fpspc")
14726    (set_attr "mode" "<MODE>")])
14727
14728 (define_insn "fist<mode>2"
14729   [(set (match_operand:SWI24 0 "memory_operand" "=m")
14730         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14731                       UNSPEC_FIST))]
14732   "TARGET_USE_FANCY_MATH_387"
14733   "* return output_fix_trunc (insn, operands, false);"
14734   [(set_attr "type" "fpspc")
14735    (set_attr "mode" "<MODE>")])
14736
14737 (define_insn "fist<mode>2_with_temp"
14738   [(set (match_operand:SWI24 0 "register_operand" "=r")
14739         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14740                       UNSPEC_FIST))
14741    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14742   "TARGET_USE_FANCY_MATH_387"
14743   "#"
14744   [(set_attr "type" "fpspc")
14745    (set_attr "mode" "<MODE>")])
14746
14747 (define_split
14748   [(set (match_operand:SWI24 0 "register_operand" "")
14749         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14750                       UNSPEC_FIST))
14751    (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14752   "reload_completed"
14753   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14754    (set (match_dup 0) (match_dup 2))])
14755
14756 (define_split
14757   [(set (match_operand:SWI24 0 "memory_operand" "")
14758         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14759                       UNSPEC_FIST))
14760    (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14761   "reload_completed"
14762   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14763
14764 (define_expand "lrintxf<mode>2"
14765   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14766      (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14767                      UNSPEC_FIST))]
14768   "TARGET_USE_FANCY_MATH_387")
14769
14770 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14771   [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14772      (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14773                         UNSPEC_FIX_NOTRUNC))]
14774   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14775    && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14776
14777 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14778   [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14779    (match_operand:X87MODEF 1 "register_operand" "")]
14780   "(TARGET_USE_FANCY_MATH_387
14781     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14782         || TARGET_MIX_SSE_I387)
14783     && flag_unsafe_math_optimizations)
14784    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14785        && <SWI248x:MODE>mode != HImode 
14786        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14787        && !flag_trapping_math && !flag_rounding_math)"
14788 {
14789   if (optimize_insn_for_size_p ())
14790     FAIL;
14791
14792   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14793       && <SWI248x:MODE>mode != HImode
14794       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14795       && !flag_trapping_math && !flag_rounding_math)
14796     ix86_expand_lround (operands[0], operands[1]);
14797   else
14798     ix86_emit_i387_round (operands[0], operands[1]);
14799   DONE;
14800 })
14801
14802 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14803 (define_insn_and_split "frndintxf2_floor"
14804   [(set (match_operand:XF 0 "register_operand" "")
14805         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14806          UNSPEC_FRNDINT_FLOOR))
14807    (clobber (reg:CC FLAGS_REG))]
14808   "TARGET_USE_FANCY_MATH_387
14809    && flag_unsafe_math_optimizations
14810    && can_create_pseudo_p ()"
14811   "#"
14812   "&& 1"
14813   [(const_int 0)]
14814 {
14815   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14816
14817   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14818   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14819
14820   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14821                                         operands[2], operands[3]));
14822   DONE;
14823 }
14824   [(set_attr "type" "frndint")
14825    (set_attr "i387_cw" "floor")
14826    (set_attr "mode" "XF")])
14827
14828 (define_insn "frndintxf2_floor_i387"
14829   [(set (match_operand:XF 0 "register_operand" "=f")
14830         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14831          UNSPEC_FRNDINT_FLOOR))
14832    (use (match_operand:HI 2 "memory_operand" "m"))
14833    (use (match_operand:HI 3 "memory_operand" "m"))]
14834   "TARGET_USE_FANCY_MATH_387
14835    && flag_unsafe_math_optimizations"
14836   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14837   [(set_attr "type" "frndint")
14838    (set_attr "i387_cw" "floor")
14839    (set_attr "mode" "XF")])
14840
14841 (define_expand "floorxf2"
14842   [(use (match_operand:XF 0 "register_operand" ""))
14843    (use (match_operand:XF 1 "register_operand" ""))]
14844   "TARGET_USE_FANCY_MATH_387
14845    && flag_unsafe_math_optimizations"
14846 {
14847   if (optimize_insn_for_size_p ())
14848     FAIL;
14849   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14850   DONE;
14851 })
14852
14853 (define_expand "floor<mode>2"
14854   [(use (match_operand:MODEF 0 "register_operand" ""))
14855    (use (match_operand:MODEF 1 "register_operand" ""))]
14856   "(TARGET_USE_FANCY_MATH_387
14857     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14858         || TARGET_MIX_SSE_I387)
14859     && flag_unsafe_math_optimizations)
14860    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14861        && !flag_trapping_math)"
14862 {
14863   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14864       && !flag_trapping_math)
14865     {
14866       if (TARGET_ROUND)
14867         emit_insn (gen_sse4_1_round<mode>2
14868                    (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14869       else if (optimize_insn_for_size_p ())
14870         FAIL;
14871       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14872         ix86_expand_floorceil (operands[0], operands[1], true);
14873       else
14874         ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14875     }
14876   else
14877     {
14878       rtx op0, op1;
14879
14880       if (optimize_insn_for_size_p ())
14881         FAIL;
14882
14883       op0 = gen_reg_rtx (XFmode);
14884       op1 = gen_reg_rtx (XFmode);
14885       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14886       emit_insn (gen_frndintxf2_floor (op0, op1));
14887
14888       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14889     }
14890   DONE;
14891 })
14892
14893 (define_insn_and_split "*fist<mode>2_floor_1"
14894   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14895         (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14896                         UNSPEC_FIST_FLOOR))
14897    (clobber (reg:CC FLAGS_REG))]
14898   "TARGET_USE_FANCY_MATH_387
14899    && flag_unsafe_math_optimizations
14900    && can_create_pseudo_p ()"
14901   "#"
14902   "&& 1"
14903   [(const_int 0)]
14904 {
14905   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14906
14907   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14908   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14909   if (memory_operand (operands[0], VOIDmode))
14910     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14911                                       operands[2], operands[3]));
14912   else
14913     {
14914       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14915       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14916                                                   operands[2], operands[3],
14917                                                   operands[4]));
14918     }
14919   DONE;
14920 }
14921   [(set_attr "type" "fistp")
14922    (set_attr "i387_cw" "floor")
14923    (set_attr "mode" "<MODE>")])
14924
14925 (define_insn "fistdi2_floor"
14926   [(set (match_operand:DI 0 "memory_operand" "=m")
14927         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14928                    UNSPEC_FIST_FLOOR))
14929    (use (match_operand:HI 2 "memory_operand" "m"))
14930    (use (match_operand:HI 3 "memory_operand" "m"))
14931    (clobber (match_scratch:XF 4 "=&1f"))]
14932   "TARGET_USE_FANCY_MATH_387
14933    && flag_unsafe_math_optimizations"
14934   "* return output_fix_trunc (insn, operands, false);"
14935   [(set_attr "type" "fistp")
14936    (set_attr "i387_cw" "floor")
14937    (set_attr "mode" "DI")])
14938
14939 (define_insn "fistdi2_floor_with_temp"
14940   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14941         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14942                    UNSPEC_FIST_FLOOR))
14943    (use (match_operand:HI 2 "memory_operand" "m,m"))
14944    (use (match_operand:HI 3 "memory_operand" "m,m"))
14945    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14946    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14947   "TARGET_USE_FANCY_MATH_387
14948    && flag_unsafe_math_optimizations"
14949   "#"
14950   [(set_attr "type" "fistp")
14951    (set_attr "i387_cw" "floor")
14952    (set_attr "mode" "DI")])
14953
14954 (define_split
14955   [(set (match_operand:DI 0 "register_operand" "")
14956         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14957                    UNSPEC_FIST_FLOOR))
14958    (use (match_operand:HI 2 "memory_operand" ""))
14959    (use (match_operand:HI 3 "memory_operand" ""))
14960    (clobber (match_operand:DI 4 "memory_operand" ""))
14961    (clobber (match_scratch 5 ""))]
14962   "reload_completed"
14963   [(parallel [(set (match_dup 4)
14964                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14965               (use (match_dup 2))
14966               (use (match_dup 3))
14967               (clobber (match_dup 5))])
14968    (set (match_dup 0) (match_dup 4))])
14969
14970 (define_split
14971   [(set (match_operand:DI 0 "memory_operand" "")
14972         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14973                    UNSPEC_FIST_FLOOR))
14974    (use (match_operand:HI 2 "memory_operand" ""))
14975    (use (match_operand:HI 3 "memory_operand" ""))
14976    (clobber (match_operand:DI 4 "memory_operand" ""))
14977    (clobber (match_scratch 5 ""))]
14978   "reload_completed"
14979   [(parallel [(set (match_dup 0)
14980                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14981               (use (match_dup 2))
14982               (use (match_dup 3))
14983               (clobber (match_dup 5))])])
14984
14985 (define_insn "fist<mode>2_floor"
14986   [(set (match_operand:SWI24 0 "memory_operand" "=m")
14987         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14988                       UNSPEC_FIST_FLOOR))
14989    (use (match_operand:HI 2 "memory_operand" "m"))
14990    (use (match_operand:HI 3 "memory_operand" "m"))]
14991   "TARGET_USE_FANCY_MATH_387
14992    && flag_unsafe_math_optimizations"
14993   "* return output_fix_trunc (insn, operands, false);"
14994   [(set_attr "type" "fistp")
14995    (set_attr "i387_cw" "floor")
14996    (set_attr "mode" "<MODE>")])
14997
14998 (define_insn "fist<mode>2_floor_with_temp"
14999   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15000         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15001                       UNSPEC_FIST_FLOOR))
15002    (use (match_operand:HI 2 "memory_operand" "m,m"))
15003    (use (match_operand:HI 3 "memory_operand" "m,m"))
15004    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15005   "TARGET_USE_FANCY_MATH_387
15006    && flag_unsafe_math_optimizations"
15007   "#"
15008   [(set_attr "type" "fistp")
15009    (set_attr "i387_cw" "floor")
15010    (set_attr "mode" "<MODE>")])
15011
15012 (define_split
15013   [(set (match_operand:SWI24 0 "register_operand" "")
15014         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15015                       UNSPEC_FIST_FLOOR))
15016    (use (match_operand:HI 2 "memory_operand" ""))
15017    (use (match_operand:HI 3 "memory_operand" ""))
15018    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15019   "reload_completed"
15020   [(parallel [(set (match_dup 4)
15021                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15022               (use (match_dup 2))
15023               (use (match_dup 3))])
15024    (set (match_dup 0) (match_dup 4))])
15025
15026 (define_split
15027   [(set (match_operand:SWI24 0 "memory_operand" "")
15028         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15029                       UNSPEC_FIST_FLOOR))
15030    (use (match_operand:HI 2 "memory_operand" ""))
15031    (use (match_operand:HI 3 "memory_operand" ""))
15032    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15033   "reload_completed"
15034   [(parallel [(set (match_dup 0)
15035                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15036               (use (match_dup 2))
15037               (use (match_dup 3))])])
15038
15039 (define_expand "lfloorxf<mode>2"
15040   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15041                    (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15042                                    UNSPEC_FIST_FLOOR))
15043               (clobber (reg:CC FLAGS_REG))])]
15044   "TARGET_USE_FANCY_MATH_387
15045    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15046    && flag_unsafe_math_optimizations")
15047
15048 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15049   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15050    (match_operand:MODEF 1 "register_operand" "")]
15051   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15052    && !flag_trapping_math"
15053 {
15054   if (TARGET_64BIT && optimize_insn_for_size_p ())
15055     FAIL;
15056   ix86_expand_lfloorceil (operands[0], operands[1], true);
15057   DONE;
15058 })
15059
15060 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15061 (define_insn_and_split "frndintxf2_ceil"
15062   [(set (match_operand:XF 0 "register_operand" "")
15063         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15064          UNSPEC_FRNDINT_CEIL))
15065    (clobber (reg:CC FLAGS_REG))]
15066   "TARGET_USE_FANCY_MATH_387
15067    && flag_unsafe_math_optimizations
15068    && can_create_pseudo_p ()"
15069   "#"
15070   "&& 1"
15071   [(const_int 0)]
15072 {
15073   ix86_optimize_mode_switching[I387_CEIL] = 1;
15074
15075   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15076   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15077
15078   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15079                                        operands[2], operands[3]));
15080   DONE;
15081 }
15082   [(set_attr "type" "frndint")
15083    (set_attr "i387_cw" "ceil")
15084    (set_attr "mode" "XF")])
15085
15086 (define_insn "frndintxf2_ceil_i387"
15087   [(set (match_operand:XF 0 "register_operand" "=f")
15088         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15089          UNSPEC_FRNDINT_CEIL))
15090    (use (match_operand:HI 2 "memory_operand" "m"))
15091    (use (match_operand:HI 3 "memory_operand" "m"))]
15092   "TARGET_USE_FANCY_MATH_387
15093    && flag_unsafe_math_optimizations"
15094   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15095   [(set_attr "type" "frndint")
15096    (set_attr "i387_cw" "ceil")
15097    (set_attr "mode" "XF")])
15098
15099 (define_expand "ceilxf2"
15100   [(use (match_operand:XF 0 "register_operand" ""))
15101    (use (match_operand:XF 1 "register_operand" ""))]
15102   "TARGET_USE_FANCY_MATH_387
15103    && flag_unsafe_math_optimizations"
15104 {
15105   if (optimize_insn_for_size_p ())
15106     FAIL;
15107   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15108   DONE;
15109 })
15110
15111 (define_expand "ceil<mode>2"
15112   [(use (match_operand:MODEF 0 "register_operand" ""))
15113    (use (match_operand:MODEF 1 "register_operand" ""))]
15114   "(TARGET_USE_FANCY_MATH_387
15115     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15116         || TARGET_MIX_SSE_I387)
15117     && flag_unsafe_math_optimizations)
15118    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15119        && !flag_trapping_math)"
15120 {
15121   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15122       && !flag_trapping_math)
15123     {
15124       if (TARGET_ROUND)
15125         emit_insn (gen_sse4_1_round<mode>2
15126                    (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15127       else if (optimize_insn_for_size_p ())
15128         FAIL;
15129       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15130         ix86_expand_floorceil (operands[0], operands[1], false);
15131       else
15132         ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15133     }
15134   else
15135     {
15136       rtx op0, op1;
15137
15138       if (optimize_insn_for_size_p ())
15139         FAIL;
15140
15141       op0 = gen_reg_rtx (XFmode);
15142       op1 = gen_reg_rtx (XFmode);
15143       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15144       emit_insn (gen_frndintxf2_ceil (op0, op1));
15145
15146       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15147     }
15148   DONE;
15149 })
15150
15151 (define_insn_and_split "*fist<mode>2_ceil_1"
15152   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15153         (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15154                         UNSPEC_FIST_CEIL))
15155    (clobber (reg:CC FLAGS_REG))]
15156   "TARGET_USE_FANCY_MATH_387
15157    && flag_unsafe_math_optimizations
15158    && can_create_pseudo_p ()"
15159   "#"
15160   "&& 1"
15161   [(const_int 0)]
15162 {
15163   ix86_optimize_mode_switching[I387_CEIL] = 1;
15164
15165   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15166   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15167   if (memory_operand (operands[0], VOIDmode))
15168     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15169                                      operands[2], operands[3]));
15170   else
15171     {
15172       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15173       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15174                                                  operands[2], operands[3],
15175                                                  operands[4]));
15176     }
15177   DONE;
15178 }
15179   [(set_attr "type" "fistp")
15180    (set_attr "i387_cw" "ceil")
15181    (set_attr "mode" "<MODE>")])
15182
15183 (define_insn "fistdi2_ceil"
15184   [(set (match_operand:DI 0 "memory_operand" "=m")
15185         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15186                    UNSPEC_FIST_CEIL))
15187    (use (match_operand:HI 2 "memory_operand" "m"))
15188    (use (match_operand:HI 3 "memory_operand" "m"))
15189    (clobber (match_scratch:XF 4 "=&1f"))]
15190   "TARGET_USE_FANCY_MATH_387
15191    && flag_unsafe_math_optimizations"
15192   "* return output_fix_trunc (insn, operands, false);"
15193   [(set_attr "type" "fistp")
15194    (set_attr "i387_cw" "ceil")
15195    (set_attr "mode" "DI")])
15196
15197 (define_insn "fistdi2_ceil_with_temp"
15198   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15199         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15200                    UNSPEC_FIST_CEIL))
15201    (use (match_operand:HI 2 "memory_operand" "m,m"))
15202    (use (match_operand:HI 3 "memory_operand" "m,m"))
15203    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15204    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15205   "TARGET_USE_FANCY_MATH_387
15206    && flag_unsafe_math_optimizations"
15207   "#"
15208   [(set_attr "type" "fistp")
15209    (set_attr "i387_cw" "ceil")
15210    (set_attr "mode" "DI")])
15211
15212 (define_split
15213   [(set (match_operand:DI 0 "register_operand" "")
15214         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15215                    UNSPEC_FIST_CEIL))
15216    (use (match_operand:HI 2 "memory_operand" ""))
15217    (use (match_operand:HI 3 "memory_operand" ""))
15218    (clobber (match_operand:DI 4 "memory_operand" ""))
15219    (clobber (match_scratch 5 ""))]
15220   "reload_completed"
15221   [(parallel [(set (match_dup 4)
15222                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15223               (use (match_dup 2))
15224               (use (match_dup 3))
15225               (clobber (match_dup 5))])
15226    (set (match_dup 0) (match_dup 4))])
15227
15228 (define_split
15229   [(set (match_operand:DI 0 "memory_operand" "")
15230         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15231                    UNSPEC_FIST_CEIL))
15232    (use (match_operand:HI 2 "memory_operand" ""))
15233    (use (match_operand:HI 3 "memory_operand" ""))
15234    (clobber (match_operand:DI 4 "memory_operand" ""))
15235    (clobber (match_scratch 5 ""))]
15236   "reload_completed"
15237   [(parallel [(set (match_dup 0)
15238                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15239               (use (match_dup 2))
15240               (use (match_dup 3))
15241               (clobber (match_dup 5))])])
15242
15243 (define_insn "fist<mode>2_ceil"
15244   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15245         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15246                       UNSPEC_FIST_CEIL))
15247    (use (match_operand:HI 2 "memory_operand" "m"))
15248    (use (match_operand:HI 3 "memory_operand" "m"))]
15249   "TARGET_USE_FANCY_MATH_387
15250    && flag_unsafe_math_optimizations"
15251   "* return output_fix_trunc (insn, operands, false);"
15252   [(set_attr "type" "fistp")
15253    (set_attr "i387_cw" "ceil")
15254    (set_attr "mode" "<MODE>")])
15255
15256 (define_insn "fist<mode>2_ceil_with_temp"
15257   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15258         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15259                       UNSPEC_FIST_CEIL))
15260    (use (match_operand:HI 2 "memory_operand" "m,m"))
15261    (use (match_operand:HI 3 "memory_operand" "m,m"))
15262    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15263   "TARGET_USE_FANCY_MATH_387
15264    && flag_unsafe_math_optimizations"
15265   "#"
15266   [(set_attr "type" "fistp")
15267    (set_attr "i387_cw" "ceil")
15268    (set_attr "mode" "<MODE>")])
15269
15270 (define_split
15271   [(set (match_operand:SWI24 0 "register_operand" "")
15272         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15273                       UNSPEC_FIST_CEIL))
15274    (use (match_operand:HI 2 "memory_operand" ""))
15275    (use (match_operand:HI 3 "memory_operand" ""))
15276    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15277   "reload_completed"
15278   [(parallel [(set (match_dup 4)
15279                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15280               (use (match_dup 2))
15281               (use (match_dup 3))])
15282    (set (match_dup 0) (match_dup 4))])
15283
15284 (define_split
15285   [(set (match_operand:SWI24 0 "memory_operand" "")
15286         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15287                       UNSPEC_FIST_CEIL))
15288    (use (match_operand:HI 2 "memory_operand" ""))
15289    (use (match_operand:HI 3 "memory_operand" ""))
15290    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15291   "reload_completed"
15292   [(parallel [(set (match_dup 0)
15293                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15294               (use (match_dup 2))
15295               (use (match_dup 3))])])
15296
15297 (define_expand "lceilxf<mode>2"
15298   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15299                    (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15300                                    UNSPEC_FIST_CEIL))
15301               (clobber (reg:CC FLAGS_REG))])]
15302   "TARGET_USE_FANCY_MATH_387
15303    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15304    && flag_unsafe_math_optimizations")
15305
15306 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15307   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15308    (match_operand:MODEF 1 "register_operand" "")]
15309   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15310    && !flag_trapping_math"
15311 {
15312   ix86_expand_lfloorceil (operands[0], operands[1], false);
15313   DONE;
15314 })
15315
15316 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15317 (define_insn_and_split "frndintxf2_trunc"
15318   [(set (match_operand:XF 0 "register_operand" "")
15319         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15320          UNSPEC_FRNDINT_TRUNC))
15321    (clobber (reg:CC FLAGS_REG))]
15322   "TARGET_USE_FANCY_MATH_387
15323    && flag_unsafe_math_optimizations
15324    && can_create_pseudo_p ()"
15325   "#"
15326   "&& 1"
15327   [(const_int 0)]
15328 {
15329   ix86_optimize_mode_switching[I387_TRUNC] = 1;
15330
15331   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15332   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15333
15334   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15335                                         operands[2], operands[3]));
15336   DONE;
15337 }
15338   [(set_attr "type" "frndint")
15339    (set_attr "i387_cw" "trunc")
15340    (set_attr "mode" "XF")])
15341
15342 (define_insn "frndintxf2_trunc_i387"
15343   [(set (match_operand:XF 0 "register_operand" "=f")
15344         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15345          UNSPEC_FRNDINT_TRUNC))
15346    (use (match_operand:HI 2 "memory_operand" "m"))
15347    (use (match_operand:HI 3 "memory_operand" "m"))]
15348   "TARGET_USE_FANCY_MATH_387
15349    && flag_unsafe_math_optimizations"
15350   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15351   [(set_attr "type" "frndint")
15352    (set_attr "i387_cw" "trunc")
15353    (set_attr "mode" "XF")])
15354
15355 (define_expand "btruncxf2"
15356   [(use (match_operand:XF 0 "register_operand" ""))
15357    (use (match_operand:XF 1 "register_operand" ""))]
15358   "TARGET_USE_FANCY_MATH_387
15359    && flag_unsafe_math_optimizations"
15360 {
15361   if (optimize_insn_for_size_p ())
15362     FAIL;
15363   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15364   DONE;
15365 })
15366
15367 (define_expand "btrunc<mode>2"
15368   [(use (match_operand:MODEF 0 "register_operand" ""))
15369    (use (match_operand:MODEF 1 "register_operand" ""))]
15370   "(TARGET_USE_FANCY_MATH_387
15371     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15372         || TARGET_MIX_SSE_I387)
15373     && flag_unsafe_math_optimizations)
15374    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15375        && !flag_trapping_math)"
15376 {
15377   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15378       && !flag_trapping_math)
15379     {
15380       if (TARGET_ROUND)
15381         emit_insn (gen_sse4_1_round<mode>2
15382                    (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15383       else if (optimize_insn_for_size_p ())
15384         FAIL;
15385       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15386         ix86_expand_trunc (operands[0], operands[1]);
15387       else
15388         ix86_expand_truncdf_32 (operands[0], operands[1]);
15389     }
15390   else
15391     {
15392       rtx op0, op1;
15393
15394       if (optimize_insn_for_size_p ())
15395         FAIL;
15396
15397       op0 = gen_reg_rtx (XFmode);
15398       op1 = gen_reg_rtx (XFmode);
15399       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15400       emit_insn (gen_frndintxf2_trunc (op0, op1));
15401
15402       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15403     }
15404   DONE;
15405 })
15406
15407 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15408 (define_insn_and_split "frndintxf2_mask_pm"
15409   [(set (match_operand:XF 0 "register_operand" "")
15410         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15411          UNSPEC_FRNDINT_MASK_PM))
15412    (clobber (reg:CC FLAGS_REG))]
15413   "TARGET_USE_FANCY_MATH_387
15414    && flag_unsafe_math_optimizations
15415    && can_create_pseudo_p ()"
15416   "#"
15417   "&& 1"
15418   [(const_int 0)]
15419 {
15420   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15421
15422   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15423   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15424
15425   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15426                                           operands[2], operands[3]));
15427   DONE;
15428 }
15429   [(set_attr "type" "frndint")
15430    (set_attr "i387_cw" "mask_pm")
15431    (set_attr "mode" "XF")])
15432
15433 (define_insn "frndintxf2_mask_pm_i387"
15434   [(set (match_operand:XF 0 "register_operand" "=f")
15435         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15436          UNSPEC_FRNDINT_MASK_PM))
15437    (use (match_operand:HI 2 "memory_operand" "m"))
15438    (use (match_operand:HI 3 "memory_operand" "m"))]
15439   "TARGET_USE_FANCY_MATH_387
15440    && flag_unsafe_math_optimizations"
15441   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15442   [(set_attr "type" "frndint")
15443    (set_attr "i387_cw" "mask_pm")
15444    (set_attr "mode" "XF")])
15445
15446 (define_expand "nearbyintxf2"
15447   [(use (match_operand:XF 0 "register_operand" ""))
15448    (use (match_operand:XF 1 "register_operand" ""))]
15449   "TARGET_USE_FANCY_MATH_387
15450    && flag_unsafe_math_optimizations"
15451 {
15452   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15453   DONE;
15454 })
15455
15456 (define_expand "nearbyint<mode>2"
15457   [(use (match_operand:MODEF 0 "register_operand" ""))
15458    (use (match_operand:MODEF 1 "register_operand" ""))]
15459   "TARGET_USE_FANCY_MATH_387
15460    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15461        || TARGET_MIX_SSE_I387)
15462    && flag_unsafe_math_optimizations"
15463 {
15464   rtx op0 = gen_reg_rtx (XFmode);
15465   rtx op1 = gen_reg_rtx (XFmode);
15466
15467   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15468   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15469
15470   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15471   DONE;
15472 })
15473
15474 (define_insn "fxam<mode>2_i387"
15475   [(set (match_operand:HI 0 "register_operand" "=a")
15476         (unspec:HI
15477           [(match_operand:X87MODEF 1 "register_operand" "f")]
15478           UNSPEC_FXAM))]
15479   "TARGET_USE_FANCY_MATH_387"
15480   "fxam\n\tfnstsw\t%0"
15481   [(set_attr "type" "multi")
15482    (set_attr "length" "4")
15483    (set_attr "unit" "i387")
15484    (set_attr "mode" "<MODE>")])
15485
15486 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15487   [(set (match_operand:HI 0 "register_operand" "")
15488         (unspec:HI
15489           [(match_operand:MODEF 1 "memory_operand" "")]
15490           UNSPEC_FXAM_MEM))]
15491   "TARGET_USE_FANCY_MATH_387
15492    && can_create_pseudo_p ()"
15493   "#"
15494   "&& 1"
15495   [(set (match_dup 2)(match_dup 1))
15496    (set (match_dup 0)
15497         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15498 {
15499   operands[2] = gen_reg_rtx (<MODE>mode);
15500
15501   MEM_VOLATILE_P (operands[1]) = 1;
15502 }
15503   [(set_attr "type" "multi")
15504    (set_attr "unit" "i387")
15505    (set_attr "mode" "<MODE>")])
15506
15507 (define_expand "isinfxf2"
15508   [(use (match_operand:SI 0 "register_operand" ""))
15509    (use (match_operand:XF 1 "register_operand" ""))]
15510   "TARGET_USE_FANCY_MATH_387
15511    && TARGET_C99_FUNCTIONS"
15512 {
15513   rtx mask = GEN_INT (0x45);
15514   rtx val = GEN_INT (0x05);
15515
15516   rtx cond;
15517
15518   rtx scratch = gen_reg_rtx (HImode);
15519   rtx res = gen_reg_rtx (QImode);
15520
15521   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15522
15523   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15524   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15525   cond = gen_rtx_fmt_ee (EQ, QImode,
15526                          gen_rtx_REG (CCmode, FLAGS_REG),
15527                          const0_rtx);
15528   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15529   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15530   DONE;
15531 })
15532
15533 (define_expand "isinf<mode>2"
15534   [(use (match_operand:SI 0 "register_operand" ""))
15535    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15536   "TARGET_USE_FANCY_MATH_387
15537    && TARGET_C99_FUNCTIONS
15538    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15539 {
15540   rtx mask = GEN_INT (0x45);
15541   rtx val = GEN_INT (0x05);
15542
15543   rtx cond;
15544
15545   rtx scratch = gen_reg_rtx (HImode);
15546   rtx res = gen_reg_rtx (QImode);
15547
15548   /* Remove excess precision by forcing value through memory. */
15549   if (memory_operand (operands[1], VOIDmode))
15550     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15551   else
15552     {
15553       enum ix86_stack_slot slot = (virtuals_instantiated
15554                                    ? SLOT_TEMP
15555                                    : SLOT_VIRTUAL);
15556       rtx temp = assign_386_stack_local (<MODE>mode, slot);
15557
15558       emit_move_insn (temp, operands[1]);
15559       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15560     }
15561
15562   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15563   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15564   cond = gen_rtx_fmt_ee (EQ, QImode,
15565                          gen_rtx_REG (CCmode, FLAGS_REG),
15566                          const0_rtx);
15567   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15568   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15569   DONE;
15570 })
15571
15572 (define_expand "signbitxf2"
15573   [(use (match_operand:SI 0 "register_operand" ""))
15574    (use (match_operand:XF 1 "register_operand" ""))]
15575   "TARGET_USE_FANCY_MATH_387"
15576 {
15577   rtx scratch = gen_reg_rtx (HImode);
15578
15579   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15580   emit_insn (gen_andsi3 (operands[0],
15581              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15582   DONE;
15583 })
15584
15585 (define_insn "movmsk_df"
15586   [(set (match_operand:SI 0 "register_operand" "=r")
15587         (unspec:SI
15588           [(match_operand:DF 1 "register_operand" "x")]
15589           UNSPEC_MOVMSK))]
15590   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15591   "%vmovmskpd\t{%1, %0|%0, %1}"
15592   [(set_attr "type" "ssemov")
15593    (set_attr "prefix" "maybe_vex")
15594    (set_attr "mode" "DF")])
15595
15596 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15597 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15598 (define_expand "signbitdf2"
15599   [(use (match_operand:SI 0 "register_operand" ""))
15600    (use (match_operand:DF 1 "register_operand" ""))]
15601   "TARGET_USE_FANCY_MATH_387
15602    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15603 {
15604   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15605     {
15606       emit_insn (gen_movmsk_df (operands[0], operands[1]));
15607       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15608     }
15609   else
15610     {
15611       rtx scratch = gen_reg_rtx (HImode);
15612
15613       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15614       emit_insn (gen_andsi3 (operands[0],
15615                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15616     }
15617   DONE;
15618 })
15619
15620 (define_expand "signbitsf2"
15621   [(use (match_operand:SI 0 "register_operand" ""))
15622    (use (match_operand:SF 1 "register_operand" ""))]
15623   "TARGET_USE_FANCY_MATH_387
15624    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15625 {
15626   rtx scratch = gen_reg_rtx (HImode);
15627
15628   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15629   emit_insn (gen_andsi3 (operands[0],
15630              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15631   DONE;
15632 })
15633 \f
15634 ;; Block operation instructions
15635
15636 (define_insn "cld"
15637   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15638   ""
15639   "cld"
15640   [(set_attr "length" "1")
15641    (set_attr "length_immediate" "0")
15642    (set_attr "modrm" "0")])
15643
15644 (define_expand "movmem<mode>"
15645   [(use (match_operand:BLK 0 "memory_operand" ""))
15646    (use (match_operand:BLK 1 "memory_operand" ""))
15647    (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15648    (use (match_operand:SWI48 3 "const_int_operand" ""))
15649    (use (match_operand:SI 4 "const_int_operand" ""))
15650    (use (match_operand:SI 5 "const_int_operand" ""))]
15651   ""
15652 {
15653  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15654                          operands[4], operands[5]))
15655    DONE;
15656  else
15657    FAIL;
15658 })
15659
15660 ;; Most CPUs don't like single string operations
15661 ;; Handle this case here to simplify previous expander.
15662
15663 (define_expand "strmov"
15664   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15665    (set (match_operand 1 "memory_operand" "") (match_dup 4))
15666    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15667               (clobber (reg:CC FLAGS_REG))])
15668    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15669               (clobber (reg:CC FLAGS_REG))])]
15670   ""
15671 {
15672   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15673
15674   /* If .md ever supports :P for Pmode, these can be directly
15675      in the pattern above.  */
15676   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15677   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15678
15679   /* Can't use this if the user has appropriated esi or edi.  */
15680   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15681       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15682     {
15683       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15684                                       operands[2], operands[3],
15685                                       operands[5], operands[6]));
15686       DONE;
15687     }
15688
15689   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15690 })
15691
15692 (define_expand "strmov_singleop"
15693   [(parallel [(set (match_operand 1 "memory_operand" "")
15694                    (match_operand 3 "memory_operand" ""))
15695               (set (match_operand 0 "register_operand" "")
15696                    (match_operand 4 "" ""))
15697               (set (match_operand 2 "register_operand" "")
15698                    (match_operand 5 "" ""))])]
15699   ""
15700   "ix86_current_function_needs_cld = 1;")
15701
15702 (define_insn "*strmovdi_rex_1"
15703   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15704         (mem:DI (match_operand:DI 3 "register_operand" "1")))
15705    (set (match_operand:DI 0 "register_operand" "=D")
15706         (plus:DI (match_dup 2)
15707                  (const_int 8)))
15708    (set (match_operand:DI 1 "register_operand" "=S")
15709         (plus:DI (match_dup 3)
15710                  (const_int 8)))]
15711   "TARGET_64BIT
15712    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15713   "movsq"
15714   [(set_attr "type" "str")
15715    (set_attr "memory" "both")
15716    (set_attr "mode" "DI")])
15717
15718 (define_insn "*strmovsi_1"
15719   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15720         (mem:SI (match_operand:P 3 "register_operand" "1")))
15721    (set (match_operand:P 0 "register_operand" "=D")
15722         (plus:P (match_dup 2)
15723                 (const_int 4)))
15724    (set (match_operand:P 1 "register_operand" "=S")
15725         (plus:P (match_dup 3)
15726                 (const_int 4)))]
15727   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15728   "movs{l|d}"
15729   [(set_attr "type" "str")
15730    (set_attr "memory" "both")
15731    (set_attr "mode" "SI")])
15732
15733 (define_insn "*strmovhi_1"
15734   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15735         (mem:HI (match_operand:P 3 "register_operand" "1")))
15736    (set (match_operand:P 0 "register_operand" "=D")
15737         (plus:P (match_dup 2)
15738                 (const_int 2)))
15739    (set (match_operand:P 1 "register_operand" "=S")
15740         (plus:P (match_dup 3)
15741                 (const_int 2)))]
15742   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15743   "movsw"
15744   [(set_attr "type" "str")
15745    (set_attr "memory" "both")
15746    (set_attr "mode" "HI")])
15747
15748 (define_insn "*strmovqi_1"
15749   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15750         (mem:QI (match_operand:P 3 "register_operand" "1")))
15751    (set (match_operand:P 0 "register_operand" "=D")
15752         (plus:P (match_dup 2)
15753                 (const_int 1)))
15754    (set (match_operand:P 1 "register_operand" "=S")
15755         (plus:P (match_dup 3)
15756                 (const_int 1)))]
15757   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15758   "movsb"
15759   [(set_attr "type" "str")
15760    (set_attr "memory" "both")
15761    (set (attr "prefix_rex")
15762         (if_then_else
15763           (match_test "<P:MODE>mode == DImode")
15764           (const_string "0")
15765           (const_string "*")))
15766    (set_attr "mode" "QI")])
15767
15768 (define_expand "rep_mov"
15769   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15770               (set (match_operand 0 "register_operand" "")
15771                    (match_operand 5 "" ""))
15772               (set (match_operand 2 "register_operand" "")
15773                    (match_operand 6 "" ""))
15774               (set (match_operand 1 "memory_operand" "")
15775                    (match_operand 3 "memory_operand" ""))
15776               (use (match_dup 4))])]
15777   ""
15778   "ix86_current_function_needs_cld = 1;")
15779
15780 (define_insn "*rep_movdi_rex64"
15781   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15782    (set (match_operand:DI 0 "register_operand" "=D")
15783         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15784                             (const_int 3))
15785                  (match_operand:DI 3 "register_operand" "0")))
15786    (set (match_operand:DI 1 "register_operand" "=S")
15787         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15788                  (match_operand:DI 4 "register_operand" "1")))
15789    (set (mem:BLK (match_dup 3))
15790         (mem:BLK (match_dup 4)))
15791    (use (match_dup 5))]
15792   "TARGET_64BIT
15793    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15794   "rep{%;} movsq"
15795   [(set_attr "type" "str")
15796    (set_attr "prefix_rep" "1")
15797    (set_attr "memory" "both")
15798    (set_attr "mode" "DI")])
15799
15800 (define_insn "*rep_movsi"
15801   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15802    (set (match_operand:P 0 "register_operand" "=D")
15803         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15804                           (const_int 2))
15805                  (match_operand:P 3 "register_operand" "0")))
15806    (set (match_operand:P 1 "register_operand" "=S")
15807         (plus:P (ashift:P (match_dup 5) (const_int 2))
15808                 (match_operand:P 4 "register_operand" "1")))
15809    (set (mem:BLK (match_dup 3))
15810         (mem:BLK (match_dup 4)))
15811    (use (match_dup 5))]
15812   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15813   "rep{%;} movs{l|d}"
15814   [(set_attr "type" "str")
15815    (set_attr "prefix_rep" "1")
15816    (set_attr "memory" "both")
15817    (set_attr "mode" "SI")])
15818
15819 (define_insn "*rep_movqi"
15820   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15821    (set (match_operand:P 0 "register_operand" "=D")
15822         (plus:P (match_operand:P 3 "register_operand" "0")
15823                 (match_operand:P 5 "register_operand" "2")))
15824    (set (match_operand:P 1 "register_operand" "=S")
15825         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15826    (set (mem:BLK (match_dup 3))
15827         (mem:BLK (match_dup 4)))
15828    (use (match_dup 5))]
15829   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15830   "rep{%;} movsb"
15831   [(set_attr "type" "str")
15832    (set_attr "prefix_rep" "1")
15833    (set_attr "memory" "both")
15834    (set_attr "mode" "QI")])
15835
15836 (define_expand "setmem<mode>"
15837    [(use (match_operand:BLK 0 "memory_operand" ""))
15838     (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15839     (use (match_operand:QI 2 "nonmemory_operand" ""))
15840     (use (match_operand 3 "const_int_operand" ""))
15841     (use (match_operand:SI 4 "const_int_operand" ""))
15842     (use (match_operand:SI 5 "const_int_operand" ""))]
15843   ""
15844 {
15845  if (ix86_expand_setmem (operands[0], operands[1],
15846                          operands[2], operands[3],
15847                          operands[4], operands[5]))
15848    DONE;
15849  else
15850    FAIL;
15851 })
15852
15853 ;; Most CPUs don't like single string operations
15854 ;; Handle this case here to simplify previous expander.
15855
15856 (define_expand "strset"
15857   [(set (match_operand 1 "memory_operand" "")
15858         (match_operand 2 "register_operand" ""))
15859    (parallel [(set (match_operand 0 "register_operand" "")
15860                    (match_dup 3))
15861               (clobber (reg:CC FLAGS_REG))])]
15862   ""
15863 {
15864   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15865     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15866
15867   /* If .md ever supports :P for Pmode, this can be directly
15868      in the pattern above.  */
15869   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15870                               GEN_INT (GET_MODE_SIZE (GET_MODE
15871                                                       (operands[2]))));
15872   /* Can't use this if the user has appropriated eax or edi.  */
15873   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15874       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15875     {
15876       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15877                                       operands[3]));
15878       DONE;
15879     }
15880 })
15881
15882 (define_expand "strset_singleop"
15883   [(parallel [(set (match_operand 1 "memory_operand" "")
15884                    (match_operand 2 "register_operand" ""))
15885               (set (match_operand 0 "register_operand" "")
15886                    (match_operand 3 "" ""))])]
15887   ""
15888   "ix86_current_function_needs_cld = 1;")
15889
15890 (define_insn "*strsetdi_rex_1"
15891   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15892         (match_operand:DI 2 "register_operand" "a"))
15893    (set (match_operand:DI 0 "register_operand" "=D")
15894         (plus:DI (match_dup 1)
15895                  (const_int 8)))]
15896   "TARGET_64BIT
15897    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15898   "stosq"
15899   [(set_attr "type" "str")
15900    (set_attr "memory" "store")
15901    (set_attr "mode" "DI")])
15902
15903 (define_insn "*strsetsi_1"
15904   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15905         (match_operand:SI 2 "register_operand" "a"))
15906    (set (match_operand:P 0 "register_operand" "=D")
15907         (plus:P (match_dup 1)
15908                 (const_int 4)))]
15909   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15910   "stos{l|d}"
15911   [(set_attr "type" "str")
15912    (set_attr "memory" "store")
15913    (set_attr "mode" "SI")])
15914
15915 (define_insn "*strsethi_1"
15916   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15917         (match_operand:HI 2 "register_operand" "a"))
15918    (set (match_operand:P 0 "register_operand" "=D")
15919         (plus:P (match_dup 1)
15920                 (const_int 2)))]
15921   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15922   "stosw"
15923   [(set_attr "type" "str")
15924    (set_attr "memory" "store")
15925    (set_attr "mode" "HI")])
15926
15927 (define_insn "*strsetqi_1"
15928   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15929         (match_operand:QI 2 "register_operand" "a"))
15930    (set (match_operand:P 0 "register_operand" "=D")
15931         (plus:P (match_dup 1)
15932                 (const_int 1)))]
15933   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15934   "stosb"
15935   [(set_attr "type" "str")
15936    (set_attr "memory" "store")
15937    (set (attr "prefix_rex")
15938         (if_then_else
15939           (match_test "<P:MODE>mode == DImode")
15940           (const_string "0")
15941           (const_string "*")))
15942    (set_attr "mode" "QI")])
15943
15944 (define_expand "rep_stos"
15945   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15946               (set (match_operand 0 "register_operand" "")
15947                    (match_operand 4 "" ""))
15948               (set (match_operand 2 "memory_operand" "") (const_int 0))
15949               (use (match_operand 3 "register_operand" ""))
15950               (use (match_dup 1))])]
15951   ""
15952   "ix86_current_function_needs_cld = 1;")
15953
15954 (define_insn "*rep_stosdi_rex64"
15955   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15956    (set (match_operand:DI 0 "register_operand" "=D")
15957         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15958                             (const_int 3))
15959                  (match_operand:DI 3 "register_operand" "0")))
15960    (set (mem:BLK (match_dup 3))
15961         (const_int 0))
15962    (use (match_operand:DI 2 "register_operand" "a"))
15963    (use (match_dup 4))]
15964   "TARGET_64BIT
15965    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15966   "rep{%;} stosq"
15967   [(set_attr "type" "str")
15968    (set_attr "prefix_rep" "1")
15969    (set_attr "memory" "store")
15970    (set_attr "mode" "DI")])
15971
15972 (define_insn "*rep_stossi"
15973   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15974    (set (match_operand:P 0 "register_operand" "=D")
15975         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15976                           (const_int 2))
15977                  (match_operand:P 3 "register_operand" "0")))
15978    (set (mem:BLK (match_dup 3))
15979         (const_int 0))
15980    (use (match_operand:SI 2 "register_operand" "a"))
15981    (use (match_dup 4))]
15982   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15983   "rep{%;} stos{l|d}"
15984   [(set_attr "type" "str")
15985    (set_attr "prefix_rep" "1")
15986    (set_attr "memory" "store")
15987    (set_attr "mode" "SI")])
15988
15989 (define_insn "*rep_stosqi"
15990   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15991    (set (match_operand:P 0 "register_operand" "=D")
15992         (plus:P (match_operand:P 3 "register_operand" "0")
15993                 (match_operand:P 4 "register_operand" "1")))
15994    (set (mem:BLK (match_dup 3))
15995         (const_int 0))
15996    (use (match_operand:QI 2 "register_operand" "a"))
15997    (use (match_dup 4))]
15998   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15999   "rep{%;} stosb"
16000   [(set_attr "type" "str")
16001    (set_attr "prefix_rep" "1")
16002    (set_attr "memory" "store")
16003    (set (attr "prefix_rex")
16004         (if_then_else
16005           (match_test "<P:MODE>mode == DImode")
16006           (const_string "0")
16007           (const_string "*")))
16008    (set_attr "mode" "QI")])
16009
16010 (define_expand "cmpstrnsi"
16011   [(set (match_operand:SI 0 "register_operand" "")
16012         (compare:SI (match_operand:BLK 1 "general_operand" "")
16013                     (match_operand:BLK 2 "general_operand" "")))
16014    (use (match_operand 3 "general_operand" ""))
16015    (use (match_operand 4 "immediate_operand" ""))]
16016   ""
16017 {
16018   rtx addr1, addr2, out, outlow, count, countreg, align;
16019
16020   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16021     FAIL;
16022
16023   /* Can't use this if the user has appropriated ecx, esi or edi.  */
16024   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16025     FAIL;
16026
16027   out = operands[0];
16028   if (!REG_P (out))
16029     out = gen_reg_rtx (SImode);
16030
16031   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16032   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16033   if (addr1 != XEXP (operands[1], 0))
16034     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16035   if (addr2 != XEXP (operands[2], 0))
16036     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16037
16038   count = operands[3];
16039   countreg = ix86_zero_extend_to_Pmode (count);
16040
16041   /* %%% Iff we are testing strict equality, we can use known alignment
16042      to good advantage.  This may be possible with combine, particularly
16043      once cc0 is dead.  */
16044   align = operands[4];
16045
16046   if (CONST_INT_P (count))
16047     {
16048       if (INTVAL (count) == 0)
16049         {
16050           emit_move_insn (operands[0], const0_rtx);
16051           DONE;
16052         }
16053       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16054                                      operands[1], operands[2]));
16055     }
16056   else
16057     {
16058       rtx (*gen_cmp) (rtx, rtx);
16059
16060       gen_cmp = (TARGET_64BIT
16061                  ? gen_cmpdi_1 : gen_cmpsi_1);
16062
16063       emit_insn (gen_cmp (countreg, countreg));
16064       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16065                                   operands[1], operands[2]));
16066     }
16067
16068   outlow = gen_lowpart (QImode, out);
16069   emit_insn (gen_cmpintqi (outlow));
16070   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16071
16072   if (operands[0] != out)
16073     emit_move_insn (operands[0], out);
16074
16075   DONE;
16076 })
16077
16078 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16079
16080 (define_expand "cmpintqi"
16081   [(set (match_dup 1)
16082         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16083    (set (match_dup 2)
16084         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16085    (parallel [(set (match_operand:QI 0 "register_operand" "")
16086                    (minus:QI (match_dup 1)
16087                              (match_dup 2)))
16088               (clobber (reg:CC FLAGS_REG))])]
16089   ""
16090 {
16091   operands[1] = gen_reg_rtx (QImode);
16092   operands[2] = gen_reg_rtx (QImode);
16093 })
16094
16095 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16096 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16097
16098 (define_expand "cmpstrnqi_nz_1"
16099   [(parallel [(set (reg:CC FLAGS_REG)
16100                    (compare:CC (match_operand 4 "memory_operand" "")
16101                                (match_operand 5 "memory_operand" "")))
16102               (use (match_operand 2 "register_operand" ""))
16103               (use (match_operand:SI 3 "immediate_operand" ""))
16104               (clobber (match_operand 0 "register_operand" ""))
16105               (clobber (match_operand 1 "register_operand" ""))
16106               (clobber (match_dup 2))])]
16107   ""
16108   "ix86_current_function_needs_cld = 1;")
16109
16110 (define_insn "*cmpstrnqi_nz_1"
16111   [(set (reg:CC FLAGS_REG)
16112         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16113                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16114    (use (match_operand:P 6 "register_operand" "2"))
16115    (use (match_operand:SI 3 "immediate_operand" "i"))
16116    (clobber (match_operand:P 0 "register_operand" "=S"))
16117    (clobber (match_operand:P 1 "register_operand" "=D"))
16118    (clobber (match_operand:P 2 "register_operand" "=c"))]
16119   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16120   "repz{%;} cmpsb"
16121   [(set_attr "type" "str")
16122    (set_attr "mode" "QI")
16123    (set (attr "prefix_rex")
16124         (if_then_else
16125           (match_test "<P:MODE>mode == DImode")
16126           (const_string "0")
16127           (const_string "*")))
16128    (set_attr "prefix_rep" "1")])
16129
16130 ;; The same, but the count is not known to not be zero.
16131
16132 (define_expand "cmpstrnqi_1"
16133   [(parallel [(set (reg:CC FLAGS_REG)
16134                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16135                                      (const_int 0))
16136                   (compare:CC (match_operand 4 "memory_operand" "")
16137                               (match_operand 5 "memory_operand" ""))
16138                   (const_int 0)))
16139               (use (match_operand:SI 3 "immediate_operand" ""))
16140               (use (reg:CC FLAGS_REG))
16141               (clobber (match_operand 0 "register_operand" ""))
16142               (clobber (match_operand 1 "register_operand" ""))
16143               (clobber (match_dup 2))])]
16144   ""
16145   "ix86_current_function_needs_cld = 1;")
16146
16147 (define_insn "*cmpstrnqi_1"
16148   [(set (reg:CC FLAGS_REG)
16149         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16150                              (const_int 0))
16151           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16152                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
16153           (const_int 0)))
16154    (use (match_operand:SI 3 "immediate_operand" "i"))
16155    (use (reg:CC FLAGS_REG))
16156    (clobber (match_operand:P 0 "register_operand" "=S"))
16157    (clobber (match_operand:P 1 "register_operand" "=D"))
16158    (clobber (match_operand:P 2 "register_operand" "=c"))]
16159   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16160   "repz{%;} cmpsb"
16161   [(set_attr "type" "str")
16162    (set_attr "mode" "QI")
16163    (set (attr "prefix_rex")
16164         (if_then_else
16165           (match_test "<P:MODE>mode == DImode")
16166           (const_string "0")
16167           (const_string "*")))
16168    (set_attr "prefix_rep" "1")])
16169
16170 (define_expand "strlen<mode>"
16171   [(set (match_operand:P 0 "register_operand" "")
16172         (unspec:P [(match_operand:BLK 1 "general_operand" "")
16173                    (match_operand:QI 2 "immediate_operand" "")
16174                    (match_operand 3 "immediate_operand" "")]
16175                   UNSPEC_SCAS))]
16176   ""
16177 {
16178  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16179    DONE;
16180  else
16181    FAIL;
16182 })
16183
16184 (define_expand "strlenqi_1"
16185   [(parallel [(set (match_operand 0 "register_operand" "")
16186                    (match_operand 2 "" ""))
16187               (clobber (match_operand 1 "register_operand" ""))
16188               (clobber (reg:CC FLAGS_REG))])]
16189   ""
16190   "ix86_current_function_needs_cld = 1;")
16191
16192 (define_insn "*strlenqi_1"
16193   [(set (match_operand:P 0 "register_operand" "=&c")
16194         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16195                    (match_operand:QI 2 "register_operand" "a")
16196                    (match_operand:P 3 "immediate_operand" "i")
16197                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16198    (clobber (match_operand:P 1 "register_operand" "=D"))
16199    (clobber (reg:CC FLAGS_REG))]
16200   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16201   "repnz{%;} scasb"
16202   [(set_attr "type" "str")
16203    (set_attr "mode" "QI")
16204    (set (attr "prefix_rex")
16205         (if_then_else
16206           (match_test "<P:MODE>mode == DImode")
16207           (const_string "0")
16208           (const_string "*")))
16209    (set_attr "prefix_rep" "1")])
16210
16211 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
16212 ;; handled in combine, but it is not currently up to the task.
16213 ;; When used for their truth value, the cmpstrn* expanders generate
16214 ;; code like this:
16215 ;;
16216 ;;   repz cmpsb
16217 ;;   seta       %al
16218 ;;   setb       %dl
16219 ;;   cmpb       %al, %dl
16220 ;;   jcc        label
16221 ;;
16222 ;; The intermediate three instructions are unnecessary.
16223
16224 ;; This one handles cmpstrn*_nz_1...
16225 (define_peephole2
16226   [(parallel[
16227      (set (reg:CC FLAGS_REG)
16228           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16229                       (mem:BLK (match_operand 5 "register_operand" ""))))
16230      (use (match_operand 6 "register_operand" ""))
16231      (use (match_operand:SI 3 "immediate_operand" ""))
16232      (clobber (match_operand 0 "register_operand" ""))
16233      (clobber (match_operand 1 "register_operand" ""))
16234      (clobber (match_operand 2 "register_operand" ""))])
16235    (set (match_operand:QI 7 "register_operand" "")
16236         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16237    (set (match_operand:QI 8 "register_operand" "")
16238         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16239    (set (reg FLAGS_REG)
16240         (compare (match_dup 7) (match_dup 8)))
16241   ]
16242   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16243   [(parallel[
16244      (set (reg:CC FLAGS_REG)
16245           (compare:CC (mem:BLK (match_dup 4))
16246                       (mem:BLK (match_dup 5))))
16247      (use (match_dup 6))
16248      (use (match_dup 3))
16249      (clobber (match_dup 0))
16250      (clobber (match_dup 1))
16251      (clobber (match_dup 2))])])
16252
16253 ;; ...and this one handles cmpstrn*_1.
16254 (define_peephole2
16255   [(parallel[
16256      (set (reg:CC FLAGS_REG)
16257           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16258                                (const_int 0))
16259             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16260                         (mem:BLK (match_operand 5 "register_operand" "")))
16261             (const_int 0)))
16262      (use (match_operand:SI 3 "immediate_operand" ""))
16263      (use (reg:CC FLAGS_REG))
16264      (clobber (match_operand 0 "register_operand" ""))
16265      (clobber (match_operand 1 "register_operand" ""))
16266      (clobber (match_operand 2 "register_operand" ""))])
16267    (set (match_operand:QI 7 "register_operand" "")
16268         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16269    (set (match_operand:QI 8 "register_operand" "")
16270         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16271    (set (reg FLAGS_REG)
16272         (compare (match_dup 7) (match_dup 8)))
16273   ]
16274   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16275   [(parallel[
16276      (set (reg:CC FLAGS_REG)
16277           (if_then_else:CC (ne (match_dup 6)
16278                                (const_int 0))
16279             (compare:CC (mem:BLK (match_dup 4))
16280                         (mem:BLK (match_dup 5)))
16281             (const_int 0)))
16282      (use (match_dup 3))
16283      (use (reg:CC FLAGS_REG))
16284      (clobber (match_dup 0))
16285      (clobber (match_dup 1))
16286      (clobber (match_dup 2))])])
16287 \f
16288 ;; Conditional move instructions.
16289
16290 (define_expand "mov<mode>cc"
16291   [(set (match_operand:SWIM 0 "register_operand" "")
16292         (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16293                            (match_operand:SWIM 2 "<general_operand>" "")
16294                            (match_operand:SWIM 3 "<general_operand>" "")))]
16295   ""
16296   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16297
16298 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16299 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16300 ;; So just document what we're doing explicitly.
16301
16302 (define_expand "x86_mov<mode>cc_0_m1"
16303   [(parallel
16304     [(set (match_operand:SWI48 0 "register_operand" "")
16305           (if_then_else:SWI48
16306             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16307              [(match_operand 1 "flags_reg_operand" "")
16308               (const_int 0)])
16309             (const_int -1)
16310             (const_int 0)))
16311      (clobber (reg:CC FLAGS_REG))])])
16312
16313 (define_insn "*x86_mov<mode>cc_0_m1"
16314   [(set (match_operand:SWI48 0 "register_operand" "=r")
16315         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16316                              [(reg FLAGS_REG) (const_int 0)])
16317           (const_int -1)
16318           (const_int 0)))
16319    (clobber (reg:CC FLAGS_REG))]
16320   ""
16321   "sbb{<imodesuffix>}\t%0, %0"
16322   ; Since we don't have the proper number of operands for an alu insn,
16323   ; fill in all the blanks.
16324   [(set_attr "type" "alu")
16325    (set_attr "use_carry" "1")
16326    (set_attr "pent_pair" "pu")
16327    (set_attr "memory" "none")
16328    (set_attr "imm_disp" "false")
16329    (set_attr "mode" "<MODE>")
16330    (set_attr "length_immediate" "0")])
16331
16332 (define_insn "*x86_mov<mode>cc_0_m1_se"
16333   [(set (match_operand:SWI48 0 "register_operand" "=r")
16334         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16335                              [(reg FLAGS_REG) (const_int 0)])
16336                             (const_int 1)
16337                             (const_int 0)))
16338    (clobber (reg:CC FLAGS_REG))]
16339   ""
16340   "sbb{<imodesuffix>}\t%0, %0"
16341   [(set_attr "type" "alu")
16342    (set_attr "use_carry" "1")
16343    (set_attr "pent_pair" "pu")
16344    (set_attr "memory" "none")
16345    (set_attr "imm_disp" "false")
16346    (set_attr "mode" "<MODE>")
16347    (set_attr "length_immediate" "0")])
16348
16349 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16350   [(set (match_operand:SWI48 0 "register_operand" "=r")
16351         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16352                     [(reg FLAGS_REG) (const_int 0)])))]
16353   ""
16354   "sbb{<imodesuffix>}\t%0, %0"
16355   [(set_attr "type" "alu")
16356    (set_attr "use_carry" "1")
16357    (set_attr "pent_pair" "pu")
16358    (set_attr "memory" "none")
16359    (set_attr "imm_disp" "false")
16360    (set_attr "mode" "<MODE>")
16361    (set_attr "length_immediate" "0")])
16362
16363 (define_insn "*mov<mode>cc_noc"
16364   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16365         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16366                                [(reg FLAGS_REG) (const_int 0)])
16367           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16368           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16369   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16370   "@
16371    cmov%O2%C1\t{%2, %0|%0, %2}
16372    cmov%O2%c1\t{%3, %0|%0, %3}"
16373   [(set_attr "type" "icmov")
16374    (set_attr "mode" "<MODE>")])
16375
16376 (define_insn_and_split "*movqicc_noc"
16377   [(set (match_operand:QI 0 "register_operand" "=r,r")
16378         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16379                            [(match_operand 4 "flags_reg_operand" "")
16380                             (const_int 0)])
16381                       (match_operand:QI 2 "register_operand" "r,0")
16382                       (match_operand:QI 3 "register_operand" "0,r")))]
16383   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16384   "#"
16385   "&& reload_completed"
16386   [(set (match_dup 0)
16387         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16388                       (match_dup 2)
16389                       (match_dup 3)))]
16390   "operands[0] = gen_lowpart (SImode, operands[0]);
16391    operands[2] = gen_lowpart (SImode, operands[2]);
16392    operands[3] = gen_lowpart (SImode, operands[3]);"
16393   [(set_attr "type" "icmov")
16394    (set_attr "mode" "SI")])
16395
16396 (define_expand "mov<mode>cc"
16397   [(set (match_operand:X87MODEF 0 "register_operand" "")
16398         (if_then_else:X87MODEF
16399           (match_operand 1 "ix86_fp_comparison_operator" "")
16400           (match_operand:X87MODEF 2 "register_operand" "")
16401           (match_operand:X87MODEF 3 "register_operand" "")))]
16402   "(TARGET_80387 && TARGET_CMOVE)
16403    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16404   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16405
16406 (define_insn "*movxfcc_1"
16407   [(set (match_operand:XF 0 "register_operand" "=f,f")
16408         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16409                                 [(reg FLAGS_REG) (const_int 0)])
16410                       (match_operand:XF 2 "register_operand" "f,0")
16411                       (match_operand:XF 3 "register_operand" "0,f")))]
16412   "TARGET_80387 && TARGET_CMOVE"
16413   "@
16414    fcmov%F1\t{%2, %0|%0, %2}
16415    fcmov%f1\t{%3, %0|%0, %3}"
16416   [(set_attr "type" "fcmov")
16417    (set_attr "mode" "XF")])
16418
16419 (define_insn "*movdfcc_1_rex64"
16420   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16421         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16422                                 [(reg FLAGS_REG) (const_int 0)])
16423                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16424                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16425   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16426    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16427   "@
16428    fcmov%F1\t{%2, %0|%0, %2}
16429    fcmov%f1\t{%3, %0|%0, %3}
16430    cmov%O2%C1\t{%2, %0|%0, %2}
16431    cmov%O2%c1\t{%3, %0|%0, %3}"
16432   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16433    (set_attr "mode" "DF,DF,DI,DI")])
16434
16435 (define_insn "*movdfcc_1"
16436   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16437         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16438                                 [(reg FLAGS_REG) (const_int 0)])
16439                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16440                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16441   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16442    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16443   "@
16444    fcmov%F1\t{%2, %0|%0, %2}
16445    fcmov%f1\t{%3, %0|%0, %3}
16446    #
16447    #"
16448   [(set_attr "type" "fcmov,fcmov,multi,multi")
16449    (set_attr "mode" "DF,DF,DI,DI")])
16450
16451 (define_split
16452   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16453         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16454                                 [(match_operand 4 "flags_reg_operand" "")
16455                                  (const_int 0)])
16456                       (match_operand:DF 2 "nonimmediate_operand" "")
16457                       (match_operand:DF 3 "nonimmediate_operand" "")))]
16458   "!TARGET_64BIT && reload_completed"
16459   [(set (match_dup 2)
16460         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16461                       (match_dup 5)
16462                       (match_dup 6)))
16463    (set (match_dup 3)
16464         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16465                       (match_dup 7)
16466                       (match_dup 8)))]
16467 {
16468   split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16469   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16470 })
16471
16472 (define_insn "*movsfcc_1_387"
16473   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16474         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16475                                 [(reg FLAGS_REG) (const_int 0)])
16476                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16477                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16478   "TARGET_80387 && TARGET_CMOVE
16479    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16480   "@
16481    fcmov%F1\t{%2, %0|%0, %2}
16482    fcmov%f1\t{%3, %0|%0, %3}
16483    cmov%O2%C1\t{%2, %0|%0, %2}
16484    cmov%O2%c1\t{%3, %0|%0, %3}"
16485   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16486    (set_attr "mode" "SF,SF,SI,SI")])
16487
16488 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16489 ;; the scalar versions to have only XMM registers as operands.
16490
16491 ;; XOP conditional move
16492 (define_insn "*xop_pcmov_<mode>"
16493   [(set (match_operand:MODEF 0 "register_operand" "=x")
16494         (if_then_else:MODEF
16495           (match_operand:MODEF 1 "register_operand" "x")
16496           (match_operand:MODEF 2 "register_operand" "x")
16497           (match_operand:MODEF 3 "register_operand" "x")))]
16498   "TARGET_XOP"
16499   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16500   [(set_attr "type" "sse4arg")])
16501
16502 ;; These versions of the min/max patterns are intentionally ignorant of
16503 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16504 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16505 ;; are undefined in this condition, we're certain this is correct.
16506
16507 (define_insn "<code><mode>3"
16508   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16509         (smaxmin:MODEF
16510           (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16511           (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16512   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16513   "@
16514    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16515    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16516   [(set_attr "isa" "noavx,avx")
16517    (set_attr "prefix" "orig,vex")
16518    (set_attr "type" "sseadd")
16519    (set_attr "mode" "<MODE>")])
16520
16521 ;; These versions of the min/max patterns implement exactly the operations
16522 ;;   min = (op1 < op2 ? op1 : op2)
16523 ;;   max = (!(op1 < op2) ? op1 : op2)
16524 ;; Their operands are not commutative, and thus they may be used in the
16525 ;; presence of -0.0 and NaN.
16526
16527 (define_insn "*ieee_smin<mode>3"
16528   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16529         (unspec:MODEF
16530           [(match_operand:MODEF 1 "register_operand" "0,x")
16531            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16532          UNSPEC_IEEE_MIN))]
16533   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16534   "@
16535    min<ssemodesuffix>\t{%2, %0|%0, %2}
16536    vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16537   [(set_attr "isa" "noavx,avx")
16538    (set_attr "prefix" "orig,vex")
16539    (set_attr "type" "sseadd")
16540    (set_attr "mode" "<MODE>")])
16541
16542 (define_insn "*ieee_smax<mode>3"
16543   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16544         (unspec:MODEF
16545           [(match_operand:MODEF 1 "register_operand" "0,x")
16546            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16547          UNSPEC_IEEE_MAX))]
16548   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16549   "@
16550    max<ssemodesuffix>\t{%2, %0|%0, %2}
16551    vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16552   [(set_attr "isa" "noavx,avx")
16553    (set_attr "prefix" "orig,vex")
16554    (set_attr "type" "sseadd")
16555    (set_attr "mode" "<MODE>")])
16556
16557 ;; Make two stack loads independent:
16558 ;;   fld aa              fld aa
16559 ;;   fld %st(0)     ->   fld bb
16560 ;;   fmul bb             fmul %st(1), %st
16561 ;;
16562 ;; Actually we only match the last two instructions for simplicity.
16563 (define_peephole2
16564   [(set (match_operand 0 "fp_register_operand" "")
16565         (match_operand 1 "fp_register_operand" ""))
16566    (set (match_dup 0)
16567         (match_operator 2 "binary_fp_operator"
16568            [(match_dup 0)
16569             (match_operand 3 "memory_operand" "")]))]
16570   "REGNO (operands[0]) != REGNO (operands[1])"
16571   [(set (match_dup 0) (match_dup 3))
16572    (set (match_dup 0) (match_dup 4))]
16573
16574   ;; The % modifier is not operational anymore in peephole2's, so we have to
16575   ;; swap the operands manually in the case of addition and multiplication.
16576 {
16577   rtx op0, op1;
16578
16579   if (COMMUTATIVE_ARITH_P (operands[2]))
16580     op0 = operands[0], op1 = operands[1];
16581   else
16582     op0 = operands[1], op1 = operands[0];
16583
16584   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16585                                 GET_MODE (operands[2]),
16586                                 op0, op1);
16587 })
16588
16589 ;; Conditional addition patterns
16590 (define_expand "add<mode>cc"
16591   [(match_operand:SWI 0 "register_operand" "")
16592    (match_operand 1 "ordered_comparison_operator" "")
16593    (match_operand:SWI 2 "register_operand" "")
16594    (match_operand:SWI 3 "const_int_operand" "")]
16595   ""
16596   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16597 \f
16598 ;; Misc patterns (?)
16599
16600 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16601 ;; Otherwise there will be nothing to keep
16602 ;;
16603 ;; [(set (reg ebp) (reg esp))]
16604 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16605 ;;  (clobber (eflags)]
16606 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16607 ;;
16608 ;; in proper program order.
16609
16610 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16611   [(set (match_operand:P 0 "register_operand" "=r,r")
16612         (plus:P (match_operand:P 1 "register_operand" "0,r")
16613                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16614    (clobber (reg:CC FLAGS_REG))
16615    (clobber (mem:BLK (scratch)))]
16616   ""
16617 {
16618   switch (get_attr_type (insn))
16619     {
16620     case TYPE_IMOV:
16621       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16622
16623     case TYPE_ALU:
16624       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16625       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16626         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16627
16628       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16629
16630     default:
16631       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16632       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16633     }
16634 }
16635   [(set (attr "type")
16636         (cond [(and (eq_attr "alternative" "0")
16637                     (not (match_test "TARGET_OPT_AGU")))
16638                  (const_string "alu")
16639                (match_operand:<MODE> 2 "const0_operand" "")
16640                  (const_string "imov")
16641               ]
16642               (const_string "lea")))
16643    (set (attr "length_immediate")
16644         (cond [(eq_attr "type" "imov")
16645                  (const_string "0")
16646                (and (eq_attr "type" "alu")
16647                     (match_operand 2 "const128_operand" ""))
16648                  (const_string "1")
16649               ]
16650               (const_string "*")))
16651    (set_attr "mode" "<MODE>")])
16652
16653 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16654   [(set (match_operand:P 0 "register_operand" "=r")
16655         (minus:P (match_operand:P 1 "register_operand" "0")
16656                  (match_operand:P 2 "register_operand" "r")))
16657    (clobber (reg:CC FLAGS_REG))
16658    (clobber (mem:BLK (scratch)))]
16659   ""
16660   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16661   [(set_attr "type" "alu")
16662    (set_attr "mode" "<MODE>")])
16663
16664 (define_insn "allocate_stack_worker_probe_<mode>"
16665   [(set (match_operand:P 0 "register_operand" "=a")
16666         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16667                             UNSPECV_STACK_PROBE))
16668    (clobber (reg:CC FLAGS_REG))]
16669   "ix86_target_stack_probe ()"
16670   "call\t___chkstk_ms"
16671   [(set_attr "type" "multi")
16672    (set_attr "length" "5")])
16673
16674 (define_expand "allocate_stack"
16675   [(match_operand 0 "register_operand" "")
16676    (match_operand 1 "general_operand" "")]
16677   "ix86_target_stack_probe ()"
16678 {
16679   rtx x;
16680
16681 #ifndef CHECK_STACK_LIMIT
16682 #define CHECK_STACK_LIMIT 0
16683 #endif
16684
16685   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16686       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16687     {
16688       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16689                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16690       if (x != stack_pointer_rtx)
16691         emit_move_insn (stack_pointer_rtx, x);
16692     }
16693   else
16694     {
16695       x = copy_to_mode_reg (Pmode, operands[1]);
16696       if (TARGET_64BIT)
16697         emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16698       else
16699         emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16700       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16701                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16702       if (x != stack_pointer_rtx)
16703         emit_move_insn (stack_pointer_rtx, x);
16704     }
16705
16706   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16707   DONE;
16708 })
16709
16710 ;; Use IOR for stack probes, this is shorter.
16711 (define_expand "probe_stack"
16712   [(match_operand 0 "memory_operand" "")]
16713   ""
16714 {
16715   rtx (*gen_ior3) (rtx, rtx, rtx);
16716
16717   gen_ior3 = (GET_MODE (operands[0]) == DImode
16718               ? gen_iordi3 : gen_iorsi3);
16719
16720   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16721   DONE;
16722 })
16723
16724 (define_insn "adjust_stack_and_probe<mode>"
16725   [(set (match_operand:P 0 "register_operand" "=r")
16726         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16727                             UNSPECV_PROBE_STACK_RANGE))
16728    (set (reg:P SP_REG)
16729         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16730    (clobber (reg:CC FLAGS_REG))
16731    (clobber (mem:BLK (scratch)))]
16732   ""
16733   "* return output_adjust_stack_and_probe (operands[0]);"
16734   [(set_attr "type" "multi")])
16735
16736 (define_insn "probe_stack_range<mode>"
16737   [(set (match_operand:P 0 "register_operand" "=r")
16738         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16739                             (match_operand:P 2 "const_int_operand" "n")]
16740                             UNSPECV_PROBE_STACK_RANGE))
16741    (clobber (reg:CC FLAGS_REG))]
16742   ""
16743   "* return output_probe_stack_range (operands[0], operands[2]);"
16744   [(set_attr "type" "multi")])
16745
16746 (define_expand "builtin_setjmp_receiver"
16747   [(label_ref (match_operand 0 "" ""))]
16748   "!TARGET_64BIT && flag_pic"
16749 {
16750 #if TARGET_MACHO
16751   if (TARGET_MACHO)
16752     {
16753       rtx xops[3];
16754       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16755       rtx label_rtx = gen_label_rtx ();
16756       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16757       xops[0] = xops[1] = picreg;
16758       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16759       ix86_expand_binary_operator (MINUS, SImode, xops);
16760     }
16761   else
16762 #endif
16763     emit_insn (gen_set_got (pic_offset_table_rtx));
16764   DONE;
16765 })
16766 \f
16767 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16768
16769 (define_split
16770   [(set (match_operand 0 "register_operand" "")
16771         (match_operator 3 "promotable_binary_operator"
16772            [(match_operand 1 "register_operand" "")
16773             (match_operand 2 "aligned_operand" "")]))
16774    (clobber (reg:CC FLAGS_REG))]
16775   "! TARGET_PARTIAL_REG_STALL && reload_completed
16776    && ((GET_MODE (operands[0]) == HImode
16777         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16778             /* ??? next two lines just !satisfies_constraint_K (...) */
16779             || !CONST_INT_P (operands[2])
16780             || satisfies_constraint_K (operands[2])))
16781        || (GET_MODE (operands[0]) == QImode
16782            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16783   [(parallel [(set (match_dup 0)
16784                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16785               (clobber (reg:CC FLAGS_REG))])]
16786 {
16787   operands[0] = gen_lowpart (SImode, operands[0]);
16788   operands[1] = gen_lowpart (SImode, operands[1]);
16789   if (GET_CODE (operands[3]) != ASHIFT)
16790     operands[2] = gen_lowpart (SImode, operands[2]);
16791   PUT_MODE (operands[3], SImode);
16792 })
16793
16794 ; Promote the QImode tests, as i386 has encoding of the AND
16795 ; instruction with 32-bit sign-extended immediate and thus the
16796 ; instruction size is unchanged, except in the %eax case for
16797 ; which it is increased by one byte, hence the ! optimize_size.
16798 (define_split
16799   [(set (match_operand 0 "flags_reg_operand" "")
16800         (match_operator 2 "compare_operator"
16801           [(and (match_operand 3 "aligned_operand" "")
16802                 (match_operand 4 "const_int_operand" ""))
16803            (const_int 0)]))
16804    (set (match_operand 1 "register_operand" "")
16805         (and (match_dup 3) (match_dup 4)))]
16806   "! TARGET_PARTIAL_REG_STALL && reload_completed
16807    && optimize_insn_for_speed_p ()
16808    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16809        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16810    /* Ensure that the operand will remain sign-extended immediate.  */
16811    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16812   [(parallel [(set (match_dup 0)
16813                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16814                                     (const_int 0)]))
16815               (set (match_dup 1)
16816                    (and:SI (match_dup 3) (match_dup 4)))])]
16817 {
16818   operands[4]
16819     = gen_int_mode (INTVAL (operands[4])
16820                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16821   operands[1] = gen_lowpart (SImode, operands[1]);
16822   operands[3] = gen_lowpart (SImode, operands[3]);
16823 })
16824
16825 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16826 ; the TEST instruction with 32-bit sign-extended immediate and thus
16827 ; the instruction size would at least double, which is not what we
16828 ; want even with ! optimize_size.
16829 (define_split
16830   [(set (match_operand 0 "flags_reg_operand" "")
16831         (match_operator 1 "compare_operator"
16832           [(and (match_operand:HI 2 "aligned_operand" "")
16833                 (match_operand:HI 3 "const_int_operand" ""))
16834            (const_int 0)]))]
16835   "! TARGET_PARTIAL_REG_STALL && reload_completed
16836    && ! TARGET_FAST_PREFIX
16837    && optimize_insn_for_speed_p ()
16838    /* Ensure that the operand will remain sign-extended immediate.  */
16839    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16840   [(set (match_dup 0)
16841         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16842                          (const_int 0)]))]
16843 {
16844   operands[3]
16845     = gen_int_mode (INTVAL (operands[3])
16846                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16847   operands[2] = gen_lowpart (SImode, operands[2]);
16848 })
16849
16850 (define_split
16851   [(set (match_operand 0 "register_operand" "")
16852         (neg (match_operand 1 "register_operand" "")))
16853    (clobber (reg:CC FLAGS_REG))]
16854   "! TARGET_PARTIAL_REG_STALL && reload_completed
16855    && (GET_MODE (operands[0]) == HImode
16856        || (GET_MODE (operands[0]) == QImode
16857            && (TARGET_PROMOTE_QImode
16858                || optimize_insn_for_size_p ())))"
16859   [(parallel [(set (match_dup 0)
16860                    (neg:SI (match_dup 1)))
16861               (clobber (reg:CC FLAGS_REG))])]
16862 {
16863   operands[0] = gen_lowpart (SImode, operands[0]);
16864   operands[1] = gen_lowpart (SImode, operands[1]);
16865 })
16866
16867 (define_split
16868   [(set (match_operand 0 "register_operand" "")
16869         (not (match_operand 1 "register_operand" "")))]
16870   "! TARGET_PARTIAL_REG_STALL && reload_completed
16871    && (GET_MODE (operands[0]) == HImode
16872        || (GET_MODE (operands[0]) == QImode
16873            && (TARGET_PROMOTE_QImode
16874                || optimize_insn_for_size_p ())))"
16875   [(set (match_dup 0)
16876         (not:SI (match_dup 1)))]
16877 {
16878   operands[0] = gen_lowpart (SImode, operands[0]);
16879   operands[1] = gen_lowpart (SImode, operands[1]);
16880 })
16881
16882 (define_split
16883   [(set (match_operand 0 "register_operand" "")
16884         (if_then_else (match_operator 1 "ordered_comparison_operator"
16885                                 [(reg FLAGS_REG) (const_int 0)])
16886                       (match_operand 2 "register_operand" "")
16887                       (match_operand 3 "register_operand" "")))]
16888   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16889    && (GET_MODE (operands[0]) == HImode
16890        || (GET_MODE (operands[0]) == QImode
16891            && (TARGET_PROMOTE_QImode
16892                || optimize_insn_for_size_p ())))"
16893   [(set (match_dup 0)
16894         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16895 {
16896   operands[0] = gen_lowpart (SImode, operands[0]);
16897   operands[2] = gen_lowpart (SImode, operands[2]);
16898   operands[3] = gen_lowpart (SImode, operands[3]);
16899 })
16900 \f
16901 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
16902 ;; transform a complex memory operation into two memory to register operations.
16903
16904 ;; Don't push memory operands
16905 (define_peephole2
16906   [(set (match_operand:SWI 0 "push_operand" "")
16907         (match_operand:SWI 1 "memory_operand" ""))
16908    (match_scratch:SWI 2 "<r>")]
16909   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16910    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16911   [(set (match_dup 2) (match_dup 1))
16912    (set (match_dup 0) (match_dup 2))])
16913
16914 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16915 ;; SImode pushes.
16916 (define_peephole2
16917   [(set (match_operand:SF 0 "push_operand" "")
16918         (match_operand:SF 1 "memory_operand" ""))
16919    (match_scratch:SF 2 "r")]
16920   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16921    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16922   [(set (match_dup 2) (match_dup 1))
16923    (set (match_dup 0) (match_dup 2))])
16924
16925 ;; Don't move an immediate directly to memory when the instruction
16926 ;; gets too big.
16927 (define_peephole2
16928   [(match_scratch:SWI124 1 "<r>")
16929    (set (match_operand:SWI124 0 "memory_operand" "")
16930         (const_int 0))]
16931   "optimize_insn_for_speed_p ()
16932    && !TARGET_USE_MOV0
16933    && TARGET_SPLIT_LONG_MOVES
16934    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16935    && peep2_regno_dead_p (0, FLAGS_REG)"
16936   [(parallel [(set (match_dup 2) (const_int 0))
16937               (clobber (reg:CC FLAGS_REG))])
16938    (set (match_dup 0) (match_dup 1))]
16939   "operands[2] = gen_lowpart (SImode, operands[1]);")
16940
16941 (define_peephole2
16942   [(match_scratch:SWI124 2 "<r>")
16943    (set (match_operand:SWI124 0 "memory_operand" "")
16944         (match_operand:SWI124 1 "immediate_operand" ""))]
16945   "optimize_insn_for_speed_p ()
16946    && TARGET_SPLIT_LONG_MOVES
16947    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16948   [(set (match_dup 2) (match_dup 1))
16949    (set (match_dup 0) (match_dup 2))])
16950
16951 ;; Don't compare memory with zero, load and use a test instead.
16952 (define_peephole2
16953   [(set (match_operand 0 "flags_reg_operand" "")
16954         (match_operator 1 "compare_operator"
16955           [(match_operand:SI 2 "memory_operand" "")
16956            (const_int 0)]))
16957    (match_scratch:SI 3 "r")]
16958   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16959   [(set (match_dup 3) (match_dup 2))
16960    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16961
16962 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16963 ;; Don't split NOTs with a displacement operand, because resulting XOR
16964 ;; will not be pairable anyway.
16965 ;;
16966 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16967 ;; represented using a modRM byte.  The XOR replacement is long decoded,
16968 ;; so this split helps here as well.
16969 ;;
16970 ;; Note: Can't do this as a regular split because we can't get proper
16971 ;; lifetime information then.
16972
16973 (define_peephole2
16974   [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16975         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16976   "optimize_insn_for_speed_p ()
16977    && ((TARGET_NOT_UNPAIRABLE
16978         && (!MEM_P (operands[0])
16979             || !memory_displacement_operand (operands[0], <MODE>mode)))
16980        || (TARGET_NOT_VECTORMODE
16981            && long_memory_operand (operands[0], <MODE>mode)))
16982    && peep2_regno_dead_p (0, FLAGS_REG)"
16983   [(parallel [(set (match_dup 0)
16984                    (xor:SWI124 (match_dup 1) (const_int -1)))
16985               (clobber (reg:CC FLAGS_REG))])])
16986
16987 ;; Non pairable "test imm, reg" instructions can be translated to
16988 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
16989 ;; byte opcode instead of two, have a short form for byte operands),
16990 ;; so do it for other CPUs as well.  Given that the value was dead,
16991 ;; this should not create any new dependencies.  Pass on the sub-word
16992 ;; versions if we're concerned about partial register stalls.
16993
16994 (define_peephole2
16995   [(set (match_operand 0 "flags_reg_operand" "")
16996         (match_operator 1 "compare_operator"
16997           [(and:SI (match_operand:SI 2 "register_operand" "")
16998                    (match_operand:SI 3 "immediate_operand" ""))
16999            (const_int 0)]))]
17000   "ix86_match_ccmode (insn, CCNOmode)
17001    && (true_regnum (operands[2]) != AX_REG
17002        || satisfies_constraint_K (operands[3]))
17003    && peep2_reg_dead_p (1, operands[2])"
17004   [(parallel
17005      [(set (match_dup 0)
17006            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17007                             (const_int 0)]))
17008       (set (match_dup 2)
17009            (and:SI (match_dup 2) (match_dup 3)))])])
17010
17011 ;; We don't need to handle HImode case, because it will be promoted to SImode
17012 ;; on ! TARGET_PARTIAL_REG_STALL
17013
17014 (define_peephole2
17015   [(set (match_operand 0 "flags_reg_operand" "")
17016         (match_operator 1 "compare_operator"
17017           [(and:QI (match_operand:QI 2 "register_operand" "")
17018                    (match_operand:QI 3 "immediate_operand" ""))
17019            (const_int 0)]))]
17020   "! TARGET_PARTIAL_REG_STALL
17021    && ix86_match_ccmode (insn, CCNOmode)
17022    && true_regnum (operands[2]) != AX_REG
17023    && peep2_reg_dead_p (1, operands[2])"
17024   [(parallel
17025      [(set (match_dup 0)
17026            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17027                             (const_int 0)]))
17028       (set (match_dup 2)
17029            (and:QI (match_dup 2) (match_dup 3)))])])
17030
17031 (define_peephole2
17032   [(set (match_operand 0 "flags_reg_operand" "")
17033         (match_operator 1 "compare_operator"
17034           [(and:SI
17035              (zero_extract:SI
17036                (match_operand 2 "ext_register_operand" "")
17037                (const_int 8)
17038                (const_int 8))
17039              (match_operand 3 "const_int_operand" ""))
17040            (const_int 0)]))]
17041   "! TARGET_PARTIAL_REG_STALL
17042    && ix86_match_ccmode (insn, CCNOmode)
17043    && true_regnum (operands[2]) != AX_REG
17044    && peep2_reg_dead_p (1, operands[2])"
17045   [(parallel [(set (match_dup 0)
17046                    (match_op_dup 1
17047                      [(and:SI
17048                         (zero_extract:SI
17049                           (match_dup 2)
17050                           (const_int 8)
17051                           (const_int 8))
17052                         (match_dup 3))
17053                       (const_int 0)]))
17054               (set (zero_extract:SI (match_dup 2)
17055                                     (const_int 8)
17056                                     (const_int 8))
17057                    (and:SI
17058                      (zero_extract:SI
17059                        (match_dup 2)
17060                        (const_int 8)
17061                        (const_int 8))
17062                      (match_dup 3)))])])
17063
17064 ;; Don't do logical operations with memory inputs.
17065 (define_peephole2
17066   [(match_scratch:SI 2 "r")
17067    (parallel [(set (match_operand:SI 0 "register_operand" "")
17068                    (match_operator:SI 3 "arith_or_logical_operator"
17069                      [(match_dup 0)
17070                       (match_operand:SI 1 "memory_operand" "")]))
17071               (clobber (reg:CC FLAGS_REG))])]
17072   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17073   [(set (match_dup 2) (match_dup 1))
17074    (parallel [(set (match_dup 0)
17075                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17076               (clobber (reg:CC FLAGS_REG))])])
17077
17078 (define_peephole2
17079   [(match_scratch:SI 2 "r")
17080    (parallel [(set (match_operand:SI 0 "register_operand" "")
17081                    (match_operator:SI 3 "arith_or_logical_operator"
17082                      [(match_operand:SI 1 "memory_operand" "")
17083                       (match_dup 0)]))
17084               (clobber (reg:CC FLAGS_REG))])]
17085   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17086   [(set (match_dup 2) (match_dup 1))
17087    (parallel [(set (match_dup 0)
17088                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17089               (clobber (reg:CC FLAGS_REG))])])
17090
17091 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17092 ;; refers to the destination of the load!
17093
17094 (define_peephole2
17095   [(set (match_operand:SI 0 "register_operand" "")
17096         (match_operand:SI 1 "register_operand" ""))
17097    (parallel [(set (match_dup 0)
17098                    (match_operator:SI 3 "commutative_operator"
17099                      [(match_dup 0)
17100                       (match_operand:SI 2 "memory_operand" "")]))
17101               (clobber (reg:CC FLAGS_REG))])]
17102   "REGNO (operands[0]) != REGNO (operands[1])
17103    && GENERAL_REGNO_P (REGNO (operands[0]))
17104    && GENERAL_REGNO_P (REGNO (operands[1]))"
17105   [(set (match_dup 0) (match_dup 4))
17106    (parallel [(set (match_dup 0)
17107                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17108               (clobber (reg:CC FLAGS_REG))])]
17109   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17110
17111 (define_peephole2
17112   [(set (match_operand 0 "register_operand" "")
17113         (match_operand 1 "register_operand" ""))
17114    (set (match_dup 0)
17115                    (match_operator 3 "commutative_operator"
17116                      [(match_dup 0)
17117                       (match_operand 2 "memory_operand" "")]))]
17118   "REGNO (operands[0]) != REGNO (operands[1])
17119    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
17120        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17121   [(set (match_dup 0) (match_dup 2))
17122    (set (match_dup 0)
17123         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17124
17125 ; Don't do logical operations with memory outputs
17126 ;
17127 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17128 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17129 ; the same decoder scheduling characteristics as the original.
17130
17131 (define_peephole2
17132   [(match_scratch:SI 2 "r")
17133    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17134                    (match_operator:SI 3 "arith_or_logical_operator"
17135                      [(match_dup 0)
17136                       (match_operand:SI 1 "nonmemory_operand" "")]))
17137               (clobber (reg:CC FLAGS_REG))])]
17138   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17139    /* Do not split stack checking probes.  */
17140    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17141   [(set (match_dup 2) (match_dup 0))
17142    (parallel [(set (match_dup 2)
17143                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17144               (clobber (reg:CC FLAGS_REG))])
17145    (set (match_dup 0) (match_dup 2))])
17146
17147 (define_peephole2
17148   [(match_scratch:SI 2 "r")
17149    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17150                    (match_operator:SI 3 "arith_or_logical_operator"
17151                      [(match_operand:SI 1 "nonmemory_operand" "")
17152                       (match_dup 0)]))
17153               (clobber (reg:CC FLAGS_REG))])]
17154   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17155    /* Do not split stack checking probes.  */
17156    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17157   [(set (match_dup 2) (match_dup 0))
17158    (parallel [(set (match_dup 2)
17159                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17160               (clobber (reg:CC FLAGS_REG))])
17161    (set (match_dup 0) (match_dup 2))])
17162
17163 ;; Attempt to use arith or logical operations with memory outputs with
17164 ;; setting of flags.
17165 (define_peephole2
17166   [(set (match_operand:SWI 0 "register_operand" "")
17167         (match_operand:SWI 1 "memory_operand" ""))
17168    (parallel [(set (match_dup 0)
17169                    (match_operator:SWI 3 "plusminuslogic_operator"
17170                      [(match_dup 0)
17171                       (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17172               (clobber (reg:CC FLAGS_REG))])
17173    (set (match_dup 1) (match_dup 0))
17174    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17175   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17176    && peep2_reg_dead_p (4, operands[0])
17177    && !reg_overlap_mentioned_p (operands[0], operands[1])
17178    && ix86_match_ccmode (peep2_next_insn (3),
17179                          (GET_CODE (operands[3]) == PLUS
17180                           || GET_CODE (operands[3]) == MINUS)
17181                          ? CCGOCmode : CCNOmode)"
17182   [(parallel [(set (match_dup 4) (match_dup 5))
17183               (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17184                                                   (match_dup 2)]))])]
17185 {
17186   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17187   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17188                                 copy_rtx (operands[1]),
17189                                 copy_rtx (operands[2]));
17190   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17191                                  operands[5], const0_rtx);
17192 })
17193
17194 (define_peephole2
17195   [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17196                    (match_operator:SWI 2 "plusminuslogic_operator"
17197                      [(match_dup 0)
17198                       (match_operand:SWI 1 "memory_operand" "")]))
17199               (clobber (reg:CC FLAGS_REG))])
17200    (set (match_dup 1) (match_dup 0))
17201    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17202   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17203    && GET_CODE (operands[2]) != MINUS
17204    && peep2_reg_dead_p (3, operands[0])
17205    && !reg_overlap_mentioned_p (operands[0], operands[1])
17206    && ix86_match_ccmode (peep2_next_insn (2),
17207                          GET_CODE (operands[2]) == PLUS
17208                          ? CCGOCmode : CCNOmode)"
17209   [(parallel [(set (match_dup 3) (match_dup 4))
17210               (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17211                                                   (match_dup 0)]))])]
17212 {
17213   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17214   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17215                                 copy_rtx (operands[1]),
17216                                 copy_rtx (operands[0]));
17217   operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17218                                  operands[4], const0_rtx);
17219 })
17220
17221 (define_peephole2
17222   [(set (match_operand:SWI12 0 "register_operand" "")
17223         (match_operand:SWI12 1 "memory_operand" ""))
17224    (parallel [(set (match_operand:SI 4 "register_operand" "")
17225                    (match_operator:SI 3 "plusminuslogic_operator"
17226                      [(match_dup 4)
17227                       (match_operand:SI 2 "nonmemory_operand" "")]))
17228               (clobber (reg:CC FLAGS_REG))])
17229    (set (match_dup 1) (match_dup 0))
17230    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17231   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17232    && REG_P (operands[0]) && REG_P (operands[4])
17233    && REGNO (operands[0]) == REGNO (operands[4])
17234    && peep2_reg_dead_p (4, operands[0])
17235    && (<MODE>mode != QImode
17236        || immediate_operand (operands[2], SImode)
17237        || q_regs_operand (operands[2], SImode))
17238    && !reg_overlap_mentioned_p (operands[0], operands[1])
17239    && ix86_match_ccmode (peep2_next_insn (3),
17240                          (GET_CODE (operands[3]) == PLUS
17241                           || GET_CODE (operands[3]) == MINUS)
17242                          ? CCGOCmode : CCNOmode)"
17243   [(parallel [(set (match_dup 4) (match_dup 5))
17244               (set (match_dup 1) (match_dup 6))])]
17245 {
17246   operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17247   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17248   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17249                                 copy_rtx (operands[1]), operands[2]);
17250   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17251                                  operands[5], const0_rtx);
17252   operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17253                                 copy_rtx (operands[1]),
17254                                 copy_rtx (operands[2]));
17255 })
17256
17257 ;; Attempt to always use XOR for zeroing registers.
17258 (define_peephole2
17259   [(set (match_operand 0 "register_operand" "")
17260         (match_operand 1 "const0_operand" ""))]
17261   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17262    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17263    && GENERAL_REG_P (operands[0])
17264    && peep2_regno_dead_p (0, FLAGS_REG)"
17265   [(parallel [(set (match_dup 0) (const_int 0))
17266               (clobber (reg:CC FLAGS_REG))])]
17267   "operands[0] = gen_lowpart (word_mode, operands[0]);")
17268
17269 (define_peephole2
17270   [(set (strict_low_part (match_operand 0 "register_operand" ""))
17271         (const_int 0))]
17272   "(GET_MODE (operands[0]) == QImode
17273     || GET_MODE (operands[0]) == HImode)
17274    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17275    && peep2_regno_dead_p (0, FLAGS_REG)"
17276   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17277               (clobber (reg:CC FLAGS_REG))])])
17278
17279 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17280 (define_peephole2
17281   [(set (match_operand:SWI248 0 "register_operand" "")
17282         (const_int -1))]
17283   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17284    && peep2_regno_dead_p (0, FLAGS_REG)"
17285   [(parallel [(set (match_dup 0) (const_int -1))
17286               (clobber (reg:CC FLAGS_REG))])]
17287 {
17288   if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17289     operands[0] = gen_lowpart (SImode, operands[0]);
17290 })
17291
17292 ;; Attempt to convert simple lea to add/shift.
17293 ;; These can be created by move expanders.
17294
17295 (define_peephole2
17296   [(set (match_operand:SWI48 0 "register_operand" "")
17297         (plus:SWI48 (match_dup 0)
17298                     (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17299   "peep2_regno_dead_p (0, FLAGS_REG)"
17300   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17301               (clobber (reg:CC FLAGS_REG))])])
17302
17303 (define_peephole2
17304   [(set (match_operand:SI 0 "register_operand" "")
17305         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17306                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17307   "TARGET_64BIT
17308    && peep2_regno_dead_p (0, FLAGS_REG)
17309    && REGNO (operands[0]) == REGNO (operands[1])"
17310   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17311               (clobber (reg:CC FLAGS_REG))])]
17312   "operands[2] = gen_lowpart (SImode, operands[2]);")
17313
17314 (define_peephole2
17315   [(set (match_operand:SWI48 0 "register_operand" "")
17316         (mult:SWI48 (match_dup 0)
17317                     (match_operand:SWI48 1 "const_int_operand" "")))]
17318   "exact_log2 (INTVAL (operands[1])) >= 0
17319    && peep2_regno_dead_p (0, FLAGS_REG)"
17320   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17321               (clobber (reg:CC FLAGS_REG))])]
17322   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17323
17324 (define_peephole2
17325   [(set (match_operand:SI 0 "register_operand" "")
17326         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17327                    (match_operand:DI 2 "const_int_operand" "")) 0))]
17328   "TARGET_64BIT
17329    && exact_log2 (INTVAL (operands[2])) >= 0
17330    && REGNO (operands[0]) == REGNO (operands[1])
17331    && peep2_regno_dead_p (0, FLAGS_REG)"
17332   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17333               (clobber (reg:CC FLAGS_REG))])]
17334   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17335
17336 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17337 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17338 ;; On many CPUs it is also faster, since special hardware to avoid esp
17339 ;; dependencies is present.
17340
17341 ;; While some of these conversions may be done using splitters, we use
17342 ;; peepholes in order to allow combine_stack_adjustments pass to see
17343 ;; nonobfuscated RTL.
17344
17345 ;; Convert prologue esp subtractions to push.
17346 ;; We need register to push.  In order to keep verify_flow_info happy we have
17347 ;; two choices
17348 ;; - use scratch and clobber it in order to avoid dependencies
17349 ;; - use already live register
17350 ;; We can't use the second way right now, since there is no reliable way how to
17351 ;; verify that given register is live.  First choice will also most likely in
17352 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17353 ;; call clobbered registers are dead.  We may want to use base pointer as an
17354 ;; alternative when no register is available later.
17355
17356 (define_peephole2
17357   [(match_scratch:P 1 "r")
17358    (parallel [(set (reg:P SP_REG)
17359                    (plus:P (reg:P SP_REG)
17360                            (match_operand:P 0 "const_int_operand" "")))
17361               (clobber (reg:CC FLAGS_REG))
17362               (clobber (mem:BLK (scratch)))])]
17363   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17364    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17365   [(clobber (match_dup 1))
17366    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17367               (clobber (mem:BLK (scratch)))])])
17368
17369 (define_peephole2
17370   [(match_scratch:P 1 "r")
17371    (parallel [(set (reg:P SP_REG)
17372                    (plus:P (reg:P SP_REG)
17373                            (match_operand:P 0 "const_int_operand" "")))
17374               (clobber (reg:CC FLAGS_REG))
17375               (clobber (mem:BLK (scratch)))])]
17376   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17377    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17378   [(clobber (match_dup 1))
17379    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17380    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17381               (clobber (mem:BLK (scratch)))])])
17382
17383 ;; Convert esp subtractions to push.
17384 (define_peephole2
17385   [(match_scratch:P 1 "r")
17386    (parallel [(set (reg:P SP_REG)
17387                    (plus:P (reg:P SP_REG)
17388                            (match_operand:P 0 "const_int_operand" "")))
17389               (clobber (reg:CC FLAGS_REG))])]
17390   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17391    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17392   [(clobber (match_dup 1))
17393    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17394
17395 (define_peephole2
17396   [(match_scratch:P 1 "r")
17397    (parallel [(set (reg:P SP_REG)
17398                    (plus:P (reg:P SP_REG)
17399                            (match_operand:P 0 "const_int_operand" "")))
17400               (clobber (reg:CC FLAGS_REG))])]
17401   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17402    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17403   [(clobber (match_dup 1))
17404    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17405    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17406
17407 ;; Convert epilogue deallocator to pop.
17408 (define_peephole2
17409   [(match_scratch:P 1 "r")
17410    (parallel [(set (reg:P SP_REG)
17411                    (plus:P (reg:P SP_REG)
17412                            (match_operand:P 0 "const_int_operand" "")))
17413               (clobber (reg:CC FLAGS_REG))
17414               (clobber (mem:BLK (scratch)))])]
17415   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17416    && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17417   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17418               (clobber (mem:BLK (scratch)))])])
17419
17420 ;; Two pops case is tricky, since pop causes dependency
17421 ;; on destination register.  We use two registers if available.
17422 (define_peephole2
17423   [(match_scratch:P 1 "r")
17424    (match_scratch:P 2 "r")
17425    (parallel [(set (reg:P SP_REG)
17426                    (plus:P (reg:P SP_REG)
17427                            (match_operand:P 0 "const_int_operand" "")))
17428               (clobber (reg:CC FLAGS_REG))
17429               (clobber (mem:BLK (scratch)))])]
17430   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17431    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17432   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17433               (clobber (mem:BLK (scratch)))])
17434    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17435
17436 (define_peephole2
17437   [(match_scratch:P 1 "r")
17438    (parallel [(set (reg:P SP_REG)
17439                    (plus:P (reg:P SP_REG)
17440                            (match_operand:P 0 "const_int_operand" "")))
17441               (clobber (reg:CC FLAGS_REG))
17442               (clobber (mem:BLK (scratch)))])]
17443   "optimize_insn_for_size_p ()
17444    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17445   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17446               (clobber (mem:BLK (scratch)))])
17447    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17448
17449 ;; Convert esp additions to pop.
17450 (define_peephole2
17451   [(match_scratch:P 1 "r")
17452    (parallel [(set (reg:P SP_REG)
17453                    (plus:P (reg:P SP_REG)
17454                            (match_operand:P 0 "const_int_operand" "")))
17455               (clobber (reg:CC FLAGS_REG))])]
17456   "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17457   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17458
17459 ;; Two pops case is tricky, since pop causes dependency
17460 ;; on destination register.  We use two registers if available.
17461 (define_peephole2
17462   [(match_scratch:P 1 "r")
17463    (match_scratch:P 2 "r")
17464    (parallel [(set (reg:P SP_REG)
17465                    (plus:P (reg:P SP_REG)
17466                            (match_operand:P 0 "const_int_operand" "")))
17467               (clobber (reg:CC FLAGS_REG))])]
17468   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17469   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17470    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17471
17472 (define_peephole2
17473   [(match_scratch:P 1 "r")
17474    (parallel [(set (reg:P SP_REG)
17475                    (plus:P (reg:P SP_REG)
17476                            (match_operand:P 0 "const_int_operand" "")))
17477               (clobber (reg:CC FLAGS_REG))])]
17478   "optimize_insn_for_size_p ()
17479    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17480   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17481    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17482 \f
17483 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17484 ;; required and register dies.  Similarly for 128 to -128.
17485 (define_peephole2
17486   [(set (match_operand 0 "flags_reg_operand" "")
17487         (match_operator 1 "compare_operator"
17488           [(match_operand 2 "register_operand" "")
17489            (match_operand 3 "const_int_operand" "")]))]
17490   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17491      && incdec_operand (operands[3], GET_MODE (operands[3])))
17492     || (!TARGET_FUSE_CMP_AND_BRANCH
17493         && INTVAL (operands[3]) == 128))
17494    && ix86_match_ccmode (insn, CCGCmode)
17495    && peep2_reg_dead_p (1, operands[2])"
17496   [(parallel [(set (match_dup 0)
17497                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17498               (clobber (match_dup 2))])])
17499 \f
17500 ;; Convert imul by three, five and nine into lea
17501 (define_peephole2
17502   [(parallel
17503     [(set (match_operand:SWI48 0 "register_operand" "")
17504           (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17505                       (match_operand:SWI48 2 "const359_operand" "")))
17506      (clobber (reg:CC FLAGS_REG))])]
17507   "!TARGET_PARTIAL_REG_STALL
17508    || <MODE>mode == SImode
17509    || optimize_function_for_size_p (cfun)"
17510   [(set (match_dup 0)
17511         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17512                     (match_dup 1)))]
17513   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17514
17515 (define_peephole2
17516   [(parallel
17517     [(set (match_operand:SWI48 0 "register_operand" "")
17518           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17519                       (match_operand:SWI48 2 "const359_operand" "")))
17520      (clobber (reg:CC FLAGS_REG))])]
17521   "optimize_insn_for_speed_p ()
17522    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17523   [(set (match_dup 0) (match_dup 1))
17524    (set (match_dup 0)
17525         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17526                     (match_dup 0)))]
17527   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17528
17529 ;; imul $32bit_imm, mem, reg is vector decoded, while
17530 ;; imul $32bit_imm, reg, reg is direct decoded.
17531 (define_peephole2
17532   [(match_scratch:SWI48 3 "r")
17533    (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17534                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17535                                (match_operand:SWI48 2 "immediate_operand" "")))
17536               (clobber (reg:CC FLAGS_REG))])]
17537   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17538    && !satisfies_constraint_K (operands[2])"
17539   [(set (match_dup 3) (match_dup 1))
17540    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17541               (clobber (reg:CC FLAGS_REG))])])
17542
17543 (define_peephole2
17544   [(match_scratch:SI 3 "r")
17545    (parallel [(set (match_operand:DI 0 "register_operand" "")
17546                    (zero_extend:DI
17547                      (mult:SI (match_operand:SI 1 "memory_operand" "")
17548                               (match_operand:SI 2 "immediate_operand" ""))))
17549               (clobber (reg:CC FLAGS_REG))])]
17550   "TARGET_64BIT
17551    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17552    && !satisfies_constraint_K (operands[2])"
17553   [(set (match_dup 3) (match_dup 1))
17554    (parallel [(set (match_dup 0)
17555                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17556               (clobber (reg:CC FLAGS_REG))])])
17557
17558 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17559 ;; Convert it into imul reg, reg
17560 ;; It would be better to force assembler to encode instruction using long
17561 ;; immediate, but there is apparently no way to do so.
17562 (define_peephole2
17563   [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17564                    (mult:SWI248
17565                     (match_operand:SWI248 1 "nonimmediate_operand" "")
17566                     (match_operand:SWI248 2 "const_int_operand" "")))
17567               (clobber (reg:CC FLAGS_REG))])
17568    (match_scratch:SWI248 3 "r")]
17569   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17570    && satisfies_constraint_K (operands[2])"
17571   [(set (match_dup 3) (match_dup 2))
17572    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17573               (clobber (reg:CC FLAGS_REG))])]
17574 {
17575   if (!rtx_equal_p (operands[0], operands[1]))
17576     emit_move_insn (operands[0], operands[1]);
17577 })
17578
17579 ;; After splitting up read-modify operations, array accesses with memory
17580 ;; operands might end up in form:
17581 ;;  sall    $2, %eax
17582 ;;  movl    4(%esp), %edx
17583 ;;  addl    %edx, %eax
17584 ;; instead of pre-splitting:
17585 ;;  sall    $2, %eax
17586 ;;  addl    4(%esp), %eax
17587 ;; Turn it into:
17588 ;;  movl    4(%esp), %edx
17589 ;;  leal    (%edx,%eax,4), %eax
17590
17591 (define_peephole2
17592   [(match_scratch:P 5 "r")
17593    (parallel [(set (match_operand 0 "register_operand" "")
17594                    (ashift (match_operand 1 "register_operand" "")
17595                            (match_operand 2 "const_int_operand" "")))
17596                (clobber (reg:CC FLAGS_REG))])
17597    (parallel [(set (match_operand 3 "register_operand" "")
17598                    (plus (match_dup 0)
17599                          (match_operand 4 "x86_64_general_operand" "")))
17600                    (clobber (reg:CC FLAGS_REG))])]
17601   "IN_RANGE (INTVAL (operands[2]), 1, 3)
17602    /* Validate MODE for lea.  */
17603    && ((!TARGET_PARTIAL_REG_STALL
17604         && (GET_MODE (operands[0]) == QImode
17605             || GET_MODE (operands[0]) == HImode))
17606        || GET_MODE (operands[0]) == SImode
17607        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17608    && (rtx_equal_p (operands[0], operands[3])
17609        || peep2_reg_dead_p (2, operands[0]))
17610    /* We reorder load and the shift.  */
17611    && !reg_overlap_mentioned_p (operands[0], operands[4])"
17612   [(set (match_dup 5) (match_dup 4))
17613    (set (match_dup 0) (match_dup 1))]
17614 {
17615   enum machine_mode op1mode = GET_MODE (operands[1]);
17616   enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17617   int scale = 1 << INTVAL (operands[2]);
17618   rtx index = gen_lowpart (Pmode, operands[1]);
17619   rtx base = gen_lowpart (Pmode, operands[5]);
17620   rtx dest = gen_lowpart (mode, operands[3]);
17621
17622   operands[1] = gen_rtx_PLUS (Pmode, base,
17623                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17624   operands[5] = base;
17625   if (mode != Pmode)
17626     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17627   if (op1mode != Pmode)
17628     operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17629   operands[0] = dest;
17630 })
17631 \f
17632 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17633 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17634 ;; caught for use by garbage collectors and the like.  Using an insn that
17635 ;; maps to SIGILL makes it more likely the program will rightfully die.
17636 ;; Keeping with tradition, "6" is in honor of #UD.
17637 (define_insn "trap"
17638   [(trap_if (const_int 1) (const_int 6))]
17639   ""
17640   { return ASM_SHORT "0x0b0f"; }
17641   [(set_attr "length" "2")])
17642
17643 (define_expand "prefetch"
17644   [(prefetch (match_operand 0 "address_operand" "")
17645              (match_operand:SI 1 "const_int_operand" "")
17646              (match_operand:SI 2 "const_int_operand" ""))]
17647   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17648 {
17649   int rw = INTVAL (operands[1]);
17650   int locality = INTVAL (operands[2]);
17651
17652   gcc_assert (rw == 0 || rw == 1);
17653   gcc_assert (locality >= 0 && locality <= 3);
17654   gcc_assert (GET_MODE (operands[0]) == Pmode
17655               || GET_MODE (operands[0]) == VOIDmode);
17656
17657   /* Use 3dNOW prefetch in case we are asking for write prefetch not
17658      supported by SSE counterpart or the SSE prefetch is not available
17659      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17660      of locality.  */
17661   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17662     operands[2] = GEN_INT (3);
17663   else
17664     operands[1] = const0_rtx;
17665 })
17666
17667 (define_insn "*prefetch_sse_<mode>"
17668   [(prefetch (match_operand:P 0 "address_operand" "p")
17669              (const_int 0)
17670              (match_operand:SI 1 "const_int_operand" ""))]
17671   "TARGET_PREFETCH_SSE"
17672 {
17673   static const char * const patterns[4] = {
17674    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17675   };
17676
17677   int locality = INTVAL (operands[1]);
17678   gcc_assert (locality >= 0 && locality <= 3);
17679
17680   return patterns[locality];
17681 }
17682   [(set_attr "type" "sse")
17683    (set_attr "atom_sse_attr" "prefetch")
17684    (set (attr "length_address")
17685         (symbol_ref "memory_address_length (operands[0])"))
17686    (set_attr "memory" "none")])
17687
17688 (define_insn "*prefetch_3dnow_<mode>"
17689   [(prefetch (match_operand:P 0 "address_operand" "p")
17690              (match_operand:SI 1 "const_int_operand" "n")
17691              (const_int 3))]
17692   "TARGET_3DNOW"
17693 {
17694   if (INTVAL (operands[1]) == 0)
17695     return "prefetch\t%a0";
17696   else
17697     return "prefetchw\t%a0";
17698 }
17699   [(set_attr "type" "mmx")
17700    (set (attr "length_address")
17701         (symbol_ref "memory_address_length (operands[0])"))
17702    (set_attr "memory" "none")])
17703
17704 (define_expand "stack_protect_set"
17705   [(match_operand 0 "memory_operand" "")
17706    (match_operand 1 "memory_operand" "")]
17707   ""
17708 {
17709   rtx (*insn)(rtx, rtx);
17710
17711 #ifdef TARGET_THREAD_SSP_OFFSET
17712   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17713   insn = (TARGET_LP64
17714           ? gen_stack_tls_protect_set_di
17715           : gen_stack_tls_protect_set_si);
17716 #else
17717   insn = (TARGET_LP64
17718           ? gen_stack_protect_set_di
17719           : gen_stack_protect_set_si);
17720 #endif
17721
17722   emit_insn (insn (operands[0], operands[1]));
17723   DONE;
17724 })
17725
17726 (define_insn "stack_protect_set_<mode>"
17727   [(set (match_operand:PTR 0 "memory_operand" "=m")
17728         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17729                     UNSPEC_SP_SET))
17730    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17731    (clobber (reg:CC FLAGS_REG))]
17732   ""
17733   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17734   [(set_attr "type" "multi")])
17735
17736 (define_insn "stack_tls_protect_set_<mode>"
17737   [(set (match_operand:PTR 0 "memory_operand" "=m")
17738         (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17739                     UNSPEC_SP_TLS_SET))
17740    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17741    (clobber (reg:CC FLAGS_REG))]
17742   ""
17743   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17744   [(set_attr "type" "multi")])
17745
17746 (define_expand "stack_protect_test"
17747   [(match_operand 0 "memory_operand" "")
17748    (match_operand 1 "memory_operand" "")
17749    (match_operand 2 "" "")]
17750   ""
17751 {
17752   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17753
17754   rtx (*insn)(rtx, rtx, rtx);
17755
17756 #ifdef TARGET_THREAD_SSP_OFFSET
17757   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17758   insn = (TARGET_LP64
17759           ? gen_stack_tls_protect_test_di
17760           : gen_stack_tls_protect_test_si);
17761 #else
17762   insn = (TARGET_LP64
17763           ? gen_stack_protect_test_di
17764           : gen_stack_protect_test_si);
17765 #endif
17766
17767   emit_insn (insn (flags, operands[0], operands[1]));
17768
17769   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17770                                   flags, const0_rtx, operands[2]));
17771   DONE;
17772 })
17773
17774 (define_insn "stack_protect_test_<mode>"
17775   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17776         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17777                      (match_operand:PTR 2 "memory_operand" "m")]
17778                     UNSPEC_SP_TEST))
17779    (clobber (match_scratch:PTR 3 "=&r"))]
17780   ""
17781   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17782   [(set_attr "type" "multi")])
17783
17784 (define_insn "stack_tls_protect_test_<mode>"
17785   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17786         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17787                      (match_operand:PTR 2 "const_int_operand" "i")]
17788                     UNSPEC_SP_TLS_TEST))
17789    (clobber (match_scratch:PTR 3 "=r"))]
17790   ""
17791   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17792   [(set_attr "type" "multi")])
17793
17794 (define_insn "sse4_2_crc32<mode>"
17795   [(set (match_operand:SI 0 "register_operand" "=r")
17796         (unspec:SI
17797           [(match_operand:SI 1 "register_operand" "0")
17798            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17799           UNSPEC_CRC32))]
17800   "TARGET_SSE4_2 || TARGET_CRC32"
17801   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17802   [(set_attr "type" "sselog1")
17803    (set_attr "prefix_rep" "1")
17804    (set_attr "prefix_extra" "1")
17805    (set (attr "prefix_data16")
17806      (if_then_else (match_operand:HI 2 "" "")
17807        (const_string "1")
17808        (const_string "*")))
17809    (set (attr "prefix_rex")
17810      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17811        (const_string "1")
17812        (const_string "*")))
17813    (set_attr "mode" "SI")])
17814
17815 (define_insn "sse4_2_crc32di"
17816   [(set (match_operand:DI 0 "register_operand" "=r")
17817         (unspec:DI
17818           [(match_operand:DI 1 "register_operand" "0")
17819            (match_operand:DI 2 "nonimmediate_operand" "rm")]
17820           UNSPEC_CRC32))]
17821   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17822   "crc32{q}\t{%2, %0|%0, %2}"
17823   [(set_attr "type" "sselog1")
17824    (set_attr "prefix_rep" "1")
17825    (set_attr "prefix_extra" "1")
17826    (set_attr "mode" "DI")])
17827
17828 (define_expand "rdpmc"
17829   [(match_operand:DI 0 "register_operand" "")
17830    (match_operand:SI 1 "register_operand" "")]
17831   ""
17832 {
17833   rtx reg = gen_reg_rtx (DImode);
17834   rtx si;
17835
17836   /* Force operand 1 into ECX.  */
17837   rtx ecx = gen_rtx_REG (SImode, CX_REG);
17838   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17839   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17840                                 UNSPECV_RDPMC);
17841
17842   if (TARGET_64BIT)
17843     {
17844       rtvec vec = rtvec_alloc (2);
17845       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17846       rtx upper = gen_reg_rtx (DImode);
17847       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17848                                         gen_rtvec (1, const0_rtx),
17849                                         UNSPECV_RDPMC);
17850       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17851       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17852       emit_insn (load);
17853       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17854                                    NULL, 1, OPTAB_DIRECT);
17855       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17856                                  OPTAB_DIRECT);
17857     }
17858   else
17859     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17860   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17861   DONE;
17862 })
17863
17864 (define_insn "*rdpmc"
17865   [(set (match_operand:DI 0 "register_operand" "=A")
17866         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17867                             UNSPECV_RDPMC))]
17868   "!TARGET_64BIT"
17869   "rdpmc"
17870   [(set_attr "type" "other")
17871    (set_attr "length" "2")])
17872
17873 (define_insn "*rdpmc_rex64"
17874   [(set (match_operand:DI 0 "register_operand" "=a")
17875         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17876                             UNSPECV_RDPMC))
17877   (set (match_operand:DI 1 "register_operand" "=d")
17878        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17879   "TARGET_64BIT"
17880   "rdpmc"
17881   [(set_attr "type" "other")
17882    (set_attr "length" "2")])
17883
17884 (define_expand "rdtsc"
17885   [(set (match_operand:DI 0 "register_operand" "")
17886         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17887   ""
17888 {
17889   if (TARGET_64BIT)
17890     {
17891       rtvec vec = rtvec_alloc (2);
17892       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17893       rtx upper = gen_reg_rtx (DImode);
17894       rtx lower = gen_reg_rtx (DImode);
17895       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17896                                          gen_rtvec (1, const0_rtx),
17897                                          UNSPECV_RDTSC);
17898       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17899       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17900       emit_insn (load);
17901       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17902                                    NULL, 1, OPTAB_DIRECT);
17903       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17904                                    OPTAB_DIRECT);
17905       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17906       DONE;
17907     }
17908 })
17909
17910 (define_insn "*rdtsc"
17911   [(set (match_operand:DI 0 "register_operand" "=A")
17912         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17913   "!TARGET_64BIT"
17914   "rdtsc"
17915   [(set_attr "type" "other")
17916    (set_attr "length" "2")])
17917
17918 (define_insn "*rdtsc_rex64"
17919   [(set (match_operand:DI 0 "register_operand" "=a")
17920         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17921    (set (match_operand:DI 1 "register_operand" "=d")
17922         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17923   "TARGET_64BIT"
17924   "rdtsc"
17925   [(set_attr "type" "other")
17926    (set_attr "length" "2")])
17927
17928 (define_expand "rdtscp"
17929   [(match_operand:DI 0 "register_operand" "")
17930    (match_operand:SI 1 "memory_operand" "")]
17931   ""
17932 {
17933   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17934                                     gen_rtvec (1, const0_rtx),
17935                                     UNSPECV_RDTSCP);
17936   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17937                                     gen_rtvec (1, const0_rtx),
17938                                     UNSPECV_RDTSCP);
17939   rtx reg = gen_reg_rtx (DImode);
17940   rtx tmp = gen_reg_rtx (SImode);
17941
17942   if (TARGET_64BIT)
17943     {
17944       rtvec vec = rtvec_alloc (3);
17945       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17946       rtx upper = gen_reg_rtx (DImode);
17947       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17948       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17949       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17950       emit_insn (load);
17951       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17952                                    NULL, 1, OPTAB_DIRECT);
17953       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17954                                  OPTAB_DIRECT);
17955     }
17956   else
17957     {
17958       rtvec vec = rtvec_alloc (2);
17959       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17960       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17961       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17962       emit_insn (load);
17963     }
17964   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17965   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17966   DONE;
17967 })
17968
17969 (define_insn "*rdtscp"
17970   [(set (match_operand:DI 0 "register_operand" "=A")
17971         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17972    (set (match_operand:SI 1 "register_operand" "=c")
17973         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17974   "!TARGET_64BIT"
17975   "rdtscp"
17976   [(set_attr "type" "other")
17977    (set_attr "length" "3")])
17978
17979 (define_insn "*rdtscp_rex64"
17980   [(set (match_operand:DI 0 "register_operand" "=a")
17981         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17982    (set (match_operand:DI 1 "register_operand" "=d")
17983         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17984    (set (match_operand:SI 2 "register_operand" "=c")
17985         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17986   "TARGET_64BIT"
17987   "rdtscp"
17988   [(set_attr "type" "other")
17989    (set_attr "length" "3")])
17990
17991 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17992 ;;
17993 ;; LWP instructions
17994 ;;
17995 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17996
17997 (define_expand "lwp_llwpcb"
17998   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17999                     UNSPECV_LLWP_INTRINSIC)]
18000   "TARGET_LWP")
18001
18002 (define_insn "*lwp_llwpcb<mode>1"
18003   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18004                     UNSPECV_LLWP_INTRINSIC)]
18005   "TARGET_LWP"
18006   "llwpcb\t%0"
18007   [(set_attr "type" "lwp")
18008    (set_attr "mode" "<MODE>")
18009    (set_attr "length" "5")])
18010
18011 (define_expand "lwp_slwpcb"
18012   [(set (match_operand 0 "register_operand" "=r")
18013         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18014   "TARGET_LWP"
18015 {
18016   rtx (*insn)(rtx);
18017
18018   insn = (TARGET_64BIT
18019           ? gen_lwp_slwpcbdi
18020           : gen_lwp_slwpcbsi);
18021
18022   emit_insn (insn (operands[0]));
18023   DONE;
18024 })
18025
18026 (define_insn "lwp_slwpcb<mode>"
18027   [(set (match_operand:P 0 "register_operand" "=r")
18028         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18029   "TARGET_LWP"
18030   "slwpcb\t%0"
18031   [(set_attr "type" "lwp")
18032    (set_attr "mode" "<MODE>")
18033    (set_attr "length" "5")])
18034
18035 (define_expand "lwp_lwpval<mode>3"
18036   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18037                      (match_operand:SI 2 "nonimmediate_operand" "rm")
18038                      (match_operand:SI 3 "const_int_operand" "i")]
18039                     UNSPECV_LWPVAL_INTRINSIC)]
18040   "TARGET_LWP"
18041   ;; Avoid unused variable warning.
18042   "(void) operands[0];")
18043
18044 (define_insn "*lwp_lwpval<mode>3_1"
18045   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18046                      (match_operand:SI 1 "nonimmediate_operand" "rm")
18047                      (match_operand:SI 2 "const_int_operand" "i")]
18048                     UNSPECV_LWPVAL_INTRINSIC)]
18049   "TARGET_LWP"
18050   "lwpval\t{%2, %1, %0|%0, %1, %2}"
18051   [(set_attr "type" "lwp")
18052    (set_attr "mode" "<MODE>")
18053    (set (attr "length")
18054         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18055
18056 (define_expand "lwp_lwpins<mode>3"
18057   [(set (reg:CCC FLAGS_REG)
18058         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18059                               (match_operand:SI 2 "nonimmediate_operand" "rm")
18060                               (match_operand:SI 3 "const_int_operand" "i")]
18061                              UNSPECV_LWPINS_INTRINSIC))
18062    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18063         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18064   "TARGET_LWP")
18065
18066 (define_insn "*lwp_lwpins<mode>3_1"
18067   [(set (reg:CCC FLAGS_REG)
18068         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18069                               (match_operand:SI 1 "nonimmediate_operand" "rm")
18070                               (match_operand:SI 2 "const_int_operand" "i")]
18071                              UNSPECV_LWPINS_INTRINSIC))]
18072   "TARGET_LWP"
18073   "lwpins\t{%2, %1, %0|%0, %1, %2}"
18074   [(set_attr "type" "lwp")
18075    (set_attr "mode" "<MODE>")
18076    (set (attr "length")
18077         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18078
18079 (define_insn "rdfsbase<mode>"
18080   [(set (match_operand:SWI48 0 "register_operand" "=r")
18081         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18082   "TARGET_64BIT && TARGET_FSGSBASE"
18083   "rdfsbase %0"
18084   [(set_attr "type" "other")
18085    (set_attr "prefix_extra" "2")])
18086
18087 (define_insn "rdgsbase<mode>"
18088   [(set (match_operand:SWI48 0 "register_operand" "=r")
18089         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18090   "TARGET_64BIT && TARGET_FSGSBASE"
18091   "rdgsbase %0"
18092   [(set_attr "type" "other")
18093    (set_attr "prefix_extra" "2")])
18094
18095 (define_insn "wrfsbase<mode>"
18096   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18097                     UNSPECV_WRFSBASE)]
18098   "TARGET_64BIT && TARGET_FSGSBASE"
18099   "wrfsbase %0"
18100   [(set_attr "type" "other")
18101    (set_attr "prefix_extra" "2")])
18102
18103 (define_insn "wrgsbase<mode>"
18104   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18105                     UNSPECV_WRGSBASE)]
18106   "TARGET_64BIT && TARGET_FSGSBASE"
18107   "wrgsbase %0"
18108   [(set_attr "type" "other")
18109    (set_attr "prefix_extra" "2")])
18110
18111 (define_insn "rdrand<mode>_1"
18112   [(set (match_operand:SWI248 0 "register_operand" "=r")
18113         (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18114    (set (reg:CCC FLAGS_REG)
18115         (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18116   "TARGET_RDRND"
18117   "rdrand\t%0"
18118   [(set_attr "type" "other")
18119    (set_attr "prefix_extra" "1")])
18120
18121 (define_expand "pause"
18122   [(set (match_dup 0)
18123         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18124   ""
18125 {
18126   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18127   MEM_VOLATILE_P (operands[0]) = 1;
18128 })
18129
18130 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18131 ;; They have the same encoding.
18132 (define_insn "*pause"
18133   [(set (match_operand:BLK 0 "" "")
18134         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18135   ""
18136   "rep; nop"
18137   [(set_attr "length" "2")
18138    (set_attr "memory" "unknown")])
18139
18140 (include "mmx.md")
18141 (include "sse.md")
18142 (include "sync.md")