OSDN Git Service

Backport from mainline
[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 ;; E -- print address with DImode register names if TARGET_64BIT.
42 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
43 ;; s -- print a shift double count, followed by the assemblers argument
44 ;;      delimiter.
45 ;; b -- print the QImode name of the register for the indicated operand.
46 ;;      %b0 would print %al if operands[0] is reg 0.
47 ;; w --  likewise, print the HImode name of the register.
48 ;; k --  likewise, print the SImode name of the register.
49 ;; q --  likewise, print the DImode name of the register.
50 ;; x --  likewise, print the V4SFmode name of the register.
51 ;; t --  likewise, print the V8SFmode name of the register.
52 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
53 ;; y -- print "st(0)" instead of "st" as a register.
54 ;; d -- print duplicated register operand for AVX instruction.
55 ;; D -- print condition for SSE cmp instruction.
56 ;; P -- if PIC, print an @PLT suffix.
57 ;; p -- print raw symbol name.
58 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
59 ;; & -- print some in-use local-dynamic symbol name.
60 ;; H -- print a memory address offset by 8; used for sse high-parts
61 ;; Y -- print condition for XOP pcom* instruction.
62 ;; + -- print a branch hint as 'cs' or 'ds' prefix
63 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
64 ;; @ -- print a segment register of thread base pointer load
65
66 (define_c_enum "unspec" [
67   ;; Relocation specifiers
68   UNSPEC_GOT
69   UNSPEC_GOTOFF
70   UNSPEC_GOTPCREL
71   UNSPEC_GOTTPOFF
72   UNSPEC_TPOFF
73   UNSPEC_NTPOFF
74   UNSPEC_DTPOFF
75   UNSPEC_GOTNTPOFF
76   UNSPEC_INDNTPOFF
77   UNSPEC_PLTOFF
78   UNSPEC_MACHOPIC_OFFSET
79   UNSPEC_PCREL
80
81   ;; Prologue support
82   UNSPEC_STACK_ALLOC
83   UNSPEC_SET_GOT
84   UNSPEC_SET_RIP
85   UNSPEC_SET_GOT_OFFSET
86   UNSPEC_MEMORY_BLOCKAGE
87   UNSPEC_STACK_CHECK
88
89   ;; TLS support
90   UNSPEC_TP
91   UNSPEC_TLS_GD
92   UNSPEC_TLS_LD_BASE
93   UNSPEC_TLSDESC
94   UNSPEC_TLS_IE_SUN
95
96   ;; Other random patterns
97   UNSPEC_SCAS
98   UNSPEC_FNSTSW
99   UNSPEC_SAHF
100   UNSPEC_PARITY
101   UNSPEC_FSTCW
102   UNSPEC_ADD_CARRY
103   UNSPEC_FLDCW
104   UNSPEC_REP
105   UNSPEC_LD_MPIC        ; load_macho_picbase
106   UNSPEC_TRUNC_NOOP
107   UNSPEC_DIV_ALREADY_SPLIT
108   UNSPEC_MS_TO_SYSV_CALL
109   UNSPEC_CALL_NEEDS_VZEROUPPER
110   UNSPEC_PAUSE
111   UNSPEC_LEA_ADDR
112
113   ;; For SSE/MMX support:
114   UNSPEC_FIX_NOTRUNC
115   UNSPEC_MASKMOV
116   UNSPEC_MOVMSK
117   UNSPEC_RCP
118   UNSPEC_RSQRT
119   UNSPEC_PSADBW
120
121   ;; Generic math support
122   UNSPEC_COPYSIGN
123   UNSPEC_IEEE_MIN       ; not commutative
124   UNSPEC_IEEE_MAX       ; not commutative
125
126   ;; x87 Floating point
127   UNSPEC_SIN
128   UNSPEC_COS
129   UNSPEC_FPATAN
130   UNSPEC_FYL2X
131   UNSPEC_FYL2XP1
132   UNSPEC_FRNDINT
133   UNSPEC_FIST
134   UNSPEC_F2XM1
135   UNSPEC_TAN
136   UNSPEC_FXAM
137
138   ;; x87 Rounding
139   UNSPEC_FRNDINT_FLOOR
140   UNSPEC_FRNDINT_CEIL
141   UNSPEC_FRNDINT_TRUNC
142   UNSPEC_FRNDINT_MASK_PM
143   UNSPEC_FIST_FLOOR
144   UNSPEC_FIST_CEIL
145
146   ;; x87 Double output FP
147   UNSPEC_SINCOS_COS
148   UNSPEC_SINCOS_SIN
149   UNSPEC_XTRACT_FRACT
150   UNSPEC_XTRACT_EXP
151   UNSPEC_FSCALE_FRACT
152   UNSPEC_FSCALE_EXP
153   UNSPEC_FPREM_F
154   UNSPEC_FPREM_U
155   UNSPEC_FPREM1_F
156   UNSPEC_FPREM1_U
157
158   UNSPEC_C2_FLAG
159   UNSPEC_FXAM_MEM
160
161   ;; SSP patterns
162   UNSPEC_SP_SET
163   UNSPEC_SP_TEST
164   UNSPEC_SP_TLS_SET
165   UNSPEC_SP_TLS_TEST
166
167   ;; For ROUND support
168   UNSPEC_ROUND
169
170   ;; For CRC32 support
171   UNSPEC_CRC32
172
173   ;; For BMI support
174   UNSPEC_BEXTR
175
176   ;; For BMI2 support
177   UNSPEC_PDEP
178   UNSPEC_PEXT
179 ])
180
181 (define_c_enum "unspecv" [
182   UNSPECV_BLOCKAGE
183   UNSPECV_STACK_PROBE
184   UNSPECV_PROBE_STACK_RANGE
185   UNSPECV_ALIGN
186   UNSPECV_PROLOGUE_USE
187   UNSPECV_SPLIT_STACK_RETURN
188   UNSPECV_CLD
189   UNSPECV_NOPS
190   UNSPECV_RDTSC
191   UNSPECV_RDTSCP
192   UNSPECV_RDPMC
193   UNSPECV_LLWP_INTRINSIC
194   UNSPECV_SLWP_INTRINSIC
195   UNSPECV_LWPVAL_INTRINSIC
196   UNSPECV_LWPINS_INTRINSIC
197   UNSPECV_RDFSBASE
198   UNSPECV_RDGSBASE
199   UNSPECV_WRFSBASE
200   UNSPECV_WRGSBASE
201
202   ;; For RDRAND support
203   UNSPECV_RDRAND
204 ])
205
206 ;; Constants to represent rounding modes in the ROUND instruction
207 (define_constants
208   [(ROUND_FLOOR                 0x1)
209    (ROUND_CEIL                  0x2)
210    (ROUND_TRUNC                 0x3)
211    (ROUND_MXCSR                 0x4)
212    (ROUND_NO_EXC                0x8)
213   ])
214
215 ;; Constants to represent pcomtrue/pcomfalse variants
216 (define_constants
217   [(PCOM_FALSE                  0)
218    (PCOM_TRUE                   1)
219    (COM_FALSE_S                 2)
220    (COM_FALSE_P                 3)
221    (COM_TRUE_S                  4)
222    (COM_TRUE_P                  5)
223   ])
224
225 ;; Constants used in the XOP pperm instruction
226 (define_constants
227   [(PPERM_SRC                   0x00)   /* copy source */
228    (PPERM_INVERT                0x20)   /* invert source */
229    (PPERM_REVERSE               0x40)   /* bit reverse source */
230    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
231    (PPERM_ZERO                  0x80)   /* all 0's */
232    (PPERM_ONES                  0xa0)   /* all 1's */
233    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
234    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
235    (PPERM_SRC1                  0x00)   /* use first source byte */
236    (PPERM_SRC2                  0x10)   /* use second source byte */
237    ])
238
239 ;; Registers by name.
240 (define_constants
241   [(AX_REG                       0)
242    (DX_REG                       1)
243    (CX_REG                       2)
244    (BX_REG                       3)
245    (SI_REG                       4)
246    (DI_REG                       5)
247    (BP_REG                       6)
248    (SP_REG                       7)
249    (ST0_REG                      8)
250    (ST1_REG                      9)
251    (ST2_REG                     10)
252    (ST3_REG                     11)
253    (ST4_REG                     12)
254    (ST5_REG                     13)
255    (ST6_REG                     14)
256    (ST7_REG                     15)
257    (FLAGS_REG                   17)
258    (FPSR_REG                    18)
259    (FPCR_REG                    19)
260    (XMM0_REG                    21)
261    (XMM1_REG                    22)
262    (XMM2_REG                    23)
263    (XMM3_REG                    24)
264    (XMM4_REG                    25)
265    (XMM5_REG                    26)
266    (XMM6_REG                    27)
267    (XMM7_REG                    28)
268    (MM0_REG                     29)
269    (MM1_REG                     30)
270    (MM2_REG                     31)
271    (MM3_REG                     32)
272    (MM4_REG                     33)
273    (MM5_REG                     34)
274    (MM6_REG                     35)
275    (MM7_REG                     36)
276    (R8_REG                      37)
277    (R9_REG                      38)
278    (R10_REG                     39)
279    (R11_REG                     40)
280    (R12_REG                     41)
281    (R13_REG                     42)
282    (XMM8_REG                    45)
283    (XMM9_REG                    46)
284    (XMM10_REG                   47)
285    (XMM11_REG                   48)
286    (XMM12_REG                   49)
287    (XMM13_REG                   50)
288    (XMM14_REG                   51)
289    (XMM15_REG                   52)
290   ])
291
292 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
293 ;; from i386.c.
294
295 ;; In C guard expressions, put expressions which may be compile-time
296 ;; constants first.  This allows for better optimization.  For
297 ;; example, write "TARGET_64BIT && reload_completed", not
298 ;; "reload_completed && TARGET_64BIT".
299
300 \f
301 ;; Processor type.
302 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
303                     atom,generic64,amdfam10,bdver1,bdver2,btver1"
304   (const (symbol_ref "ix86_schedule")))
305
306 ;; A basic instruction type.  Refinements due to arguments to be
307 ;; provided in other attributes.
308 (define_attr "type"
309   "other,multi,
310    alu,alu1,negnot,imov,imovx,lea,
311    incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
312    icmp,test,ibr,setcc,icmov,
313    push,pop,call,callv,leave,
314    str,bitmanip,
315    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
316    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
317    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
318    ssemuladd,sse4arg,lwp,
319    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
320   (const_string "other"))
321
322 ;; Main data type used by the insn
323 (define_attr "mode"
324   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
325   (const_string "unknown"))
326
327 ;; The CPU unit operations uses.
328 (define_attr "unit" "integer,i387,sse,mmx,unknown"
329   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
330            (const_string "i387")
331          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
332                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
333                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
334            (const_string "sse")
335          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
336            (const_string "mmx")
337          (eq_attr "type" "other")
338            (const_string "unknown")]
339          (const_string "integer")))
340
341 ;; The (bounding maximum) length of an instruction immediate.
342 (define_attr "length_immediate" ""
343   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
344                           bitmanip,imulx")
345            (const_int 0)
346          (eq_attr "unit" "i387,sse,mmx")
347            (const_int 0)
348          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
349                           rotate,rotatex,rotate1,imul,icmp,push,pop")
350            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
351          (eq_attr "type" "imov,test")
352            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
353          (eq_attr "type" "call")
354            (if_then_else (match_operand 0 "constant_call_address_operand" "")
355              (const_int 4)
356              (const_int 0))
357          (eq_attr "type" "callv")
358            (if_then_else (match_operand 1 "constant_call_address_operand" "")
359              (const_int 4)
360              (const_int 0))
361          ;; We don't know the size before shorten_branches.  Expect
362          ;; the instruction to fit for better scheduling.
363          (eq_attr "type" "ibr")
364            (const_int 1)
365          ]
366          (symbol_ref "/* Update immediate_length and other attributes! */
367                       gcc_unreachable (),1")))
368
369 ;; The (bounding maximum) length of an instruction address.
370 (define_attr "length_address" ""
371   (cond [(eq_attr "type" "str,other,multi,fxch")
372            (const_int 0)
373          (and (eq_attr "type" "call")
374               (match_operand 0 "constant_call_address_operand" ""))
375              (const_int 0)
376          (and (eq_attr "type" "callv")
377               (match_operand 1 "constant_call_address_operand" ""))
378              (const_int 0)
379          ]
380          (symbol_ref "ix86_attr_length_address_default (insn)")))
381
382 ;; Set when length prefix is used.
383 (define_attr "prefix_data16" ""
384   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
385            (const_int 0)
386          (eq_attr "mode" "HI")
387            (const_int 1)
388          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
389            (const_int 1)
390         ]
391         (const_int 0)))
392
393 ;; Set when string REP prefix is used.
394 (define_attr "prefix_rep" ""
395   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
396            (const_int 0)
397          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
398            (const_int 1)
399         ]
400         (const_int 0)))
401
402 ;; Set when 0f opcode prefix is used.
403 (define_attr "prefix_0f" ""
404   (if_then_else
405     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
406          (eq_attr "unit" "sse,mmx"))
407     (const_int 1)
408     (const_int 0)))
409
410 ;; Set when REX opcode prefix is used.
411 (define_attr "prefix_rex" ""
412   (cond [(not (match_test "TARGET_64BIT"))
413            (const_int 0)
414          (and (eq_attr "mode" "DI")
415               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
416                    (eq_attr "unit" "!mmx")))
417            (const_int 1)
418          (and (eq_attr "mode" "QI")
419               (match_test "x86_extended_QIreg_mentioned_p (insn)"))
420            (const_int 1)
421          (match_test "x86_extended_reg_mentioned_p (insn)")
422            (const_int 1)
423          (and (eq_attr "type" "imovx")
424               (match_operand:QI 1 "ext_QIreg_operand" ""))
425            (const_int 1)
426         ]
427         (const_int 0)))
428
429 ;; There are also additional prefixes in 3DNOW, SSSE3.
430 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
431 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
432 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
433 (define_attr "prefix_extra" ""
434   (cond [(eq_attr "type" "ssemuladd,sse4arg")
435            (const_int 2)
436          (eq_attr "type" "sseiadd1,ssecvt1")
437            (const_int 1)
438         ]
439         (const_int 0)))
440
441 ;; Prefix used: original, VEX or maybe VEX.
442 (define_attr "prefix" "orig,vex,maybe_vex"
443   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
444     (const_string "vex")
445     (const_string "orig")))
446
447 ;; VEX W bit is used.
448 (define_attr "prefix_vex_w" "" (const_int 0))
449
450 ;; The length of VEX prefix
451 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
452 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
453 ;; still prefix_0f 1, with prefix_extra 1.
454 (define_attr "length_vex" ""
455   (if_then_else (and (eq_attr "prefix_0f" "1")
456                      (eq_attr "prefix_extra" "0"))
457     (if_then_else (eq_attr "prefix_vex_w" "1")
458       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
459       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
460     (if_then_else (eq_attr "prefix_vex_w" "1")
461       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
462       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
463
464 ;; Set when modrm byte is used.
465 (define_attr "modrm" ""
466   (cond [(eq_attr "type" "str,leave")
467            (const_int 0)
468          (eq_attr "unit" "i387")
469            (const_int 0)
470          (and (eq_attr "type" "incdec")
471               (and (not (match_test "TARGET_64BIT"))
472                    (ior (match_operand:SI 1 "register_operand" "")
473                         (match_operand:HI 1 "register_operand" ""))))
474            (const_int 0)
475          (and (eq_attr "type" "push")
476               (not (match_operand 1 "memory_operand" "")))
477            (const_int 0)
478          (and (eq_attr "type" "pop")
479               (not (match_operand 0 "memory_operand" "")))
480            (const_int 0)
481          (and (eq_attr "type" "imov")
482               (and (not (eq_attr "mode" "DI"))
483                    (ior (and (match_operand 0 "register_operand" "")
484                              (match_operand 1 "immediate_operand" ""))
485                         (ior (and (match_operand 0 "ax_reg_operand" "")
486                                   (match_operand 1 "memory_displacement_only_operand" ""))
487                              (and (match_operand 0 "memory_displacement_only_operand" "")
488                                   (match_operand 1 "ax_reg_operand" ""))))))
489            (const_int 0)
490          (and (eq_attr "type" "call")
491               (match_operand 0 "constant_call_address_operand" ""))
492              (const_int 0)
493          (and (eq_attr "type" "callv")
494               (match_operand 1 "constant_call_address_operand" ""))
495              (const_int 0)
496          (and (eq_attr "type" "alu,alu1,icmp,test")
497               (match_operand 0 "ax_reg_operand" ""))
498              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
499          ]
500          (const_int 1)))
501
502 ;; The (bounding maximum) length of an instruction in bytes.
503 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
504 ;; Later we may want to split them and compute proper length as for
505 ;; other insns.
506 (define_attr "length" ""
507   (cond [(eq_attr "type" "other,multi,fistp,frndint")
508            (const_int 16)
509          (eq_attr "type" "fcmp")
510            (const_int 4)
511          (eq_attr "unit" "i387")
512            (plus (const_int 2)
513                  (plus (attr "prefix_data16")
514                        (attr "length_address")))
515          (ior (eq_attr "prefix" "vex")
516               (and (eq_attr "prefix" "maybe_vex")
517                    (match_test "TARGET_AVX")))
518            (plus (attr "length_vex")
519                  (plus (attr "length_immediate")
520                        (plus (attr "modrm")
521                              (attr "length_address"))))]
522          (plus (plus (attr "modrm")
523                      (plus (attr "prefix_0f")
524                            (plus (attr "prefix_rex")
525                                  (plus (attr "prefix_extra")
526                                        (const_int 1)))))
527                (plus (attr "prefix_rep")
528                      (plus (attr "prefix_data16")
529                            (plus (attr "length_immediate")
530                                  (attr "length_address")))))))
531
532 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
533 ;; `store' if there is a simple memory reference therein, or `unknown'
534 ;; if the instruction is complex.
535
536 (define_attr "memory" "none,load,store,both,unknown"
537   (cond [(eq_attr "type" "other,multi,str,lwp")
538            (const_string "unknown")
539          (eq_attr "type" "lea,fcmov,fpspc")
540            (const_string "none")
541          (eq_attr "type" "fistp,leave")
542            (const_string "both")
543          (eq_attr "type" "frndint")
544            (const_string "load")
545          (eq_attr "type" "push")
546            (if_then_else (match_operand 1 "memory_operand" "")
547              (const_string "both")
548              (const_string "store"))
549          (eq_attr "type" "pop")
550            (if_then_else (match_operand 0 "memory_operand" "")
551              (const_string "both")
552              (const_string "load"))
553          (eq_attr "type" "setcc")
554            (if_then_else (match_operand 0 "memory_operand" "")
555              (const_string "store")
556              (const_string "none"))
557          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
558            (if_then_else (ior (match_operand 0 "memory_operand" "")
559                               (match_operand 1 "memory_operand" ""))
560              (const_string "load")
561              (const_string "none"))
562          (eq_attr "type" "ibr")
563            (if_then_else (match_operand 0 "memory_operand" "")
564              (const_string "load")
565              (const_string "none"))
566          (eq_attr "type" "call")
567            (if_then_else (match_operand 0 "constant_call_address_operand" "")
568              (const_string "none")
569              (const_string "load"))
570          (eq_attr "type" "callv")
571            (if_then_else (match_operand 1 "constant_call_address_operand" "")
572              (const_string "none")
573              (const_string "load"))
574          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
575               (match_operand 1 "memory_operand" ""))
576            (const_string "both")
577          (and (match_operand 0 "memory_operand" "")
578               (match_operand 1 "memory_operand" ""))
579            (const_string "both")
580          (match_operand 0 "memory_operand" "")
581            (const_string "store")
582          (match_operand 1 "memory_operand" "")
583            (const_string "load")
584          (and (eq_attr "type"
585                  "!alu1,negnot,ishift1,
586                    imov,imovx,icmp,test,bitmanip,
587                    fmov,fcmp,fsgn,
588                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
589                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
590               (match_operand 2 "memory_operand" ""))
591            (const_string "load")
592          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
593               (match_operand 3 "memory_operand" ""))
594            (const_string "load")
595         ]
596         (const_string "none")))
597
598 ;; Indicates if an instruction has both an immediate and a displacement.
599
600 (define_attr "imm_disp" "false,true,unknown"
601   (cond [(eq_attr "type" "other,multi")
602            (const_string "unknown")
603          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
604               (and (match_operand 0 "memory_displacement_operand" "")
605                    (match_operand 1 "immediate_operand" "")))
606            (const_string "true")
607          (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
608               (and (match_operand 0 "memory_displacement_operand" "")
609                    (match_operand 2 "immediate_operand" "")))
610            (const_string "true")
611         ]
612         (const_string "false")))
613
614 ;; Indicates if an FP operation has an integer source.
615
616 (define_attr "fp_int_src" "false,true"
617   (const_string "false"))
618
619 ;; Defines rounding mode of an FP operation.
620
621 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
622   (const_string "any"))
623
624 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
625 (define_attr "use_carry" "0,1" (const_string "0"))
626
627 ;; Define attribute to indicate unaligned ssemov insns
628 (define_attr "movu" "0,1" (const_string "0"))
629
630 ;; Used to control the "enabled" attribute on a per-instruction basis.
631 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,
632                     bmi2,fma4,fma"
633   (const_string "base"))
634
635 (define_attr "enabled" ""
636   (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
637          (eq_attr "isa" "sse2_noavx")
638            (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
639          (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
640          (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
641          (eq_attr "isa" "sse4_noavx")
642            (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
643          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
644          (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
645          (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
646          (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
647          (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
648         ]
649         (const_int 1)))
650
651 ;; Describe a user's asm statement.
652 (define_asm_attributes
653   [(set_attr "length" "128")
654    (set_attr "type" "multi")])
655
656 (define_code_iterator plusminus [plus minus])
657
658 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
659
660 ;; Base name for define_insn
661 (define_code_attr plusminus_insn
662   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
663    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
664
665 ;; Base name for insn mnemonic.
666 (define_code_attr plusminus_mnemonic
667   [(plus "add") (ss_plus "adds") (us_plus "addus")
668    (minus "sub") (ss_minus "subs") (us_minus "subus")])
669 (define_code_attr plusminus_carry_mnemonic
670   [(plus "adc") (minus "sbb")])
671
672 ;; Mark commutative operators as such in constraints.
673 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
674                         (minus "") (ss_minus "") (us_minus "")])
675
676 ;; Mapping of max and min
677 (define_code_iterator maxmin [smax smin umax umin])
678
679 ;; Mapping of signed max and min
680 (define_code_iterator smaxmin [smax smin])
681
682 ;; Mapping of unsigned max and min
683 (define_code_iterator umaxmin [umax umin])
684
685 ;; Base name for integer and FP insn mnemonic
686 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
687                               (umax "maxu") (umin "minu")])
688 (define_code_attr maxmin_float [(smax "max") (smin "min")])
689
690 ;; Mapping of logic operators
691 (define_code_iterator any_logic [and ior xor])
692 (define_code_iterator any_or [ior xor])
693
694 ;; Base name for insn mnemonic.
695 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
696
697 ;; Mapping of logic-shift operators
698 (define_code_iterator any_lshift [ashift lshiftrt])
699
700 ;; Mapping of shift-right operators
701 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
702
703 ;; Base name for define_insn
704 (define_code_attr shift_insn
705   [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
706
707 ;; Base name for insn mnemonic.
708 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
709 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
710
711 ;; Mapping of rotate operators
712 (define_code_iterator any_rotate [rotate rotatert])
713
714 ;; Base name for define_insn
715 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
716
717 ;; Base name for insn mnemonic.
718 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
719
720 ;; Mapping of abs neg operators
721 (define_code_iterator absneg [abs neg])
722
723 ;; Base name for x87 insn mnemonic.
724 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
725
726 ;; Used in signed and unsigned widening multiplications.
727 (define_code_iterator any_extend [sign_extend zero_extend])
728
729 ;; Prefix for insn menmonic.
730 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
731
732 ;; Prefix for define_insn
733 (define_code_attr u [(sign_extend "") (zero_extend "u")])
734 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
735
736 ;; All integer modes.
737 (define_mode_iterator SWI1248x [QI HI SI DI])
738
739 ;; All integer modes without QImode.
740 (define_mode_iterator SWI248x [HI SI DI])
741
742 ;; All integer modes without QImode and HImode.
743 (define_mode_iterator SWI48x [SI DI])
744
745 ;; All integer modes without SImode and DImode.
746 (define_mode_iterator SWI12 [QI HI])
747
748 ;; All integer modes without DImode.
749 (define_mode_iterator SWI124 [QI HI SI])
750
751 ;; All integer modes without QImode and DImode.
752 (define_mode_iterator SWI24 [HI SI])
753
754 ;; Single word integer modes.
755 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
756
757 ;; Single word integer modes without QImode.
758 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
759
760 ;; Single word integer modes without QImode and HImode.
761 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
762
763 ;; All math-dependant single and double word integer modes.
764 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
765                              (HI "TARGET_HIMODE_MATH")
766                              SI DI (TI "TARGET_64BIT")])
767
768 ;; Math-dependant single word integer modes.
769 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
770                             (HI "TARGET_HIMODE_MATH")
771                             SI (DI "TARGET_64BIT")])
772
773 ;; Math-dependant integer modes without DImode.
774 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
775                                (HI "TARGET_HIMODE_MATH")
776                                SI])
777
778 ;; Math-dependant single word integer modes without QImode.
779 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
780                                SI (DI "TARGET_64BIT")])
781
782 ;; Double word integer modes.
783 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
784                            (TI "TARGET_64BIT")])
785
786 ;; Double word integer modes as mode attribute.
787 (define_mode_attr DWI [(SI "DI") (DI "TI")])
788 (define_mode_attr dwi [(SI "di") (DI "ti")])
789
790 ;; Half mode for double word integer modes.
791 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
792                             (DI "TARGET_64BIT")])
793
794 ;; Instruction suffix for integer modes.
795 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
796
797 ;; Pointer size prefix for integer modes (Intel asm dialect)
798 (define_mode_attr iptrsize [(QI "BYTE")
799                             (HI "WORD")
800                             (SI "DWORD")
801                             (DI "QWORD")])
802
803 ;; Register class for integer modes.
804 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
805
806 ;; Immediate operand constraint for integer modes.
807 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
808
809 ;; General operand constraint for word modes.
810 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
811
812 ;; Immediate operand constraint for double integer modes.
813 (define_mode_attr di [(SI "nF") (DI "e")])
814
815 ;; Immediate operand constraint for shifts.
816 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
817
818 ;; General operand predicate for integer modes.
819 (define_mode_attr general_operand
820         [(QI "general_operand")
821          (HI "general_operand")
822          (SI "x86_64_general_operand")
823          (DI "x86_64_general_operand")
824          (TI "x86_64_general_operand")])
825
826 ;; General sign/zero extend operand predicate for integer modes.
827 (define_mode_attr general_szext_operand
828         [(QI "general_operand")
829          (HI "general_operand")
830          (SI "x86_64_szext_general_operand")
831          (DI "x86_64_szext_general_operand")])
832
833 ;; Immediate operand predicate for integer modes.
834 (define_mode_attr immediate_operand
835         [(QI "immediate_operand")
836          (HI "immediate_operand")
837          (SI "x86_64_immediate_operand")
838          (DI "x86_64_immediate_operand")])
839
840 ;; Nonmemory operand predicate for integer modes.
841 (define_mode_attr nonmemory_operand
842         [(QI "nonmemory_operand")
843          (HI "nonmemory_operand")
844          (SI "x86_64_nonmemory_operand")
845          (DI "x86_64_nonmemory_operand")])
846
847 ;; Operand predicate for shifts.
848 (define_mode_attr shift_operand
849         [(QI "nonimmediate_operand")
850          (HI "nonimmediate_operand")
851          (SI "nonimmediate_operand")
852          (DI "shiftdi_operand")
853          (TI "register_operand")])
854
855 ;; Operand predicate for shift argument.
856 (define_mode_attr shift_immediate_operand
857         [(QI "const_1_to_31_operand")
858          (HI "const_1_to_31_operand")
859          (SI "const_1_to_31_operand")
860          (DI "const_1_to_63_operand")])
861
862 ;; Input operand predicate for arithmetic left shifts.
863 (define_mode_attr ashl_input_operand
864         [(QI "nonimmediate_operand")
865          (HI "nonimmediate_operand")
866          (SI "nonimmediate_operand")
867          (DI "ashldi_input_operand")
868          (TI "reg_or_pm1_operand")])
869
870 ;; SSE and x87 SFmode and DFmode floating point modes
871 (define_mode_iterator MODEF [SF DF])
872
873 ;; All x87 floating point modes
874 (define_mode_iterator X87MODEF [SF DF XF])
875
876 ;; SSE instruction suffix for various modes
877 (define_mode_attr ssemodesuffix
878   [(SF "ss") (DF "sd")
879    (V8SF "ps") (V4DF "pd")
880    (V4SF "ps") (V2DF "pd")
881    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
882    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
883
884 ;; SSE vector suffix for floating point modes
885 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
886
887 ;; SSE vector mode corresponding to a scalar mode
888 (define_mode_attr ssevecmode
889   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
890
891 ;; Instruction suffix for REX 64bit operators.
892 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
893
894 ;; This mode iterator allows :P to be used for patterns that operate on
895 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
896 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
897
898 ;; This mode iterator allows :PTR to be used for patterns that operate on
899 ;; ptr_mode sized quantities.
900 (define_mode_iterator PTR
901   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
902 \f
903 ;; Scheduling descriptions
904
905 (include "pentium.md")
906 (include "ppro.md")
907 (include "k6.md")
908 (include "athlon.md")
909 (include "bdver1.md")
910 (include "geode.md")
911 (include "atom.md")
912 (include "core2.md")
913
914 \f
915 ;; Operand and operator predicates and constraints
916
917 (include "predicates.md")
918 (include "constraints.md")
919
920 \f
921 ;; Compare and branch/compare and store instructions.
922
923 (define_expand "cbranch<mode>4"
924   [(set (reg:CC FLAGS_REG)
925         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
926                     (match_operand:SDWIM 2 "<general_operand>" "")))
927    (set (pc) (if_then_else
928                (match_operator 0 "ordered_comparison_operator"
929                 [(reg:CC FLAGS_REG) (const_int 0)])
930                (label_ref (match_operand 3 "" ""))
931                (pc)))]
932   ""
933 {
934   if (MEM_P (operands[1]) && MEM_P (operands[2]))
935     operands[1] = force_reg (<MODE>mode, operands[1]);
936   ix86_expand_branch (GET_CODE (operands[0]),
937                       operands[1], operands[2], operands[3]);
938   DONE;
939 })
940
941 (define_expand "cstore<mode>4"
942   [(set (reg:CC FLAGS_REG)
943         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
944                     (match_operand:SWIM 3 "<general_operand>" "")))
945    (set (match_operand:QI 0 "register_operand" "")
946         (match_operator 1 "ordered_comparison_operator"
947           [(reg:CC FLAGS_REG) (const_int 0)]))]
948   ""
949 {
950   if (MEM_P (operands[2]) && MEM_P (operands[3]))
951     operands[2] = force_reg (<MODE>mode, operands[2]);
952   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
953                      operands[2], operands[3]);
954   DONE;
955 })
956
957 (define_expand "cmp<mode>_1"
958   [(set (reg:CC FLAGS_REG)
959         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
960                     (match_operand:SWI48 1 "<general_operand>" "")))])
961
962 (define_insn "*cmp<mode>_ccno_1"
963   [(set (reg FLAGS_REG)
964         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
965                  (match_operand:SWI 1 "const0_operand" "")))]
966   "ix86_match_ccmode (insn, CCNOmode)"
967   "@
968    test{<imodesuffix>}\t%0, %0
969    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
970   [(set_attr "type" "test,icmp")
971    (set_attr "length_immediate" "0,1")
972    (set_attr "mode" "<MODE>")])
973
974 (define_insn "*cmp<mode>_1"
975   [(set (reg FLAGS_REG)
976         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
977                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
978   "ix86_match_ccmode (insn, CCmode)"
979   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
980   [(set_attr "type" "icmp")
981    (set_attr "mode" "<MODE>")])
982
983 (define_insn "*cmp<mode>_minus_1"
984   [(set (reg FLAGS_REG)
985         (compare
986           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
987                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
988           (const_int 0)))]
989   "ix86_match_ccmode (insn, CCGOCmode)"
990   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
991   [(set_attr "type" "icmp")
992    (set_attr "mode" "<MODE>")])
993
994 (define_insn "*cmpqi_ext_1"
995   [(set (reg FLAGS_REG)
996         (compare
997           (match_operand:QI 0 "general_operand" "Qm")
998           (subreg:QI
999             (zero_extract:SI
1000               (match_operand 1 "ext_register_operand" "Q")
1001               (const_int 8)
1002               (const_int 8)) 0)))]
1003   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1004   "cmp{b}\t{%h1, %0|%0, %h1}"
1005   [(set_attr "type" "icmp")
1006    (set_attr "mode" "QI")])
1007
1008 (define_insn "*cmpqi_ext_1_rex64"
1009   [(set (reg FLAGS_REG)
1010         (compare
1011           (match_operand:QI 0 "register_operand" "Q")
1012           (subreg:QI
1013             (zero_extract:SI
1014               (match_operand 1 "ext_register_operand" "Q")
1015               (const_int 8)
1016               (const_int 8)) 0)))]
1017   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1018   "cmp{b}\t{%h1, %0|%0, %h1}"
1019   [(set_attr "type" "icmp")
1020    (set_attr "mode" "QI")])
1021
1022 (define_insn "*cmpqi_ext_2"
1023   [(set (reg FLAGS_REG)
1024         (compare
1025           (subreg:QI
1026             (zero_extract:SI
1027               (match_operand 0 "ext_register_operand" "Q")
1028               (const_int 8)
1029               (const_int 8)) 0)
1030           (match_operand:QI 1 "const0_operand" "")))]
1031   "ix86_match_ccmode (insn, CCNOmode)"
1032   "test{b}\t%h0, %h0"
1033   [(set_attr "type" "test")
1034    (set_attr "length_immediate" "0")
1035    (set_attr "mode" "QI")])
1036
1037 (define_expand "cmpqi_ext_3"
1038   [(set (reg:CC FLAGS_REG)
1039         (compare:CC
1040           (subreg:QI
1041             (zero_extract:SI
1042               (match_operand 0 "ext_register_operand" "")
1043               (const_int 8)
1044               (const_int 8)) 0)
1045           (match_operand:QI 1 "immediate_operand" "")))])
1046
1047 (define_insn "*cmpqi_ext_3_insn"
1048   [(set (reg FLAGS_REG)
1049         (compare
1050           (subreg:QI
1051             (zero_extract:SI
1052               (match_operand 0 "ext_register_operand" "Q")
1053               (const_int 8)
1054               (const_int 8)) 0)
1055           (match_operand:QI 1 "general_operand" "Qmn")))]
1056   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1057   "cmp{b}\t{%1, %h0|%h0, %1}"
1058   [(set_attr "type" "icmp")
1059    (set_attr "modrm" "1")
1060    (set_attr "mode" "QI")])
1061
1062 (define_insn "*cmpqi_ext_3_insn_rex64"
1063   [(set (reg FLAGS_REG)
1064         (compare
1065           (subreg:QI
1066             (zero_extract:SI
1067               (match_operand 0 "ext_register_operand" "Q")
1068               (const_int 8)
1069               (const_int 8)) 0)
1070           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1071   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1072   "cmp{b}\t{%1, %h0|%h0, %1}"
1073   [(set_attr "type" "icmp")
1074    (set_attr "modrm" "1")
1075    (set_attr "mode" "QI")])
1076
1077 (define_insn "*cmpqi_ext_4"
1078   [(set (reg FLAGS_REG)
1079         (compare
1080           (subreg:QI
1081             (zero_extract:SI
1082               (match_operand 0 "ext_register_operand" "Q")
1083               (const_int 8)
1084               (const_int 8)) 0)
1085           (subreg:QI
1086             (zero_extract:SI
1087               (match_operand 1 "ext_register_operand" "Q")
1088               (const_int 8)
1089               (const_int 8)) 0)))]
1090   "ix86_match_ccmode (insn, CCmode)"
1091   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1092   [(set_attr "type" "icmp")
1093    (set_attr "mode" "QI")])
1094
1095 ;; These implement float point compares.
1096 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1097 ;; which would allow mix and match FP modes on the compares.  Which is what
1098 ;; the old patterns did, but with many more of them.
1099
1100 (define_expand "cbranchxf4"
1101   [(set (reg:CC FLAGS_REG)
1102         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1103                     (match_operand:XF 2 "nonmemory_operand" "")))
1104    (set (pc) (if_then_else
1105               (match_operator 0 "ix86_fp_comparison_operator"
1106                [(reg:CC FLAGS_REG)
1107                 (const_int 0)])
1108               (label_ref (match_operand 3 "" ""))
1109               (pc)))]
1110   "TARGET_80387"
1111 {
1112   ix86_expand_branch (GET_CODE (operands[0]),
1113                       operands[1], operands[2], operands[3]);
1114   DONE;
1115 })
1116
1117 (define_expand "cstorexf4"
1118   [(set (reg:CC FLAGS_REG)
1119         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1120                     (match_operand:XF 3 "nonmemory_operand" "")))
1121    (set (match_operand:QI 0 "register_operand" "")
1122               (match_operator 1 "ix86_fp_comparison_operator"
1123                [(reg:CC FLAGS_REG)
1124                 (const_int 0)]))]
1125   "TARGET_80387"
1126 {
1127   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1128                      operands[2], operands[3]);
1129   DONE;
1130 })
1131
1132 (define_expand "cbranch<mode>4"
1133   [(set (reg:CC FLAGS_REG)
1134         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1135                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1136    (set (pc) (if_then_else
1137               (match_operator 0 "ix86_fp_comparison_operator"
1138                [(reg:CC FLAGS_REG)
1139                 (const_int 0)])
1140               (label_ref (match_operand 3 "" ""))
1141               (pc)))]
1142   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1143 {
1144   ix86_expand_branch (GET_CODE (operands[0]),
1145                       operands[1], operands[2], operands[3]);
1146   DONE;
1147 })
1148
1149 (define_expand "cstore<mode>4"
1150   [(set (reg:CC FLAGS_REG)
1151         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1152                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1153    (set (match_operand:QI 0 "register_operand" "")
1154               (match_operator 1 "ix86_fp_comparison_operator"
1155                [(reg:CC FLAGS_REG)
1156                 (const_int 0)]))]
1157   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1158 {
1159   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1160                      operands[2], operands[3]);
1161   DONE;
1162 })
1163
1164 (define_expand "cbranchcc4"
1165   [(set (pc) (if_then_else
1166               (match_operator 0 "comparison_operator"
1167                [(match_operand 1 "flags_reg_operand" "")
1168                 (match_operand 2 "const0_operand" "")])
1169               (label_ref (match_operand 3 "" ""))
1170               (pc)))]
1171   ""
1172 {
1173   ix86_expand_branch (GET_CODE (operands[0]),
1174                       operands[1], operands[2], operands[3]);
1175   DONE;
1176 })
1177
1178 (define_expand "cstorecc4"
1179   [(set (match_operand:QI 0 "register_operand" "")
1180               (match_operator 1 "comparison_operator"
1181                [(match_operand 2 "flags_reg_operand" "")
1182                 (match_operand 3 "const0_operand" "")]))]
1183   ""
1184 {
1185   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1186                      operands[2], operands[3]);
1187   DONE;
1188 })
1189
1190
1191 ;; FP compares, step 1:
1192 ;; Set the FP condition codes.
1193 ;;
1194 ;; CCFPmode     compare with exceptions
1195 ;; CCFPUmode    compare with no exceptions
1196
1197 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1198 ;; used to manage the reg stack popping would not be preserved.
1199
1200 (define_insn "*cmpfp_0"
1201   [(set (match_operand:HI 0 "register_operand" "=a")
1202         (unspec:HI
1203           [(compare:CCFP
1204              (match_operand 1 "register_operand" "f")
1205              (match_operand 2 "const0_operand" ""))]
1206         UNSPEC_FNSTSW))]
1207   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1208    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1209   "* return output_fp_compare (insn, operands, false, false);"
1210   [(set_attr "type" "multi")
1211    (set_attr "unit" "i387")
1212    (set (attr "mode")
1213      (cond [(match_operand:SF 1 "" "")
1214               (const_string "SF")
1215             (match_operand:DF 1 "" "")
1216               (const_string "DF")
1217            ]
1218            (const_string "XF")))])
1219
1220 (define_insn_and_split "*cmpfp_0_cc"
1221   [(set (reg:CCFP FLAGS_REG)
1222         (compare:CCFP
1223           (match_operand 1 "register_operand" "f")
1224           (match_operand 2 "const0_operand" "")))
1225    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1226   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1227    && TARGET_SAHF && !TARGET_CMOVE
1228    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1229   "#"
1230   "&& reload_completed"
1231   [(set (match_dup 0)
1232         (unspec:HI
1233           [(compare:CCFP (match_dup 1)(match_dup 2))]
1234         UNSPEC_FNSTSW))
1235    (set (reg:CC FLAGS_REG)
1236         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1237   ""
1238   [(set_attr "type" "multi")
1239    (set_attr "unit" "i387")
1240    (set (attr "mode")
1241      (cond [(match_operand:SF 1 "" "")
1242               (const_string "SF")
1243             (match_operand:DF 1 "" "")
1244               (const_string "DF")
1245            ]
1246            (const_string "XF")))])
1247
1248 (define_insn "*cmpfp_xf"
1249   [(set (match_operand:HI 0 "register_operand" "=a")
1250         (unspec:HI
1251           [(compare:CCFP
1252              (match_operand:XF 1 "register_operand" "f")
1253              (match_operand:XF 2 "register_operand" "f"))]
1254           UNSPEC_FNSTSW))]
1255   "TARGET_80387"
1256   "* return output_fp_compare (insn, operands, false, false);"
1257   [(set_attr "type" "multi")
1258    (set_attr "unit" "i387")
1259    (set_attr "mode" "XF")])
1260
1261 (define_insn_and_split "*cmpfp_xf_cc"
1262   [(set (reg:CCFP FLAGS_REG)
1263         (compare:CCFP
1264           (match_operand:XF 1 "register_operand" "f")
1265           (match_operand:XF 2 "register_operand" "f")))
1266    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1267   "TARGET_80387
1268    && TARGET_SAHF && !TARGET_CMOVE"
1269   "#"
1270   "&& reload_completed"
1271   [(set (match_dup 0)
1272         (unspec:HI
1273           [(compare:CCFP (match_dup 1)(match_dup 2))]
1274         UNSPEC_FNSTSW))
1275    (set (reg:CC FLAGS_REG)
1276         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1277   ""
1278   [(set_attr "type" "multi")
1279    (set_attr "unit" "i387")
1280    (set_attr "mode" "XF")])
1281
1282 (define_insn "*cmpfp_<mode>"
1283   [(set (match_operand:HI 0 "register_operand" "=a")
1284         (unspec:HI
1285           [(compare:CCFP
1286              (match_operand:MODEF 1 "register_operand" "f")
1287              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1288           UNSPEC_FNSTSW))]
1289   "TARGET_80387"
1290   "* return output_fp_compare (insn, operands, false, false);"
1291   [(set_attr "type" "multi")
1292    (set_attr "unit" "i387")
1293    (set_attr "mode" "<MODE>")])
1294
1295 (define_insn_and_split "*cmpfp_<mode>_cc"
1296   [(set (reg:CCFP FLAGS_REG)
1297         (compare:CCFP
1298           (match_operand:MODEF 1 "register_operand" "f")
1299           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1300    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1301   "TARGET_80387
1302    && TARGET_SAHF && !TARGET_CMOVE"
1303   "#"
1304   "&& reload_completed"
1305   [(set (match_dup 0)
1306         (unspec:HI
1307           [(compare:CCFP (match_dup 1)(match_dup 2))]
1308         UNSPEC_FNSTSW))
1309    (set (reg:CC FLAGS_REG)
1310         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1311   ""
1312   [(set_attr "type" "multi")
1313    (set_attr "unit" "i387")
1314    (set_attr "mode" "<MODE>")])
1315
1316 (define_insn "*cmpfp_u"
1317   [(set (match_operand:HI 0 "register_operand" "=a")
1318         (unspec:HI
1319           [(compare:CCFPU
1320              (match_operand 1 "register_operand" "f")
1321              (match_operand 2 "register_operand" "f"))]
1322           UNSPEC_FNSTSW))]
1323   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1324    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1325   "* return output_fp_compare (insn, operands, false, true);"
1326   [(set_attr "type" "multi")
1327    (set_attr "unit" "i387")
1328    (set (attr "mode")
1329      (cond [(match_operand:SF 1 "" "")
1330               (const_string "SF")
1331             (match_operand:DF 1 "" "")
1332               (const_string "DF")
1333            ]
1334            (const_string "XF")))])
1335
1336 (define_insn_and_split "*cmpfp_u_cc"
1337   [(set (reg:CCFPU FLAGS_REG)
1338         (compare:CCFPU
1339           (match_operand 1 "register_operand" "f")
1340           (match_operand 2 "register_operand" "f")))
1341    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1342   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1343    && TARGET_SAHF && !TARGET_CMOVE
1344    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1345   "#"
1346   "&& reload_completed"
1347   [(set (match_dup 0)
1348         (unspec:HI
1349           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1350         UNSPEC_FNSTSW))
1351    (set (reg:CC FLAGS_REG)
1352         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1353   ""
1354   [(set_attr "type" "multi")
1355    (set_attr "unit" "i387")
1356    (set (attr "mode")
1357      (cond [(match_operand:SF 1 "" "")
1358               (const_string "SF")
1359             (match_operand:DF 1 "" "")
1360               (const_string "DF")
1361            ]
1362            (const_string "XF")))])
1363
1364 (define_insn "*cmpfp_<mode>"
1365   [(set (match_operand:HI 0 "register_operand" "=a")
1366         (unspec:HI
1367           [(compare:CCFP
1368              (match_operand 1 "register_operand" "f")
1369              (match_operator 3 "float_operator"
1370                [(match_operand:SWI24 2 "memory_operand" "m")]))]
1371           UNSPEC_FNSTSW))]
1372   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1373    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1374    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1375   "* return output_fp_compare (insn, operands, false, false);"
1376   [(set_attr "type" "multi")
1377    (set_attr "unit" "i387")
1378    (set_attr "fp_int_src" "true")
1379    (set_attr "mode" "<MODE>")])
1380
1381 (define_insn_and_split "*cmpfp_<mode>_cc"
1382   [(set (reg:CCFP FLAGS_REG)
1383         (compare:CCFP
1384           (match_operand 1 "register_operand" "f")
1385           (match_operator 3 "float_operator"
1386             [(match_operand:SWI24 2 "memory_operand" "m")])))
1387    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1388   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1389    && TARGET_SAHF && !TARGET_CMOVE
1390    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1391    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1392   "#"
1393   "&& reload_completed"
1394   [(set (match_dup 0)
1395         (unspec:HI
1396           [(compare:CCFP
1397              (match_dup 1)
1398              (match_op_dup 3 [(match_dup 2)]))]
1399         UNSPEC_FNSTSW))
1400    (set (reg:CC FLAGS_REG)
1401         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1402   ""
1403   [(set_attr "type" "multi")
1404    (set_attr "unit" "i387")
1405    (set_attr "fp_int_src" "true")
1406    (set_attr "mode" "<MODE>")])
1407
1408 ;; FP compares, step 2
1409 ;; Move the fpsw to ax.
1410
1411 (define_insn "x86_fnstsw_1"
1412   [(set (match_operand:HI 0 "register_operand" "=a")
1413         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1414   "TARGET_80387"
1415   "fnstsw\t%0"
1416   [(set (attr "length")
1417         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1418    (set_attr "mode" "SI")
1419    (set_attr "unit" "i387")])
1420
1421 ;; FP compares, step 3
1422 ;; Get ax into flags, general case.
1423
1424 (define_insn "x86_sahf_1"
1425   [(set (reg:CC FLAGS_REG)
1426         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1427                    UNSPEC_SAHF))]
1428   "TARGET_SAHF"
1429 {
1430 #ifndef HAVE_AS_IX86_SAHF
1431   if (TARGET_64BIT)
1432     return ASM_BYTE "0x9e";
1433   else
1434 #endif
1435   return "sahf";
1436 }
1437   [(set_attr "length" "1")
1438    (set_attr "athlon_decode" "vector")
1439    (set_attr "amdfam10_decode" "direct")
1440    (set_attr "bdver1_decode" "direct")
1441    (set_attr "mode" "SI")])
1442
1443 ;; Pentium Pro can do steps 1 through 3 in one go.
1444 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1445 ;; (these i387 instructions set flags directly)
1446 (define_insn "*cmpfp_i_mixed"
1447   [(set (reg:CCFP FLAGS_REG)
1448         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1449                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1450   "TARGET_MIX_SSE_I387
1451    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1452    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1453   "* return output_fp_compare (insn, operands, true, false);"
1454   [(set_attr "type" "fcmp,ssecomi")
1455    (set_attr "prefix" "orig,maybe_vex")
1456    (set (attr "mode")
1457      (if_then_else (match_operand:SF 1 "" "")
1458         (const_string "SF")
1459         (const_string "DF")))
1460    (set (attr "prefix_rep")
1461         (if_then_else (eq_attr "type" "ssecomi")
1462                       (const_string "0")
1463                       (const_string "*")))
1464    (set (attr "prefix_data16")
1465         (cond [(eq_attr "type" "fcmp")
1466                  (const_string "*")
1467                (eq_attr "mode" "DF")
1468                  (const_string "1")
1469               ]
1470               (const_string "0")))
1471    (set_attr "athlon_decode" "vector")
1472    (set_attr "amdfam10_decode" "direct")
1473    (set_attr "bdver1_decode" "double")])
1474
1475 (define_insn "*cmpfp_i_sse"
1476   [(set (reg:CCFP FLAGS_REG)
1477         (compare:CCFP (match_operand 0 "register_operand" "x")
1478                       (match_operand 1 "nonimmediate_operand" "xm")))]
1479   "TARGET_SSE_MATH
1480    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1481    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1482   "* return output_fp_compare (insn, operands, true, false);"
1483   [(set_attr "type" "ssecomi")
1484    (set_attr "prefix" "maybe_vex")
1485    (set (attr "mode")
1486      (if_then_else (match_operand:SF 1 "" "")
1487         (const_string "SF")
1488         (const_string "DF")))
1489    (set_attr "prefix_rep" "0")
1490    (set (attr "prefix_data16")
1491         (if_then_else (eq_attr "mode" "DF")
1492                       (const_string "1")
1493                       (const_string "0")))
1494    (set_attr "athlon_decode" "vector")
1495    (set_attr "amdfam10_decode" "direct")
1496    (set_attr "bdver1_decode" "double")])
1497
1498 (define_insn "*cmpfp_i_i387"
1499   [(set (reg:CCFP FLAGS_REG)
1500         (compare:CCFP (match_operand 0 "register_operand" "f")
1501                       (match_operand 1 "register_operand" "f")))]
1502   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1503    && TARGET_CMOVE
1504    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1505    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1506   "* return output_fp_compare (insn, operands, true, false);"
1507   [(set_attr "type" "fcmp")
1508    (set (attr "mode")
1509      (cond [(match_operand:SF 1 "" "")
1510               (const_string "SF")
1511             (match_operand:DF 1 "" "")
1512               (const_string "DF")
1513            ]
1514            (const_string "XF")))
1515    (set_attr "athlon_decode" "vector")
1516    (set_attr "amdfam10_decode" "direct")
1517    (set_attr "bdver1_decode" "double")])
1518
1519 (define_insn "*cmpfp_iu_mixed"
1520   [(set (reg:CCFPU FLAGS_REG)
1521         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1522                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1523   "TARGET_MIX_SSE_I387
1524    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1525    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1526   "* return output_fp_compare (insn, operands, true, true);"
1527   [(set_attr "type" "fcmp,ssecomi")
1528    (set_attr "prefix" "orig,maybe_vex")
1529    (set (attr "mode")
1530      (if_then_else (match_operand:SF 1 "" "")
1531         (const_string "SF")
1532         (const_string "DF")))
1533    (set (attr "prefix_rep")
1534         (if_then_else (eq_attr "type" "ssecomi")
1535                       (const_string "0")
1536                       (const_string "*")))
1537    (set (attr "prefix_data16")
1538         (cond [(eq_attr "type" "fcmp")
1539                  (const_string "*")
1540                (eq_attr "mode" "DF")
1541                  (const_string "1")
1542               ]
1543               (const_string "0")))
1544    (set_attr "athlon_decode" "vector")
1545    (set_attr "amdfam10_decode" "direct")
1546    (set_attr "bdver1_decode" "double")])
1547
1548 (define_insn "*cmpfp_iu_sse"
1549   [(set (reg:CCFPU FLAGS_REG)
1550         (compare:CCFPU (match_operand 0 "register_operand" "x")
1551                        (match_operand 1 "nonimmediate_operand" "xm")))]
1552   "TARGET_SSE_MATH
1553    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1554    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1555   "* return output_fp_compare (insn, operands, true, true);"
1556   [(set_attr "type" "ssecomi")
1557    (set_attr "prefix" "maybe_vex")
1558    (set (attr "mode")
1559      (if_then_else (match_operand:SF 1 "" "")
1560         (const_string "SF")
1561         (const_string "DF")))
1562    (set_attr "prefix_rep" "0")
1563    (set (attr "prefix_data16")
1564         (if_then_else (eq_attr "mode" "DF")
1565                       (const_string "1")
1566                       (const_string "0")))
1567    (set_attr "athlon_decode" "vector")
1568    (set_attr "amdfam10_decode" "direct")
1569    (set_attr "bdver1_decode" "double")])
1570
1571 (define_insn "*cmpfp_iu_387"
1572   [(set (reg:CCFPU FLAGS_REG)
1573         (compare:CCFPU (match_operand 0 "register_operand" "f")
1574                        (match_operand 1 "register_operand" "f")))]
1575   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1576    && TARGET_CMOVE
1577    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1578    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1579   "* return output_fp_compare (insn, operands, true, true);"
1580   [(set_attr "type" "fcmp")
1581    (set (attr "mode")
1582      (cond [(match_operand:SF 1 "" "")
1583               (const_string "SF")
1584             (match_operand:DF 1 "" "")
1585               (const_string "DF")
1586            ]
1587            (const_string "XF")))
1588    (set_attr "athlon_decode" "vector")
1589    (set_attr "amdfam10_decode" "direct")
1590    (set_attr "bdver1_decode" "direct")])
1591 \f
1592 ;; Push/pop instructions.
1593
1594 (define_insn "*push<mode>2"
1595   [(set (match_operand:DWI 0 "push_operand" "=<")
1596         (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1597   ""
1598   "#"
1599   [(set_attr "type" "multi")
1600    (set_attr "mode" "<MODE>")])
1601
1602 (define_split
1603   [(set (match_operand:TI 0 "push_operand" "")
1604         (match_operand:TI 1 "general_operand" ""))]
1605   "TARGET_64BIT && reload_completed
1606    && !SSE_REG_P (operands[1])"
1607   [(const_int 0)]
1608   "ix86_split_long_move (operands); DONE;")
1609
1610 (define_insn "*pushdi2_rex64"
1611   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1612         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1613   "TARGET_64BIT"
1614   "@
1615    push{q}\t%1
1616    #"
1617   [(set_attr "type" "push,multi")
1618    (set_attr "mode" "DI")])
1619
1620 ;; Convert impossible pushes of immediate to existing instructions.
1621 ;; First try to get scratch register and go through it.  In case this
1622 ;; fails, push sign extended lower part first and then overwrite
1623 ;; upper part by 32bit move.
1624 (define_peephole2
1625   [(match_scratch:DI 2 "r")
1626    (set (match_operand:DI 0 "push_operand" "")
1627         (match_operand:DI 1 "immediate_operand" ""))]
1628   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1629    && !x86_64_immediate_operand (operands[1], DImode)"
1630   [(set (match_dup 2) (match_dup 1))
1631    (set (match_dup 0) (match_dup 2))])
1632
1633 ;; We need to define this as both peepholer and splitter for case
1634 ;; peephole2 pass is not run.
1635 ;; "&& 1" is needed to keep it from matching the previous pattern.
1636 (define_peephole2
1637   [(set (match_operand:DI 0 "push_operand" "")
1638         (match_operand:DI 1 "immediate_operand" ""))]
1639   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1640    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1641   [(set (match_dup 0) (match_dup 1))
1642    (set (match_dup 2) (match_dup 3))]
1643 {
1644   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1645
1646   operands[1] = gen_lowpart (DImode, operands[2]);
1647   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1648                                                    GEN_INT (4)));
1649 })
1650
1651 (define_split
1652   [(set (match_operand:DI 0 "push_operand" "")
1653         (match_operand:DI 1 "immediate_operand" ""))]
1654   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1655                     ? epilogue_completed : reload_completed)
1656    && !symbolic_operand (operands[1], DImode)
1657    && !x86_64_immediate_operand (operands[1], DImode)"
1658   [(set (match_dup 0) (match_dup 1))
1659    (set (match_dup 2) (match_dup 3))]
1660 {
1661   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1662
1663   operands[1] = gen_lowpart (DImode, operands[2]);
1664   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1665                                                    GEN_INT (4)));
1666 })
1667
1668 (define_split
1669   [(set (match_operand:DI 0 "push_operand" "")
1670         (match_operand:DI 1 "general_operand" ""))]
1671   "!TARGET_64BIT && reload_completed
1672    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1673   [(const_int 0)]
1674   "ix86_split_long_move (operands); DONE;")
1675
1676 (define_insn "*pushsi2"
1677   [(set (match_operand:SI 0 "push_operand" "=<")
1678         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1679   "!TARGET_64BIT"
1680   "push{l}\t%1"
1681   [(set_attr "type" "push")
1682    (set_attr "mode" "SI")])
1683
1684 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1685 ;; "push a byte/word".  But actually we use pushl, which has the effect
1686 ;; of rounding the amount pushed up to a word.
1687
1688 ;; For TARGET_64BIT we always round up to 8 bytes.
1689 (define_insn "*push<mode>2_rex64"
1690   [(set (match_operand:SWI124 0 "push_operand" "=X")
1691         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1692   "TARGET_64BIT"
1693   "push{q}\t%q1"
1694   [(set_attr "type" "push")
1695    (set_attr "mode" "DI")])
1696
1697 (define_insn "*push<mode>2"
1698   [(set (match_operand:SWI12 0 "push_operand" "=X")
1699         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1700   "!TARGET_64BIT"
1701   "push{l}\t%k1"
1702   [(set_attr "type" "push")
1703    (set_attr "mode" "SI")])
1704
1705 (define_insn "*push<mode>2_prologue"
1706   [(set (match_operand:P 0 "push_operand" "=<")
1707         (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1708    (clobber (mem:BLK (scratch)))]
1709   ""
1710   "push{<imodesuffix>}\t%1"
1711   [(set_attr "type" "push")
1712    (set_attr "mode" "<MODE>")])
1713
1714 (define_insn "*pop<mode>1"
1715   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1716         (match_operand:P 1 "pop_operand" ">"))]
1717   ""
1718   "pop{<imodesuffix>}\t%0"
1719   [(set_attr "type" "pop")
1720    (set_attr "mode" "<MODE>")])
1721
1722 (define_insn "*pop<mode>1_epilogue"
1723   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1724         (match_operand:P 1 "pop_operand" ">"))
1725    (clobber (mem:BLK (scratch)))]
1726   ""
1727   "pop{<imodesuffix>}\t%0"
1728   [(set_attr "type" "pop")
1729    (set_attr "mode" "<MODE>")])
1730 \f
1731 ;; Move instructions.
1732
1733 (define_expand "movoi"
1734   [(set (match_operand:OI 0 "nonimmediate_operand" "")
1735         (match_operand:OI 1 "general_operand" ""))]
1736   "TARGET_AVX"
1737   "ix86_expand_move (OImode, operands); DONE;")
1738
1739 (define_expand "movti"
1740   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1741         (match_operand:TI 1 "nonimmediate_operand" ""))]
1742   "TARGET_64BIT || TARGET_SSE"
1743 {
1744   if (TARGET_64BIT)
1745     ix86_expand_move (TImode, operands);
1746   else if (push_operand (operands[0], TImode))
1747     ix86_expand_push (TImode, operands[1]);
1748   else
1749     ix86_expand_vector_move (TImode, operands);
1750   DONE;
1751 })
1752
1753 ;; This expands to what emit_move_complex would generate if we didn't
1754 ;; have a movti pattern.  Having this avoids problems with reload on
1755 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1756 ;; to have around all the time.
1757 (define_expand "movcdi"
1758   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1759         (match_operand:CDI 1 "general_operand" ""))]
1760   ""
1761 {
1762   if (push_operand (operands[0], CDImode))
1763     emit_move_complex_push (CDImode, operands[0], operands[1]);
1764   else
1765     emit_move_complex_parts (operands[0], operands[1]);
1766   DONE;
1767 })
1768
1769 (define_expand "mov<mode>"
1770   [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1771         (match_operand:SWI1248x 1 "general_operand" ""))]
1772   ""
1773   "ix86_expand_move (<MODE>mode, operands); DONE;")
1774
1775 (define_insn "*mov<mode>_xor"
1776   [(set (match_operand:SWI48 0 "register_operand" "=r")
1777         (match_operand:SWI48 1 "const0_operand" ""))
1778    (clobber (reg:CC FLAGS_REG))]
1779   "reload_completed"
1780   "xor{l}\t%k0, %k0"
1781   [(set_attr "type" "alu1")
1782    (set_attr "mode" "SI")
1783    (set_attr "length_immediate" "0")])
1784
1785 (define_insn "*mov<mode>_or"
1786   [(set (match_operand:SWI48 0 "register_operand" "=r")
1787         (match_operand:SWI48 1 "const_int_operand" ""))
1788    (clobber (reg:CC FLAGS_REG))]
1789   "reload_completed
1790    && operands[1] == constm1_rtx"
1791   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1792   [(set_attr "type" "alu1")
1793    (set_attr "mode" "<MODE>")
1794    (set_attr "length_immediate" "1")])
1795
1796 (define_insn "*movoi_internal_avx"
1797   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1798         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1799   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1800 {
1801   switch (which_alternative)
1802     {
1803     case 0:
1804       return standard_sse_constant_opcode (insn, operands[1]);
1805     case 1:
1806     case 2:
1807       if (misaligned_operand (operands[0], OImode)
1808           || misaligned_operand (operands[1], OImode))
1809         return "vmovdqu\t{%1, %0|%0, %1}";
1810       else
1811         return "vmovdqa\t{%1, %0|%0, %1}";
1812     default:
1813       gcc_unreachable ();
1814     }
1815 }
1816   [(set_attr "type" "sselog1,ssemov,ssemov")
1817    (set_attr "prefix" "vex")
1818    (set_attr "mode" "OI")])
1819
1820 (define_insn "*movti_internal_rex64"
1821   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,m")
1822         (match_operand:TI 1 "general_operand" "riFo,re,C,xm,x"))]
1823   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1824 {
1825   switch (which_alternative)
1826     {
1827     case 0:
1828     case 1:
1829       return "#";
1830     case 2:
1831       return standard_sse_constant_opcode (insn, operands[1]);
1832     case 3:
1833     case 4:
1834       /* TDmode values are passed as TImode on the stack.  Moving them
1835          to stack may result in unaligned memory access.  */
1836       if (misaligned_operand (operands[0], TImode)
1837           || misaligned_operand (operands[1], TImode))
1838         {
1839           if (get_attr_mode (insn) == MODE_V4SF)
1840             return "%vmovups\t{%1, %0|%0, %1}";
1841           else
1842             return "%vmovdqu\t{%1, %0|%0, %1}";
1843         }
1844       else
1845         {
1846           if (get_attr_mode (insn) == MODE_V4SF)
1847             return "%vmovaps\t{%1, %0|%0, %1}";
1848           else
1849             return "%vmovdqa\t{%1, %0|%0, %1}";
1850         }
1851     default:
1852       gcc_unreachable ();
1853     }
1854 }
1855   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1856    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1857    (set (attr "mode")
1858         (cond [(eq_attr "alternative" "2,3")
1859                  (if_then_else
1860                    (match_test "optimize_function_for_size_p (cfun)")
1861                    (const_string "V4SF")
1862                    (const_string "TI"))
1863                (eq_attr "alternative" "4")
1864                  (if_then_else
1865                    (ior (match_test "TARGET_SSE_TYPELESS_STORES")
1866                         (match_test "optimize_function_for_size_p (cfun)"))
1867                    (const_string "V4SF")
1868                    (const_string "TI"))]
1869                (const_string "DI")))])
1870
1871 (define_split
1872   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1873         (match_operand:TI 1 "general_operand" ""))]
1874   "reload_completed
1875    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1876   [(const_int 0)]
1877   "ix86_split_long_move (operands); DONE;")
1878
1879 (define_insn "*movti_internal_sse"
1880   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1881         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1882   "TARGET_SSE && !TARGET_64BIT
1883    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1884 {
1885   switch (which_alternative)
1886     {
1887     case 0:
1888       return standard_sse_constant_opcode (insn, operands[1]);
1889     case 1:
1890     case 2:
1891       /* TDmode values are passed as TImode on the stack.  Moving them
1892          to stack may result in unaligned memory access.  */
1893       if (misaligned_operand (operands[0], TImode)
1894           || misaligned_operand (operands[1], TImode))
1895         {
1896           if (get_attr_mode (insn) == MODE_V4SF)
1897             return "%vmovups\t{%1, %0|%0, %1}";
1898           else
1899             return "%vmovdqu\t{%1, %0|%0, %1}";
1900         }
1901       else
1902         {
1903           if (get_attr_mode (insn) == MODE_V4SF)
1904             return "%vmovaps\t{%1, %0|%0, %1}";
1905           else
1906             return "%vmovdqa\t{%1, %0|%0, %1}";
1907         }
1908     default:
1909       gcc_unreachable ();
1910     }
1911 }
1912   [(set_attr "type" "sselog1,ssemov,ssemov")
1913    (set_attr "prefix" "maybe_vex")
1914    (set (attr "mode")
1915         (cond [(ior (not (match_test "TARGET_SSE2"))
1916                     (match_test "optimize_function_for_size_p (cfun)"))
1917                  (const_string "V4SF")
1918                (and (eq_attr "alternative" "2")
1919                     (match_test "TARGET_SSE_TYPELESS_STORES"))
1920                  (const_string "V4SF")]
1921               (const_string "TI")))])
1922
1923 (define_insn "*movdi_internal_rex64"
1924   [(set (match_operand:DI 0 "nonimmediate_operand"
1925           "=r,r  ,r,m ,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1926         (match_operand:DI 1 "general_operand"
1927           "Z ,rem,i,re,C ,*y ,m  ,*Ym,r   ,C ,*x,*x,m ,*Yi,r   ,*Ym,*x"))]
1928   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1929 {
1930   switch (get_attr_type (insn))
1931     {
1932     case TYPE_SSECVT:
1933       if (SSE_REG_P (operands[0]))
1934         return "movq2dq\t{%1, %0|%0, %1}";
1935       else
1936         return "movdq2q\t{%1, %0|%0, %1}";
1937
1938     case TYPE_SSEMOV:
1939       if (get_attr_mode (insn) == MODE_TI)
1940         return "%vmovdqa\t{%1, %0|%0, %1}";
1941       /* Handle broken assemblers that require movd instead of movq.  */
1942       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1943         return "%vmovd\t{%1, %0|%0, %1}";
1944       else
1945         return "%vmovq\t{%1, %0|%0, %1}";
1946
1947     case TYPE_MMXMOV:
1948       /* Handle broken assemblers that require movd instead of movq.  */
1949       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1950         return "movd\t{%1, %0|%0, %1}";
1951       else
1952         return "movq\t{%1, %0|%0, %1}";
1953
1954     case TYPE_SSELOG1:
1955       return standard_sse_constant_opcode (insn, operands[1]);
1956
1957     case TYPE_MMX:
1958       return "pxor\t%0, %0";
1959
1960     case TYPE_LEA:
1961       return "lea{q}\t{%E1, %0|%0, %E1}";
1962
1963     default:
1964       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1965       if (get_attr_mode (insn) == MODE_SI)
1966         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1967       else if (which_alternative == 2)
1968         return "movabs{q}\t{%1, %0|%0, %1}";
1969       else if (ix86_use_lea_for_mov (insn, operands))
1970         return "lea{q}\t{%E1, %0|%0, %E1}";
1971       else
1972         return "mov{q}\t{%1, %0|%0, %1}";
1973     }
1974 }
1975   [(set (attr "type")
1976      (cond [(eq_attr "alternative" "4")
1977               (const_string "mmx")
1978             (eq_attr "alternative" "5,6,7,8")
1979               (const_string "mmxmov")
1980             (eq_attr "alternative" "9")
1981               (const_string "sselog1")
1982             (eq_attr "alternative" "10,11,12,13,14")
1983               (const_string "ssemov")
1984             (eq_attr "alternative" "15,16")
1985               (const_string "ssecvt")
1986             (match_operand 1 "pic_32bit_operand" "")
1987               (const_string "lea")
1988            ]
1989            (const_string "imov")))
1990    (set (attr "modrm")
1991      (if_then_else
1992        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
1993          (const_string "0")
1994          (const_string "*")))
1995    (set (attr "length_immediate")
1996      (if_then_else
1997        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
1998          (const_string "8")
1999          (const_string "*")))
2000    (set (attr "prefix_rex")
2001      (if_then_else (eq_attr "alternative" "7,8")
2002        (const_string "1")
2003        (const_string "*")))
2004    (set (attr "prefix_data16")
2005      (if_then_else (eq_attr "alternative" "10")
2006        (const_string "1")
2007        (const_string "*")))
2008    (set (attr "prefix")
2009      (if_then_else (eq_attr "alternative" "11,12,13,14,15")
2010        (const_string "maybe_vex")
2011        (const_string "orig")))
2012    (set_attr "mode" "SI,DI,DI,DI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2013
2014 ;; Reload patterns to support multi-word load/store
2015 ;; with non-offsetable address.
2016 (define_expand "reload_noff_store"
2017   [(parallel [(match_operand 0 "memory_operand" "=m")
2018               (match_operand 1 "register_operand" "r")
2019               (match_operand:DI 2 "register_operand" "=&r")])]
2020   "TARGET_64BIT"
2021 {
2022   rtx mem = operands[0];
2023   rtx addr = XEXP (mem, 0);
2024
2025   emit_move_insn (operands[2], addr);
2026   mem = replace_equiv_address_nv (mem, operands[2]);
2027
2028   emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2029   DONE;
2030 })
2031
2032 (define_expand "reload_noff_load"
2033   [(parallel [(match_operand 0 "register_operand" "=r")
2034               (match_operand 1 "memory_operand" "m")
2035               (match_operand:DI 2 "register_operand" "=r")])]
2036   "TARGET_64BIT"
2037 {
2038   rtx mem = operands[1];
2039   rtx addr = XEXP (mem, 0);
2040
2041   emit_move_insn (operands[2], addr);
2042   mem = replace_equiv_address_nv (mem, operands[2]);
2043
2044   emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2045   DONE;
2046 })
2047
2048 (define_insn "*movdi_internal"
2049   [(set (match_operand:DI 0 "nonimmediate_operand"
2050           "=r  ,o  ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2051         (match_operand:DI 1 "general_operand"
2052           "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2053   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2054 {
2055   switch (get_attr_type (insn))
2056     {
2057     case TYPE_SSECVT:
2058       if (SSE_REG_P (operands[0]))
2059         return "movq2dq\t{%1, %0|%0, %1}";
2060       else
2061         return "movdq2q\t{%1, %0|%0, %1}";
2062
2063     case TYPE_SSEMOV:
2064       switch (get_attr_mode (insn))
2065         {
2066         case MODE_TI:
2067           return "%vmovdqa\t{%1, %0|%0, %1}";
2068         case MODE_DI:
2069            return "%vmovq\t{%1, %0|%0, %1}";
2070         case MODE_V4SF:
2071           return "movaps\t{%1, %0|%0, %1}";
2072         case MODE_V2SF:
2073           return "movlps\t{%1, %0|%0, %1}";
2074         default:
2075           gcc_unreachable ();
2076         }
2077
2078     case TYPE_MMXMOV:
2079       return "movq\t{%1, %0|%0, %1}";
2080
2081     case TYPE_SSELOG1:
2082       return standard_sse_constant_opcode (insn, operands[1]);
2083
2084     case TYPE_MMX:
2085       return "pxor\t%0, %0";
2086
2087     case TYPE_MULTI:
2088       return "#";
2089
2090     default:
2091       gcc_unreachable ();
2092     }
2093 }
2094   [(set (attr "isa")
2095      (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2096               (const_string "sse2")
2097             (eq_attr "alternative" "9,10,11,12")
2098               (const_string "noavx")
2099            ]
2100            (const_string "*")))
2101    (set (attr "type")
2102      (cond [(eq_attr "alternative" "0,1")
2103               (const_string "multi")
2104             (eq_attr "alternative" "2")
2105               (const_string "mmx")
2106             (eq_attr "alternative" "3,4")
2107               (const_string "mmxmov")
2108             (eq_attr "alternative" "5,9")
2109               (const_string "sselog1")
2110             (eq_attr "alternative" "13,14")
2111               (const_string "ssecvt")
2112            ]
2113            (const_string "ssemov")))
2114    (set (attr "prefix")
2115      (if_then_else (eq_attr "alternative" "5,6,7,8")
2116        (const_string "maybe_vex")
2117        (const_string "orig")))
2118    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2119
2120 (define_split
2121   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2122         (match_operand:DI 1 "general_operand" ""))]
2123   "!TARGET_64BIT && reload_completed
2124    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2125    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2126   [(const_int 0)]
2127   "ix86_split_long_move (operands); DONE;")
2128
2129 (define_insn "*movsi_internal"
2130   [(set (match_operand:SI 0 "nonimmediate_operand"
2131                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2132         (match_operand:SI 1 "general_operand"
2133                         "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
2134   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2135 {
2136   switch (get_attr_type (insn))
2137     {
2138     case TYPE_SSELOG1:
2139       return standard_sse_constant_opcode (insn, operands[1]);
2140
2141     case TYPE_SSEMOV:
2142       switch (get_attr_mode (insn))
2143         {
2144         case MODE_TI:
2145           return "%vmovdqa\t{%1, %0|%0, %1}";
2146         case MODE_V4SF:
2147           return "%vmovaps\t{%1, %0|%0, %1}";
2148         case MODE_SI:
2149           return "%vmovd\t{%1, %0|%0, %1}";
2150         case MODE_SF:
2151           return "%vmovss\t{%1, %0|%0, %1}";
2152         default:
2153           gcc_unreachable ();
2154         }
2155
2156     case TYPE_MMX:
2157       return "pxor\t%0, %0";
2158
2159     case TYPE_MMXMOV:
2160       if (get_attr_mode (insn) == MODE_DI)
2161         return "movq\t{%1, %0|%0, %1}";
2162       return "movd\t{%1, %0|%0, %1}";
2163
2164     case TYPE_LEA:
2165       return "lea{l}\t{%E1, %0|%0, %E1}";
2166
2167     default:
2168       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2169       if (ix86_use_lea_for_mov (insn, operands))
2170         return "lea{l}\t{%E1, %0|%0, %E1}";
2171       else
2172         return "mov{l}\t{%1, %0|%0, %1}";
2173     }
2174 }
2175   [(set (attr "type")
2176      (cond [(eq_attr "alternative" "2")
2177               (const_string "mmx")
2178             (eq_attr "alternative" "3,4,5")
2179               (const_string "mmxmov")
2180             (eq_attr "alternative" "6")
2181               (const_string "sselog1")
2182             (eq_attr "alternative" "7,8,9,10,11")
2183               (const_string "ssemov")
2184             (match_operand 1 "pic_32bit_operand" "")
2185               (const_string "lea")
2186            ]
2187            (const_string "imov")))
2188    (set (attr "prefix")
2189      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2190        (const_string "orig")
2191        (const_string "maybe_vex")))
2192    (set (attr "prefix_data16")
2193      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2194        (const_string "1")
2195        (const_string "*")))
2196    (set (attr "mode")
2197      (cond [(eq_attr "alternative" "2,3")
2198               (const_string "DI")
2199             (eq_attr "alternative" "6,7")
2200               (if_then_else
2201                 (not (match_test "TARGET_SSE2"))
2202                 (const_string "V4SF")
2203                 (const_string "TI"))
2204             (and (eq_attr "alternative" "8,9,10,11")
2205                  (not (match_test "TARGET_SSE2")))
2206               (const_string "SF")
2207            ]
2208            (const_string "SI")))])
2209
2210 (define_insn "*movhi_internal"
2211   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2212         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2213   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2214 {
2215   switch (get_attr_type (insn))
2216     {
2217     case TYPE_IMOVX:
2218       /* movzwl is faster than movw on p2 due to partial word stalls,
2219          though not as fast as an aligned movl.  */
2220       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2221     default:
2222       if (get_attr_mode (insn) == MODE_SI)
2223         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2224       else
2225         return "mov{w}\t{%1, %0|%0, %1}";
2226     }
2227 }
2228   [(set (attr "type")
2229      (cond [(match_test "optimize_function_for_size_p (cfun)")
2230               (const_string "imov")
2231             (and (eq_attr "alternative" "0")
2232                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2233                       (not (match_test "TARGET_HIMODE_MATH"))))
2234               (const_string "imov")
2235             (and (eq_attr "alternative" "1,2")
2236                  (match_operand:HI 1 "aligned_operand" ""))
2237               (const_string "imov")
2238             (and (match_test "TARGET_MOVX")
2239                  (eq_attr "alternative" "0,2"))
2240               (const_string "imovx")
2241            ]
2242            (const_string "imov")))
2243     (set (attr "mode")
2244       (cond [(eq_attr "type" "imovx")
2245                (const_string "SI")
2246              (and (eq_attr "alternative" "1,2")
2247                   (match_operand:HI 1 "aligned_operand" ""))
2248                (const_string "SI")
2249              (and (eq_attr "alternative" "0")
2250                   (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2251                        (not (match_test "TARGET_HIMODE_MATH"))))
2252                (const_string "SI")
2253             ]
2254             (const_string "HI")))])
2255
2256 ;; Situation is quite tricky about when to choose full sized (SImode) move
2257 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2258 ;; partial register dependency machines (such as AMD Athlon), where QImode
2259 ;; moves issue extra dependency and for partial register stalls machines
2260 ;; that don't use QImode patterns (and QImode move cause stall on the next
2261 ;; instruction).
2262 ;;
2263 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2264 ;; register stall machines with, where we use QImode instructions, since
2265 ;; partial register stall can be caused there.  Then we use movzx.
2266 (define_insn "*movqi_internal"
2267   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2268         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2269   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2270 {
2271   switch (get_attr_type (insn))
2272     {
2273     case TYPE_IMOVX:
2274       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2275       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2276     default:
2277       if (get_attr_mode (insn) == MODE_SI)
2278         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2279       else
2280         return "mov{b}\t{%1, %0|%0, %1}";
2281     }
2282 }
2283   [(set (attr "type")
2284      (cond [(and (eq_attr "alternative" "5")
2285                  (not (match_operand:QI 1 "aligned_operand" "")))
2286               (const_string "imovx")
2287             (match_test "optimize_function_for_size_p (cfun)")
2288               (const_string "imov")
2289             (and (eq_attr "alternative" "3")
2290                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2291                       (not (match_test "TARGET_QIMODE_MATH"))))
2292               (const_string "imov")
2293             (eq_attr "alternative" "3,5")
2294               (const_string "imovx")
2295             (and (match_test "TARGET_MOVX")
2296                  (eq_attr "alternative" "2"))
2297               (const_string "imovx")
2298            ]
2299            (const_string "imov")))
2300    (set (attr "mode")
2301       (cond [(eq_attr "alternative" "3,4,5")
2302                (const_string "SI")
2303              (eq_attr "alternative" "6")
2304                (const_string "QI")
2305              (eq_attr "type" "imovx")
2306                (const_string "SI")
2307              (and (eq_attr "type" "imov")
2308                   (and (eq_attr "alternative" "0,1")
2309                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2310                             (and (not (match_test "optimize_function_for_size_p (cfun)"))
2311                                  (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2312                (const_string "SI")
2313              ;; Avoid partial register stalls when not using QImode arithmetic
2314              (and (eq_attr "type" "imov")
2315                   (and (eq_attr "alternative" "0,1")
2316                        (and (match_test "TARGET_PARTIAL_REG_STALL")
2317                             (not (match_test "TARGET_QIMODE_MATH")))))
2318                (const_string "SI")
2319            ]
2320            (const_string "QI")))])
2321
2322 ;; Stores and loads of ax to arbitrary constant address.
2323 ;; We fake an second form of instruction to force reload to load address
2324 ;; into register when rax is not available
2325 (define_insn "*movabs<mode>_1"
2326   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2327         (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2328   "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2329   "@
2330    movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2331    mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2332   [(set_attr "type" "imov")
2333    (set_attr "modrm" "0,*")
2334    (set_attr "length_address" "8,0")
2335    (set_attr "length_immediate" "0,*")
2336    (set_attr "memory" "store")
2337    (set_attr "mode" "<MODE>")])
2338
2339 (define_insn "*movabs<mode>_2"
2340   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2341         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2342   "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2343   "@
2344    movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2345    mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2346   [(set_attr "type" "imov")
2347    (set_attr "modrm" "0,*")
2348    (set_attr "length_address" "8,0")
2349    (set_attr "length_immediate" "0")
2350    (set_attr "memory" "load")
2351    (set_attr "mode" "<MODE>")])
2352
2353 (define_insn "*swap<mode>"
2354   [(set (match_operand:SWI48 0 "register_operand" "+r")
2355         (match_operand:SWI48 1 "register_operand" "+r"))
2356    (set (match_dup 1)
2357         (match_dup 0))]
2358   ""
2359   "xchg{<imodesuffix>}\t%1, %0"
2360   [(set_attr "type" "imov")
2361    (set_attr "mode" "<MODE>")
2362    (set_attr "pent_pair" "np")
2363    (set_attr "athlon_decode" "vector")
2364    (set_attr "amdfam10_decode" "double")
2365    (set_attr "bdver1_decode" "double")])
2366
2367 (define_insn "*swap<mode>_1"
2368   [(set (match_operand:SWI12 0 "register_operand" "+r")
2369         (match_operand:SWI12 1 "register_operand" "+r"))
2370    (set (match_dup 1)
2371         (match_dup 0))]
2372   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2373   "xchg{l}\t%k1, %k0"
2374   [(set_attr "type" "imov")
2375    (set_attr "mode" "SI")
2376    (set_attr "pent_pair" "np")
2377    (set_attr "athlon_decode" "vector")
2378    (set_attr "amdfam10_decode" "double")
2379    (set_attr "bdver1_decode" "double")])
2380
2381 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2382 ;; is disabled for AMDFAM10
2383 (define_insn "*swap<mode>_2"
2384   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2385         (match_operand:SWI12 1 "register_operand" "+<r>"))
2386    (set (match_dup 1)
2387         (match_dup 0))]
2388   "TARGET_PARTIAL_REG_STALL"
2389   "xchg{<imodesuffix>}\t%1, %0"
2390   [(set_attr "type" "imov")
2391    (set_attr "mode" "<MODE>")
2392    (set_attr "pent_pair" "np")
2393    (set_attr "athlon_decode" "vector")])
2394
2395 (define_expand "movstrict<mode>"
2396   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2397         (match_operand:SWI12 1 "general_operand" ""))]
2398   ""
2399 {
2400   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2401     FAIL;
2402   if (GET_CODE (operands[0]) == SUBREG
2403       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2404     FAIL;
2405   /* Don't generate memory->memory moves, go through a register */
2406   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2407     operands[1] = force_reg (<MODE>mode, operands[1]);
2408 })
2409
2410 (define_insn "*movstrict<mode>_1"
2411   [(set (strict_low_part
2412           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2413         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2414   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2415    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2416   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2417   [(set_attr "type" "imov")
2418    (set_attr "mode" "<MODE>")])
2419
2420 (define_insn "*movstrict<mode>_xor"
2421   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2422         (match_operand:SWI12 1 "const0_operand" ""))
2423    (clobber (reg:CC FLAGS_REG))]
2424   "reload_completed"
2425   "xor{<imodesuffix>}\t%0, %0"
2426   [(set_attr "type" "alu1")
2427    (set_attr "mode" "<MODE>")
2428    (set_attr "length_immediate" "0")])
2429
2430 (define_insn "*mov<mode>_extv_1"
2431   [(set (match_operand:SWI24 0 "register_operand" "=R")
2432         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2433                             (const_int 8)
2434                             (const_int 8)))]
2435   ""
2436   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2437   [(set_attr "type" "imovx")
2438    (set_attr "mode" "SI")])
2439
2440 (define_insn "*movqi_extv_1_rex64"
2441   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2442         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2443                          (const_int 8)
2444                          (const_int 8)))]
2445   "TARGET_64BIT"
2446 {
2447   switch (get_attr_type (insn))
2448     {
2449     case TYPE_IMOVX:
2450       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2451     default:
2452       return "mov{b}\t{%h1, %0|%0, %h1}";
2453     }
2454 }
2455   [(set (attr "type")
2456      (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2457                         (match_test "TARGET_MOVX"))
2458         (const_string "imovx")
2459         (const_string "imov")))
2460    (set (attr "mode")
2461      (if_then_else (eq_attr "type" "imovx")
2462         (const_string "SI")
2463         (const_string "QI")))])
2464
2465 (define_insn "*movqi_extv_1"
2466   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2467         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2468                          (const_int 8)
2469                          (const_int 8)))]
2470   "!TARGET_64BIT"
2471 {
2472   switch (get_attr_type (insn))
2473     {
2474     case TYPE_IMOVX:
2475       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2476     default:
2477       return "mov{b}\t{%h1, %0|%0, %h1}";
2478     }
2479 }
2480   [(set (attr "type")
2481      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2482                         (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2483                              (match_test "TARGET_MOVX")))
2484         (const_string "imovx")
2485         (const_string "imov")))
2486    (set (attr "mode")
2487      (if_then_else (eq_attr "type" "imovx")
2488         (const_string "SI")
2489         (const_string "QI")))])
2490
2491 (define_insn "*mov<mode>_extzv_1"
2492   [(set (match_operand:SWI48 0 "register_operand" "=R")
2493         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2494                             (const_int 8)
2495                             (const_int 8)))]
2496   ""
2497   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2498   [(set_attr "type" "imovx")
2499    (set_attr "mode" "SI")])
2500
2501 (define_insn "*movqi_extzv_2_rex64"
2502   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2503         (subreg:QI
2504           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2505                            (const_int 8)
2506                            (const_int 8)) 0))]
2507   "TARGET_64BIT"
2508 {
2509   switch (get_attr_type (insn))
2510     {
2511     case TYPE_IMOVX:
2512       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2513     default:
2514       return "mov{b}\t{%h1, %0|%0, %h1}";
2515     }
2516 }
2517   [(set (attr "type")
2518      (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2519                         (match_test "TARGET_MOVX"))
2520         (const_string "imovx")
2521         (const_string "imov")))
2522    (set (attr "mode")
2523      (if_then_else (eq_attr "type" "imovx")
2524         (const_string "SI")
2525         (const_string "QI")))])
2526
2527 (define_insn "*movqi_extzv_2"
2528   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2529         (subreg:QI
2530           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2531                            (const_int 8)
2532                            (const_int 8)) 0))]
2533   "!TARGET_64BIT"
2534 {
2535   switch (get_attr_type (insn))
2536     {
2537     case TYPE_IMOVX:
2538       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2539     default:
2540       return "mov{b}\t{%h1, %0|%0, %h1}";
2541     }
2542 }
2543   [(set (attr "type")
2544      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2545                         (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2546                              (match_test "TARGET_MOVX")))
2547         (const_string "imovx")
2548         (const_string "imov")))
2549    (set (attr "mode")
2550      (if_then_else (eq_attr "type" "imovx")
2551         (const_string "SI")
2552         (const_string "QI")))])
2553
2554 (define_expand "mov<mode>_insv_1"
2555   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2556                             (const_int 8)
2557                             (const_int 8))
2558         (match_operand:SWI48 1 "nonmemory_operand" ""))])
2559
2560 (define_insn "*mov<mode>_insv_1_rex64"
2561   [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2562                              (const_int 8)
2563                              (const_int 8))
2564         (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2565   "TARGET_64BIT"
2566 {
2567   if (CONST_INT_P (operands[1]))
2568     operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2569   return "mov{b}\t{%b1, %h0|%h0, %b1}";
2570 }
2571   [(set_attr "type" "imov")
2572    (set_attr "mode" "QI")])
2573
2574 (define_insn "*movsi_insv_1"
2575   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2576                          (const_int 8)
2577                          (const_int 8))
2578         (match_operand:SI 1 "general_operand" "Qmn"))]
2579   "!TARGET_64BIT"
2580 {
2581   if (CONST_INT_P (operands[1]))
2582     operands[1] = simplify_gen_subreg (QImode, operands[1], SImode, 0);
2583   return "mov{b}\t{%b1, %h0|%h0, %b1}";
2584 }
2585   [(set_attr "type" "imov")
2586    (set_attr "mode" "QI")])
2587
2588 (define_insn "*movqi_insv_2"
2589   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2590                          (const_int 8)
2591                          (const_int 8))
2592         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2593                      (const_int 8)))]
2594   ""
2595   "mov{b}\t{%h1, %h0|%h0, %h1}"
2596   [(set_attr "type" "imov")
2597    (set_attr "mode" "QI")])
2598 \f
2599 ;; Floating point push instructions.
2600
2601 (define_insn "*pushtf"
2602   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2603         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2604   "TARGET_SSE2"
2605 {
2606   /* This insn should be already split before reg-stack.  */
2607   gcc_unreachable ();
2608 }
2609   [(set_attr "type" "multi")
2610    (set_attr "unit" "sse,*,*")
2611    (set_attr "mode" "TF,SI,SI")])
2612
2613 ;; %%% Kill this when call knows how to work this out.
2614 (define_split
2615   [(set (match_operand:TF 0 "push_operand" "")
2616         (match_operand:TF 1 "sse_reg_operand" ""))]
2617   "TARGET_SSE2 && reload_completed"
2618   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2619    (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2620
2621 (define_insn "*pushxf"
2622   [(set (match_operand:XF 0 "push_operand" "=<,<")
2623         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2624   "optimize_function_for_speed_p (cfun)"
2625 {
2626   /* This insn should be already split before reg-stack.  */
2627   gcc_unreachable ();
2628 }
2629   [(set_attr "type" "multi")
2630    (set_attr "unit" "i387,*")
2631    (set_attr "mode" "XF,SI")])
2632
2633 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2634 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2635 ;; Pushing using integer instructions is longer except for constants
2636 ;; and direct memory references (assuming that any given constant is pushed
2637 ;; only once, but this ought to be handled elsewhere).
2638
2639 (define_insn "*pushxf_nointeger"
2640   [(set (match_operand:XF 0 "push_operand" "=<,<")
2641         (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2642   "optimize_function_for_size_p (cfun)"
2643 {
2644   /* This insn should be already split before reg-stack.  */
2645   gcc_unreachable ();
2646 }
2647   [(set_attr "type" "multi")
2648    (set_attr "unit" "i387,*")
2649    (set_attr "mode" "XF,SI")])
2650
2651 ;; %%% Kill this when call knows how to work this out.
2652 (define_split
2653   [(set (match_operand:XF 0 "push_operand" "")
2654         (match_operand:XF 1 "fp_register_operand" ""))]
2655   "reload_completed"
2656   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2657    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2658   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2659
2660 (define_insn "*pushdf_rex64"
2661   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2662         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2663   "TARGET_64BIT"
2664 {
2665   /* This insn should be already split before reg-stack.  */
2666   gcc_unreachable ();
2667 }
2668   [(set_attr "type" "multi")
2669    (set_attr "unit" "i387,*,*")
2670    (set_attr "mode" "DF,DI,DF")])
2671
2672 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2673 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2674 ;; On the average, pushdf using integers can be still shorter.
2675
2676 (define_insn "*pushdf"
2677   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2678         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2679   "!TARGET_64BIT"
2680 {
2681   /* This insn should be already split before reg-stack.  */
2682   gcc_unreachable ();
2683 }
2684   [(set_attr "isa" "*,*,sse2")
2685    (set_attr "type" "multi")
2686    (set_attr "unit" "i387,*,*")
2687    (set_attr "mode" "DF,DI,DF")])
2688
2689 ;; %%% Kill this when call knows how to work this out.
2690 (define_split
2691   [(set (match_operand:DF 0 "push_operand" "")
2692         (match_operand:DF 1 "any_fp_register_operand" ""))]
2693   "reload_completed"
2694   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2695    (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2696
2697 (define_insn "*pushsf_rex64"
2698   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2699         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2700   "TARGET_64BIT"
2701 {
2702   /* Anything else should be already split before reg-stack.  */
2703   gcc_assert (which_alternative == 1);
2704   return "push{q}\t%q1";
2705 }
2706   [(set_attr "type" "multi,push,multi")
2707    (set_attr "unit" "i387,*,*")
2708    (set_attr "mode" "SF,DI,SF")])
2709
2710 (define_insn "*pushsf"
2711   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2712         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2713   "!TARGET_64BIT"
2714 {
2715   /* Anything else should be already split before reg-stack.  */
2716   gcc_assert (which_alternative == 1);
2717   return "push{l}\t%1";
2718 }
2719   [(set_attr "type" "multi,push,multi")
2720    (set_attr "unit" "i387,*,*")
2721    (set_attr "mode" "SF,SI,SF")])
2722
2723 ;; %%% Kill this when call knows how to work this out.
2724 (define_split
2725   [(set (match_operand:SF 0 "push_operand" "")
2726         (match_operand:SF 1 "any_fp_register_operand" ""))]
2727   "reload_completed"
2728   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2729    (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2730   "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2731
2732 (define_split
2733   [(set (match_operand:SF 0 "push_operand" "")
2734         (match_operand:SF 1 "memory_operand" ""))]
2735   "reload_completed
2736    && (operands[2] = find_constant_src (insn))"
2737   [(set (match_dup 0) (match_dup 2))])
2738
2739 (define_split
2740   [(set (match_operand 0 "push_operand" "")
2741         (match_operand 1 "general_operand" ""))]
2742   "reload_completed
2743    && (GET_MODE (operands[0]) == TFmode
2744        || GET_MODE (operands[0]) == XFmode
2745        || GET_MODE (operands[0]) == DFmode)
2746    && !ANY_FP_REG_P (operands[1])"
2747   [(const_int 0)]
2748   "ix86_split_long_move (operands); DONE;")
2749 \f
2750 ;; Floating point move instructions.
2751
2752 (define_expand "movtf"
2753   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2754         (match_operand:TF 1 "nonimmediate_operand" ""))]
2755   "TARGET_64BIT || TARGET_SSE2"
2756 {
2757   ix86_expand_move (TFmode, operands);
2758   DONE;
2759 })
2760
2761 (define_expand "mov<mode>"
2762   [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2763         (match_operand:X87MODEF 1 "general_operand" ""))]
2764   ""
2765   "ix86_expand_move (<MODE>mode, operands); DONE;")
2766
2767 (define_insn "*movtf_internal_rex64"
2768   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2769         (match_operand:TF 1 "general_operand"      "xm,x,C,*roF,*r"))]
2770   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2771    && (!can_create_pseudo_p ()
2772        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2773        || GET_CODE (operands[1]) != CONST_DOUBLE
2774        || (optimize_function_for_size_p (cfun)
2775            && standard_sse_constant_p (operands[1])
2776            && !memory_operand (operands[0], TFmode))
2777        || (!TARGET_MEMORY_MISMATCH_STALL
2778            && memory_operand (operands[0], TFmode)))"
2779 {
2780   switch (which_alternative)
2781     {
2782     case 0:
2783     case 1:
2784       /* Handle misaligned load/store since we
2785          don't have movmisaligntf pattern. */
2786       if (misaligned_operand (operands[0], TFmode)
2787           || misaligned_operand (operands[1], TFmode))
2788         {
2789           if (get_attr_mode (insn) == MODE_V4SF)
2790             return "%vmovups\t{%1, %0|%0, %1}";
2791           else
2792             return "%vmovdqu\t{%1, %0|%0, %1}";
2793         }
2794       else
2795         {
2796           if (get_attr_mode (insn) == MODE_V4SF)
2797             return "%vmovaps\t{%1, %0|%0, %1}";
2798           else
2799             return "%vmovdqa\t{%1, %0|%0, %1}";
2800         }
2801
2802     case 2:
2803       return standard_sse_constant_opcode (insn, operands[1]);
2804
2805     case 3:
2806     case 4:
2807         return "#";
2808
2809     default:
2810       gcc_unreachable ();
2811     }
2812 }
2813   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2814    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2815    (set (attr "mode")
2816         (cond [(eq_attr "alternative" "0,2")
2817                  (if_then_else
2818                    (match_test "optimize_function_for_size_p (cfun)")
2819                    (const_string "V4SF")
2820                    (const_string "TI"))
2821                (eq_attr "alternative" "1")
2822                  (if_then_else
2823                    (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2824                         (match_test "optimize_function_for_size_p (cfun)"))
2825                    (const_string "V4SF")
2826                    (const_string "TI"))]
2827                (const_string "DI")))])
2828
2829 (define_insn "*movtf_internal_sse2"
2830   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x")
2831         (match_operand:TF 1 "general_operand"      "xm,x,C"))]
2832   "TARGET_SSE2 && !TARGET_64BIT
2833    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2834    && (!can_create_pseudo_p ()
2835        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2836        || GET_CODE (operands[1]) != CONST_DOUBLE
2837        || (optimize_function_for_size_p (cfun)
2838            && standard_sse_constant_p (operands[1])
2839            && !memory_operand (operands[0], TFmode))
2840        || (!TARGET_MEMORY_MISMATCH_STALL
2841            && memory_operand (operands[0], TFmode)))"
2842 {
2843   switch (which_alternative)
2844     {
2845     case 0:
2846     case 1:
2847       /* Handle misaligned load/store since we
2848          don't have movmisaligntf pattern. */
2849       if (misaligned_operand (operands[0], TFmode)
2850           || misaligned_operand (operands[1], TFmode))
2851         {
2852           if (get_attr_mode (insn) == MODE_V4SF)
2853             return "%vmovups\t{%1, %0|%0, %1}";
2854           else
2855             return "%vmovdqu\t{%1, %0|%0, %1}";
2856         }
2857       else
2858         {
2859           if (get_attr_mode (insn) == MODE_V4SF)
2860             return "%vmovaps\t{%1, %0|%0, %1}";
2861           else
2862             return "%vmovdqa\t{%1, %0|%0, %1}";
2863         }
2864
2865     case 2:
2866       return standard_sse_constant_opcode (insn, operands[1]);
2867
2868     default:
2869       gcc_unreachable ();
2870     }
2871 }
2872   [(set_attr "type" "ssemov,ssemov,sselog1")
2873    (set_attr "prefix" "maybe_vex")
2874    (set (attr "mode")
2875         (cond [(eq_attr "alternative" "0,2")
2876                  (if_then_else
2877                    (match_test "optimize_function_for_size_p (cfun)")
2878                    (const_string "V4SF")
2879                    (const_string "TI"))
2880                (eq_attr "alternative" "1")
2881                  (if_then_else
2882                    (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2883                         (match_test "optimize_function_for_size_p (cfun)"))
2884                    (const_string "V4SF")
2885                    (const_string "TI"))]
2886                (const_string "DI")))])
2887
2888 (define_insn "*movxf_internal_rex64"
2889   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2890         (match_operand:XF 1 "general_operand"      "fm,f,G,Yx*roF,Yx*rC"))]
2891   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2892    && (!can_create_pseudo_p ()
2893        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2894        || GET_CODE (operands[1]) != CONST_DOUBLE
2895        || (optimize_function_for_size_p (cfun)
2896            && standard_80387_constant_p (operands[1]) > 0
2897            && !memory_operand (operands[0], XFmode))
2898        || (!TARGET_MEMORY_MISMATCH_STALL
2899            && memory_operand (operands[0], XFmode)))"
2900 {
2901   switch (which_alternative)
2902     {
2903     case 0:
2904     case 1:
2905       return output_387_reg_move (insn, operands);
2906
2907     case 2:
2908       return standard_80387_constant_opcode (operands[1]);
2909
2910     case 3:
2911     case 4:
2912       return "#";
2913
2914     default:
2915       gcc_unreachable ();
2916     }
2917 }
2918   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2919    (set_attr "mode" "XF,XF,XF,SI,SI")])
2920
2921 ;; Possible store forwarding (partial memory) stall in alternative 4.
2922 (define_insn "*movxf_internal"
2923   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2924         (match_operand:XF 1 "general_operand"      "fm,f,G,Yx*roF,Yx*rF"))]
2925   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2926    && (!can_create_pseudo_p ()
2927        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2928        || GET_CODE (operands[1]) != CONST_DOUBLE
2929        || (optimize_function_for_size_p (cfun)
2930            && standard_80387_constant_p (operands[1]) > 0
2931            && !memory_operand (operands[0], XFmode))
2932        || (!TARGET_MEMORY_MISMATCH_STALL
2933            && memory_operand (operands[0], XFmode)))"
2934 {
2935   switch (which_alternative)
2936     {
2937     case 0:
2938     case 1:
2939       return output_387_reg_move (insn, operands);
2940
2941     case 2:
2942       return standard_80387_constant_opcode (operands[1]);
2943
2944     case 3:
2945     case 4:
2946       return "#";
2947
2948     default:
2949       gcc_unreachable ();
2950     }
2951 }
2952   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2953    (set_attr "mode" "XF,XF,XF,SI,SI")])
2954
2955 (define_insn "*movdf_internal_rex64"
2956   [(set (match_operand:DF 0 "nonimmediate_operand"
2957                 "=?Yf*f,?m   ,?Yf*f,?r,?m,?r,?r,x,x,x,m,Yi,r ")
2958         (match_operand:DF 1 "general_operand"
2959                 "Yf*fm ,Yf*f ,G    ,rm,rC,C ,F ,C,x,m,x,r ,Yi"))]
2960   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2961    && (!can_create_pseudo_p ()
2962        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2963        || GET_CODE (operands[1]) != CONST_DOUBLE
2964        || (optimize_function_for_size_p (cfun)
2965            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2966                 && standard_80387_constant_p (operands[1]) > 0)
2967                || (TARGET_SSE2 && TARGET_SSE_MATH
2968                    && standard_sse_constant_p (operands[1]))))
2969        || memory_operand (operands[0], DFmode))"
2970 {
2971   switch (which_alternative)
2972     {
2973     case 0:
2974     case 1:
2975       return output_387_reg_move (insn, operands);
2976
2977     case 2:
2978       return standard_80387_constant_opcode (operands[1]);
2979
2980     case 3:
2981     case 4:
2982       return "mov{q}\t{%1, %0|%0, %1}";
2983
2984     case 5:
2985       return "mov{l}\t{%1, %k0|%k0, %1}";
2986
2987     case 6:
2988       return "movabs{q}\t{%1, %0|%0, %1}";
2989
2990     case 7:
2991       return standard_sse_constant_opcode (insn, operands[1]);
2992
2993     case 8:
2994     case 9:
2995     case 10:
2996       switch (get_attr_mode (insn))
2997         {
2998         case MODE_V2DF:
2999           if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3000             return "%vmovapd\t{%1, %0|%0, %1}";
3001         case MODE_V4SF:
3002           return "%vmovaps\t{%1, %0|%0, %1}";
3003
3004         case MODE_DI:
3005           return "%vmovq\t{%1, %0|%0, %1}";
3006         case MODE_DF:
3007           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3008             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3009           return "%vmovsd\t{%1, %0|%0, %1}";
3010         case MODE_V1DF:
3011           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3012         case MODE_V2SF:
3013           return "%vmovlps\t{%1, %d0|%d0, %1}";
3014         default:
3015           gcc_unreachable ();
3016         }
3017
3018     case 11:
3019     case 12:
3020       /* Handle broken assemblers that require movd instead of movq.  */
3021       return "%vmovd\t{%1, %0|%0, %1}";
3022
3023     default:
3024       gcc_unreachable();
3025     }
3026 }
3027   [(set (attr "type")
3028         (cond [(eq_attr "alternative" "0,1,2")
3029                  (const_string "fmov")
3030                (eq_attr "alternative" "3,4,5,6")
3031                  (const_string "imov")
3032                (eq_attr "alternative" "7")
3033                  (const_string "sselog1")
3034               ]
3035               (const_string "ssemov")))
3036    (set (attr "modrm")
3037      (if_then_else
3038        (and (eq_attr "alternative" "6") (eq_attr "type" "imov"))
3039          (const_string "0")
3040          (const_string "*")))
3041    (set (attr "length_immediate")
3042      (if_then_else
3043        (and (eq_attr "alternative" "6") (eq_attr "type" "imov"))
3044          (const_string "8")
3045          (const_string "*")))
3046    (set (attr "prefix")
3047      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3048        (const_string "orig")
3049        (const_string "maybe_vex")))
3050    (set (attr "prefix_data16")
3051      (if_then_else (eq_attr "mode" "V1DF")
3052        (const_string "1")
3053        (const_string "*")))
3054    (set (attr "mode")
3055         (cond [(eq_attr "alternative" "0,1,2")
3056                  (const_string "DF")
3057                (eq_attr "alternative" "3,4,6,11,12")
3058                  (const_string "DI")
3059                (eq_attr "alternative" "5")
3060                  (const_string "SI")
3061
3062                /* xorps is one byte shorter.  */
3063                (eq_attr "alternative" "7")
3064                  (cond [(match_test "optimize_function_for_size_p (cfun)")
3065                           (const_string "V4SF")
3066                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3067                           (const_string "TI")
3068                        ]
3069                        (const_string "V2DF"))
3070
3071                /* For architectures resolving dependencies on
3072                   whole SSE registers use APD move to break dependency
3073                   chains, otherwise use short move to avoid extra work.
3074
3075                   movaps encodes one byte shorter.  */
3076                (eq_attr "alternative" "8")
3077                  (cond
3078                    [(match_test "optimize_function_for_size_p (cfun)")
3079                       (const_string "V4SF")
3080                     (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3081                       (const_string "V2DF")
3082                    ]
3083                    (const_string "DF"))
3084                /* For architectures resolving dependencies on register
3085                   parts we may avoid extra work to zero out upper part
3086                   of register.  */
3087                (eq_attr "alternative" "9")
3088                  (if_then_else
3089                    (match_test "TARGET_SSE_SPLIT_REGS")
3090                    (const_string "V1DF")
3091                    (const_string "DF"))
3092               ]
3093               (const_string "DF")))])
3094
3095 ;; Possible store forwarding (partial memory) stall in alternative 4.
3096 (define_insn "*movdf_internal"
3097   [(set (match_operand:DF 0 "nonimmediate_operand"
3098                 "=Yf*f,m   ,Yf*f,?Yd*r ,!o   ,x,x,x,m,*x,*x,*x,m")
3099         (match_operand:DF 1 "general_operand"
3100                 "Yf*fm,Yf*f,G   ,Yd*roF,Yd*rF,C,x,m,x,C ,*x,m ,*x"))]
3101   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3102    && (!can_create_pseudo_p ()
3103        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3104        || GET_CODE (operands[1]) != CONST_DOUBLE
3105        || (optimize_function_for_size_p (cfun)
3106            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3107                 && standard_80387_constant_p (operands[1]) > 0)
3108                || (TARGET_SSE2 && TARGET_SSE_MATH
3109                    && standard_sse_constant_p (operands[1])))
3110            && !memory_operand (operands[0], DFmode))
3111        || (!TARGET_MEMORY_MISMATCH_STALL
3112            && memory_operand (operands[0], DFmode)))"
3113 {
3114   switch (which_alternative)
3115     {
3116     case 0:
3117     case 1:
3118       return output_387_reg_move (insn, operands);
3119
3120     case 2:
3121       return standard_80387_constant_opcode (operands[1]);
3122
3123     case 3:
3124     case 4:
3125       return "#";
3126
3127     case 5:
3128     case 9:
3129       return standard_sse_constant_opcode (insn, operands[1]);
3130
3131     case 6:
3132     case 7:
3133     case 8:
3134     case 10:
3135     case 11:
3136     case 12:
3137       switch (get_attr_mode (insn))
3138         {
3139         case MODE_V2DF:
3140           if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3141             return "%vmovapd\t{%1, %0|%0, %1}";
3142         case MODE_V4SF:
3143           return "%vmovaps\t{%1, %0|%0, %1}";
3144
3145         case MODE_DI:
3146           return "%vmovq\t{%1, %0|%0, %1}";
3147         case MODE_DF:
3148           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3149             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3150           return "%vmovsd\t{%1, %0|%0, %1}";
3151         case MODE_V1DF:
3152           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3153         case MODE_V2SF:
3154           return "%vmovlps\t{%1, %d0|%d0, %1}";
3155         default:
3156           gcc_unreachable ();
3157         }
3158
3159     default:
3160       gcc_unreachable ();
3161     }
3162 }
3163   [(set (attr "isa")
3164      (if_then_else (eq_attr "alternative" "5,6,7,8")
3165        (const_string "sse2")
3166        (const_string "*")))
3167    (set (attr "type")
3168         (cond [(eq_attr "alternative" "0,1,2")
3169                  (const_string "fmov")
3170                (eq_attr "alternative" "3,4")
3171                  (const_string "multi")
3172                (eq_attr "alternative" "5,9")
3173                  (const_string "sselog1")
3174               ]
3175               (const_string "ssemov")))
3176    (set (attr "prefix")
3177      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3178        (const_string "orig")
3179        (const_string "maybe_vex")))
3180    (set (attr "prefix_data16")
3181      (if_then_else (eq_attr "mode" "V1DF")
3182        (const_string "1")
3183        (const_string "*")))
3184    (set (attr "mode")
3185         (cond [(eq_attr "alternative" "0,1,2")
3186                  (const_string "DF")
3187                (eq_attr "alternative" "3,4")
3188                  (const_string "SI")
3189
3190                /* For SSE1, we have many fewer alternatives.  */
3191                (not (match_test "TARGET_SSE2"))
3192                  (if_then_else
3193                    (eq_attr "alternative" "5,6,9,10")
3194                    (const_string "V4SF")
3195                    (const_string "V2SF"))
3196
3197                /* xorps is one byte shorter.  */
3198                (eq_attr "alternative" "5,9")
3199                  (cond [(match_test "optimize_function_for_size_p (cfun)")
3200                           (const_string "V4SF")
3201                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3202                           (const_string "TI")
3203                        ]
3204                        (const_string "V2DF"))
3205
3206                /* For architectures resolving dependencies on
3207                   whole SSE registers use APD move to break dependency
3208                   chains, otherwise use short move to avoid extra work.
3209
3210                   movaps encodes one byte shorter.  */
3211                (eq_attr "alternative" "6,10")
3212                  (cond
3213                    [(match_test "optimize_function_for_size_p (cfun)")
3214                       (const_string "V4SF")
3215                     (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3216                       (const_string "V2DF")
3217                    ]
3218                    (const_string "DF"))
3219                /* For architectures resolving dependencies on register
3220                   parts we may avoid extra work to zero out upper part
3221                   of register.  */
3222                (eq_attr "alternative" "7,11")
3223                  (if_then_else
3224                    (match_test "TARGET_SSE_SPLIT_REGS")
3225                    (const_string "V1DF")
3226                    (const_string "DF"))
3227               ]
3228               (const_string "DF")))])
3229
3230 (define_insn "*movsf_internal"
3231   [(set (match_operand:SF 0 "nonimmediate_operand"
3232           "=Yf*f,m   ,Yf*f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3233         (match_operand:SF 1 "general_operand"
3234           "Yf*fm,Yf*f,G   ,rmF,rF,C,x,m,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
3235   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3236    && (!can_create_pseudo_p ()
3237        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3238        || GET_CODE (operands[1]) != CONST_DOUBLE
3239        || (optimize_function_for_size_p (cfun)
3240            && ((!TARGET_SSE_MATH
3241                 && standard_80387_constant_p (operands[1]) > 0)
3242                || (TARGET_SSE_MATH
3243                    && standard_sse_constant_p (operands[1]))))
3244        || memory_operand (operands[0], SFmode))"
3245 {
3246   switch (which_alternative)
3247     {
3248     case 0:
3249     case 1:
3250       return output_387_reg_move (insn, operands);
3251
3252     case 2:
3253       return standard_80387_constant_opcode (operands[1]);
3254
3255     case 3:
3256     case 4:
3257       return "mov{l}\t{%1, %0|%0, %1}";
3258
3259     case 5:
3260       return standard_sse_constant_opcode (insn, operands[1]);
3261
3262     case 6:
3263       if (get_attr_mode (insn) == MODE_V4SF)
3264         return "%vmovaps\t{%1, %0|%0, %1}";
3265       if (TARGET_AVX)
3266         return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3267
3268     case 7:
3269     case 8:
3270       return "%vmovss\t{%1, %0|%0, %1}";
3271
3272     case 9:
3273     case 10:
3274     case 14:
3275     case 15:
3276       return "movd\t{%1, %0|%0, %1}";
3277
3278     case 11:
3279       return "movq\t{%1, %0|%0, %1}";
3280
3281     case 12:
3282     case 13:
3283       return "%vmovd\t{%1, %0|%0, %1}";
3284
3285     default:
3286       gcc_unreachable ();
3287     }
3288 }
3289   [(set (attr "type")
3290         (cond [(eq_attr "alternative" "0,1,2")
3291                  (const_string "fmov")
3292                (eq_attr "alternative" "3,4")
3293                  (const_string "multi")
3294                (eq_attr "alternative" "5")
3295                  (const_string "sselog1")
3296                (eq_attr "alternative" "9,10,11,14,15")
3297                  (const_string "mmxmov")
3298               ]
3299               (const_string "ssemov")))
3300    (set (attr "prefix")
3301      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3302        (const_string "maybe_vex")
3303        (const_string "orig")))
3304    (set (attr "mode")
3305         (cond [(eq_attr "alternative" "3,4,9,10")
3306                  (const_string "SI")
3307                (eq_attr "alternative" "5")
3308                  (if_then_else
3309                    (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3310                              (match_test "TARGET_SSE2"))
3311                         (not (match_test "optimize_function_for_size_p (cfun)")))
3312                    (const_string "TI")
3313                    (const_string "V4SF"))
3314                /* For architectures resolving dependencies on
3315                   whole SSE registers use APS move to break dependency
3316                   chains, otherwise use short move to avoid extra work.
3317
3318                   Do the same for architectures resolving dependencies on
3319                   the parts.  While in DF mode it is better to always handle
3320                   just register parts, the SF mode is different due to lack
3321                   of instructions to load just part of the register.  It is
3322                   better to maintain the whole registers in single format
3323                   to avoid problems on using packed logical operations.  */
3324                (eq_attr "alternative" "6")
3325                  (if_then_else
3326                    (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3327                         (match_test "TARGET_SSE_SPLIT_REGS"))
3328                    (const_string "V4SF")
3329                    (const_string "SF"))
3330                (eq_attr "alternative" "11")
3331                  (const_string "DI")]
3332                (const_string "SF")))])
3333
3334 (define_split
3335   [(set (match_operand 0 "any_fp_register_operand" "")
3336         (match_operand 1 "memory_operand" ""))]
3337   "reload_completed
3338    && (GET_MODE (operands[0]) == TFmode
3339        || GET_MODE (operands[0]) == XFmode
3340        || GET_MODE (operands[0]) == DFmode
3341        || GET_MODE (operands[0]) == SFmode)
3342    && (operands[2] = find_constant_src (insn))"
3343   [(set (match_dup 0) (match_dup 2))]
3344 {
3345   rtx c = operands[2];
3346   int r = REGNO (operands[0]);
3347
3348   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3349       || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3350     FAIL;
3351 })
3352
3353 (define_split
3354   [(set (match_operand 0 "any_fp_register_operand" "")
3355         (float_extend (match_operand 1 "memory_operand" "")))]
3356   "reload_completed
3357    && (GET_MODE (operands[0]) == TFmode
3358        || GET_MODE (operands[0]) == XFmode
3359        || GET_MODE (operands[0]) == DFmode)
3360    && (operands[2] = find_constant_src (insn))"
3361   [(set (match_dup 0) (match_dup 2))]
3362 {
3363   rtx c = operands[2];
3364   int r = REGNO (operands[0]);
3365
3366   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3367       || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3368     FAIL;
3369 })
3370
3371 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3372 (define_split
3373   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3374         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3375   "reload_completed
3376    && (standard_80387_constant_p (operands[1]) == 8
3377        || standard_80387_constant_p (operands[1]) == 9)"
3378   [(set (match_dup 0)(match_dup 1))
3379    (set (match_dup 0)
3380         (neg:X87MODEF (match_dup 0)))]
3381 {
3382   REAL_VALUE_TYPE r;
3383
3384   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3385   if (real_isnegzero (&r))
3386     operands[1] = CONST0_RTX (<MODE>mode);
3387   else
3388     operands[1] = CONST1_RTX (<MODE>mode);
3389 })
3390
3391 (define_split
3392   [(set (match_operand 0 "nonimmediate_operand" "")
3393         (match_operand 1 "general_operand" ""))]
3394   "reload_completed
3395    && (GET_MODE (operands[0]) == TFmode
3396        || GET_MODE (operands[0]) == XFmode
3397        || GET_MODE (operands[0]) == DFmode)
3398    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3399   [(const_int 0)]
3400   "ix86_split_long_move (operands); DONE;")
3401
3402 (define_insn "swapxf"
3403   [(set (match_operand:XF 0 "register_operand" "+f")
3404         (match_operand:XF 1 "register_operand" "+f"))
3405    (set (match_dup 1)
3406         (match_dup 0))]
3407   "TARGET_80387"
3408 {
3409   if (STACK_TOP_P (operands[0]))
3410     return "fxch\t%1";
3411   else
3412     return "fxch\t%0";
3413 }
3414   [(set_attr "type" "fxch")
3415    (set_attr "mode" "XF")])
3416
3417 (define_insn "*swap<mode>"
3418   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3419         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3420    (set (match_dup 1)
3421         (match_dup 0))]
3422   "TARGET_80387 || reload_completed"
3423 {
3424   if (STACK_TOP_P (operands[0]))
3425     return "fxch\t%1";
3426   else
3427     return "fxch\t%0";
3428 }
3429   [(set_attr "type" "fxch")
3430    (set_attr "mode" "<MODE>")])
3431 \f
3432 ;; Zero extension instructions
3433
3434 (define_expand "zero_extendsidi2"
3435   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3436         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3437   ""
3438 {
3439   if (!TARGET_64BIT)
3440     {
3441       emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3442       DONE;
3443     }
3444 })
3445
3446 (define_insn "*zero_extendsidi2_rex64"
3447   [(set (match_operand:DI 0 "nonimmediate_operand"  "=r,o,?*Ym,?*y,?*Yi,*x")
3448         (zero_extend:DI
3449          (match_operand:SI 1 "nonimmediate_operand" "rm,0,r   ,m  ,r   ,m")))]
3450   "TARGET_64BIT"
3451   "@
3452    mov{l}\t{%1, %k0|%k0, %1}
3453    #
3454    movd\t{%1, %0|%0, %1}
3455    movd\t{%1, %0|%0, %1}
3456    %vmovd\t{%1, %0|%0, %1}
3457    %vmovd\t{%1, %0|%0, %1}"
3458   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3459    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3460    (set_attr "prefix_0f" "0,*,*,*,*,*")
3461    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3462
3463 (define_split
3464   [(set (match_operand:DI 0 "memory_operand" "")
3465         (zero_extend:DI (match_dup 0)))]
3466   "TARGET_64BIT"
3467   [(set (match_dup 4) (const_int 0))]
3468   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3469
3470 ;; %%% Kill me once multi-word ops are sane.
3471 (define_insn "zero_extendsidi2_1"
3472   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*x")
3473         (zero_extend:DI
3474          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3475    (clobber (reg:CC FLAGS_REG))]
3476   "!TARGET_64BIT"
3477   "@
3478    #
3479    #
3480    #
3481    movd\t{%1, %0|%0, %1}
3482    movd\t{%1, %0|%0, %1}
3483    %vmovd\t{%1, %0|%0, %1}
3484    %vmovd\t{%1, %0|%0, %1}"
3485   [(set_attr "isa" "*,*,*,*,*,*,sse2")
3486    (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3487    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3488    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3489
3490 (define_split
3491   [(set (match_operand:DI 0 "register_operand" "")
3492         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3493    (clobber (reg:CC FLAGS_REG))]
3494   "!TARGET_64BIT && reload_completed
3495    && true_regnum (operands[0]) == true_regnum (operands[1])"
3496   [(set (match_dup 4) (const_int 0))]
3497   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3498
3499 (define_split
3500   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3501         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3502    (clobber (reg:CC FLAGS_REG))]
3503   "!TARGET_64BIT && reload_completed
3504    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3505   [(set (match_dup 3) (match_dup 1))
3506    (set (match_dup 4) (const_int 0))]
3507   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3508
3509 (define_insn "zero_extend<mode>di2"
3510   [(set (match_operand:DI 0 "register_operand" "=r")
3511         (zero_extend:DI
3512          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3513   "TARGET_64BIT"
3514   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3515   [(set_attr "type" "imovx")
3516    (set_attr "mode" "SI")])
3517
3518 (define_expand "zero_extendhisi2"
3519   [(set (match_operand:SI 0 "register_operand" "")
3520         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3521   ""
3522 {
3523   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3524     {
3525       operands[1] = force_reg (HImode, operands[1]);
3526       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3527       DONE;
3528     }
3529 })
3530
3531 (define_insn_and_split "zero_extendhisi2_and"
3532   [(set (match_operand:SI 0 "register_operand" "=r")
3533         (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3534    (clobber (reg:CC FLAGS_REG))]
3535   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3536   "#"
3537   "&& reload_completed"
3538   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3539               (clobber (reg:CC FLAGS_REG))])]
3540   ""
3541   [(set_attr "type" "alu1")
3542    (set_attr "mode" "SI")])
3543
3544 (define_insn "*zero_extendhisi2_movzwl"
3545   [(set (match_operand:SI 0 "register_operand" "=r")
3546         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3547   "!TARGET_ZERO_EXTEND_WITH_AND
3548    || optimize_function_for_size_p (cfun)"
3549   "movz{wl|x}\t{%1, %0|%0, %1}"
3550   [(set_attr "type" "imovx")
3551    (set_attr "mode" "SI")])
3552
3553 (define_expand "zero_extendqi<mode>2"
3554   [(parallel
3555     [(set (match_operand:SWI24 0 "register_operand" "")
3556           (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3557      (clobber (reg:CC FLAGS_REG))])])
3558
3559 (define_insn "*zero_extendqi<mode>2_and"
3560   [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3561         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3562    (clobber (reg:CC FLAGS_REG))]
3563   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3564   "#"
3565   [(set_attr "type" "alu1")
3566    (set_attr "mode" "<MODE>")])
3567
3568 ;; When source and destination does not overlap, clear destination
3569 ;; first and then do the movb
3570 (define_split
3571   [(set (match_operand:SWI24 0 "register_operand" "")
3572         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3573    (clobber (reg:CC FLAGS_REG))]
3574   "reload_completed
3575    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3576    && ANY_QI_REG_P (operands[0])
3577    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3578    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3579   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3580 {
3581   operands[2] = gen_lowpart (QImode, operands[0]);
3582   ix86_expand_clear (operands[0]);
3583 })
3584
3585 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3586   [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3587         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3588    (clobber (reg:CC FLAGS_REG))]
3589   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3590   "#"
3591   [(set_attr "type" "imovx,alu1")
3592    (set_attr "mode" "<MODE>")])
3593
3594 ;; For the movzbl case strip only the clobber
3595 (define_split
3596   [(set (match_operand:SWI24 0 "register_operand" "")
3597         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3598    (clobber (reg:CC FLAGS_REG))]
3599   "reload_completed
3600    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3601    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3602   [(set (match_dup 0)
3603         (zero_extend:SWI24 (match_dup 1)))])
3604
3605 ; zero extend to SImode to avoid partial register stalls
3606 (define_insn "*zero_extendqi<mode>2_movzbl"
3607   [(set (match_operand:SWI24 0 "register_operand" "=r")
3608         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3609   "reload_completed
3610    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3611   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3612   [(set_attr "type" "imovx")
3613    (set_attr "mode" "SI")])
3614
3615 ;; Rest is handled by single and.
3616 (define_split
3617   [(set (match_operand:SWI24 0 "register_operand" "")
3618         (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3619    (clobber (reg:CC FLAGS_REG))]
3620   "reload_completed
3621    && true_regnum (operands[0]) == true_regnum (operands[1])"
3622   [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3623               (clobber (reg:CC FLAGS_REG))])])
3624 \f
3625 ;; Sign extension instructions
3626
3627 (define_expand "extendsidi2"
3628   [(set (match_operand:DI 0 "register_operand" "")
3629         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3630   ""
3631 {
3632   if (!TARGET_64BIT)
3633     {
3634       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3635       DONE;
3636     }
3637 })
3638
3639 (define_insn "*extendsidi2_rex64"
3640   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3641         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3642   "TARGET_64BIT"
3643   "@
3644    {cltq|cdqe}
3645    movs{lq|x}\t{%1, %0|%0, %1}"
3646   [(set_attr "type" "imovx")
3647    (set_attr "mode" "DI")
3648    (set_attr "prefix_0f" "0")
3649    (set_attr "modrm" "0,1")])
3650
3651 (define_insn "extendsidi2_1"
3652   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3653         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3654    (clobber (reg:CC FLAGS_REG))
3655    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3656   "!TARGET_64BIT"
3657   "#")
3658
3659 ;; Extend to memory case when source register does die.
3660 (define_split
3661   [(set (match_operand:DI 0 "memory_operand" "")
3662         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3663    (clobber (reg:CC FLAGS_REG))
3664    (clobber (match_operand:SI 2 "register_operand" ""))]
3665   "(reload_completed
3666     && dead_or_set_p (insn, operands[1])
3667     && !reg_mentioned_p (operands[1], operands[0]))"
3668   [(set (match_dup 3) (match_dup 1))
3669    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3670               (clobber (reg:CC FLAGS_REG))])
3671    (set (match_dup 4) (match_dup 1))]
3672   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3673
3674 ;; Extend to memory case when source register does not die.
3675 (define_split
3676   [(set (match_operand:DI 0 "memory_operand" "")
3677         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3678    (clobber (reg:CC FLAGS_REG))
3679    (clobber (match_operand:SI 2 "register_operand" ""))]
3680   "reload_completed"
3681   [(const_int 0)]
3682 {
3683   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3684
3685   emit_move_insn (operands[3], operands[1]);
3686
3687   /* Generate a cltd if possible and doing so it profitable.  */
3688   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3689       && true_regnum (operands[1]) == AX_REG
3690       && true_regnum (operands[2]) == DX_REG)
3691     {
3692       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3693     }
3694   else
3695     {
3696       emit_move_insn (operands[2], operands[1]);
3697       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3698     }
3699   emit_move_insn (operands[4], operands[2]);
3700   DONE;
3701 })
3702
3703 ;; Extend to register case.  Optimize case where source and destination
3704 ;; registers match and cases where we can use cltd.
3705 (define_split
3706   [(set (match_operand:DI 0 "register_operand" "")
3707         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3708    (clobber (reg:CC FLAGS_REG))
3709    (clobber (match_scratch:SI 2 ""))]
3710   "reload_completed"
3711   [(const_int 0)]
3712 {
3713   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3714
3715   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3716     emit_move_insn (operands[3], operands[1]);
3717
3718   /* Generate a cltd if possible and doing so it profitable.  */
3719   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3720       && true_regnum (operands[3]) == AX_REG
3721       && true_regnum (operands[4]) == DX_REG)
3722     {
3723       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3724       DONE;
3725     }
3726
3727   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3728     emit_move_insn (operands[4], operands[1]);
3729
3730   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3731   DONE;
3732 })
3733
3734 (define_insn "extend<mode>di2"
3735   [(set (match_operand:DI 0 "register_operand" "=r")
3736         (sign_extend:DI
3737          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3738   "TARGET_64BIT"
3739   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3740   [(set_attr "type" "imovx")
3741    (set_attr "mode" "DI")])
3742
3743 (define_insn "extendhisi2"
3744   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3745         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3746   ""
3747 {
3748   switch (get_attr_prefix_0f (insn))
3749     {
3750     case 0:
3751       return "{cwtl|cwde}";
3752     default:
3753       return "movs{wl|x}\t{%1, %0|%0, %1}";
3754     }
3755 }
3756   [(set_attr "type" "imovx")
3757    (set_attr "mode" "SI")
3758    (set (attr "prefix_0f")
3759      ;; movsx is short decodable while cwtl is vector decoded.
3760      (if_then_else (and (eq_attr "cpu" "!k6")
3761                         (eq_attr "alternative" "0"))
3762         (const_string "0")
3763         (const_string "1")))
3764    (set (attr "modrm")
3765      (if_then_else (eq_attr "prefix_0f" "0")
3766         (const_string "0")
3767         (const_string "1")))])
3768
3769 (define_insn "*extendhisi2_zext"
3770   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3771         (zero_extend:DI
3772          (sign_extend:SI
3773           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3774   "TARGET_64BIT"
3775 {
3776   switch (get_attr_prefix_0f (insn))
3777     {
3778     case 0:
3779       return "{cwtl|cwde}";
3780     default:
3781       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3782     }
3783 }
3784   [(set_attr "type" "imovx")
3785    (set_attr "mode" "SI")
3786    (set (attr "prefix_0f")
3787      ;; movsx is short decodable while cwtl is vector decoded.
3788      (if_then_else (and (eq_attr "cpu" "!k6")
3789                         (eq_attr "alternative" "0"))
3790         (const_string "0")
3791         (const_string "1")))
3792    (set (attr "modrm")
3793      (if_then_else (eq_attr "prefix_0f" "0")
3794         (const_string "0")
3795         (const_string "1")))])
3796
3797 (define_insn "extendqisi2"
3798   [(set (match_operand:SI 0 "register_operand" "=r")
3799         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3800   ""
3801   "movs{bl|x}\t{%1, %0|%0, %1}"
3802    [(set_attr "type" "imovx")
3803     (set_attr "mode" "SI")])
3804
3805 (define_insn "*extendqisi2_zext"
3806   [(set (match_operand:DI 0 "register_operand" "=r")
3807         (zero_extend:DI
3808           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3809   "TARGET_64BIT"
3810   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3811    [(set_attr "type" "imovx")
3812     (set_attr "mode" "SI")])
3813
3814 (define_insn "extendqihi2"
3815   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3816         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3817   ""
3818 {
3819   switch (get_attr_prefix_0f (insn))
3820     {
3821     case 0:
3822       return "{cbtw|cbw}";
3823     default:
3824       return "movs{bw|x}\t{%1, %0|%0, %1}";
3825     }
3826 }
3827   [(set_attr "type" "imovx")
3828    (set_attr "mode" "HI")
3829    (set (attr "prefix_0f")
3830      ;; movsx is short decodable while cwtl is vector decoded.
3831      (if_then_else (and (eq_attr "cpu" "!k6")
3832                         (eq_attr "alternative" "0"))
3833         (const_string "0")
3834         (const_string "1")))
3835    (set (attr "modrm")
3836      (if_then_else (eq_attr "prefix_0f" "0")
3837         (const_string "0")
3838         (const_string "1")))])
3839 \f
3840 ;; Conversions between float and double.
3841
3842 ;; These are all no-ops in the model used for the 80387.
3843 ;; So just emit moves.
3844
3845 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3846 (define_split
3847   [(set (match_operand:DF 0 "push_operand" "")
3848         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3849   "reload_completed"
3850   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3851    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3852
3853 (define_split
3854   [(set (match_operand:XF 0 "push_operand" "")
3855         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3856   "reload_completed"
3857   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3858    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3859   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3860
3861 (define_expand "extendsfdf2"
3862   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3863         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3864   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3865 {
3866   /* ??? Needed for compress_float_constant since all fp constants
3867      are TARGET_LEGITIMATE_CONSTANT_P.  */
3868   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3869     {
3870       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3871           && standard_80387_constant_p (operands[1]) > 0)
3872         {
3873           operands[1] = simplify_const_unary_operation
3874             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3875           emit_move_insn_1 (operands[0], operands[1]);
3876           DONE;
3877         }
3878       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3879     }
3880 })
3881
3882 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3883    cvtss2sd:
3884       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3885       cvtps2pd xmm2,xmm1
3886    We do the conversion post reload to avoid producing of 128bit spills
3887    that might lead to ICE on 32bit target.  The sequence unlikely combine
3888    anyway.  */
3889 (define_split
3890   [(set (match_operand:DF 0 "register_operand" "")
3891         (float_extend:DF
3892           (match_operand:SF 1 "nonimmediate_operand" "")))]
3893   "TARGET_USE_VECTOR_FP_CONVERTS
3894    && optimize_insn_for_speed_p ()
3895    && reload_completed && SSE_REG_P (operands[0])"
3896    [(set (match_dup 2)
3897          (float_extend:V2DF
3898            (vec_select:V2SF
3899              (match_dup 3)
3900              (parallel [(const_int 0) (const_int 1)]))))]
3901 {
3902   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3903   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3904   /* Use movss for loading from memory, unpcklps reg, reg for registers.
3905      Try to avoid move when unpacking can be done in source.  */
3906   if (REG_P (operands[1]))
3907     {
3908       /* If it is unsafe to overwrite upper half of source, we need
3909          to move to destination and unpack there.  */
3910       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3911            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3912           && true_regnum (operands[0]) != true_regnum (operands[1]))
3913         {
3914           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3915           emit_move_insn (tmp, operands[1]);
3916         }
3917       else
3918         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3919       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3920                                              operands[3]));
3921     }
3922   else
3923     emit_insn (gen_vec_setv4sf_0 (operands[3],
3924                                   CONST0_RTX (V4SFmode), operands[1]));
3925 })
3926
3927 (define_insn "*extendsfdf2_mixed"
3928   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3929         (float_extend:DF
3930           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3931   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3932 {
3933   switch (which_alternative)
3934     {
3935     case 0:
3936     case 1:
3937       return output_387_reg_move (insn, operands);
3938
3939     case 2:
3940       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3941
3942     default:
3943       gcc_unreachable ();
3944     }
3945 }
3946   [(set_attr "type" "fmov,fmov,ssecvt")
3947    (set_attr "prefix" "orig,orig,maybe_vex")
3948    (set_attr "mode" "SF,XF,DF")])
3949
3950 (define_insn "*extendsfdf2_sse"
3951   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3952         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3953   "TARGET_SSE2 && TARGET_SSE_MATH"
3954   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3955   [(set_attr "type" "ssecvt")
3956    (set_attr "prefix" "maybe_vex")
3957    (set_attr "mode" "DF")])
3958
3959 (define_insn "*extendsfdf2_i387"
3960   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3961         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3962   "TARGET_80387"
3963   "* return output_387_reg_move (insn, operands);"
3964   [(set_attr "type" "fmov")
3965    (set_attr "mode" "SF,XF")])
3966
3967 (define_expand "extend<mode>xf2"
3968   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3969         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3970   "TARGET_80387"
3971 {
3972   /* ??? Needed for compress_float_constant since all fp constants
3973      are TARGET_LEGITIMATE_CONSTANT_P.  */
3974   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3975     {
3976       if (standard_80387_constant_p (operands[1]) > 0)
3977         {
3978           operands[1] = simplify_const_unary_operation
3979             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3980           emit_move_insn_1 (operands[0], operands[1]);
3981           DONE;
3982         }
3983       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3984     }
3985 })
3986
3987 (define_insn "*extend<mode>xf2_i387"
3988   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3989         (float_extend:XF
3990           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3991   "TARGET_80387"
3992   "* return output_387_reg_move (insn, operands);"
3993   [(set_attr "type" "fmov")
3994    (set_attr "mode" "<MODE>,XF")])
3995
3996 ;; %%% This seems bad bad news.
3997 ;; This cannot output into an f-reg because there is no way to be sure
3998 ;; of truncating in that case.  Otherwise this is just like a simple move
3999 ;; insn.  So we pretend we can output to a reg in order to get better
4000 ;; register preferencing, but we really use a stack slot.
4001
4002 ;; Conversion from DFmode to SFmode.
4003
4004 (define_expand "truncdfsf2"
4005   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4006         (float_truncate:SF
4007           (match_operand:DF 1 "nonimmediate_operand" "")))]
4008   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4009 {
4010   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4011     ;
4012   else if (flag_unsafe_math_optimizations)
4013     ;
4014   else
4015     {
4016       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4017       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4018       DONE;
4019     }
4020 })
4021
4022 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4023    cvtsd2ss:
4024       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4025       cvtpd2ps xmm2,xmm1
4026    We do the conversion post reload to avoid producing of 128bit spills
4027    that might lead to ICE on 32bit target.  The sequence unlikely combine
4028    anyway.  */
4029 (define_split
4030   [(set (match_operand:SF 0 "register_operand" "")
4031         (float_truncate:SF
4032           (match_operand:DF 1 "nonimmediate_operand" "")))]
4033   "TARGET_USE_VECTOR_FP_CONVERTS
4034    && optimize_insn_for_speed_p ()
4035    && reload_completed && SSE_REG_P (operands[0])"
4036    [(set (match_dup 2)
4037          (vec_concat:V4SF
4038            (float_truncate:V2SF
4039              (match_dup 4))
4040            (match_dup 3)))]
4041 {
4042   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4043   operands[3] = CONST0_RTX (V2SFmode);
4044   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4045   /* Use movsd for loading from memory, unpcklpd for registers.
4046      Try to avoid move when unpacking can be done in source, or SSE3
4047      movddup is available.  */
4048   if (REG_P (operands[1]))
4049     {
4050       if (!TARGET_SSE3
4051           && true_regnum (operands[0]) != true_regnum (operands[1])
4052           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4053               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4054         {
4055           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4056           emit_move_insn (tmp, operands[1]);
4057           operands[1] = tmp;
4058         }
4059       else if (!TARGET_SSE3)
4060         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4061       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4062     }
4063   else
4064     emit_insn (gen_sse2_loadlpd (operands[4],
4065                                  CONST0_RTX (V2DFmode), operands[1]));
4066 })
4067
4068 (define_expand "truncdfsf2_with_temp"
4069   [(parallel [(set (match_operand:SF 0 "" "")
4070                    (float_truncate:SF (match_operand:DF 1 "" "")))
4071               (clobber (match_operand:SF 2 "" ""))])])
4072
4073 (define_insn "*truncdfsf_fast_mixed"
4074   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4075         (float_truncate:SF
4076           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4077   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4078 {
4079   switch (which_alternative)
4080     {
4081     case 0:
4082       return output_387_reg_move (insn, operands);
4083     case 1:
4084       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4085     default:
4086       gcc_unreachable ();
4087     }
4088 }
4089   [(set_attr "type" "fmov,ssecvt")
4090    (set_attr "prefix" "orig,maybe_vex")
4091    (set_attr "mode" "SF")])
4092
4093 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4094 ;; because nothing we do here is unsafe.
4095 (define_insn "*truncdfsf_fast_sse"
4096   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4097         (float_truncate:SF
4098           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4099   "TARGET_SSE2 && TARGET_SSE_MATH"
4100   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4101   [(set_attr "type" "ssecvt")
4102    (set_attr "prefix" "maybe_vex")
4103    (set_attr "mode" "SF")])
4104
4105 (define_insn "*truncdfsf_fast_i387"
4106   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4107         (float_truncate:SF
4108           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4109   "TARGET_80387 && flag_unsafe_math_optimizations"
4110   "* return output_387_reg_move (insn, operands);"
4111   [(set_attr "type" "fmov")
4112    (set_attr "mode" "SF")])
4113
4114 (define_insn "*truncdfsf_mixed"
4115   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,x ,?f,?x,?*r")
4116         (float_truncate:SF
4117           (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4118    (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
4119   "TARGET_MIX_SSE_I387"
4120 {
4121   switch (which_alternative)
4122     {
4123     case 0:
4124       return output_387_reg_move (insn, operands);
4125     case 1:
4126       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4127
4128     default:
4129       return "#";
4130     }
4131 }
4132   [(set_attr "isa" "*,sse2,*,*,*")
4133    (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4134    (set_attr "unit" "*,*,i387,i387,i387")
4135    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4136    (set_attr "mode" "SF")])
4137
4138 (define_insn "*truncdfsf_i387"
4139   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4140         (float_truncate:SF
4141           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4142    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4143   "TARGET_80387"
4144 {
4145   switch (which_alternative)
4146     {
4147     case 0:
4148       return output_387_reg_move (insn, operands);
4149
4150     default:
4151       return "#";
4152     }
4153 }
4154   [(set_attr "type" "fmov,multi,multi,multi")
4155    (set_attr "unit" "*,i387,i387,i387")
4156    (set_attr "mode" "SF")])
4157
4158 (define_insn "*truncdfsf2_i387_1"
4159   [(set (match_operand:SF 0 "memory_operand" "=m")
4160         (float_truncate:SF
4161           (match_operand:DF 1 "register_operand" "f")))]
4162   "TARGET_80387
4163    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4164    && !TARGET_MIX_SSE_I387"
4165   "* return output_387_reg_move (insn, operands);"
4166   [(set_attr "type" "fmov")
4167    (set_attr "mode" "SF")])
4168
4169 (define_split
4170   [(set (match_operand:SF 0 "register_operand" "")
4171         (float_truncate:SF
4172          (match_operand:DF 1 "fp_register_operand" "")))
4173    (clobber (match_operand 2 "" ""))]
4174   "reload_completed"
4175   [(set (match_dup 2) (match_dup 1))
4176    (set (match_dup 0) (match_dup 2))]
4177   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4178
4179 ;; Conversion from XFmode to {SF,DF}mode
4180
4181 (define_expand "truncxf<mode>2"
4182   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4183                    (float_truncate:MODEF
4184                      (match_operand:XF 1 "register_operand" "")))
4185               (clobber (match_dup 2))])]
4186   "TARGET_80387"
4187 {
4188   if (flag_unsafe_math_optimizations)
4189     {
4190       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4191       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4192       if (reg != operands[0])
4193         emit_move_insn (operands[0], reg);
4194       DONE;
4195     }
4196   else
4197     operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4198 })
4199
4200 (define_insn "*truncxfsf2_mixed"
4201   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4202         (float_truncate:SF
4203           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4204    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4205   "TARGET_80387"
4206 {
4207   gcc_assert (!which_alternative);
4208   return output_387_reg_move (insn, operands);
4209 }
4210   [(set_attr "type" "fmov,multi,multi,multi")
4211    (set_attr "unit" "*,i387,i387,i387")
4212    (set_attr "mode" "SF")])
4213
4214 (define_insn "*truncxfdf2_mixed"
4215   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4216         (float_truncate:DF
4217           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4218    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4219   "TARGET_80387"
4220 {
4221   gcc_assert (!which_alternative);
4222   return output_387_reg_move (insn, operands);
4223 }
4224   [(set_attr "isa" "*,*,sse2,*")
4225    (set_attr "type" "fmov,multi,multi,multi")
4226    (set_attr "unit" "*,i387,i387,i387")
4227    (set_attr "mode" "DF")])
4228
4229 (define_insn "truncxf<mode>2_i387_noop"
4230   [(set (match_operand:MODEF 0 "register_operand" "=f")
4231         (float_truncate:MODEF
4232           (match_operand:XF 1 "register_operand" "f")))]
4233   "TARGET_80387 && flag_unsafe_math_optimizations"
4234   "* return output_387_reg_move (insn, operands);"
4235   [(set_attr "type" "fmov")
4236    (set_attr "mode" "<MODE>")])
4237
4238 (define_insn "*truncxf<mode>2_i387"
4239   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4240         (float_truncate:MODEF
4241           (match_operand:XF 1 "register_operand" "f")))]
4242   "TARGET_80387"
4243   "* return output_387_reg_move (insn, operands);"
4244   [(set_attr "type" "fmov")
4245    (set_attr "mode" "<MODE>")])
4246
4247 (define_split
4248   [(set (match_operand:MODEF 0 "register_operand" "")
4249         (float_truncate:MODEF
4250           (match_operand:XF 1 "register_operand" "")))
4251    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4252   "TARGET_80387 && reload_completed"
4253   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4254    (set (match_dup 0) (match_dup 2))])
4255
4256 (define_split
4257   [(set (match_operand:MODEF 0 "memory_operand" "")
4258         (float_truncate:MODEF
4259           (match_operand:XF 1 "register_operand" "")))
4260    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4261   "TARGET_80387"
4262   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4263 \f
4264 ;; Signed conversion to DImode.
4265
4266 (define_expand "fix_truncxfdi2"
4267   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4268                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4269               (clobber (reg:CC FLAGS_REG))])]
4270   "TARGET_80387"
4271 {
4272   if (TARGET_FISTTP)
4273    {
4274      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4275      DONE;
4276    }
4277 })
4278
4279 (define_expand "fix_trunc<mode>di2"
4280   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4281                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4282               (clobber (reg:CC FLAGS_REG))])]
4283   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4284 {
4285   if (TARGET_FISTTP
4286       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4287    {
4288      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4289      DONE;
4290    }
4291   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4292    {
4293      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4294      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4295      if (out != operands[0])
4296         emit_move_insn (operands[0], out);
4297      DONE;
4298    }
4299 })
4300
4301 ;; Signed conversion to SImode.
4302
4303 (define_expand "fix_truncxfsi2"
4304   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4305                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4306               (clobber (reg:CC FLAGS_REG))])]
4307   "TARGET_80387"
4308 {
4309   if (TARGET_FISTTP)
4310    {
4311      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4312      DONE;
4313    }
4314 })
4315
4316 (define_expand "fix_trunc<mode>si2"
4317   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4318                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4319               (clobber (reg:CC FLAGS_REG))])]
4320   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4321 {
4322   if (TARGET_FISTTP
4323       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4324    {
4325      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4326      DONE;
4327    }
4328   if (SSE_FLOAT_MODE_P (<MODE>mode))
4329    {
4330      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4331      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4332      if (out != operands[0])
4333         emit_move_insn (operands[0], out);
4334      DONE;
4335    }
4336 })
4337
4338 ;; Signed conversion to HImode.
4339
4340 (define_expand "fix_trunc<mode>hi2"
4341   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4342                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4343               (clobber (reg:CC FLAGS_REG))])]
4344   "TARGET_80387
4345    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4346 {
4347   if (TARGET_FISTTP)
4348    {
4349      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4350      DONE;
4351    }
4352 })
4353
4354 ;; Unsigned conversion to SImode.
4355
4356 (define_expand "fixuns_trunc<mode>si2"
4357   [(parallel
4358     [(set (match_operand:SI 0 "register_operand" "")
4359           (unsigned_fix:SI
4360             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4361      (use (match_dup 2))
4362      (clobber (match_scratch:<ssevecmode> 3 ""))
4363      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4364   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4365 {
4366   enum machine_mode mode = <MODE>mode;
4367   enum machine_mode vecmode = <ssevecmode>mode;
4368   REAL_VALUE_TYPE TWO31r;
4369   rtx two31;
4370
4371   if (optimize_insn_for_size_p ())
4372     FAIL;
4373
4374   real_ldexp (&TWO31r, &dconst1, 31);
4375   two31 = const_double_from_real_value (TWO31r, mode);
4376   two31 = ix86_build_const_vector (vecmode, true, two31);
4377   operands[2] = force_reg (vecmode, two31);
4378 })
4379
4380 (define_insn_and_split "*fixuns_trunc<mode>_1"
4381   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4382         (unsigned_fix:SI
4383           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4384    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4385    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4386    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4387   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4388    && optimize_function_for_speed_p (cfun)"
4389   "#"
4390   "&& reload_completed"
4391   [(const_int 0)]
4392 {
4393   ix86_split_convert_uns_si_sse (operands);
4394   DONE;
4395 })
4396
4397 ;; Unsigned conversion to HImode.
4398 ;; Without these patterns, we'll try the unsigned SI conversion which
4399 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4400
4401 (define_expand "fixuns_trunc<mode>hi2"
4402   [(set (match_dup 2)
4403         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4404    (set (match_operand:HI 0 "nonimmediate_operand" "")
4405         (subreg:HI (match_dup 2) 0))]
4406   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4407   "operands[2] = gen_reg_rtx (SImode);")
4408
4409 ;; When SSE is available, it is always faster to use it!
4410 (define_insn "fix_trunc<mode>di_sse"
4411   [(set (match_operand:DI 0 "register_operand" "=r,r")
4412         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4413   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4414    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4415   "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4416   [(set_attr "type" "sseicvt")
4417    (set_attr "prefix" "maybe_vex")
4418    (set_attr "prefix_rex" "1")
4419    (set_attr "mode" "<MODE>")
4420    (set_attr "athlon_decode" "double,vector")
4421    (set_attr "amdfam10_decode" "double,double")
4422    (set_attr "bdver1_decode" "double,double")])
4423
4424 (define_insn "fix_trunc<mode>si_sse"
4425   [(set (match_operand:SI 0 "register_operand" "=r,r")
4426         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4427   "SSE_FLOAT_MODE_P (<MODE>mode)
4428    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4429   "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4430   [(set_attr "type" "sseicvt")
4431    (set_attr "prefix" "maybe_vex")
4432    (set_attr "mode" "<MODE>")
4433    (set_attr "athlon_decode" "double,vector")
4434    (set_attr "amdfam10_decode" "double,double")
4435    (set_attr "bdver1_decode" "double,double")])
4436
4437 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4438 (define_peephole2
4439   [(set (match_operand:MODEF 0 "register_operand" "")
4440         (match_operand:MODEF 1 "memory_operand" ""))
4441    (set (match_operand:SWI48x 2 "register_operand" "")
4442         (fix:SWI48x (match_dup 0)))]
4443   "TARGET_SHORTEN_X87_SSE
4444    && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4445    && peep2_reg_dead_p (2, operands[0])"
4446   [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4447
4448 ;; Avoid vector decoded forms of the instruction.
4449 (define_peephole2
4450   [(match_scratch:DF 2 "x")
4451    (set (match_operand:SWI48x 0 "register_operand" "")
4452         (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4453   "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4454   [(set (match_dup 2) (match_dup 1))
4455    (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4456
4457 (define_peephole2
4458   [(match_scratch:SF 2 "x")
4459    (set (match_operand:SWI48x 0 "register_operand" "")
4460         (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4461   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4462   [(set (match_dup 2) (match_dup 1))
4463    (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4464
4465 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4466   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4467         (fix:SWI248x (match_operand 1 "register_operand" "")))]
4468   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4469    && TARGET_FISTTP
4470    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4471          && (TARGET_64BIT || <MODE>mode != DImode))
4472         && TARGET_SSE_MATH)
4473    && can_create_pseudo_p ()"
4474   "#"
4475   "&& 1"
4476   [(const_int 0)]
4477 {
4478   if (memory_operand (operands[0], VOIDmode))
4479     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4480   else
4481     {
4482       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4483       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4484                                                             operands[1],
4485                                                             operands[2]));
4486     }
4487   DONE;
4488 }
4489   [(set_attr "type" "fisttp")
4490    (set_attr "mode" "<MODE>")])
4491
4492 (define_insn "fix_trunc<mode>_i387_fisttp"
4493   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4494         (fix:SWI248x (match_operand 1 "register_operand" "f")))
4495    (clobber (match_scratch:XF 2 "=&1f"))]
4496   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4497    && TARGET_FISTTP
4498    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4499          && (TARGET_64BIT || <MODE>mode != DImode))
4500         && TARGET_SSE_MATH)"
4501   "* return output_fix_trunc (insn, operands, true);"
4502   [(set_attr "type" "fisttp")
4503    (set_attr "mode" "<MODE>")])
4504
4505 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4506   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4507         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4508    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4509    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4510   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4511    && TARGET_FISTTP
4512    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4513         && (TARGET_64BIT || <MODE>mode != DImode))
4514         && TARGET_SSE_MATH)"
4515   "#"
4516   [(set_attr "type" "fisttp")
4517    (set_attr "mode" "<MODE>")])
4518
4519 (define_split
4520   [(set (match_operand:SWI248x 0 "register_operand" "")
4521         (fix:SWI248x (match_operand 1 "register_operand" "")))
4522    (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4523    (clobber (match_scratch 3 ""))]
4524   "reload_completed"
4525   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4526               (clobber (match_dup 3))])
4527    (set (match_dup 0) (match_dup 2))])
4528
4529 (define_split
4530   [(set (match_operand:SWI248x 0 "memory_operand" "")
4531         (fix:SWI248x (match_operand 1 "register_operand" "")))
4532    (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4533    (clobber (match_scratch 3 ""))]
4534   "reload_completed"
4535   [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4536               (clobber (match_dup 3))])])
4537
4538 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4539 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4540 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4541 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4542 ;; function in i386.c.
4543 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4544   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4545         (fix:SWI248x (match_operand 1 "register_operand" "")))
4546    (clobber (reg:CC FLAGS_REG))]
4547   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4548    && !TARGET_FISTTP
4549    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4550          && (TARGET_64BIT || <MODE>mode != DImode))
4551    && can_create_pseudo_p ()"
4552   "#"
4553   "&& 1"
4554   [(const_int 0)]
4555 {
4556   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4557
4558   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4559   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4560   if (memory_operand (operands[0], VOIDmode))
4561     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4562                                          operands[2], operands[3]));
4563   else
4564     {
4565       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4566       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4567                                                      operands[2], operands[3],
4568                                                      operands[4]));
4569     }
4570   DONE;
4571 }
4572   [(set_attr "type" "fistp")
4573    (set_attr "i387_cw" "trunc")
4574    (set_attr "mode" "<MODE>")])
4575
4576 (define_insn "fix_truncdi_i387"
4577   [(set (match_operand:DI 0 "memory_operand" "=m")
4578         (fix:DI (match_operand 1 "register_operand" "f")))
4579    (use (match_operand:HI 2 "memory_operand" "m"))
4580    (use (match_operand:HI 3 "memory_operand" "m"))
4581    (clobber (match_scratch:XF 4 "=&1f"))]
4582   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4583    && !TARGET_FISTTP
4584    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4585   "* return output_fix_trunc (insn, operands, false);"
4586   [(set_attr "type" "fistp")
4587    (set_attr "i387_cw" "trunc")
4588    (set_attr "mode" "DI")])
4589
4590 (define_insn "fix_truncdi_i387_with_temp"
4591   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4592         (fix:DI (match_operand 1 "register_operand" "f,f")))
4593    (use (match_operand:HI 2 "memory_operand" "m,m"))
4594    (use (match_operand:HI 3 "memory_operand" "m,m"))
4595    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4596    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4597   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4598    && !TARGET_FISTTP
4599    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4600   "#"
4601   [(set_attr "type" "fistp")
4602    (set_attr "i387_cw" "trunc")
4603    (set_attr "mode" "DI")])
4604
4605 (define_split
4606   [(set (match_operand:DI 0 "register_operand" "")
4607         (fix:DI (match_operand 1 "register_operand" "")))
4608    (use (match_operand:HI 2 "memory_operand" ""))
4609    (use (match_operand:HI 3 "memory_operand" ""))
4610    (clobber (match_operand:DI 4 "memory_operand" ""))
4611    (clobber (match_scratch 5 ""))]
4612   "reload_completed"
4613   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4614               (use (match_dup 2))
4615               (use (match_dup 3))
4616               (clobber (match_dup 5))])
4617    (set (match_dup 0) (match_dup 4))])
4618
4619 (define_split
4620   [(set (match_operand:DI 0 "memory_operand" "")
4621         (fix:DI (match_operand 1 "register_operand" "")))
4622    (use (match_operand:HI 2 "memory_operand" ""))
4623    (use (match_operand:HI 3 "memory_operand" ""))
4624    (clobber (match_operand:DI 4 "memory_operand" ""))
4625    (clobber (match_scratch 5 ""))]
4626   "reload_completed"
4627   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4628               (use (match_dup 2))
4629               (use (match_dup 3))
4630               (clobber (match_dup 5))])])
4631
4632 (define_insn "fix_trunc<mode>_i387"
4633   [(set (match_operand:SWI24 0 "memory_operand" "=m")
4634         (fix:SWI24 (match_operand 1 "register_operand" "f")))
4635    (use (match_operand:HI 2 "memory_operand" "m"))
4636    (use (match_operand:HI 3 "memory_operand" "m"))]
4637   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4638    && !TARGET_FISTTP
4639    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4640   "* return output_fix_trunc (insn, operands, false);"
4641   [(set_attr "type" "fistp")
4642    (set_attr "i387_cw" "trunc")
4643    (set_attr "mode" "<MODE>")])
4644
4645 (define_insn "fix_trunc<mode>_i387_with_temp"
4646   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4647         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4648    (use (match_operand:HI 2 "memory_operand" "m,m"))
4649    (use (match_operand:HI 3 "memory_operand" "m,m"))
4650    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4651   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4652    && !TARGET_FISTTP
4653    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4654   "#"
4655   [(set_attr "type" "fistp")
4656    (set_attr "i387_cw" "trunc")
4657    (set_attr "mode" "<MODE>")])
4658
4659 (define_split
4660   [(set (match_operand:SWI24 0 "register_operand" "")
4661         (fix:SWI24 (match_operand 1 "register_operand" "")))
4662    (use (match_operand:HI 2 "memory_operand" ""))
4663    (use (match_operand:HI 3 "memory_operand" ""))
4664    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4665   "reload_completed"
4666   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4667               (use (match_dup 2))
4668               (use (match_dup 3))])
4669    (set (match_dup 0) (match_dup 4))])
4670
4671 (define_split
4672   [(set (match_operand:SWI24 0 "memory_operand" "")
4673         (fix:SWI24 (match_operand 1 "register_operand" "")))
4674    (use (match_operand:HI 2 "memory_operand" ""))
4675    (use (match_operand:HI 3 "memory_operand" ""))
4676    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4677   "reload_completed"
4678   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4679               (use (match_dup 2))
4680               (use (match_dup 3))])])
4681
4682 (define_insn "x86_fnstcw_1"
4683   [(set (match_operand:HI 0 "memory_operand" "=m")
4684         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4685   "TARGET_80387"
4686   "fnstcw\t%0"
4687   [(set (attr "length")
4688         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4689    (set_attr "mode" "HI")
4690    (set_attr "unit" "i387")
4691    (set_attr "bdver1_decode" "vector")])
4692
4693 (define_insn "x86_fldcw_1"
4694   [(set (reg:HI FPCR_REG)
4695         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4696   "TARGET_80387"
4697   "fldcw\t%0"
4698   [(set (attr "length")
4699         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4700    (set_attr "mode" "HI")
4701    (set_attr "unit" "i387")
4702    (set_attr "athlon_decode" "vector")
4703    (set_attr "amdfam10_decode" "vector")
4704    (set_attr "bdver1_decode" "vector")])
4705 \f
4706 ;; Conversion between fixed point and floating point.
4707
4708 ;; Even though we only accept memory inputs, the backend _really_
4709 ;; wants to be able to do this between registers.
4710
4711 (define_expand "floathi<mode>2"
4712   [(set (match_operand:X87MODEF 0 "register_operand" "")
4713         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4714   "TARGET_80387
4715    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4716        || TARGET_MIX_SSE_I387)")
4717
4718 ;; Pre-reload splitter to add memory clobber to the pattern.
4719 (define_insn_and_split "*floathi<mode>2_1"
4720   [(set (match_operand:X87MODEF 0 "register_operand" "")
4721         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4722   "TARGET_80387
4723    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4724        || TARGET_MIX_SSE_I387)
4725    && can_create_pseudo_p ()"
4726   "#"
4727   "&& 1"
4728   [(parallel [(set (match_dup 0)
4729               (float:X87MODEF (match_dup 1)))
4730    (clobber (match_dup 2))])]
4731   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4732
4733 (define_insn "*floathi<mode>2_i387_with_temp"
4734   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4735         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4736   (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4737   "TARGET_80387
4738    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4739        || TARGET_MIX_SSE_I387)"
4740   "#"
4741   [(set_attr "type" "fmov,multi")
4742    (set_attr "mode" "<MODE>")
4743    (set_attr "unit" "*,i387")
4744    (set_attr "fp_int_src" "true")])
4745
4746 (define_insn "*floathi<mode>2_i387"
4747   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4748         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4749   "TARGET_80387
4750    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4751        || TARGET_MIX_SSE_I387)"
4752   "fild%Z1\t%1"
4753   [(set_attr "type" "fmov")
4754    (set_attr "mode" "<MODE>")
4755    (set_attr "fp_int_src" "true")])
4756
4757 (define_split
4758   [(set (match_operand:X87MODEF 0 "register_operand" "")
4759         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4760    (clobber (match_operand:HI 2 "memory_operand" ""))]
4761   "TARGET_80387
4762    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4763        || TARGET_MIX_SSE_I387)
4764    && reload_completed"
4765   [(set (match_dup 2) (match_dup 1))
4766    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4767
4768 (define_split
4769   [(set (match_operand:X87MODEF 0 "register_operand" "")
4770         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4771    (clobber (match_operand:HI 2 "memory_operand" ""))]
4772    "TARGET_80387
4773     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4774         || TARGET_MIX_SSE_I387)
4775     && reload_completed"
4776   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4777
4778 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4779   [(set (match_operand:X87MODEF 0 "register_operand" "")
4780         (float:X87MODEF
4781           (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4782   "TARGET_80387
4783    || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4784        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4785 {
4786   if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4787         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4788       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4789     {
4790       rtx reg = gen_reg_rtx (XFmode);
4791       rtx (*insn)(rtx, rtx);
4792
4793       emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4794
4795       if (<X87MODEF:MODE>mode == SFmode)
4796         insn = gen_truncxfsf2;
4797       else if (<X87MODEF:MODE>mode == DFmode)
4798         insn = gen_truncxfdf2;
4799       else
4800         gcc_unreachable ();
4801
4802       emit_insn (insn (operands[0], reg));
4803       DONE;
4804     }
4805 })
4806
4807 ;; Pre-reload splitter to add memory clobber to the pattern.
4808 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4809   [(set (match_operand:X87MODEF 0 "register_operand" "")
4810         (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4811   "((TARGET_80387
4812      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4813      && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4814            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4815          || TARGET_MIX_SSE_I387))
4816     || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4817         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4818         && ((<SWI48x:MODE>mode == SImode
4819              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4820              && optimize_function_for_speed_p (cfun)
4821              && flag_trapping_math)
4822             || !(TARGET_INTER_UNIT_CONVERSIONS
4823                  || optimize_function_for_size_p (cfun)))))
4824    && can_create_pseudo_p ()"
4825   "#"
4826   "&& 1"
4827   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4828               (clobber (match_dup 2))])]
4829 {
4830   operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4831
4832   /* Avoid store forwarding (partial memory) stall penalty
4833      by passing DImode value through XMM registers.  */
4834   if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4835       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4836       && optimize_function_for_speed_p (cfun))
4837     {
4838       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4839                                                             operands[1],
4840                                                             operands[2]));
4841       DONE;
4842     }
4843 })
4844
4845 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4846   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4847         (float:MODEF
4848           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4849    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4850   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4851    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4852   "#"
4853   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4854    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4855    (set_attr "unit" "*,i387,*,*,*")
4856    (set_attr "athlon_decode" "*,*,double,direct,double")
4857    (set_attr "amdfam10_decode" "*,*,vector,double,double")
4858    (set_attr "bdver1_decode" "*,*,double,direct,double")
4859    (set_attr "fp_int_src" "true")])
4860
4861 (define_insn "*floatsi<mode>2_vector_mixed"
4862   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4863         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4864   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4865    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4866   "@
4867    fild%Z1\t%1
4868    #"
4869   [(set_attr "type" "fmov,sseicvt")
4870    (set_attr "mode" "<MODE>,<ssevecmode>")
4871    (set_attr "unit" "i387,*")
4872    (set_attr "athlon_decode" "*,direct")
4873    (set_attr "amdfam10_decode" "*,double")
4874    (set_attr "bdver1_decode" "*,direct")
4875    (set_attr "fp_int_src" "true")])
4876
4877 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4878   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4879         (float:MODEF
4880           (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4881    (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4882   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4883    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4884   "#"
4885   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4886    (set_attr "mode" "<MODEF:MODE>")
4887    (set_attr "unit" "*,i387,*,*")
4888    (set_attr "athlon_decode" "*,*,double,direct")
4889    (set_attr "amdfam10_decode" "*,*,vector,double")
4890    (set_attr "bdver1_decode" "*,*,double,direct")
4891    (set_attr "fp_int_src" "true")])
4892
4893 (define_split
4894   [(set (match_operand:MODEF 0 "register_operand" "")
4895         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4896    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4897   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4898    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4899    && TARGET_INTER_UNIT_CONVERSIONS
4900    && reload_completed
4901    && (SSE_REG_P (operands[0])
4902        || (GET_CODE (operands[0]) == SUBREG
4903            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4904   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4905
4906 (define_split
4907   [(set (match_operand:MODEF 0 "register_operand" "")
4908         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4909    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4910   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4911    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4912    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4913    && reload_completed
4914    && (SSE_REG_P (operands[0])
4915        || (GET_CODE (operands[0]) == SUBREG
4916            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4917   [(set (match_dup 2) (match_dup 1))
4918    (set (match_dup 0) (float:MODEF (match_dup 2)))])
4919
4920 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4921   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4922         (float:MODEF
4923           (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4924   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4925    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4926    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4927   "@
4928    fild%Z1\t%1
4929    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4930    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4931   [(set_attr "type" "fmov,sseicvt,sseicvt")
4932    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4933    (set_attr "mode" "<MODEF:MODE>")
4934    (set (attr "prefix_rex")
4935      (if_then_else
4936        (and (eq_attr "prefix" "maybe_vex")
4937             (match_test "<SWI48x:MODE>mode == DImode"))
4938        (const_string "1")
4939        (const_string "*")))
4940    (set_attr "unit" "i387,*,*")
4941    (set_attr "athlon_decode" "*,double,direct")
4942    (set_attr "amdfam10_decode" "*,vector,double")
4943    (set_attr "bdver1_decode" "*,double,direct")
4944    (set_attr "fp_int_src" "true")])
4945
4946 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4947   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4948         (float:MODEF
4949           (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4950   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4951    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4952    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4953   "@
4954    fild%Z1\t%1
4955    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4956   [(set_attr "type" "fmov,sseicvt")
4957    (set_attr "prefix" "orig,maybe_vex")
4958    (set_attr "mode" "<MODEF:MODE>")
4959    (set (attr "prefix_rex")
4960      (if_then_else
4961        (and (eq_attr "prefix" "maybe_vex")
4962             (match_test "<SWI48x:MODE>mode == DImode"))
4963        (const_string "1")
4964        (const_string "*")))
4965    (set_attr "athlon_decode" "*,direct")
4966    (set_attr "amdfam10_decode" "*,double")
4967    (set_attr "bdver1_decode" "*,direct")
4968    (set_attr "fp_int_src" "true")])
4969
4970 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4971   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4972         (float:MODEF
4973           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4974    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4975   "TARGET_SSE2 && TARGET_SSE_MATH
4976    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4977   "#"
4978   [(set_attr "type" "sseicvt")
4979    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4980    (set_attr "athlon_decode" "double,direct,double")
4981    (set_attr "amdfam10_decode" "vector,double,double")
4982    (set_attr "bdver1_decode" "double,direct,double")
4983    (set_attr "fp_int_src" "true")])
4984
4985 (define_insn "*floatsi<mode>2_vector_sse"
4986   [(set (match_operand:MODEF 0 "register_operand" "=x")
4987         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4988   "TARGET_SSE2 && TARGET_SSE_MATH
4989    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4990   "#"
4991   [(set_attr "type" "sseicvt")
4992    (set_attr "mode" "<MODE>")
4993    (set_attr "athlon_decode" "direct")
4994    (set_attr "amdfam10_decode" "double")
4995    (set_attr "bdver1_decode" "direct")
4996    (set_attr "fp_int_src" "true")])
4997
4998 (define_split
4999   [(set (match_operand:MODEF 0 "register_operand" "")
5000         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5001    (clobber (match_operand:SI 2 "memory_operand" ""))]
5002   "TARGET_SSE2 && TARGET_SSE_MATH
5003    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5004    && reload_completed
5005    && (SSE_REG_P (operands[0])
5006        || (GET_CODE (operands[0]) == SUBREG
5007            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5008   [(const_int 0)]
5009 {
5010   rtx op1 = operands[1];
5011
5012   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5013                                      <MODE>mode, 0);
5014   if (GET_CODE (op1) == SUBREG)
5015     op1 = SUBREG_REG (op1);
5016
5017   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5018     {
5019       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5020       emit_insn (gen_sse2_loadld (operands[4],
5021                                   CONST0_RTX (V4SImode), operands[1]));
5022     }
5023   /* We can ignore possible trapping value in the
5024      high part of SSE register for non-trapping math. */
5025   else if (SSE_REG_P (op1) && !flag_trapping_math)
5026     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5027   else
5028     {
5029       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5030       emit_move_insn (operands[2], operands[1]);
5031       emit_insn (gen_sse2_loadld (operands[4],
5032                                   CONST0_RTX (V4SImode), operands[2]));
5033     }
5034   if (<ssevecmode>mode == V4SFmode)
5035     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5036   else
5037     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5038   DONE;
5039 })
5040
5041 (define_split
5042   [(set (match_operand:MODEF 0 "register_operand" "")
5043         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5044    (clobber (match_operand:SI 2 "memory_operand" ""))]
5045   "TARGET_SSE2 && TARGET_SSE_MATH
5046    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5047    && reload_completed
5048    && (SSE_REG_P (operands[0])
5049        || (GET_CODE (operands[0]) == SUBREG
5050            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5051   [(const_int 0)]
5052 {
5053   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5054                                      <MODE>mode, 0);
5055   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5056
5057   emit_insn (gen_sse2_loadld (operands[4],
5058                               CONST0_RTX (V4SImode), operands[1]));
5059   if (<ssevecmode>mode == V4SFmode)
5060     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5061   else
5062     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5063   DONE;
5064 })
5065
5066 (define_split
5067   [(set (match_operand:MODEF 0 "register_operand" "")
5068         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5069   "TARGET_SSE2 && TARGET_SSE_MATH
5070    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5071    && reload_completed
5072    && (SSE_REG_P (operands[0])
5073        || (GET_CODE (operands[0]) == SUBREG
5074            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5075   [(const_int 0)]
5076 {
5077   rtx op1 = operands[1];
5078
5079   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5080                                      <MODE>mode, 0);
5081   if (GET_CODE (op1) == SUBREG)
5082     op1 = SUBREG_REG (op1);
5083
5084   if (GENERAL_REG_P (op1))
5085     {
5086       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5087       if (TARGET_INTER_UNIT_MOVES)
5088         emit_insn (gen_sse2_loadld (operands[4],
5089                                     CONST0_RTX (V4SImode), operands[1]));
5090       else
5091         {
5092           operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5093                                               operands[1]);
5094           emit_insn (gen_sse2_loadld (operands[4],
5095                                       CONST0_RTX (V4SImode), operands[5]));
5096           ix86_free_from_memory (GET_MODE (operands[1]));
5097         }
5098     }
5099   /* We can ignore possible trapping value in the
5100      high part of SSE register for non-trapping math. */
5101   else if (SSE_REG_P (op1) && !flag_trapping_math)
5102     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5103   else
5104     gcc_unreachable ();
5105   if (<ssevecmode>mode == V4SFmode)
5106     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5107   else
5108     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5109   DONE;
5110 })
5111
5112 (define_split
5113   [(set (match_operand:MODEF 0 "register_operand" "")
5114         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5115   "TARGET_SSE2 && TARGET_SSE_MATH
5116    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5117    && reload_completed
5118    && (SSE_REG_P (operands[0])
5119        || (GET_CODE (operands[0]) == SUBREG
5120            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5121   [(const_int 0)]
5122 {
5123   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5124                                      <MODE>mode, 0);
5125   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5126
5127   emit_insn (gen_sse2_loadld (operands[4],
5128                               CONST0_RTX (V4SImode), operands[1]));
5129   if (<ssevecmode>mode == V4SFmode)
5130     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5131   else
5132     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5133   DONE;
5134 })
5135
5136 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5137   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5138         (float:MODEF
5139           (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5140   (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5141   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5142    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5143   "#"
5144   [(set_attr "type" "sseicvt")
5145    (set_attr "mode" "<MODEF:MODE>")
5146    (set_attr "athlon_decode" "double,direct")
5147    (set_attr "amdfam10_decode" "vector,double")
5148    (set_attr "bdver1_decode" "double,direct")
5149    (set_attr "fp_int_src" "true")])
5150
5151 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5152   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5153         (float:MODEF
5154           (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5155   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5156    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5157    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5158   "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5159   [(set_attr "type" "sseicvt")
5160    (set_attr "prefix" "maybe_vex")
5161    (set_attr "mode" "<MODEF:MODE>")
5162    (set (attr "prefix_rex")
5163      (if_then_else
5164        (and (eq_attr "prefix" "maybe_vex")
5165             (match_test "<SWI48x:MODE>mode == DImode"))
5166        (const_string "1")
5167        (const_string "*")))
5168    (set_attr "athlon_decode" "double,direct")
5169    (set_attr "amdfam10_decode" "vector,double")
5170    (set_attr "bdver1_decode" "double,direct")
5171    (set_attr "fp_int_src" "true")])
5172
5173 (define_split
5174   [(set (match_operand:MODEF 0 "register_operand" "")
5175         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5176    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5177   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5178    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5179    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5180    && reload_completed
5181    && (SSE_REG_P (operands[0])
5182        || (GET_CODE (operands[0]) == SUBREG
5183            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5184   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5185
5186 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5187   [(set (match_operand:MODEF 0 "register_operand" "=x")
5188         (float:MODEF
5189           (match_operand:SWI48x 1 "memory_operand" "m")))]
5190   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5191    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5192    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5193   "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5194   [(set_attr "type" "sseicvt")
5195    (set_attr "prefix" "maybe_vex")
5196    (set_attr "mode" "<MODEF:MODE>")
5197    (set (attr "prefix_rex")
5198      (if_then_else
5199        (and (eq_attr "prefix" "maybe_vex")
5200             (match_test "<SWI48x:MODE>mode == DImode"))
5201        (const_string "1")
5202        (const_string "*")))
5203    (set_attr "athlon_decode" "direct")
5204    (set_attr "amdfam10_decode" "double")
5205    (set_attr "bdver1_decode" "direct")
5206    (set_attr "fp_int_src" "true")])
5207
5208 (define_split
5209   [(set (match_operand:MODEF 0 "register_operand" "")
5210         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5211    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5212   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5213    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5214    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5215    && reload_completed
5216    && (SSE_REG_P (operands[0])
5217        || (GET_CODE (operands[0]) == SUBREG
5218            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5219   [(set (match_dup 2) (match_dup 1))
5220    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5221
5222 (define_split
5223   [(set (match_operand:MODEF 0 "register_operand" "")
5224         (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5225    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5226   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5227    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5228    && reload_completed
5229    && (SSE_REG_P (operands[0])
5230        || (GET_CODE (operands[0]) == SUBREG
5231            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5232   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5233
5234 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5235   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5236         (float:X87MODEF
5237           (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5238   (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5239   "TARGET_80387
5240    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5241   "@
5242    fild%Z1\t%1
5243    #"
5244   [(set_attr "type" "fmov,multi")
5245    (set_attr "mode" "<X87MODEF:MODE>")
5246    (set_attr "unit" "*,i387")
5247    (set_attr "fp_int_src" "true")])
5248
5249 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5250   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5251         (float:X87MODEF
5252           (match_operand:SWI48x 1 "memory_operand" "m")))]
5253   "TARGET_80387
5254    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5255   "fild%Z1\t%1"
5256   [(set_attr "type" "fmov")
5257    (set_attr "mode" "<X87MODEF:MODE>")
5258    (set_attr "fp_int_src" "true")])
5259
5260 (define_split
5261   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5262         (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5263    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5264   "TARGET_80387
5265    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5266    && reload_completed"
5267   [(set (match_dup 2) (match_dup 1))
5268    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5269
5270 (define_split
5271   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5272         (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5273    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5274   "TARGET_80387
5275    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5276    && reload_completed"
5277   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5278
5279 ;; Avoid store forwarding (partial memory) stall penalty
5280 ;; by passing DImode value through XMM registers.  */
5281
5282 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5283   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5284         (float:X87MODEF
5285           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5286    (clobber (match_scratch:V4SI 3 "=X,x"))
5287    (clobber (match_scratch:V4SI 4 "=X,x"))
5288    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5289   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5290    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5291    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5292   "#"
5293   [(set_attr "type" "multi")
5294    (set_attr "mode" "<X87MODEF:MODE>")
5295    (set_attr "unit" "i387")
5296    (set_attr "fp_int_src" "true")])
5297
5298 (define_split
5299   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5300         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5301    (clobber (match_scratch:V4SI 3 ""))
5302    (clobber (match_scratch:V4SI 4 ""))
5303    (clobber (match_operand:DI 2 "memory_operand" ""))]
5304   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5305    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5306    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5307    && reload_completed"
5308   [(set (match_dup 2) (match_dup 3))
5309    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5310 {
5311   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5312      Assemble the 64-bit DImode value in an xmm register.  */
5313   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5314                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5315   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5316                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5317   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5318                                          operands[4]));
5319
5320   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5321 })
5322
5323 (define_split
5324   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5325         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5326    (clobber (match_scratch:V4SI 3 ""))
5327    (clobber (match_scratch:V4SI 4 ""))
5328    (clobber (match_operand:DI 2 "memory_operand" ""))]
5329   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5330    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5331    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5332    && reload_completed"
5333   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5334
5335 ;; Avoid store forwarding (partial memory) stall penalty by extending
5336 ;; SImode value to DImode through XMM register instead of pushing two
5337 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5338 ;; targets benefit from this optimization. Also note that fild
5339 ;; loads from memory only.
5340
5341 (define_insn "*floatunssi<mode>2_1"
5342   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5343         (unsigned_float:X87MODEF
5344           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5345    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5346    (clobber (match_scratch:SI 3 "=X,x"))]
5347   "!TARGET_64BIT
5348    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5349    && TARGET_SSE"
5350   "#"
5351   [(set_attr "type" "multi")
5352    (set_attr "mode" "<MODE>")])
5353
5354 (define_split
5355   [(set (match_operand:X87MODEF 0 "register_operand" "")
5356         (unsigned_float:X87MODEF
5357           (match_operand:SI 1 "register_operand" "")))
5358    (clobber (match_operand:DI 2 "memory_operand" ""))
5359    (clobber (match_scratch:SI 3 ""))]
5360   "!TARGET_64BIT
5361    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5362    && TARGET_SSE
5363    && reload_completed"
5364   [(set (match_dup 2) (match_dup 1))
5365    (set (match_dup 0)
5366         (float:X87MODEF (match_dup 2)))]
5367   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5368
5369 (define_split
5370   [(set (match_operand:X87MODEF 0 "register_operand" "")
5371         (unsigned_float:X87MODEF
5372           (match_operand:SI 1 "memory_operand" "")))
5373    (clobber (match_operand:DI 2 "memory_operand" ""))
5374    (clobber (match_scratch:SI 3 ""))]
5375   "!TARGET_64BIT
5376    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5377    && TARGET_SSE
5378    && reload_completed"
5379   [(set (match_dup 2) (match_dup 3))
5380    (set (match_dup 0)
5381         (float:X87MODEF (match_dup 2)))]
5382 {
5383   emit_move_insn (operands[3], operands[1]);
5384   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5385 })
5386
5387 (define_expand "floatunssi<mode>2"
5388   [(parallel
5389      [(set (match_operand:X87MODEF 0 "register_operand" "")
5390            (unsigned_float:X87MODEF
5391              (match_operand:SI 1 "nonimmediate_operand" "")))
5392       (clobber (match_dup 2))
5393       (clobber (match_scratch:SI 3 ""))])]
5394   "!TARGET_64BIT
5395    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5396         && TARGET_SSE)
5397        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5398 {
5399   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5400     {
5401       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5402       DONE;
5403     }
5404   else
5405     operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5406 })
5407
5408 (define_expand "floatunsdisf2"
5409   [(use (match_operand:SF 0 "register_operand" ""))
5410    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5411   "TARGET_64BIT && TARGET_SSE_MATH"
5412   "x86_emit_floatuns (operands); DONE;")
5413
5414 (define_expand "floatunsdidf2"
5415   [(use (match_operand:DF 0 "register_operand" ""))
5416    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5417   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5418    && TARGET_SSE2 && TARGET_SSE_MATH"
5419 {
5420   if (TARGET_64BIT)
5421     x86_emit_floatuns (operands);
5422   else
5423     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5424   DONE;
5425 })
5426 \f
5427 ;; Load effective address instructions
5428
5429 (define_insn_and_split "*lea<mode>"
5430   [(set (match_operand:SWI48 0 "register_operand" "=r")
5431         (match_operand:SWI48 1 "lea_address_operand" "p"))]
5432   ""
5433 {
5434   rtx addr = operands[1];
5435
5436   if (SImode_address_operand (addr, VOIDmode))
5437     {
5438       gcc_assert (TARGET_64BIT);
5439       return "lea{l}\t{%E1, %k0|%k0, %E1}";
5440     }
5441   else 
5442     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5443 }
5444   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5445   [(const_int 0)]
5446 {
5447   ix86_split_lea_for_addr (operands, <MODE>mode);
5448   DONE;
5449 }
5450   [(set_attr "type" "lea")
5451    (set (attr "mode")
5452      (if_then_else
5453        (match_operand 1 "SImode_address_operand")
5454        (const_string "SI")
5455        (const_string "<MODE>")))])
5456 \f
5457 ;; Add instructions
5458
5459 (define_expand "add<mode>3"
5460   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5461         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5462                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5463   ""
5464   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5465
5466 (define_insn_and_split "*add<dwi>3_doubleword"
5467   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5468         (plus:<DWI>
5469           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5470           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5471    (clobber (reg:CC FLAGS_REG))]
5472   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5473   "#"
5474   "reload_completed"
5475   [(parallel [(set (reg:CC FLAGS_REG)
5476                    (unspec:CC [(match_dup 1) (match_dup 2)]
5477                               UNSPEC_ADD_CARRY))
5478               (set (match_dup 0)
5479                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5480    (parallel [(set (match_dup 3)
5481                    (plus:DWIH
5482                      (match_dup 4)
5483                      (plus:DWIH
5484                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5485                        (match_dup 5))))
5486               (clobber (reg:CC FLAGS_REG))])]
5487   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5488
5489 (define_insn "*add<mode>3_cc"
5490   [(set (reg:CC FLAGS_REG)
5491         (unspec:CC
5492           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5493            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5494           UNSPEC_ADD_CARRY))
5495    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5496         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5497   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5498   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5499   [(set_attr "type" "alu")
5500    (set_attr "mode" "<MODE>")])
5501
5502 (define_insn "addqi3_cc"
5503   [(set (reg:CC FLAGS_REG)
5504         (unspec:CC
5505           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5506            (match_operand:QI 2 "general_operand" "qn,qm")]
5507           UNSPEC_ADD_CARRY))
5508    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5509         (plus:QI (match_dup 1) (match_dup 2)))]
5510   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5511   "add{b}\t{%2, %0|%0, %2}"
5512   [(set_attr "type" "alu")
5513    (set_attr "mode" "QI")])
5514
5515 (define_insn "*add<mode>_1"
5516   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5517         (plus:SWI48
5518           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5519           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5520    (clobber (reg:CC FLAGS_REG))]
5521   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5522 {
5523   switch (get_attr_type (insn))
5524     {
5525     case TYPE_LEA:
5526       return "#";
5527
5528     case TYPE_INCDEC:
5529       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5530       if (operands[2] == const1_rtx)
5531         return "inc{<imodesuffix>}\t%0";
5532       else
5533         {
5534           gcc_assert (operands[2] == constm1_rtx);
5535           return "dec{<imodesuffix>}\t%0";
5536         }
5537
5538     default:
5539       /* For most processors, ADD is faster than LEA.  This alternative
5540          was added to use ADD as much as possible.  */
5541       if (which_alternative == 2)
5542         {
5543           rtx tmp;
5544           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5545         }
5546         
5547       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5548       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5549         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5550
5551       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5552     }
5553 }
5554   [(set (attr "type")
5555      (cond [(eq_attr "alternative" "3")
5556               (const_string "lea")
5557             (match_operand:SWI48 2 "incdec_operand" "")
5558               (const_string "incdec")
5559            ]
5560            (const_string "alu")))
5561    (set (attr "length_immediate")
5562       (if_then_else
5563         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5564         (const_string "1")
5565         (const_string "*")))
5566    (set_attr "mode" "<MODE>")])
5567
5568 ;; It may seem that nonimmediate operand is proper one for operand 1.
5569 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5570 ;; we take care in ix86_binary_operator_ok to not allow two memory
5571 ;; operands so proper swapping will be done in reload.  This allow
5572 ;; patterns constructed from addsi_1 to match.
5573
5574 (define_insn "addsi_1_zext"
5575   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5576         (zero_extend:DI
5577           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5578                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5579    (clobber (reg:CC FLAGS_REG))]
5580   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5581 {
5582   switch (get_attr_type (insn))
5583     {
5584     case TYPE_LEA:
5585       return "#";
5586
5587     case TYPE_INCDEC:
5588       if (operands[2] == const1_rtx)
5589         return "inc{l}\t%k0";
5590       else
5591         {
5592           gcc_assert (operands[2] == constm1_rtx);
5593           return "dec{l}\t%k0";
5594         }
5595
5596     default:
5597       /* For most processors, ADD is faster than LEA.  This alternative
5598          was added to use ADD as much as possible.  */
5599       if (which_alternative == 1)
5600         {
5601           rtx tmp;
5602           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5603         }
5604
5605       if (x86_maybe_negate_const_int (&operands[2], SImode))
5606         return "sub{l}\t{%2, %k0|%k0, %2}";
5607
5608       return "add{l}\t{%2, %k0|%k0, %2}";
5609     }
5610 }
5611   [(set (attr "type")
5612      (cond [(eq_attr "alternative" "2")
5613               (const_string "lea")
5614             (match_operand:SI 2 "incdec_operand" "")
5615               (const_string "incdec")
5616            ]
5617            (const_string "alu")))
5618    (set (attr "length_immediate")
5619       (if_then_else
5620         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5621         (const_string "1")
5622         (const_string "*")))
5623    (set_attr "mode" "SI")])
5624
5625 (define_insn "*addhi_1"
5626   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5627         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5628                  (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5629    (clobber (reg:CC FLAGS_REG))]
5630   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5631 {
5632   switch (get_attr_type (insn))
5633     {
5634     case TYPE_LEA:
5635       return "#";
5636
5637     case TYPE_INCDEC:
5638       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5639       if (operands[2] == const1_rtx)
5640         return "inc{w}\t%0";
5641       else
5642         {
5643           gcc_assert (operands[2] == constm1_rtx);
5644           return "dec{w}\t%0";
5645         }
5646
5647     default:
5648       /* For most processors, ADD is faster than LEA.  This alternative
5649          was added to use ADD as much as possible.  */
5650       if (which_alternative == 2)
5651         {
5652           rtx tmp;
5653           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5654         }
5655
5656       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5657       if (x86_maybe_negate_const_int (&operands[2], HImode))
5658         return "sub{w}\t{%2, %0|%0, %2}";
5659
5660       return "add{w}\t{%2, %0|%0, %2}";
5661     }
5662 }
5663   [(set (attr "type")
5664      (cond [(eq_attr "alternative" "3")
5665               (const_string "lea")
5666             (match_operand:HI 2 "incdec_operand" "")
5667               (const_string "incdec")
5668            ]
5669            (const_string "alu")))
5670    (set (attr "length_immediate")
5671       (if_then_else
5672         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5673         (const_string "1")
5674         (const_string "*")))
5675    (set_attr "mode" "HI,HI,HI,SI")])
5676
5677 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5678 (define_insn "*addqi_1"
5679   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5680         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5681                  (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5682    (clobber (reg:CC FLAGS_REG))]
5683   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5684 {
5685   bool widen = (which_alternative == 3 || which_alternative == 4);
5686
5687   switch (get_attr_type (insn))
5688     {
5689     case TYPE_LEA:
5690       return "#";
5691
5692     case TYPE_INCDEC:
5693       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5694       if (operands[2] == const1_rtx)
5695         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5696       else
5697         {
5698           gcc_assert (operands[2] == constm1_rtx);
5699           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5700         }
5701
5702     default:
5703       /* For most processors, ADD is faster than LEA.  These alternatives
5704          were added to use ADD as much as possible.  */
5705       if (which_alternative == 2 || which_alternative == 4)
5706         {
5707           rtx tmp;
5708           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5709         }
5710
5711       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5712       if (x86_maybe_negate_const_int (&operands[2], QImode))
5713         {
5714           if (widen)
5715             return "sub{l}\t{%2, %k0|%k0, %2}";
5716           else
5717             return "sub{b}\t{%2, %0|%0, %2}";
5718         }
5719       if (widen)
5720         return "add{l}\t{%k2, %k0|%k0, %k2}";
5721       else
5722         return "add{b}\t{%2, %0|%0, %2}";
5723     }
5724 }
5725   [(set (attr "type")
5726      (cond [(eq_attr "alternative" "5")
5727               (const_string "lea")
5728             (match_operand:QI 2 "incdec_operand" "")
5729               (const_string "incdec")
5730            ]
5731            (const_string "alu")))
5732    (set (attr "length_immediate")
5733       (if_then_else
5734         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5735         (const_string "1")
5736         (const_string "*")))
5737    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5738
5739 (define_insn "*addqi_1_slp"
5740   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5741         (plus:QI (match_dup 0)
5742                  (match_operand:QI 1 "general_operand" "qn,qm")))
5743    (clobber (reg:CC FLAGS_REG))]
5744   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5745    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5746 {
5747   switch (get_attr_type (insn))
5748     {
5749     case TYPE_INCDEC:
5750       if (operands[1] == const1_rtx)
5751         return "inc{b}\t%0";
5752       else
5753         {
5754           gcc_assert (operands[1] == constm1_rtx);
5755           return "dec{b}\t%0";
5756         }
5757
5758     default:
5759       if (x86_maybe_negate_const_int (&operands[1], QImode))
5760         return "sub{b}\t{%1, %0|%0, %1}";
5761
5762       return "add{b}\t{%1, %0|%0, %1}";
5763     }
5764 }
5765   [(set (attr "type")
5766      (if_then_else (match_operand:QI 1 "incdec_operand" "")
5767         (const_string "incdec")
5768         (const_string "alu1")))
5769    (set (attr "memory")
5770      (if_then_else (match_operand 1 "memory_operand" "")
5771         (const_string "load")
5772         (const_string "none")))
5773    (set_attr "mode" "QI")])
5774
5775 ;; Split non destructive adds if we cannot use lea.
5776 (define_split
5777   [(set (match_operand:SWI48 0 "register_operand" "")
5778         (plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5779               (match_operand:SWI48 2 "nonmemory_operand" "")))
5780    (clobber (reg:CC FLAGS_REG))]
5781   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5782   [(set (match_dup 0) (match_dup 1))
5783    (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5784               (clobber (reg:CC FLAGS_REG))])])
5785
5786 ;; Convert add to the lea pattern to avoid flags dependency.
5787 (define_split
5788   [(set (match_operand:SWI 0 "register_operand" "")
5789         (plus:SWI (match_operand:SWI 1 "register_operand" "")
5790                   (match_operand:SWI 2 "<nonmemory_operand>" "")))
5791    (clobber (reg:CC FLAGS_REG))]
5792   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5793   [(const_int 0)]
5794 {
5795   enum machine_mode mode = <MODE>mode;
5796   rtx pat;
5797
5798   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5799     { 
5800       mode = SImode; 
5801       operands[0] = gen_lowpart (mode, operands[0]);
5802       operands[1] = gen_lowpart (mode, operands[1]);
5803       operands[2] = gen_lowpart (mode, operands[2]);
5804     }
5805
5806   pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5807
5808   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5809   DONE;
5810 })
5811
5812 ;; Convert add to the lea pattern to avoid flags dependency.
5813 (define_split
5814   [(set (match_operand:DI 0 "register_operand" "")
5815         (zero_extend:DI
5816           (plus:SI (match_operand:SI 1 "register_operand" "")
5817                    (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5818    (clobber (reg:CC FLAGS_REG))]
5819   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5820   [(set (match_dup 0)
5821         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5822
5823 (define_insn "*add<mode>_2"
5824   [(set (reg FLAGS_REG)
5825         (compare
5826           (plus:SWI
5827             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5828             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5829           (const_int 0)))
5830    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5831         (plus:SWI (match_dup 1) (match_dup 2)))]
5832   "ix86_match_ccmode (insn, CCGOCmode)
5833    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5834 {
5835   switch (get_attr_type (insn))
5836     {
5837     case TYPE_INCDEC:
5838       if (operands[2] == const1_rtx)
5839         return "inc{<imodesuffix>}\t%0";
5840       else
5841         {
5842           gcc_assert (operands[2] == constm1_rtx);
5843           return "dec{<imodesuffix>}\t%0";
5844         }
5845
5846     default:
5847       if (which_alternative == 2)
5848         {
5849           rtx tmp;
5850           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5851         }
5852         
5853       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5854       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5855         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5856
5857       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5858     }
5859 }
5860   [(set (attr "type")
5861      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5862         (const_string "incdec")
5863         (const_string "alu")))
5864    (set (attr "length_immediate")
5865       (if_then_else
5866         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5867         (const_string "1")
5868         (const_string "*")))
5869    (set_attr "mode" "<MODE>")])
5870
5871 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5872 (define_insn "*addsi_2_zext"
5873   [(set (reg FLAGS_REG)
5874         (compare
5875           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5876                    (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5877           (const_int 0)))
5878    (set (match_operand:DI 0 "register_operand" "=r,r")
5879         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5880   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5881    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5882 {
5883   switch (get_attr_type (insn))
5884     {
5885     case TYPE_INCDEC:
5886       if (operands[2] == const1_rtx)
5887         return "inc{l}\t%k0";
5888       else
5889         {
5890           gcc_assert (operands[2] == constm1_rtx);
5891           return "dec{l}\t%k0";
5892         }
5893
5894     default:
5895       if (which_alternative == 1)
5896         {
5897           rtx tmp;
5898           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5899         }
5900
5901       if (x86_maybe_negate_const_int (&operands[2], SImode))
5902         return "sub{l}\t{%2, %k0|%k0, %2}";
5903
5904       return "add{l}\t{%2, %k0|%k0, %2}";
5905     }
5906 }
5907   [(set (attr "type")
5908      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5909         (const_string "incdec")
5910         (const_string "alu")))
5911    (set (attr "length_immediate")
5912       (if_then_else
5913         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5914         (const_string "1")
5915         (const_string "*")))
5916    (set_attr "mode" "SI")])
5917
5918 (define_insn "*add<mode>_3"
5919   [(set (reg FLAGS_REG)
5920         (compare
5921           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5922           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5923    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5924   "ix86_match_ccmode (insn, CCZmode)
5925    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5926 {
5927   switch (get_attr_type (insn))
5928     {
5929     case TYPE_INCDEC:
5930       if (operands[2] == const1_rtx)
5931         return "inc{<imodesuffix>}\t%0";
5932       else
5933         {
5934           gcc_assert (operands[2] == constm1_rtx);
5935           return "dec{<imodesuffix>}\t%0";
5936         }
5937
5938     default:
5939       if (which_alternative == 1)
5940         {
5941           rtx tmp;
5942           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5943         }
5944
5945       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5946       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5947         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5948
5949       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5950     }
5951 }
5952   [(set (attr "type")
5953      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5954         (const_string "incdec")
5955         (const_string "alu")))
5956    (set (attr "length_immediate")
5957       (if_then_else
5958         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5959         (const_string "1")
5960         (const_string "*")))
5961    (set_attr "mode" "<MODE>")])
5962
5963 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5964 (define_insn "*addsi_3_zext"
5965   [(set (reg FLAGS_REG)
5966         (compare
5967           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5968           (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5969    (set (match_operand:DI 0 "register_operand" "=r,r")
5970         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5971   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5972    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5973 {
5974   switch (get_attr_type (insn))
5975     {
5976     case TYPE_INCDEC:
5977       if (operands[2] == const1_rtx)
5978         return "inc{l}\t%k0";
5979       else
5980         {
5981           gcc_assert (operands[2] == constm1_rtx);
5982           return "dec{l}\t%k0";
5983         }
5984
5985     default:
5986       if (which_alternative == 1)
5987         {
5988           rtx tmp;
5989           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5990         }
5991
5992       if (x86_maybe_negate_const_int (&operands[2], SImode))
5993         return "sub{l}\t{%2, %k0|%k0, %2}";
5994
5995       return "add{l}\t{%2, %k0|%k0, %2}";
5996     }
5997 }
5998   [(set (attr "type")
5999      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6000         (const_string "incdec")
6001         (const_string "alu")))
6002    (set (attr "length_immediate")
6003       (if_then_else
6004         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6005         (const_string "1")
6006         (const_string "*")))
6007    (set_attr "mode" "SI")])
6008
6009 ; For comparisons against 1, -1 and 128, we may generate better code
6010 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6011 ; is matched then.  We can't accept general immediate, because for
6012 ; case of overflows,  the result is messed up.
6013 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6014 ; only for comparisons not depending on it.
6015
6016 (define_insn "*adddi_4"
6017   [(set (reg FLAGS_REG)
6018         (compare
6019           (match_operand:DI 1 "nonimmediate_operand" "0")
6020           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6021    (clobber (match_scratch:DI 0 "=rm"))]
6022   "TARGET_64BIT
6023    && ix86_match_ccmode (insn, CCGCmode)"
6024 {
6025   switch (get_attr_type (insn))
6026     {
6027     case TYPE_INCDEC:
6028       if (operands[2] == constm1_rtx)
6029         return "inc{q}\t%0";
6030       else
6031         {
6032           gcc_assert (operands[2] == const1_rtx);
6033           return "dec{q}\t%0";
6034         }
6035
6036     default:
6037       if (x86_maybe_negate_const_int (&operands[2], DImode))
6038         return "add{q}\t{%2, %0|%0, %2}";
6039
6040       return "sub{q}\t{%2, %0|%0, %2}";
6041     }
6042 }
6043   [(set (attr "type")
6044      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6045         (const_string "incdec")
6046         (const_string "alu")))
6047    (set (attr "length_immediate")
6048       (if_then_else
6049         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6050         (const_string "1")
6051         (const_string "*")))
6052    (set_attr "mode" "DI")])
6053
6054 ; For comparisons against 1, -1 and 128, we may generate better code
6055 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6056 ; is matched then.  We can't accept general immediate, because for
6057 ; case of overflows,  the result is messed up.
6058 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6059 ; only for comparisons not depending on it.
6060
6061 (define_insn "*add<mode>_4"
6062   [(set (reg FLAGS_REG)
6063         (compare
6064           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6065           (match_operand:SWI124 2 "const_int_operand" "n")))
6066    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6067   "ix86_match_ccmode (insn, CCGCmode)"
6068 {
6069   switch (get_attr_type (insn))
6070     {
6071     case TYPE_INCDEC:
6072       if (operands[2] == constm1_rtx)
6073         return "inc{<imodesuffix>}\t%0";
6074       else
6075         {
6076           gcc_assert (operands[2] == const1_rtx);
6077           return "dec{<imodesuffix>}\t%0";
6078         }
6079
6080     default:
6081       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6082         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6083
6084       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6085     }
6086 }
6087   [(set (attr "type")
6088      (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6089         (const_string "incdec")
6090         (const_string "alu")))
6091    (set (attr "length_immediate")
6092       (if_then_else
6093         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6094         (const_string "1")
6095         (const_string "*")))
6096    (set_attr "mode" "<MODE>")])
6097
6098 (define_insn "*add<mode>_5"
6099   [(set (reg FLAGS_REG)
6100         (compare
6101           (plus:SWI
6102             (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6103             (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6104           (const_int 0)))
6105    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6106   "ix86_match_ccmode (insn, CCGOCmode)
6107    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6108 {
6109   switch (get_attr_type (insn))
6110     {
6111     case TYPE_INCDEC:
6112       if (operands[2] == const1_rtx)
6113         return "inc{<imodesuffix>}\t%0";
6114       else
6115         {
6116           gcc_assert (operands[2] == constm1_rtx);
6117           return "dec{<imodesuffix>}\t%0";
6118         }
6119
6120     default:
6121       if (which_alternative == 1)
6122         {
6123           rtx tmp;
6124           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6125         }
6126
6127       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6128       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6129         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6130
6131       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6132     }
6133 }
6134   [(set (attr "type")
6135      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6136         (const_string "incdec")
6137         (const_string "alu")))
6138    (set (attr "length_immediate")
6139       (if_then_else
6140         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6141         (const_string "1")
6142         (const_string "*")))
6143    (set_attr "mode" "<MODE>")])
6144
6145 (define_insn "*addqi_ext_1_rex64"
6146   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6147                          (const_int 8)
6148                          (const_int 8))
6149         (plus:SI
6150           (zero_extract:SI
6151             (match_operand 1 "ext_register_operand" "0")
6152             (const_int 8)
6153             (const_int 8))
6154           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6155    (clobber (reg:CC FLAGS_REG))]
6156   "TARGET_64BIT"
6157 {
6158   switch (get_attr_type (insn))
6159     {
6160     case TYPE_INCDEC:
6161       if (operands[2] == const1_rtx)
6162         return "inc{b}\t%h0";
6163       else
6164         {
6165           gcc_assert (operands[2] == constm1_rtx);
6166           return "dec{b}\t%h0";
6167         }
6168
6169     default:
6170       return "add{b}\t{%2, %h0|%h0, %2}";
6171     }
6172 }
6173   [(set (attr "type")
6174      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6175         (const_string "incdec")
6176         (const_string "alu")))
6177    (set_attr "modrm" "1")
6178    (set_attr "mode" "QI")])
6179
6180 (define_insn "addqi_ext_1"
6181   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6182                          (const_int 8)
6183                          (const_int 8))
6184         (plus:SI
6185           (zero_extract:SI
6186             (match_operand 1 "ext_register_operand" "0")
6187             (const_int 8)
6188             (const_int 8))
6189           (match_operand:QI 2 "general_operand" "Qmn")))
6190    (clobber (reg:CC FLAGS_REG))]
6191   "!TARGET_64BIT"
6192 {
6193   switch (get_attr_type (insn))
6194     {
6195     case TYPE_INCDEC:
6196       if (operands[2] == const1_rtx)
6197         return "inc{b}\t%h0";
6198       else
6199         {
6200           gcc_assert (operands[2] == constm1_rtx);
6201           return "dec{b}\t%h0";
6202         }
6203
6204     default:
6205       return "add{b}\t{%2, %h0|%h0, %2}";
6206     }
6207 }
6208   [(set (attr "type")
6209      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6210         (const_string "incdec")
6211         (const_string "alu")))
6212    (set_attr "modrm" "1")
6213    (set_attr "mode" "QI")])
6214
6215 (define_insn "*addqi_ext_2"
6216   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6217                          (const_int 8)
6218                          (const_int 8))
6219         (plus:SI
6220           (zero_extract:SI
6221             (match_operand 1 "ext_register_operand" "%0")
6222             (const_int 8)
6223             (const_int 8))
6224           (zero_extract:SI
6225             (match_operand 2 "ext_register_operand" "Q")
6226             (const_int 8)
6227             (const_int 8))))
6228    (clobber (reg:CC FLAGS_REG))]
6229   ""
6230   "add{b}\t{%h2, %h0|%h0, %h2}"
6231   [(set_attr "type" "alu")
6232    (set_attr "mode" "QI")])
6233
6234 ;; The lea patterns for modes less than 32 bits need to be matched by
6235 ;; several insns converted to real lea by splitters.
6236
6237 (define_insn_and_split "*lea_general_1"
6238   [(set (match_operand 0 "register_operand" "=r")
6239         (plus (plus (match_operand 1 "index_register_operand" "l")
6240                     (match_operand 2 "register_operand" "r"))
6241               (match_operand 3 "immediate_operand" "i")))]
6242   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6243    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6244    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6245    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6246    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6247        || GET_MODE (operands[3]) == VOIDmode)"
6248   "#"
6249   "&& reload_completed"
6250   [(const_int 0)]
6251 {
6252   enum machine_mode mode = SImode;
6253   rtx pat;
6254
6255   operands[0] = gen_lowpart (mode, operands[0]);
6256   operands[1] = gen_lowpart (mode, operands[1]);
6257   operands[2] = gen_lowpart (mode, operands[2]);
6258   operands[3] = gen_lowpart (mode, operands[3]);
6259
6260   pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6261                       operands[3]);
6262
6263   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6264   DONE;
6265 }
6266   [(set_attr "type" "lea")
6267    (set_attr "mode" "SI")])
6268
6269 (define_insn_and_split "*lea_general_2"
6270   [(set (match_operand 0 "register_operand" "=r")
6271         (plus (mult (match_operand 1 "index_register_operand" "l")
6272                     (match_operand 2 "const248_operand" "n"))
6273               (match_operand 3 "nonmemory_operand" "ri")))]
6274   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6275    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6276    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6277    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6278        || GET_MODE (operands[3]) == VOIDmode)"
6279   "#"
6280   "&& reload_completed"
6281   [(const_int 0)]
6282 {
6283   enum machine_mode mode = SImode;
6284   rtx pat;
6285
6286   operands[0] = gen_lowpart (mode, operands[0]);
6287   operands[1] = gen_lowpart (mode, operands[1]);
6288   operands[3] = gen_lowpart (mode, operands[3]);
6289
6290   pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6291                       operands[3]);
6292
6293   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6294   DONE;
6295 }
6296   [(set_attr "type" "lea")
6297    (set_attr "mode" "SI")])
6298
6299 (define_insn_and_split "*lea_general_3"
6300   [(set (match_operand 0 "register_operand" "=r")
6301         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6302                           (match_operand 2 "const248_operand" "n"))
6303                     (match_operand 3 "register_operand" "r"))
6304               (match_operand 4 "immediate_operand" "i")))]
6305   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6306    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6307    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6308    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6309   "#"
6310   "&& reload_completed"
6311   [(const_int 0)]
6312 {
6313   enum machine_mode mode = SImode;
6314   rtx pat;
6315
6316   operands[0] = gen_lowpart (mode, operands[0]);
6317   operands[1] = gen_lowpart (mode, operands[1]);
6318   operands[3] = gen_lowpart (mode, operands[3]);
6319   operands[4] = gen_lowpart (mode, operands[4]);
6320
6321   pat = gen_rtx_PLUS (mode,
6322                       gen_rtx_PLUS (mode,
6323                                     gen_rtx_MULT (mode, operands[1],
6324                                                         operands[2]),
6325                                     operands[3]),
6326                       operands[4]);
6327
6328   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6329   DONE;
6330 }
6331   [(set_attr "type" "lea")
6332    (set_attr "mode" "SI")])
6333
6334 (define_insn_and_split "*lea_general_4"
6335   [(set (match_operand 0 "register_operand" "=r")
6336         (any_or (ashift
6337                   (match_operand 1 "index_register_operand" "l")
6338                   (match_operand 2 "const_int_operand" "n"))
6339                 (match_operand 3 "const_int_operand" "n")))]
6340   "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6341       && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6342     || GET_MODE (operands[0]) == SImode
6343     || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6344    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6345    && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6346    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6347        < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6348   "#"
6349   "&& reload_completed"
6350   [(const_int 0)]
6351 {
6352   enum machine_mode mode = GET_MODE (operands[0]);
6353   rtx pat;
6354
6355   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6356     { 
6357       mode = SImode; 
6358       operands[0] = gen_lowpart (mode, operands[0]);
6359       operands[1] = gen_lowpart (mode, operands[1]);
6360     }
6361
6362   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6363
6364   pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6365                        INTVAL (operands[3]));
6366
6367   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6368   DONE;
6369 }
6370   [(set_attr "type" "lea")
6371    (set (attr "mode")
6372       (if_then_else (match_operand:DI 0 "" "")
6373         (const_string "DI")
6374         (const_string "SI")))])
6375 \f
6376 ;; Subtract instructions
6377
6378 (define_expand "sub<mode>3"
6379   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6380         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6381                      (match_operand:SDWIM 2 "<general_operand>" "")))]
6382   ""
6383   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6384
6385 (define_insn_and_split "*sub<dwi>3_doubleword"
6386   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6387         (minus:<DWI>
6388           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6389           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6390    (clobber (reg:CC FLAGS_REG))]
6391   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6392   "#"
6393   "reload_completed"
6394   [(parallel [(set (reg:CC FLAGS_REG)
6395                    (compare:CC (match_dup 1) (match_dup 2)))
6396               (set (match_dup 0)
6397                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6398    (parallel [(set (match_dup 3)
6399                    (minus:DWIH
6400                      (match_dup 4)
6401                      (plus:DWIH
6402                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6403                        (match_dup 5))))
6404               (clobber (reg:CC FLAGS_REG))])]
6405   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6406
6407 (define_insn "*sub<mode>_1"
6408   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6409         (minus:SWI
6410           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6411           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6412    (clobber (reg:CC FLAGS_REG))]
6413   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6414   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6415   [(set_attr "type" "alu")
6416    (set_attr "mode" "<MODE>")])
6417
6418 (define_insn "*subsi_1_zext"
6419   [(set (match_operand:DI 0 "register_operand" "=r")
6420         (zero_extend:DI
6421           (minus:SI (match_operand:SI 1 "register_operand" "0")
6422                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6423    (clobber (reg:CC FLAGS_REG))]
6424   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6425   "sub{l}\t{%2, %k0|%k0, %2}"
6426   [(set_attr "type" "alu")
6427    (set_attr "mode" "SI")])
6428
6429 (define_insn "*subqi_1_slp"
6430   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6431         (minus:QI (match_dup 0)
6432                   (match_operand:QI 1 "general_operand" "qn,qm")))
6433    (clobber (reg:CC FLAGS_REG))]
6434   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6435    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6436   "sub{b}\t{%1, %0|%0, %1}"
6437   [(set_attr "type" "alu1")
6438    (set_attr "mode" "QI")])
6439
6440 (define_insn "*sub<mode>_2"
6441   [(set (reg FLAGS_REG)
6442         (compare
6443           (minus:SWI
6444             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6445             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6446           (const_int 0)))
6447    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6448         (minus:SWI (match_dup 1) (match_dup 2)))]
6449   "ix86_match_ccmode (insn, CCGOCmode)
6450    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6451   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6452   [(set_attr "type" "alu")
6453    (set_attr "mode" "<MODE>")])
6454
6455 (define_insn "*subsi_2_zext"
6456   [(set (reg FLAGS_REG)
6457         (compare
6458           (minus:SI (match_operand:SI 1 "register_operand" "0")
6459                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6460           (const_int 0)))
6461    (set (match_operand:DI 0 "register_operand" "=r")
6462         (zero_extend:DI
6463           (minus:SI (match_dup 1)
6464                     (match_dup 2))))]
6465   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6466    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6467   "sub{l}\t{%2, %k0|%k0, %2}"
6468   [(set_attr "type" "alu")
6469    (set_attr "mode" "SI")])
6470
6471 (define_insn "*sub<mode>_3"
6472   [(set (reg FLAGS_REG)
6473         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6474                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6475    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6476         (minus:SWI (match_dup 1) (match_dup 2)))]
6477   "ix86_match_ccmode (insn, CCmode)
6478    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6479   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6480   [(set_attr "type" "alu")
6481    (set_attr "mode" "<MODE>")])
6482
6483 (define_insn "*subsi_3_zext"
6484   [(set (reg FLAGS_REG)
6485         (compare (match_operand:SI 1 "register_operand" "0")
6486                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6487    (set (match_operand:DI 0 "register_operand" "=r")
6488         (zero_extend:DI
6489           (minus:SI (match_dup 1)
6490                     (match_dup 2))))]
6491   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6492    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6493   "sub{l}\t{%2, %1|%1, %2}"
6494   [(set_attr "type" "alu")
6495    (set_attr "mode" "SI")])
6496 \f
6497 ;; Add with carry and subtract with borrow
6498
6499 (define_expand "<plusminus_insn><mode>3_carry"
6500   [(parallel
6501     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6502           (plusminus:SWI
6503             (match_operand:SWI 1 "nonimmediate_operand" "")
6504             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6505                        [(match_operand 3 "flags_reg_operand" "")
6506                         (const_int 0)])
6507                       (match_operand:SWI 2 "<general_operand>" ""))))
6508      (clobber (reg:CC FLAGS_REG))])]
6509   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6510
6511 (define_insn "*<plusminus_insn><mode>3_carry"
6512   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6513         (plusminus:SWI
6514           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6515           (plus:SWI
6516             (match_operator 3 "ix86_carry_flag_operator"
6517              [(reg FLAGS_REG) (const_int 0)])
6518             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6519    (clobber (reg:CC FLAGS_REG))]
6520   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6521   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6522   [(set_attr "type" "alu")
6523    (set_attr "use_carry" "1")
6524    (set_attr "pent_pair" "pu")
6525    (set_attr "mode" "<MODE>")])
6526
6527 (define_insn "*addsi3_carry_zext"
6528   [(set (match_operand:DI 0 "register_operand" "=r")
6529         (zero_extend:DI
6530           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6531                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6532                              [(reg FLAGS_REG) (const_int 0)])
6533                             (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6534    (clobber (reg:CC FLAGS_REG))]
6535   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6536   "adc{l}\t{%2, %k0|%k0, %2}"
6537   [(set_attr "type" "alu")
6538    (set_attr "use_carry" "1")
6539    (set_attr "pent_pair" "pu")
6540    (set_attr "mode" "SI")])
6541
6542 (define_insn "*subsi3_carry_zext"
6543   [(set (match_operand:DI 0 "register_operand" "=r")
6544         (zero_extend:DI
6545           (minus:SI (match_operand:SI 1 "register_operand" "0")
6546                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6547                               [(reg FLAGS_REG) (const_int 0)])
6548                              (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6549    (clobber (reg:CC FLAGS_REG))]
6550   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6551   "sbb{l}\t{%2, %k0|%k0, %2}"
6552   [(set_attr "type" "alu")
6553    (set_attr "pent_pair" "pu")
6554    (set_attr "mode" "SI")])
6555 \f
6556 ;; Overflow setting add and subtract instructions
6557
6558 (define_insn "*add<mode>3_cconly_overflow"
6559   [(set (reg:CCC FLAGS_REG)
6560         (compare:CCC
6561           (plus:SWI
6562             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6563             (match_operand:SWI 2 "<general_operand>" "<g>"))
6564           (match_dup 1)))
6565    (clobber (match_scratch:SWI 0 "=<r>"))]
6566   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6567   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6568   [(set_attr "type" "alu")
6569    (set_attr "mode" "<MODE>")])
6570
6571 (define_insn "*sub<mode>3_cconly_overflow"
6572   [(set (reg:CCC FLAGS_REG)
6573         (compare:CCC
6574           (minus:SWI
6575             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6576             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6577           (match_dup 0)))]
6578   ""
6579   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6580   [(set_attr "type" "icmp")
6581    (set_attr "mode" "<MODE>")])
6582
6583 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6584   [(set (reg:CCC FLAGS_REG)
6585         (compare:CCC
6586             (plusminus:SWI
6587                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6588                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6589             (match_dup 1)))
6590    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6591         (plusminus:SWI (match_dup 1) (match_dup 2)))]
6592   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6593   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6594   [(set_attr "type" "alu")
6595    (set_attr "mode" "<MODE>")])
6596
6597 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6598   [(set (reg:CCC FLAGS_REG)
6599         (compare:CCC
6600           (plusminus:SI
6601             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6602             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6603           (match_dup 1)))
6604    (set (match_operand:DI 0 "register_operand" "=r")
6605         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6606   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6607   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6608   [(set_attr "type" "alu")
6609    (set_attr "mode" "SI")])
6610
6611 ;; The patterns that match these are at the end of this file.
6612
6613 (define_expand "<plusminus_insn>xf3"
6614   [(set (match_operand:XF 0 "register_operand" "")
6615         (plusminus:XF
6616           (match_operand:XF 1 "register_operand" "")
6617           (match_operand:XF 2 "register_operand" "")))]
6618   "TARGET_80387")
6619
6620 (define_expand "<plusminus_insn><mode>3"
6621   [(set (match_operand:MODEF 0 "register_operand" "")
6622         (plusminus:MODEF
6623           (match_operand:MODEF 1 "register_operand" "")
6624           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6625   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6626     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6627 \f
6628 ;; Multiply instructions
6629
6630 (define_expand "mul<mode>3"
6631   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6632                    (mult:SWIM248
6633                      (match_operand:SWIM248 1 "register_operand" "")
6634                      (match_operand:SWIM248 2 "<general_operand>" "")))
6635               (clobber (reg:CC FLAGS_REG))])])
6636
6637 (define_expand "mulqi3"
6638   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6639                    (mult:QI
6640                      (match_operand:QI 1 "register_operand" "")
6641                      (match_operand:QI 2 "nonimmediate_operand" "")))
6642               (clobber (reg:CC FLAGS_REG))])]
6643   "TARGET_QIMODE_MATH")
6644
6645 ;; On AMDFAM10
6646 ;; IMUL reg32/64, reg32/64, imm8        Direct
6647 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6648 ;; IMUL reg32/64, reg32/64, imm32       Direct
6649 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6650 ;; IMUL reg32/64, reg32/64              Direct
6651 ;; IMUL reg32/64, mem32/64              Direct
6652 ;;
6653 ;; On BDVER1, all above IMULs use DirectPath
6654
6655 (define_insn "*mul<mode>3_1"
6656   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6657         (mult:SWI48
6658           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6659           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6660    (clobber (reg:CC FLAGS_REG))]
6661   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6662   "@
6663    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6664    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6665    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6666   [(set_attr "type" "imul")
6667    (set_attr "prefix_0f" "0,0,1")
6668    (set (attr "athlon_decode")
6669         (cond [(eq_attr "cpu" "athlon")
6670                   (const_string "vector")
6671                (eq_attr "alternative" "1")
6672                   (const_string "vector")
6673                (and (eq_attr "alternative" "2")
6674                     (match_operand 1 "memory_operand" ""))
6675                   (const_string "vector")]
6676               (const_string "direct")))
6677    (set (attr "amdfam10_decode")
6678         (cond [(and (eq_attr "alternative" "0,1")
6679                     (match_operand 1 "memory_operand" ""))
6680                   (const_string "vector")]
6681               (const_string "direct")))
6682    (set_attr "bdver1_decode" "direct")
6683    (set_attr "mode" "<MODE>")])
6684
6685 (define_insn "*mulsi3_1_zext"
6686   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6687         (zero_extend:DI
6688           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6689                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6690    (clobber (reg:CC FLAGS_REG))]
6691   "TARGET_64BIT
6692    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6693   "@
6694    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6695    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6696    imul{l}\t{%2, %k0|%k0, %2}"
6697   [(set_attr "type" "imul")
6698    (set_attr "prefix_0f" "0,0,1")
6699    (set (attr "athlon_decode")
6700         (cond [(eq_attr "cpu" "athlon")
6701                   (const_string "vector")
6702                (eq_attr "alternative" "1")
6703                   (const_string "vector")
6704                (and (eq_attr "alternative" "2")
6705                     (match_operand 1 "memory_operand" ""))
6706                   (const_string "vector")]
6707               (const_string "direct")))
6708    (set (attr "amdfam10_decode")
6709         (cond [(and (eq_attr "alternative" "0,1")
6710                     (match_operand 1 "memory_operand" ""))
6711                   (const_string "vector")]
6712               (const_string "direct")))
6713    (set_attr "bdver1_decode" "direct")
6714    (set_attr "mode" "SI")])
6715
6716 ;; On AMDFAM10
6717 ;; IMUL reg16, reg16, imm8      VectorPath
6718 ;; IMUL reg16, mem16, imm8      VectorPath
6719 ;; IMUL reg16, reg16, imm16     VectorPath
6720 ;; IMUL reg16, mem16, imm16     VectorPath
6721 ;; IMUL reg16, reg16            Direct
6722 ;; IMUL reg16, mem16            Direct
6723 ;;
6724 ;; On BDVER1, all HI MULs use DoublePath
6725
6726 (define_insn "*mulhi3_1"
6727   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6728         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6729                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6730    (clobber (reg:CC FLAGS_REG))]
6731   "TARGET_HIMODE_MATH
6732    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6733   "@
6734    imul{w}\t{%2, %1, %0|%0, %1, %2}
6735    imul{w}\t{%2, %1, %0|%0, %1, %2}
6736    imul{w}\t{%2, %0|%0, %2}"
6737   [(set_attr "type" "imul")
6738    (set_attr "prefix_0f" "0,0,1")
6739    (set (attr "athlon_decode")
6740         (cond [(eq_attr "cpu" "athlon")
6741                   (const_string "vector")
6742                (eq_attr "alternative" "1,2")
6743                   (const_string "vector")]
6744               (const_string "direct")))
6745    (set (attr "amdfam10_decode")
6746         (cond [(eq_attr "alternative" "0,1")
6747                   (const_string "vector")]
6748               (const_string "direct")))
6749    (set_attr "bdver1_decode" "double")
6750    (set_attr "mode" "HI")])
6751
6752 ;;On AMDFAM10 and BDVER1
6753 ;; MUL reg8     Direct
6754 ;; MUL mem8     Direct
6755
6756 (define_insn "*mulqi3_1"
6757   [(set (match_operand:QI 0 "register_operand" "=a")
6758         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6759                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6760    (clobber (reg:CC FLAGS_REG))]
6761   "TARGET_QIMODE_MATH
6762    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6763   "mul{b}\t%2"
6764   [(set_attr "type" "imul")
6765    (set_attr "length_immediate" "0")
6766    (set (attr "athlon_decode")
6767      (if_then_else (eq_attr "cpu" "athlon")
6768         (const_string "vector")
6769         (const_string "direct")))
6770    (set_attr "amdfam10_decode" "direct")
6771    (set_attr "bdver1_decode" "direct")
6772    (set_attr "mode" "QI")])
6773
6774 (define_expand "<u>mul<mode><dwi>3"
6775   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6776                    (mult:<DWI>
6777                      (any_extend:<DWI>
6778                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
6779                      (any_extend:<DWI>
6780                        (match_operand:DWIH 2 "register_operand" ""))))
6781               (clobber (reg:CC FLAGS_REG))])])
6782
6783 (define_expand "<u>mulqihi3"
6784   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6785                    (mult:HI
6786                      (any_extend:HI
6787                        (match_operand:QI 1 "nonimmediate_operand" ""))
6788                      (any_extend:HI
6789                        (match_operand:QI 2 "register_operand" ""))))
6790               (clobber (reg:CC FLAGS_REG))])]
6791   "TARGET_QIMODE_MATH")
6792
6793 (define_insn "*bmi2_umulditi3_1"
6794   [(set (match_operand:DI 0 "register_operand" "=r")
6795         (mult:DI
6796           (match_operand:DI 2 "nonimmediate_operand" "%d")
6797           (match_operand:DI 3 "nonimmediate_operand" "rm")))
6798    (set (match_operand:DI 1 "register_operand" "=r")
6799         (truncate:DI
6800           (lshiftrt:TI
6801             (mult:TI (zero_extend:TI (match_dup 2))
6802                      (zero_extend:TI (match_dup 3)))
6803             (const_int 64))))]
6804   "TARGET_64BIT && TARGET_BMI2
6805    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6806   "mulx\t{%3, %0, %1|%1, %0, %3}"
6807   [(set_attr "type" "imulx")
6808    (set_attr "prefix" "vex")
6809    (set_attr "mode" "DI")])
6810
6811 (define_insn "*bmi2_umulsidi3_1"
6812   [(set (match_operand:SI 0 "register_operand" "=r")
6813         (mult:SI
6814           (match_operand:SI 2 "nonimmediate_operand" "%d")
6815           (match_operand:SI 3 "nonimmediate_operand" "rm")))
6816    (set (match_operand:SI 1 "register_operand" "=r")
6817         (truncate:SI
6818           (lshiftrt:DI
6819             (mult:DI (zero_extend:DI (match_dup 2))
6820                      (zero_extend:DI (match_dup 3)))
6821             (const_int 32))))]
6822   "!TARGET_64BIT && TARGET_BMI2
6823    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6824   "mulx\t{%3, %0, %1|%1, %0, %3}"
6825   [(set_attr "type" "imulx")
6826    (set_attr "prefix" "vex")
6827    (set_attr "mode" "SI")])
6828
6829 (define_insn "*umul<mode><dwi>3_1"
6830   [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6831         (mult:<DWI>
6832           (zero_extend:<DWI>
6833             (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6834           (zero_extend:<DWI>
6835             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6836    (clobber (reg:CC FLAGS_REG))]
6837   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6838   "@
6839    mul{<imodesuffix>}\t%2
6840    #"
6841   [(set_attr "isa" "*,bmi2")
6842    (set_attr "type" "imul,imulx")
6843    (set_attr "length_immediate" "0,*")
6844    (set (attr "athlon_decode")
6845         (cond [(eq_attr "alternative" "0")
6846                  (if_then_else (eq_attr "cpu" "athlon")
6847                    (const_string "vector")
6848                    (const_string "double"))]
6849               (const_string "*")))
6850    (set_attr "amdfam10_decode" "double,*")
6851    (set_attr "bdver1_decode" "direct,*")
6852    (set_attr "prefix" "orig,vex")
6853    (set_attr "mode" "<MODE>")])
6854
6855 ;; Convert mul to the mulx pattern to avoid flags dependency.
6856 (define_split
6857  [(set (match_operand:<DWI> 0 "register_operand" "")
6858        (mult:<DWI>
6859          (zero_extend:<DWI>
6860            (match_operand:DWIH 1 "register_operand" ""))
6861          (zero_extend:<DWI>
6862            (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6863   (clobber (reg:CC FLAGS_REG))]
6864  "TARGET_BMI2 && reload_completed
6865   && true_regnum (operands[1]) == DX_REG"
6866   [(parallel [(set (match_dup 3)
6867                    (mult:DWIH (match_dup 1) (match_dup 2)))
6868               (set (match_dup 4)
6869                    (truncate:DWIH
6870                      (lshiftrt:<DWI>
6871                        (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6872                                    (zero_extend:<DWI> (match_dup 2)))
6873                        (match_dup 5))))])]
6874 {
6875   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6876
6877   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6878 })
6879
6880 (define_insn "*mul<mode><dwi>3_1"
6881   [(set (match_operand:<DWI> 0 "register_operand" "=A")
6882         (mult:<DWI>
6883           (sign_extend:<DWI>
6884             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6885           (sign_extend:<DWI>
6886             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6887    (clobber (reg:CC FLAGS_REG))]
6888   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6889   "imul{<imodesuffix>}\t%2"
6890   [(set_attr "type" "imul")
6891    (set_attr "length_immediate" "0")
6892    (set (attr "athlon_decode")
6893      (if_then_else (eq_attr "cpu" "athlon")
6894         (const_string "vector")
6895         (const_string "double")))
6896    (set_attr "amdfam10_decode" "double")
6897    (set_attr "bdver1_decode" "direct")
6898    (set_attr "mode" "<MODE>")])
6899
6900 (define_insn "*<u>mulqihi3_1"
6901   [(set (match_operand:HI 0 "register_operand" "=a")
6902         (mult:HI
6903           (any_extend:HI
6904             (match_operand:QI 1 "nonimmediate_operand" "%0"))
6905           (any_extend:HI
6906             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6907    (clobber (reg:CC FLAGS_REG))]
6908   "TARGET_QIMODE_MATH
6909    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6910   "<sgnprefix>mul{b}\t%2"
6911   [(set_attr "type" "imul")
6912    (set_attr "length_immediate" "0")
6913    (set (attr "athlon_decode")
6914      (if_then_else (eq_attr "cpu" "athlon")
6915         (const_string "vector")
6916         (const_string "direct")))
6917    (set_attr "amdfam10_decode" "direct")
6918    (set_attr "bdver1_decode" "direct")
6919    (set_attr "mode" "QI")])
6920
6921 (define_expand "<s>mul<mode>3_highpart"
6922   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6923                    (truncate:SWI48
6924                      (lshiftrt:<DWI>
6925                        (mult:<DWI>
6926                          (any_extend:<DWI>
6927                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
6928                          (any_extend:<DWI>
6929                            (match_operand:SWI48 2 "register_operand" "")))
6930                        (match_dup 4))))
6931               (clobber (match_scratch:SWI48 3 ""))
6932               (clobber (reg:CC FLAGS_REG))])]
6933   ""
6934   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6935
6936 (define_insn "*<s>muldi3_highpart_1"
6937   [(set (match_operand:DI 0 "register_operand" "=d")
6938         (truncate:DI
6939           (lshiftrt:TI
6940             (mult:TI
6941               (any_extend:TI
6942                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6943               (any_extend:TI
6944                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6945             (const_int 64))))
6946    (clobber (match_scratch:DI 3 "=1"))
6947    (clobber (reg:CC FLAGS_REG))]
6948   "TARGET_64BIT
6949    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6950   "<sgnprefix>mul{q}\t%2"
6951   [(set_attr "type" "imul")
6952    (set_attr "length_immediate" "0")
6953    (set (attr "athlon_decode")
6954      (if_then_else (eq_attr "cpu" "athlon")
6955         (const_string "vector")
6956         (const_string "double")))
6957    (set_attr "amdfam10_decode" "double")
6958    (set_attr "bdver1_decode" "direct")
6959    (set_attr "mode" "DI")])
6960
6961 (define_insn "*<s>mulsi3_highpart_1"
6962   [(set (match_operand:SI 0 "register_operand" "=d")
6963         (truncate:SI
6964           (lshiftrt:DI
6965             (mult:DI
6966               (any_extend:DI
6967                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6968               (any_extend:DI
6969                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6970             (const_int 32))))
6971    (clobber (match_scratch:SI 3 "=1"))
6972    (clobber (reg:CC FLAGS_REG))]
6973   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6974   "<sgnprefix>mul{l}\t%2"
6975   [(set_attr "type" "imul")
6976    (set_attr "length_immediate" "0")
6977    (set (attr "athlon_decode")
6978      (if_then_else (eq_attr "cpu" "athlon")
6979         (const_string "vector")
6980         (const_string "double")))
6981    (set_attr "amdfam10_decode" "double")
6982    (set_attr "bdver1_decode" "direct")
6983    (set_attr "mode" "SI")])
6984
6985 (define_insn "*<s>mulsi3_highpart_zext"
6986   [(set (match_operand:DI 0 "register_operand" "=d")
6987         (zero_extend:DI (truncate:SI
6988           (lshiftrt:DI
6989             (mult:DI (any_extend:DI
6990                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
6991                      (any_extend:DI
6992                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
6993             (const_int 32)))))
6994    (clobber (match_scratch:SI 3 "=1"))
6995    (clobber (reg:CC FLAGS_REG))]
6996   "TARGET_64BIT
6997    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6998   "<sgnprefix>mul{l}\t%2"
6999   [(set_attr "type" "imul")
7000    (set_attr "length_immediate" "0")
7001    (set (attr "athlon_decode")
7002      (if_then_else (eq_attr "cpu" "athlon")
7003         (const_string "vector")
7004         (const_string "double")))
7005    (set_attr "amdfam10_decode" "double")
7006    (set_attr "bdver1_decode" "direct")
7007    (set_attr "mode" "SI")])
7008
7009 ;; The patterns that match these are at the end of this file.
7010
7011 (define_expand "mulxf3"
7012   [(set (match_operand:XF 0 "register_operand" "")
7013         (mult:XF (match_operand:XF 1 "register_operand" "")
7014                  (match_operand:XF 2 "register_operand" "")))]
7015   "TARGET_80387")
7016
7017 (define_expand "mul<mode>3"
7018   [(set (match_operand:MODEF 0 "register_operand" "")
7019         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7020                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7021   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7022     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7023 \f
7024 ;; Divide instructions
7025
7026 ;; The patterns that match these are at the end of this file.
7027
7028 (define_expand "divxf3"
7029   [(set (match_operand:XF 0 "register_operand" "")
7030         (div:XF (match_operand:XF 1 "register_operand" "")
7031                 (match_operand:XF 2 "register_operand" "")))]
7032   "TARGET_80387")
7033
7034 (define_expand "divdf3"
7035   [(set (match_operand:DF 0 "register_operand" "")
7036         (div:DF (match_operand:DF 1 "register_operand" "")
7037                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7038    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7039     || (TARGET_SSE2 && TARGET_SSE_MATH)")
7040
7041 (define_expand "divsf3"
7042   [(set (match_operand:SF 0 "register_operand" "")
7043         (div:SF (match_operand:SF 1 "register_operand" "")
7044                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7045   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7046     || TARGET_SSE_MATH"
7047 {
7048   if (TARGET_SSE_MATH
7049       && TARGET_RECIP_DIV
7050       && optimize_insn_for_speed_p ()
7051       && flag_finite_math_only && !flag_trapping_math
7052       && flag_unsafe_math_optimizations)
7053     {
7054       ix86_emit_swdivsf (operands[0], operands[1],
7055                          operands[2], SFmode);
7056       DONE;
7057     }
7058 })
7059 \f
7060 ;; Divmod instructions.
7061
7062 (define_expand "divmod<mode>4"
7063   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7064                    (div:SWIM248
7065                      (match_operand:SWIM248 1 "register_operand" "")
7066                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7067               (set (match_operand:SWIM248 3 "register_operand" "")
7068                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7069               (clobber (reg:CC FLAGS_REG))])])
7070
7071 ;; Split with 8bit unsigned divide:
7072 ;;      if (dividend an divisor are in [0-255])
7073 ;;         use 8bit unsigned integer divide
7074 ;;       else
7075 ;;         use original integer divide
7076 (define_split
7077   [(set (match_operand:SWI48 0 "register_operand" "")
7078         (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7079                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7080    (set (match_operand:SWI48 1 "register_operand" "")
7081         (mod:SWI48 (match_dup 2) (match_dup 3)))
7082    (clobber (reg:CC FLAGS_REG))]
7083   "TARGET_USE_8BIT_IDIV
7084    && TARGET_QIMODE_MATH
7085    && can_create_pseudo_p ()
7086    && !optimize_insn_for_size_p ()"
7087   [(const_int 0)]
7088   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7089
7090 (define_insn_and_split "divmod<mode>4_1"
7091   [(set (match_operand:SWI48 0 "register_operand" "=a")
7092         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7093                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7094    (set (match_operand:SWI48 1 "register_operand" "=&d")
7095         (mod:SWI48 (match_dup 2) (match_dup 3)))
7096    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7097    (clobber (reg:CC FLAGS_REG))]
7098   ""
7099   "#"
7100   "reload_completed"
7101   [(parallel [(set (match_dup 1)
7102                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7103               (clobber (reg:CC FLAGS_REG))])
7104    (parallel [(set (match_dup 0)
7105                    (div:SWI48 (match_dup 2) (match_dup 3)))
7106               (set (match_dup 1)
7107                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7108               (use (match_dup 1))
7109               (clobber (reg:CC FLAGS_REG))])]
7110 {
7111   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7112
7113   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7114     operands[4] = operands[2];
7115   else
7116     {
7117       /* Avoid use of cltd in favor of a mov+shift.  */
7118       emit_move_insn (operands[1], operands[2]);
7119       operands[4] = operands[1];
7120     }
7121 }
7122   [(set_attr "type" "multi")
7123    (set_attr "mode" "<MODE>")])
7124
7125 (define_insn_and_split "*divmod<mode>4"
7126   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7127         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7128                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7129    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7130         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7131    (clobber (reg:CC FLAGS_REG))]
7132   ""
7133   "#"
7134   "reload_completed"
7135   [(parallel [(set (match_dup 1)
7136                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7137               (clobber (reg:CC FLAGS_REG))])
7138    (parallel [(set (match_dup 0)
7139                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7140               (set (match_dup 1)
7141                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7142               (use (match_dup 1))
7143               (clobber (reg:CC FLAGS_REG))])]
7144 {
7145   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7146
7147   if (<MODE>mode != HImode
7148       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7149     operands[4] = operands[2];
7150   else
7151     {
7152       /* Avoid use of cltd in favor of a mov+shift.  */
7153       emit_move_insn (operands[1], operands[2]);
7154       operands[4] = operands[1];
7155     }
7156 }
7157   [(set_attr "type" "multi")
7158    (set_attr "mode" "<MODE>")])
7159
7160 (define_insn "*divmod<mode>4_noext"
7161   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7162         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7163                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7164    (set (match_operand:SWIM248 1 "register_operand" "=d")
7165         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7166    (use (match_operand:SWIM248 4 "register_operand" "1"))
7167    (clobber (reg:CC FLAGS_REG))]
7168   ""
7169   "idiv{<imodesuffix>}\t%3"
7170   [(set_attr "type" "idiv")
7171    (set_attr "mode" "<MODE>")])
7172
7173 (define_expand "divmodqi4"
7174   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7175                    (div:QI
7176                      (match_operand:QI 1 "register_operand" "")
7177                      (match_operand:QI 2 "nonimmediate_operand" "")))
7178               (set (match_operand:QI 3 "register_operand" "")
7179                    (mod:QI (match_dup 1) (match_dup 2)))
7180               (clobber (reg:CC FLAGS_REG))])]
7181   "TARGET_QIMODE_MATH"
7182 {
7183   rtx div, mod, insn;
7184   rtx tmp0, tmp1;
7185   
7186   tmp0 = gen_reg_rtx (HImode);
7187   tmp1 = gen_reg_rtx (HImode);
7188
7189   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7190      in AX.  */
7191   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7192   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7193
7194   /* Extract remainder from AH.  */
7195   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7196   insn = emit_move_insn (operands[3], tmp1);
7197
7198   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7199   set_unique_reg_note (insn, REG_EQUAL, mod);
7200
7201   /* Extract quotient from AL.  */
7202   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7203
7204   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7205   set_unique_reg_note (insn, REG_EQUAL, div);
7206
7207   DONE;
7208 })
7209
7210 ;; Divide AX by r/m8, with result stored in
7211 ;; AL <- Quotient
7212 ;; AH <- Remainder
7213 ;; Change div/mod to HImode and extend the second argument to HImode
7214 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7215 ;; combine may fail.
7216 (define_insn "divmodhiqi3"
7217   [(set (match_operand:HI 0 "register_operand" "=a")
7218         (ior:HI
7219           (ashift:HI
7220             (zero_extend:HI
7221               (truncate:QI
7222                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7223                         (sign_extend:HI
7224                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7225             (const_int 8))
7226           (zero_extend:HI
7227             (truncate:QI
7228               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7229    (clobber (reg:CC FLAGS_REG))]
7230   "TARGET_QIMODE_MATH"
7231   "idiv{b}\t%2"
7232   [(set_attr "type" "idiv")
7233    (set_attr "mode" "QI")])
7234
7235 (define_expand "udivmod<mode>4"
7236   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7237                    (udiv:SWIM248
7238                      (match_operand:SWIM248 1 "register_operand" "")
7239                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7240               (set (match_operand:SWIM248 3 "register_operand" "")
7241                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7242               (clobber (reg:CC FLAGS_REG))])])
7243
7244 ;; Split with 8bit unsigned divide:
7245 ;;      if (dividend an divisor are in [0-255])
7246 ;;         use 8bit unsigned integer divide
7247 ;;       else
7248 ;;         use original integer divide
7249 (define_split
7250   [(set (match_operand:SWI48 0 "register_operand" "")
7251         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7252                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7253    (set (match_operand:SWI48 1 "register_operand" "")
7254         (umod:SWI48 (match_dup 2) (match_dup 3)))
7255    (clobber (reg:CC FLAGS_REG))]
7256   "TARGET_USE_8BIT_IDIV
7257    && TARGET_QIMODE_MATH
7258    && can_create_pseudo_p ()
7259    && !optimize_insn_for_size_p ()"
7260   [(const_int 0)]
7261   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7262
7263 (define_insn_and_split "udivmod<mode>4_1"
7264   [(set (match_operand:SWI48 0 "register_operand" "=a")
7265         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7266                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7267    (set (match_operand:SWI48 1 "register_operand" "=&d")
7268         (umod:SWI48 (match_dup 2) (match_dup 3)))
7269    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7270    (clobber (reg:CC FLAGS_REG))]
7271   ""
7272   "#"
7273   "reload_completed"
7274   [(set (match_dup 1) (const_int 0))
7275    (parallel [(set (match_dup 0)
7276                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7277               (set (match_dup 1)
7278                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7279               (use (match_dup 1))
7280               (clobber (reg:CC FLAGS_REG))])]
7281   ""
7282   [(set_attr "type" "multi")
7283    (set_attr "mode" "<MODE>")])
7284
7285 (define_insn_and_split "*udivmod<mode>4"
7286   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7287         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7288                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7289    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7290         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7291    (clobber (reg:CC FLAGS_REG))]
7292   ""
7293   "#"
7294   "reload_completed"
7295   [(set (match_dup 1) (const_int 0))
7296    (parallel [(set (match_dup 0)
7297                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7298               (set (match_dup 1)
7299                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7300               (use (match_dup 1))
7301               (clobber (reg:CC FLAGS_REG))])]
7302   ""
7303   [(set_attr "type" "multi")
7304    (set_attr "mode" "<MODE>")])
7305
7306 (define_insn "*udivmod<mode>4_noext"
7307   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7308         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7309                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7310    (set (match_operand:SWIM248 1 "register_operand" "=d")
7311         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7312    (use (match_operand:SWIM248 4 "register_operand" "1"))
7313    (clobber (reg:CC FLAGS_REG))]
7314   ""
7315   "div{<imodesuffix>}\t%3"
7316   [(set_attr "type" "idiv")
7317    (set_attr "mode" "<MODE>")])
7318
7319 (define_expand "udivmodqi4"
7320   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7321                    (udiv:QI
7322                      (match_operand:QI 1 "register_operand" "")
7323                      (match_operand:QI 2 "nonimmediate_operand" "")))
7324               (set (match_operand:QI 3 "register_operand" "")
7325                    (umod:QI (match_dup 1) (match_dup 2)))
7326               (clobber (reg:CC FLAGS_REG))])]
7327   "TARGET_QIMODE_MATH"
7328 {
7329   rtx div, mod, insn;
7330   rtx tmp0, tmp1;
7331   
7332   tmp0 = gen_reg_rtx (HImode);
7333   tmp1 = gen_reg_rtx (HImode);
7334
7335   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7336      in AX.  */
7337   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7338   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7339
7340   /* Extract remainder from AH.  */
7341   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7342   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7343   insn = emit_move_insn (operands[3], tmp1);
7344
7345   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7346   set_unique_reg_note (insn, REG_EQUAL, mod);
7347
7348   /* Extract quotient from AL.  */
7349   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7350
7351   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7352   set_unique_reg_note (insn, REG_EQUAL, div);
7353
7354   DONE;
7355 })
7356
7357 (define_insn "udivmodhiqi3"
7358   [(set (match_operand:HI 0 "register_operand" "=a")
7359         (ior:HI
7360           (ashift:HI
7361             (zero_extend:HI
7362               (truncate:QI
7363                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7364                         (zero_extend:HI
7365                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7366             (const_int 8))
7367           (zero_extend:HI
7368             (truncate:QI
7369               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7370    (clobber (reg:CC FLAGS_REG))]
7371   "TARGET_QIMODE_MATH"
7372   "div{b}\t%2"
7373   [(set_attr "type" "idiv")
7374    (set_attr "mode" "QI")])
7375
7376 ;; We cannot use div/idiv for double division, because it causes
7377 ;; "division by zero" on the overflow and that's not what we expect
7378 ;; from truncate.  Because true (non truncating) double division is
7379 ;; never generated, we can't create this insn anyway.
7380 ;
7381 ;(define_insn ""
7382 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7383 ;       (truncate:SI
7384 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7385 ;                  (zero_extend:DI
7386 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7387 ;   (set (match_operand:SI 3 "register_operand" "=d")
7388 ;       (truncate:SI
7389 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7390 ;   (clobber (reg:CC FLAGS_REG))]
7391 ;  ""
7392 ;  "div{l}\t{%2, %0|%0, %2}"
7393 ;  [(set_attr "type" "idiv")])
7394 \f
7395 ;;- Logical AND instructions
7396
7397 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7398 ;; Note that this excludes ah.
7399
7400 (define_expand "testsi_ccno_1"
7401   [(set (reg:CCNO FLAGS_REG)
7402         (compare:CCNO
7403           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7404                   (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7405           (const_int 0)))])
7406
7407 (define_expand "testqi_ccz_1"
7408   [(set (reg:CCZ FLAGS_REG)
7409         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7410                              (match_operand:QI 1 "nonmemory_operand" ""))
7411                  (const_int 0)))])
7412
7413 (define_expand "testdi_ccno_1"
7414   [(set (reg:CCNO FLAGS_REG)
7415         (compare:CCNO
7416           (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7417                   (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7418           (const_int 0)))]
7419   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7420
7421 (define_insn "*testdi_1"
7422   [(set (reg FLAGS_REG)
7423         (compare
7424          (and:DI
7425           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7426           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7427          (const_int 0)))]
7428   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7429    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7430   "@
7431    test{l}\t{%k1, %k0|%k0, %k1}
7432    test{l}\t{%k1, %k0|%k0, %k1}
7433    test{q}\t{%1, %0|%0, %1}
7434    test{q}\t{%1, %0|%0, %1}
7435    test{q}\t{%1, %0|%0, %1}"
7436   [(set_attr "type" "test")
7437    (set_attr "modrm" "0,1,0,1,1")
7438    (set_attr "mode" "SI,SI,DI,DI,DI")])
7439
7440 (define_insn "*testqi_1_maybe_si"
7441   [(set (reg FLAGS_REG)
7442         (compare
7443           (and:QI
7444             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7445             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7446           (const_int 0)))]
7447    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7448     && ix86_match_ccmode (insn,
7449                          CONST_INT_P (operands[1])
7450                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7451 {
7452   if (which_alternative == 3)
7453     {
7454       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7455         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7456       return "test{l}\t{%1, %k0|%k0, %1}";
7457     }
7458   return "test{b}\t{%1, %0|%0, %1}";
7459 }
7460   [(set_attr "type" "test")
7461    (set_attr "modrm" "0,1,1,1")
7462    (set_attr "mode" "QI,QI,QI,SI")
7463    (set_attr "pent_pair" "uv,np,uv,np")])
7464
7465 (define_insn "*test<mode>_1"
7466   [(set (reg FLAGS_REG)
7467         (compare
7468          (and:SWI124
7469           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7470           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7471          (const_int 0)))]
7472   "ix86_match_ccmode (insn, CCNOmode)
7473    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7474   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7475   [(set_attr "type" "test")
7476    (set_attr "modrm" "0,1,1")
7477    (set_attr "mode" "<MODE>")
7478    (set_attr "pent_pair" "uv,np,uv")])
7479
7480 (define_expand "testqi_ext_ccno_0"
7481   [(set (reg:CCNO FLAGS_REG)
7482         (compare:CCNO
7483           (and:SI
7484             (zero_extract:SI
7485               (match_operand 0 "ext_register_operand" "")
7486               (const_int 8)
7487               (const_int 8))
7488             (match_operand 1 "const_int_operand" ""))
7489           (const_int 0)))])
7490
7491 (define_insn "*testqi_ext_0"
7492   [(set (reg FLAGS_REG)
7493         (compare
7494           (and:SI
7495             (zero_extract:SI
7496               (match_operand 0 "ext_register_operand" "Q")
7497               (const_int 8)
7498               (const_int 8))
7499             (match_operand 1 "const_int_operand" "n"))
7500           (const_int 0)))]
7501   "ix86_match_ccmode (insn, CCNOmode)"
7502   "test{b}\t{%1, %h0|%h0, %1}"
7503   [(set_attr "type" "test")
7504    (set_attr "mode" "QI")
7505    (set_attr "length_immediate" "1")
7506    (set_attr "modrm" "1")
7507    (set_attr "pent_pair" "np")])
7508
7509 (define_insn "*testqi_ext_1_rex64"
7510   [(set (reg FLAGS_REG)
7511         (compare
7512           (and:SI
7513             (zero_extract:SI
7514               (match_operand 0 "ext_register_operand" "Q")
7515               (const_int 8)
7516               (const_int 8))
7517             (zero_extend:SI
7518               (match_operand:QI 1 "register_operand" "Q")))
7519           (const_int 0)))]
7520   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7521   "test{b}\t{%1, %h0|%h0, %1}"
7522   [(set_attr "type" "test")
7523    (set_attr "mode" "QI")])
7524
7525 (define_insn "*testqi_ext_1"
7526   [(set (reg FLAGS_REG)
7527         (compare
7528           (and:SI
7529             (zero_extract:SI
7530               (match_operand 0 "ext_register_operand" "Q")
7531               (const_int 8)
7532               (const_int 8))
7533             (zero_extend:SI
7534               (match_operand:QI 1 "general_operand" "Qm")))
7535           (const_int 0)))]
7536   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7537   "test{b}\t{%1, %h0|%h0, %1}"
7538   [(set_attr "type" "test")
7539    (set_attr "mode" "QI")])
7540
7541 (define_insn "*testqi_ext_2"
7542   [(set (reg FLAGS_REG)
7543         (compare
7544           (and:SI
7545             (zero_extract:SI
7546               (match_operand 0 "ext_register_operand" "Q")
7547               (const_int 8)
7548               (const_int 8))
7549             (zero_extract:SI
7550               (match_operand 1 "ext_register_operand" "Q")
7551               (const_int 8)
7552               (const_int 8)))
7553           (const_int 0)))]
7554   "ix86_match_ccmode (insn, CCNOmode)"
7555   "test{b}\t{%h1, %h0|%h0, %h1}"
7556   [(set_attr "type" "test")
7557    (set_attr "mode" "QI")])
7558
7559 (define_insn "*testqi_ext_3_rex64"
7560   [(set (reg FLAGS_REG)
7561         (compare (zero_extract:DI
7562                    (match_operand 0 "nonimmediate_operand" "rm")
7563                    (match_operand:DI 1 "const_int_operand" "")
7564                    (match_operand:DI 2 "const_int_operand" ""))
7565                  (const_int 0)))]
7566   "TARGET_64BIT
7567    && ix86_match_ccmode (insn, CCNOmode)
7568    && INTVAL (operands[1]) > 0
7569    && INTVAL (operands[2]) >= 0
7570    /* Ensure that resulting mask is zero or sign extended operand.  */
7571    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7572        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7573            && INTVAL (operands[1]) > 32))
7574    && (GET_MODE (operands[0]) == SImode
7575        || GET_MODE (operands[0]) == DImode
7576        || GET_MODE (operands[0]) == HImode
7577        || GET_MODE (operands[0]) == QImode)"
7578   "#")
7579
7580 ;; Combine likes to form bit extractions for some tests.  Humor it.
7581 (define_insn "*testqi_ext_3"
7582   [(set (reg FLAGS_REG)
7583         (compare (zero_extract:SI
7584                    (match_operand 0 "nonimmediate_operand" "rm")
7585                    (match_operand:SI 1 "const_int_operand" "")
7586                    (match_operand:SI 2 "const_int_operand" ""))
7587                  (const_int 0)))]
7588   "ix86_match_ccmode (insn, CCNOmode)
7589    && INTVAL (operands[1]) > 0
7590    && INTVAL (operands[2]) >= 0
7591    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7592    && (GET_MODE (operands[0]) == SImode
7593        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7594        || GET_MODE (operands[0]) == HImode
7595        || GET_MODE (operands[0]) == QImode)"
7596   "#")
7597
7598 (define_split
7599   [(set (match_operand 0 "flags_reg_operand" "")
7600         (match_operator 1 "compare_operator"
7601           [(zero_extract
7602              (match_operand 2 "nonimmediate_operand" "")
7603              (match_operand 3 "const_int_operand" "")
7604              (match_operand 4 "const_int_operand" ""))
7605            (const_int 0)]))]
7606   "ix86_match_ccmode (insn, CCNOmode)"
7607   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7608 {
7609   rtx val = operands[2];
7610   HOST_WIDE_INT len = INTVAL (operands[3]);
7611   HOST_WIDE_INT pos = INTVAL (operands[4]);
7612   HOST_WIDE_INT mask;
7613   enum machine_mode mode, submode;
7614
7615   mode = GET_MODE (val);
7616   if (MEM_P (val))
7617     {
7618       /* ??? Combine likes to put non-volatile mem extractions in QImode
7619          no matter the size of the test.  So find a mode that works.  */
7620       if (! MEM_VOLATILE_P (val))
7621         {
7622           mode = smallest_mode_for_size (pos + len, MODE_INT);
7623           val = adjust_address (val, mode, 0);
7624         }
7625     }
7626   else if (GET_CODE (val) == SUBREG
7627            && (submode = GET_MODE (SUBREG_REG (val)),
7628                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7629            && pos + len <= GET_MODE_BITSIZE (submode)
7630            && GET_MODE_CLASS (submode) == MODE_INT)
7631     {
7632       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7633       mode = submode;
7634       val = SUBREG_REG (val);
7635     }
7636   else if (mode == HImode && pos + len <= 8)
7637     {
7638       /* Small HImode tests can be converted to QImode.  */
7639       mode = QImode;
7640       val = gen_lowpart (QImode, val);
7641     }
7642
7643   if (len == HOST_BITS_PER_WIDE_INT)
7644     mask = -1;
7645   else
7646     mask = ((HOST_WIDE_INT)1 << len) - 1;
7647   mask <<= pos;
7648
7649   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7650 })
7651
7652 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7653 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7654 ;; this is relatively important trick.
7655 ;; Do the conversion only post-reload to avoid limiting of the register class
7656 ;; to QI regs.
7657 (define_split
7658   [(set (match_operand 0 "flags_reg_operand" "")
7659         (match_operator 1 "compare_operator"
7660           [(and (match_operand 2 "register_operand" "")
7661                 (match_operand 3 "const_int_operand" ""))
7662            (const_int 0)]))]
7663    "reload_completed
7664     && QI_REG_P (operands[2])
7665     && GET_MODE (operands[2]) != QImode
7666     && ((ix86_match_ccmode (insn, CCZmode)
7667          && !(INTVAL (operands[3]) & ~(255 << 8)))
7668         || (ix86_match_ccmode (insn, CCNOmode)
7669             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7670   [(set (match_dup 0)
7671         (match_op_dup 1
7672           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7673                    (match_dup 3))
7674            (const_int 0)]))]
7675 {
7676   operands[2] = gen_lowpart (SImode, operands[2]);
7677   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7678 })
7679
7680 (define_split
7681   [(set (match_operand 0 "flags_reg_operand" "")
7682         (match_operator 1 "compare_operator"
7683           [(and (match_operand 2 "nonimmediate_operand" "")
7684                 (match_operand 3 "const_int_operand" ""))
7685            (const_int 0)]))]
7686    "reload_completed
7687     && GET_MODE (operands[2]) != QImode
7688     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7689     && ((ix86_match_ccmode (insn, CCZmode)
7690          && !(INTVAL (operands[3]) & ~255))
7691         || (ix86_match_ccmode (insn, CCNOmode)
7692             && !(INTVAL (operands[3]) & ~127)))"
7693   [(set (match_dup 0)
7694         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7695                          (const_int 0)]))]
7696 {
7697   operands[2] = gen_lowpart (QImode, operands[2]);
7698   operands[3] = gen_lowpart (QImode, operands[3]);
7699 })
7700
7701 ;; %%% This used to optimize known byte-wide and operations to memory,
7702 ;; and sometimes to QImode registers.  If this is considered useful,
7703 ;; it should be done with splitters.
7704
7705 (define_expand "and<mode>3"
7706   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7707         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7708                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7709   ""
7710 {
7711   if (<MODE>mode == DImode
7712       && GET_CODE (operands[2]) == CONST_INT
7713       && INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff
7714       && REG_P (operands[1]))
7715     emit_insn (gen_zero_extendsidi2 (operands[0],
7716                                      gen_lowpart (SImode, operands[1])));
7717   else
7718     ix86_expand_binary_operator (AND, <MODE>mode, operands);
7719   DONE;
7720 })
7721
7722 (define_insn "*anddi_1"
7723   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7724         (and:DI
7725          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7726          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7727    (clobber (reg:CC FLAGS_REG))]
7728   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7729 {
7730   switch (get_attr_type (insn))
7731     {
7732     case TYPE_IMOVX:
7733       {
7734         enum machine_mode mode;
7735
7736         gcc_assert (CONST_INT_P (operands[2]));
7737         if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff)
7738           mode = SImode;
7739         else if (INTVAL (operands[2]) == 0xffff)
7740           mode = HImode;
7741         else
7742           {
7743             gcc_assert (INTVAL (operands[2]) == 0xff);
7744             mode = QImode;
7745           }
7746
7747         operands[1] = gen_lowpart (mode, operands[1]);
7748         if (mode == SImode)
7749           return "mov{l}\t{%1, %k0|%k0, %1}";
7750         else if (mode == HImode)
7751           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7752         else
7753           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7754       }
7755
7756     default:
7757       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7758       if (get_attr_mode (insn) == MODE_SI)
7759         return "and{l}\t{%k2, %k0|%k0, %k2}";
7760       else
7761         return "and{q}\t{%2, %0|%0, %2}";
7762     }
7763 }
7764   [(set_attr "type" "alu,alu,alu,imovx")
7765    (set_attr "length_immediate" "*,*,*,0")
7766    (set (attr "prefix_rex")
7767      (if_then_else
7768        (and (eq_attr "type" "imovx")
7769             (and (match_test "INTVAL (operands[2]) == 0xff")
7770                  (match_operand 1 "ext_QIreg_operand" "")))
7771        (const_string "1")
7772        (const_string "*")))
7773    (set_attr "mode" "SI,DI,DI,SI")])
7774
7775 (define_insn "*andsi_1"
7776   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7777         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7778                 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7779    (clobber (reg:CC FLAGS_REG))]
7780   "ix86_binary_operator_ok (AND, SImode, operands)"
7781 {
7782   switch (get_attr_type (insn))
7783     {
7784     case TYPE_IMOVX:
7785       {
7786         enum machine_mode mode;
7787
7788         gcc_assert (CONST_INT_P (operands[2]));
7789         if (INTVAL (operands[2]) == 0xffff)
7790           mode = HImode;
7791         else
7792           {
7793             gcc_assert (INTVAL (operands[2]) == 0xff);
7794             mode = QImode;
7795           }
7796
7797         operands[1] = gen_lowpart (mode, operands[1]);
7798         if (mode == HImode)
7799           return "movz{wl|x}\t{%1, %0|%0, %1}";
7800         else
7801           return "movz{bl|x}\t{%1, %0|%0, %1}";
7802       }
7803
7804     default:
7805       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7806       return "and{l}\t{%2, %0|%0, %2}";
7807     }
7808 }
7809   [(set_attr "type" "alu,alu,imovx")
7810    (set (attr "prefix_rex")
7811      (if_then_else
7812        (and (eq_attr "type" "imovx")
7813             (and (match_test "INTVAL (operands[2]) == 0xff")
7814                  (match_operand 1 "ext_QIreg_operand" "")))
7815        (const_string "1")
7816        (const_string "*")))
7817    (set_attr "length_immediate" "*,*,0")
7818    (set_attr "mode" "SI")])
7819
7820 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7821 (define_insn "*andsi_1_zext"
7822   [(set (match_operand:DI 0 "register_operand" "=r")
7823         (zero_extend:DI
7824           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7825                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7826    (clobber (reg:CC FLAGS_REG))]
7827   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7828   "and{l}\t{%2, %k0|%k0, %2}"
7829   [(set_attr "type" "alu")
7830    (set_attr "mode" "SI")])
7831
7832 (define_insn "*andhi_1"
7833   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7834         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7835                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7836    (clobber (reg:CC FLAGS_REG))]
7837   "ix86_binary_operator_ok (AND, HImode, operands)"
7838 {
7839   switch (get_attr_type (insn))
7840     {
7841     case TYPE_IMOVX:
7842       gcc_assert (CONST_INT_P (operands[2]));
7843       gcc_assert (INTVAL (operands[2]) == 0xff);
7844       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7845
7846     default:
7847       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7848
7849       return "and{w}\t{%2, %0|%0, %2}";
7850     }
7851 }
7852   [(set_attr "type" "alu,alu,imovx")
7853    (set_attr "length_immediate" "*,*,0")
7854    (set (attr "prefix_rex")
7855      (if_then_else
7856        (and (eq_attr "type" "imovx")
7857             (match_operand 1 "ext_QIreg_operand" ""))
7858        (const_string "1")
7859        (const_string "*")))
7860    (set_attr "mode" "HI,HI,SI")])
7861
7862 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7863 (define_insn "*andqi_1"
7864   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7865         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7866                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7867    (clobber (reg:CC FLAGS_REG))]
7868   "ix86_binary_operator_ok (AND, QImode, operands)"
7869   "@
7870    and{b}\t{%2, %0|%0, %2}
7871    and{b}\t{%2, %0|%0, %2}
7872    and{l}\t{%k2, %k0|%k0, %k2}"
7873   [(set_attr "type" "alu")
7874    (set_attr "mode" "QI,QI,SI")])
7875
7876 (define_insn "*andqi_1_slp"
7877   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7878         (and:QI (match_dup 0)
7879                 (match_operand:QI 1 "general_operand" "qn,qmn")))
7880    (clobber (reg:CC FLAGS_REG))]
7881   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7882    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7883   "and{b}\t{%1, %0|%0, %1}"
7884   [(set_attr "type" "alu1")
7885    (set_attr "mode" "QI")])
7886
7887 (define_split
7888   [(set (match_operand 0 "register_operand" "")
7889         (and (match_dup 0)
7890              (const_int -65536)))
7891    (clobber (reg:CC FLAGS_REG))]
7892   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7893     || optimize_function_for_size_p (cfun)"
7894   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7895   "operands[1] = gen_lowpart (HImode, operands[0]);")
7896
7897 (define_split
7898   [(set (match_operand 0 "ext_register_operand" "")
7899         (and (match_dup 0)
7900              (const_int -256)))
7901    (clobber (reg:CC FLAGS_REG))]
7902   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7903    && reload_completed"
7904   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7905   "operands[1] = gen_lowpart (QImode, operands[0]);")
7906
7907 (define_split
7908   [(set (match_operand 0 "ext_register_operand" "")
7909         (and (match_dup 0)
7910              (const_int -65281)))
7911    (clobber (reg:CC FLAGS_REG))]
7912   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7913    && reload_completed"
7914   [(parallel [(set (zero_extract:SI (match_dup 0)
7915                                     (const_int 8)
7916                                     (const_int 8))
7917                    (xor:SI
7918                      (zero_extract:SI (match_dup 0)
7919                                       (const_int 8)
7920                                       (const_int 8))
7921                      (zero_extract:SI (match_dup 0)
7922                                       (const_int 8)
7923                                       (const_int 8))))
7924               (clobber (reg:CC FLAGS_REG))])]
7925   "operands[0] = gen_lowpart (SImode, operands[0]);")
7926
7927 (define_insn "*anddi_2"
7928   [(set (reg FLAGS_REG)
7929         (compare
7930          (and:DI
7931           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7932           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7933          (const_int 0)))
7934    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7935         (and:DI (match_dup 1) (match_dup 2)))]
7936   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7937    && ix86_binary_operator_ok (AND, DImode, operands)"
7938   "@
7939    and{l}\t{%k2, %k0|%k0, %k2}
7940    and{q}\t{%2, %0|%0, %2}
7941    and{q}\t{%2, %0|%0, %2}"
7942   [(set_attr "type" "alu")
7943    (set_attr "mode" "SI,DI,DI")])
7944
7945 (define_insn "*andqi_2_maybe_si"
7946   [(set (reg FLAGS_REG)
7947         (compare (and:QI
7948                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7949                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7950                  (const_int 0)))
7951    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7952         (and:QI (match_dup 1) (match_dup 2)))]
7953   "ix86_binary_operator_ok (AND, QImode, operands)
7954    && ix86_match_ccmode (insn,
7955                          CONST_INT_P (operands[2])
7956                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7957 {
7958   if (which_alternative == 2)
7959     {
7960       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7961         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7962       return "and{l}\t{%2, %k0|%k0, %2}";
7963     }
7964   return "and{b}\t{%2, %0|%0, %2}";
7965 }
7966   [(set_attr "type" "alu")
7967    (set_attr "mode" "QI,QI,SI")])
7968
7969 (define_insn "*and<mode>_2"
7970   [(set (reg FLAGS_REG)
7971         (compare (and:SWI124
7972                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7973                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7974                  (const_int 0)))
7975    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7976         (and:SWI124 (match_dup 1) (match_dup 2)))]
7977   "ix86_match_ccmode (insn, CCNOmode)
7978    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7979   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7980   [(set_attr "type" "alu")
7981    (set_attr "mode" "<MODE>")])
7982
7983 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7984 (define_insn "*andsi_2_zext"
7985   [(set (reg FLAGS_REG)
7986         (compare (and:SI
7987                   (match_operand:SI 1 "nonimmediate_operand" "%0")
7988                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
7989                  (const_int 0)))
7990    (set (match_operand:DI 0 "register_operand" "=r")
7991         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7992   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7993    && ix86_binary_operator_ok (AND, SImode, operands)"
7994   "and{l}\t{%2, %k0|%k0, %2}"
7995   [(set_attr "type" "alu")
7996    (set_attr "mode" "SI")])
7997
7998 (define_insn "*andqi_2_slp"
7999   [(set (reg FLAGS_REG)
8000         (compare (and:QI
8001                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8002                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8003                  (const_int 0)))
8004    (set (strict_low_part (match_dup 0))
8005         (and:QI (match_dup 0) (match_dup 1)))]
8006   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8007    && ix86_match_ccmode (insn, CCNOmode)
8008    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8009   "and{b}\t{%1, %0|%0, %1}"
8010   [(set_attr "type" "alu1")
8011    (set_attr "mode" "QI")])
8012
8013 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8014 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8015 ;; for a QImode operand, which of course failed.
8016 (define_insn "andqi_ext_0"
8017   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8018                          (const_int 8)
8019                          (const_int 8))
8020         (and:SI
8021           (zero_extract:SI
8022             (match_operand 1 "ext_register_operand" "0")
8023             (const_int 8)
8024             (const_int 8))
8025           (match_operand 2 "const_int_operand" "n")))
8026    (clobber (reg:CC FLAGS_REG))]
8027   ""
8028   "and{b}\t{%2, %h0|%h0, %2}"
8029   [(set_attr "type" "alu")
8030    (set_attr "length_immediate" "1")
8031    (set_attr "modrm" "1")
8032    (set_attr "mode" "QI")])
8033
8034 ;; Generated by peephole translating test to and.  This shows up
8035 ;; often in fp comparisons.
8036 (define_insn "*andqi_ext_0_cc"
8037   [(set (reg FLAGS_REG)
8038         (compare
8039           (and:SI
8040             (zero_extract:SI
8041               (match_operand 1 "ext_register_operand" "0")
8042               (const_int 8)
8043               (const_int 8))
8044             (match_operand 2 "const_int_operand" "n"))
8045           (const_int 0)))
8046    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8047                          (const_int 8)
8048                          (const_int 8))
8049         (and:SI
8050           (zero_extract:SI
8051             (match_dup 1)
8052             (const_int 8)
8053             (const_int 8))
8054           (match_dup 2)))]
8055   "ix86_match_ccmode (insn, CCNOmode)"
8056   "and{b}\t{%2, %h0|%h0, %2}"
8057   [(set_attr "type" "alu")
8058    (set_attr "length_immediate" "1")
8059    (set_attr "modrm" "1")
8060    (set_attr "mode" "QI")])
8061
8062 (define_insn "*andqi_ext_1_rex64"
8063   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8064                          (const_int 8)
8065                          (const_int 8))
8066         (and:SI
8067           (zero_extract:SI
8068             (match_operand 1 "ext_register_operand" "0")
8069             (const_int 8)
8070             (const_int 8))
8071           (zero_extend:SI
8072             (match_operand 2 "ext_register_operand" "Q"))))
8073    (clobber (reg:CC FLAGS_REG))]
8074   "TARGET_64BIT"
8075   "and{b}\t{%2, %h0|%h0, %2}"
8076   [(set_attr "type" "alu")
8077    (set_attr "length_immediate" "0")
8078    (set_attr "mode" "QI")])
8079
8080 (define_insn "*andqi_ext_1"
8081   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8082                          (const_int 8)
8083                          (const_int 8))
8084         (and:SI
8085           (zero_extract:SI
8086             (match_operand 1 "ext_register_operand" "0")
8087             (const_int 8)
8088             (const_int 8))
8089           (zero_extend:SI
8090             (match_operand:QI 2 "general_operand" "Qm"))))
8091    (clobber (reg:CC FLAGS_REG))]
8092   "!TARGET_64BIT"
8093   "and{b}\t{%2, %h0|%h0, %2}"
8094   [(set_attr "type" "alu")
8095    (set_attr "length_immediate" "0")
8096    (set_attr "mode" "QI")])
8097
8098 (define_insn "*andqi_ext_2"
8099   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8100                          (const_int 8)
8101                          (const_int 8))
8102         (and:SI
8103           (zero_extract:SI
8104             (match_operand 1 "ext_register_operand" "%0")
8105             (const_int 8)
8106             (const_int 8))
8107           (zero_extract:SI
8108             (match_operand 2 "ext_register_operand" "Q")
8109             (const_int 8)
8110             (const_int 8))))
8111    (clobber (reg:CC FLAGS_REG))]
8112   ""
8113   "and{b}\t{%h2, %h0|%h0, %h2}"
8114   [(set_attr "type" "alu")
8115    (set_attr "length_immediate" "0")
8116    (set_attr "mode" "QI")])
8117
8118 ;; Convert wide AND instructions with immediate operand to shorter QImode
8119 ;; equivalents when possible.
8120 ;; Don't do the splitting with memory operands, since it introduces risk
8121 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8122 ;; for size, but that can (should?) be handled by generic code instead.
8123 (define_split
8124   [(set (match_operand 0 "register_operand" "")
8125         (and (match_operand 1 "register_operand" "")
8126              (match_operand 2 "const_int_operand" "")))
8127    (clobber (reg:CC FLAGS_REG))]
8128    "reload_completed
8129     && QI_REG_P (operands[0])
8130     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8131     && !(~INTVAL (operands[2]) & ~(255 << 8))
8132     && GET_MODE (operands[0]) != QImode"
8133   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8134                    (and:SI (zero_extract:SI (match_dup 1)
8135                                             (const_int 8) (const_int 8))
8136                            (match_dup 2)))
8137               (clobber (reg:CC FLAGS_REG))])]
8138 {
8139   operands[0] = gen_lowpart (SImode, operands[0]);
8140   operands[1] = gen_lowpart (SImode, operands[1]);
8141   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8142 })
8143
8144 ;; Since AND can be encoded with sign extended immediate, this is only
8145 ;; profitable when 7th bit is not set.
8146 (define_split
8147   [(set (match_operand 0 "register_operand" "")
8148         (and (match_operand 1 "general_operand" "")
8149              (match_operand 2 "const_int_operand" "")))
8150    (clobber (reg:CC FLAGS_REG))]
8151    "reload_completed
8152     && ANY_QI_REG_P (operands[0])
8153     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8154     && !(~INTVAL (operands[2]) & ~255)
8155     && !(INTVAL (operands[2]) & 128)
8156     && GET_MODE (operands[0]) != QImode"
8157   [(parallel [(set (strict_low_part (match_dup 0))
8158                    (and:QI (match_dup 1)
8159                            (match_dup 2)))
8160               (clobber (reg:CC FLAGS_REG))])]
8161 {
8162   operands[0] = gen_lowpart (QImode, operands[0]);
8163   operands[1] = gen_lowpart (QImode, operands[1]);
8164   operands[2] = gen_lowpart (QImode, operands[2]);
8165 })
8166 \f
8167 ;; Logical inclusive and exclusive OR instructions
8168
8169 ;; %%% This used to optimize known byte-wide and operations to memory.
8170 ;; If this is considered useful, it should be done with splitters.
8171
8172 (define_expand "<code><mode>3"
8173   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8174         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8175                      (match_operand:SWIM 2 "<general_operand>" "")))]
8176   ""
8177   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8178
8179 (define_insn "*<code><mode>_1"
8180   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8181         (any_or:SWI248
8182          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8183          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8184    (clobber (reg:CC FLAGS_REG))]
8185   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8186   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8187   [(set_attr "type" "alu")
8188    (set_attr "mode" "<MODE>")])
8189
8190 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8191 (define_insn "*<code>qi_1"
8192   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8193         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8194                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8195    (clobber (reg:CC FLAGS_REG))]
8196   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8197   "@
8198    <logic>{b}\t{%2, %0|%0, %2}
8199    <logic>{b}\t{%2, %0|%0, %2}
8200    <logic>{l}\t{%k2, %k0|%k0, %k2}"
8201   [(set_attr "type" "alu")
8202    (set_attr "mode" "QI,QI,SI")])
8203
8204 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8205 (define_insn "*<code>si_1_zext"
8206   [(set (match_operand:DI 0 "register_operand" "=r")
8207         (zero_extend:DI
8208          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8209                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8210    (clobber (reg:CC FLAGS_REG))]
8211   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8212   "<logic>{l}\t{%2, %k0|%k0, %2}"
8213   [(set_attr "type" "alu")
8214    (set_attr "mode" "SI")])
8215
8216 (define_insn "*<code>si_1_zext_imm"
8217   [(set (match_operand:DI 0 "register_operand" "=r")
8218         (any_or:DI
8219          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8220          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8221    (clobber (reg:CC FLAGS_REG))]
8222   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8223   "<logic>{l}\t{%2, %k0|%k0, %2}"
8224   [(set_attr "type" "alu")
8225    (set_attr "mode" "SI")])
8226
8227 (define_insn "*<code>qi_1_slp"
8228   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8229         (any_or:QI (match_dup 0)
8230                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8231    (clobber (reg:CC FLAGS_REG))]
8232   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8233    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8234   "<logic>{b}\t{%1, %0|%0, %1}"
8235   [(set_attr "type" "alu1")
8236    (set_attr "mode" "QI")])
8237
8238 (define_insn "*<code><mode>_2"
8239   [(set (reg FLAGS_REG)
8240         (compare (any_or:SWI
8241                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8242                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8243                  (const_int 0)))
8244    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8245         (any_or:SWI (match_dup 1) (match_dup 2)))]
8246   "ix86_match_ccmode (insn, CCNOmode)
8247    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8248   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8249   [(set_attr "type" "alu")
8250    (set_attr "mode" "<MODE>")])
8251
8252 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8253 ;; ??? Special case for immediate operand is missing - it is tricky.
8254 (define_insn "*<code>si_2_zext"
8255   [(set (reg FLAGS_REG)
8256         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8257                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
8258                  (const_int 0)))
8259    (set (match_operand:DI 0 "register_operand" "=r")
8260         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8261   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8262    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8263   "<logic>{l}\t{%2, %k0|%k0, %2}"
8264   [(set_attr "type" "alu")
8265    (set_attr "mode" "SI")])
8266
8267 (define_insn "*<code>si_2_zext_imm"
8268   [(set (reg FLAGS_REG)
8269         (compare (any_or:SI
8270                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8271                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8272                  (const_int 0)))
8273    (set (match_operand:DI 0 "register_operand" "=r")
8274         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8275   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8276    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8277   "<logic>{l}\t{%2, %k0|%k0, %2}"
8278   [(set_attr "type" "alu")
8279    (set_attr "mode" "SI")])
8280
8281 (define_insn "*<code>qi_2_slp"
8282   [(set (reg FLAGS_REG)
8283         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8284                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8285                  (const_int 0)))
8286    (set (strict_low_part (match_dup 0))
8287         (any_or:QI (match_dup 0) (match_dup 1)))]
8288   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8289    && ix86_match_ccmode (insn, CCNOmode)
8290    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8291   "<logic>{b}\t{%1, %0|%0, %1}"
8292   [(set_attr "type" "alu1")
8293    (set_attr "mode" "QI")])
8294
8295 (define_insn "*<code><mode>_3"
8296   [(set (reg FLAGS_REG)
8297         (compare (any_or:SWI
8298                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8299                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8300                  (const_int 0)))
8301    (clobber (match_scratch:SWI 0 "=<r>"))]
8302   "ix86_match_ccmode (insn, CCNOmode)
8303    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8304   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8305   [(set_attr "type" "alu")
8306    (set_attr "mode" "<MODE>")])
8307
8308 (define_insn "*<code>qi_ext_0"
8309   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8310                          (const_int 8)
8311                          (const_int 8))
8312         (any_or:SI
8313           (zero_extract:SI
8314             (match_operand 1 "ext_register_operand" "0")
8315             (const_int 8)
8316             (const_int 8))
8317           (match_operand 2 "const_int_operand" "n")))
8318    (clobber (reg:CC FLAGS_REG))]
8319   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8320   "<logic>{b}\t{%2, %h0|%h0, %2}"
8321   [(set_attr "type" "alu")
8322    (set_attr "length_immediate" "1")
8323    (set_attr "modrm" "1")
8324    (set_attr "mode" "QI")])
8325
8326 (define_insn "*<code>qi_ext_1_rex64"
8327   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8328                          (const_int 8)
8329                          (const_int 8))
8330         (any_or:SI
8331           (zero_extract:SI
8332             (match_operand 1 "ext_register_operand" "0")
8333             (const_int 8)
8334             (const_int 8))
8335           (zero_extend:SI
8336             (match_operand 2 "ext_register_operand" "Q"))))
8337    (clobber (reg:CC FLAGS_REG))]
8338   "TARGET_64BIT
8339    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8340   "<logic>{b}\t{%2, %h0|%h0, %2}"
8341   [(set_attr "type" "alu")
8342    (set_attr "length_immediate" "0")
8343    (set_attr "mode" "QI")])
8344
8345 (define_insn "*<code>qi_ext_1"
8346   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8347                          (const_int 8)
8348                          (const_int 8))
8349         (any_or:SI
8350           (zero_extract:SI
8351             (match_operand 1 "ext_register_operand" "0")
8352             (const_int 8)
8353             (const_int 8))
8354           (zero_extend:SI
8355             (match_operand:QI 2 "general_operand" "Qm"))))
8356    (clobber (reg:CC FLAGS_REG))]
8357   "!TARGET_64BIT
8358    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8359   "<logic>{b}\t{%2, %h0|%h0, %2}"
8360   [(set_attr "type" "alu")
8361    (set_attr "length_immediate" "0")
8362    (set_attr "mode" "QI")])
8363
8364 (define_insn "*<code>qi_ext_2"
8365   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8366                          (const_int 8)
8367                          (const_int 8))
8368         (any_or:SI
8369           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8370                            (const_int 8)
8371                            (const_int 8))
8372           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8373                            (const_int 8)
8374                            (const_int 8))))
8375    (clobber (reg:CC FLAGS_REG))]
8376   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8377   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8378   [(set_attr "type" "alu")
8379    (set_attr "length_immediate" "0")
8380    (set_attr "mode" "QI")])
8381
8382 (define_split
8383   [(set (match_operand 0 "register_operand" "")
8384         (any_or (match_operand 1 "register_operand" "")
8385                 (match_operand 2 "const_int_operand" "")))
8386    (clobber (reg:CC FLAGS_REG))]
8387    "reload_completed
8388     && QI_REG_P (operands[0])
8389     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8390     && !(INTVAL (operands[2]) & ~(255 << 8))
8391     && GET_MODE (operands[0]) != QImode"
8392   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8393                    (any_or:SI (zero_extract:SI (match_dup 1)
8394                                                (const_int 8) (const_int 8))
8395                               (match_dup 2)))
8396               (clobber (reg:CC FLAGS_REG))])]
8397 {
8398   operands[0] = gen_lowpart (SImode, operands[0]);
8399   operands[1] = gen_lowpart (SImode, operands[1]);
8400   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8401 })
8402
8403 ;; Since OR can be encoded with sign extended immediate, this is only
8404 ;; profitable when 7th bit is set.
8405 (define_split
8406   [(set (match_operand 0 "register_operand" "")
8407         (any_or (match_operand 1 "general_operand" "")
8408                 (match_operand 2 "const_int_operand" "")))
8409    (clobber (reg:CC FLAGS_REG))]
8410    "reload_completed
8411     && ANY_QI_REG_P (operands[0])
8412     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8413     && !(INTVAL (operands[2]) & ~255)
8414     && (INTVAL (operands[2]) & 128)
8415     && GET_MODE (operands[0]) != QImode"
8416   [(parallel [(set (strict_low_part (match_dup 0))
8417                    (any_or:QI (match_dup 1)
8418                               (match_dup 2)))
8419               (clobber (reg:CC FLAGS_REG))])]
8420 {
8421   operands[0] = gen_lowpart (QImode, operands[0]);
8422   operands[1] = gen_lowpart (QImode, operands[1]);
8423   operands[2] = gen_lowpart (QImode, operands[2]);
8424 })
8425
8426 (define_expand "xorqi_cc_ext_1"
8427   [(parallel [
8428      (set (reg:CCNO FLAGS_REG)
8429           (compare:CCNO
8430             (xor:SI
8431               (zero_extract:SI
8432                 (match_operand 1 "ext_register_operand" "")
8433                 (const_int 8)
8434                 (const_int 8))
8435               (match_operand:QI 2 "general_operand" ""))
8436             (const_int 0)))
8437      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8438                            (const_int 8)
8439                            (const_int 8))
8440           (xor:SI
8441             (zero_extract:SI
8442              (match_dup 1)
8443              (const_int 8)
8444              (const_int 8))
8445             (match_dup 2)))])])
8446
8447 (define_insn "*xorqi_cc_ext_1_rex64"
8448   [(set (reg FLAGS_REG)
8449         (compare
8450           (xor:SI
8451             (zero_extract:SI
8452               (match_operand 1 "ext_register_operand" "0")
8453               (const_int 8)
8454               (const_int 8))
8455             (match_operand:QI 2 "nonmemory_operand" "Qn"))
8456           (const_int 0)))
8457    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8458                          (const_int 8)
8459                          (const_int 8))
8460         (xor:SI
8461           (zero_extract:SI
8462            (match_dup 1)
8463            (const_int 8)
8464            (const_int 8))
8465           (match_dup 2)))]
8466   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8467   "xor{b}\t{%2, %h0|%h0, %2}"
8468   [(set_attr "type" "alu")
8469    (set_attr "modrm" "1")
8470    (set_attr "mode" "QI")])
8471
8472 (define_insn "*xorqi_cc_ext_1"
8473   [(set (reg FLAGS_REG)
8474         (compare
8475           (xor:SI
8476             (zero_extract:SI
8477               (match_operand 1 "ext_register_operand" "0")
8478               (const_int 8)
8479               (const_int 8))
8480             (match_operand:QI 2 "general_operand" "qmn"))
8481           (const_int 0)))
8482    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8483                          (const_int 8)
8484                          (const_int 8))
8485         (xor:SI
8486           (zero_extract:SI
8487            (match_dup 1)
8488            (const_int 8)
8489            (const_int 8))
8490           (match_dup 2)))]
8491   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8492   "xor{b}\t{%2, %h0|%h0, %2}"
8493   [(set_attr "type" "alu")
8494    (set_attr "modrm" "1")
8495    (set_attr "mode" "QI")])
8496 \f
8497 ;; Negation instructions
8498
8499 (define_expand "neg<mode>2"
8500   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8501         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8502   ""
8503   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8504
8505 (define_insn_and_split "*neg<dwi>2_doubleword"
8506   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8507         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8508    (clobber (reg:CC FLAGS_REG))]
8509   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8510   "#"
8511   "reload_completed"
8512   [(parallel
8513     [(set (reg:CCZ FLAGS_REG)
8514           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8515      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8516    (parallel
8517     [(set (match_dup 2)
8518           (plus:DWIH (match_dup 3)
8519                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8520                                 (const_int 0))))
8521      (clobber (reg:CC FLAGS_REG))])
8522    (parallel
8523     [(set (match_dup 2)
8524           (neg:DWIH (match_dup 2)))
8525      (clobber (reg:CC FLAGS_REG))])]
8526   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8527
8528 (define_insn "*neg<mode>2_1"
8529   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8530         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8531    (clobber (reg:CC FLAGS_REG))]
8532   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8533   "neg{<imodesuffix>}\t%0"
8534   [(set_attr "type" "negnot")
8535    (set_attr "mode" "<MODE>")])
8536
8537 ;; Combine is quite creative about this pattern.
8538 (define_insn "*negsi2_1_zext"
8539   [(set (match_operand:DI 0 "register_operand" "=r")
8540         (lshiftrt:DI
8541           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8542                              (const_int 32)))
8543         (const_int 32)))
8544    (clobber (reg:CC FLAGS_REG))]
8545   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8546   "neg{l}\t%k0"
8547   [(set_attr "type" "negnot")
8548    (set_attr "mode" "SI")])
8549
8550 ;; The problem with neg is that it does not perform (compare x 0),
8551 ;; it really performs (compare 0 x), which leaves us with the zero
8552 ;; flag being the only useful item.
8553
8554 (define_insn "*neg<mode>2_cmpz"
8555   [(set (reg:CCZ FLAGS_REG)
8556         (compare:CCZ
8557           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8558                    (const_int 0)))
8559    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8560         (neg:SWI (match_dup 1)))]
8561   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8562   "neg{<imodesuffix>}\t%0"
8563   [(set_attr "type" "negnot")
8564    (set_attr "mode" "<MODE>")])
8565
8566 (define_insn "*negsi2_cmpz_zext"
8567   [(set (reg:CCZ FLAGS_REG)
8568         (compare:CCZ
8569           (lshiftrt:DI
8570             (neg:DI (ashift:DI
8571                       (match_operand:DI 1 "register_operand" "0")
8572                       (const_int 32)))
8573             (const_int 32))
8574           (const_int 0)))
8575    (set (match_operand:DI 0 "register_operand" "=r")
8576         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8577                                         (const_int 32)))
8578                      (const_int 32)))]
8579   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8580   "neg{l}\t%k0"
8581   [(set_attr "type" "negnot")
8582    (set_attr "mode" "SI")])
8583
8584 ;; Changing of sign for FP values is doable using integer unit too.
8585
8586 (define_expand "<code><mode>2"
8587   [(set (match_operand:X87MODEF 0 "register_operand" "")
8588         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8589   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8590   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8591
8592 (define_insn "*absneg<mode>2_mixed"
8593   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8594         (match_operator:MODEF 3 "absneg_operator"
8595           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8596    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8597    (clobber (reg:CC FLAGS_REG))]
8598   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8599   "#")
8600
8601 (define_insn "*absneg<mode>2_sse"
8602   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8603         (match_operator:MODEF 3 "absneg_operator"
8604           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8605    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8606    (clobber (reg:CC FLAGS_REG))]
8607   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8608   "#")
8609
8610 (define_insn "*absneg<mode>2_i387"
8611   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8612         (match_operator:X87MODEF 3 "absneg_operator"
8613           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8614    (use (match_operand 2 "" ""))
8615    (clobber (reg:CC FLAGS_REG))]
8616   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8617   "#")
8618
8619 (define_expand "<code>tf2"
8620   [(set (match_operand:TF 0 "register_operand" "")
8621         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8622   "TARGET_SSE2"
8623   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8624
8625 (define_insn "*absnegtf2_sse"
8626   [(set (match_operand:TF 0 "register_operand" "=x,x")
8627         (match_operator:TF 3 "absneg_operator"
8628           [(match_operand:TF 1 "register_operand" "0,x")]))
8629    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8630    (clobber (reg:CC FLAGS_REG))]
8631   "TARGET_SSE2"
8632   "#")
8633
8634 ;; Splitters for fp abs and neg.
8635
8636 (define_split
8637   [(set (match_operand 0 "fp_register_operand" "")
8638         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8639    (use (match_operand 2 "" ""))
8640    (clobber (reg:CC FLAGS_REG))]
8641   "reload_completed"
8642   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8643
8644 (define_split
8645   [(set (match_operand 0 "register_operand" "")
8646         (match_operator 3 "absneg_operator"
8647           [(match_operand 1 "register_operand" "")]))
8648    (use (match_operand 2 "nonimmediate_operand" ""))
8649    (clobber (reg:CC FLAGS_REG))]
8650   "reload_completed && SSE_REG_P (operands[0])"
8651   [(set (match_dup 0) (match_dup 3))]
8652 {
8653   enum machine_mode mode = GET_MODE (operands[0]);
8654   enum machine_mode vmode = GET_MODE (operands[2]);
8655   rtx tmp;
8656
8657   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8658   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8659   if (operands_match_p (operands[0], operands[2]))
8660     {
8661       tmp = operands[1];
8662       operands[1] = operands[2];
8663       operands[2] = tmp;
8664     }
8665   if (GET_CODE (operands[3]) == ABS)
8666     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8667   else
8668     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8669   operands[3] = tmp;
8670 })
8671
8672 (define_split
8673   [(set (match_operand:SF 0 "register_operand" "")
8674         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8675    (use (match_operand:V4SF 2 "" ""))
8676    (clobber (reg:CC FLAGS_REG))]
8677   "reload_completed"
8678   [(parallel [(set (match_dup 0) (match_dup 1))
8679               (clobber (reg:CC FLAGS_REG))])]
8680 {
8681   rtx tmp;
8682   operands[0] = gen_lowpart (SImode, operands[0]);
8683   if (GET_CODE (operands[1]) == ABS)
8684     {
8685       tmp = gen_int_mode (0x7fffffff, SImode);
8686       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8687     }
8688   else
8689     {
8690       tmp = gen_int_mode (0x80000000, SImode);
8691       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8692     }
8693   operands[1] = tmp;
8694 })
8695
8696 (define_split
8697   [(set (match_operand:DF 0 "register_operand" "")
8698         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8699    (use (match_operand 2 "" ""))
8700    (clobber (reg:CC FLAGS_REG))]
8701   "reload_completed"
8702   [(parallel [(set (match_dup 0) (match_dup 1))
8703               (clobber (reg:CC FLAGS_REG))])]
8704 {
8705   rtx tmp;
8706   if (TARGET_64BIT)
8707     {
8708       tmp = gen_lowpart (DImode, operands[0]);
8709       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8710       operands[0] = tmp;
8711
8712       if (GET_CODE (operands[1]) == ABS)
8713         tmp = const0_rtx;
8714       else
8715         tmp = gen_rtx_NOT (DImode, tmp);
8716     }
8717   else
8718     {
8719       operands[0] = gen_highpart (SImode, operands[0]);
8720       if (GET_CODE (operands[1]) == ABS)
8721         {
8722           tmp = gen_int_mode (0x7fffffff, SImode);
8723           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8724         }
8725       else
8726         {
8727           tmp = gen_int_mode (0x80000000, SImode);
8728           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8729         }
8730     }
8731   operands[1] = tmp;
8732 })
8733
8734 (define_split
8735   [(set (match_operand:XF 0 "register_operand" "")
8736         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8737    (use (match_operand 2 "" ""))
8738    (clobber (reg:CC FLAGS_REG))]
8739   "reload_completed"
8740   [(parallel [(set (match_dup 0) (match_dup 1))
8741               (clobber (reg:CC FLAGS_REG))])]
8742 {
8743   rtx tmp;
8744   operands[0] = gen_rtx_REG (SImode,
8745                              true_regnum (operands[0])
8746                              + (TARGET_64BIT ? 1 : 2));
8747   if (GET_CODE (operands[1]) == ABS)
8748     {
8749       tmp = GEN_INT (0x7fff);
8750       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8751     }
8752   else
8753     {
8754       tmp = GEN_INT (0x8000);
8755       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8756     }
8757   operands[1] = tmp;
8758 })
8759
8760 ;; Conditionalize these after reload. If they match before reload, we
8761 ;; lose the clobber and ability to use integer instructions.
8762
8763 (define_insn "*<code><mode>2_1"
8764   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8765         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8766   "TARGET_80387
8767    && (reload_completed
8768        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8769   "f<absneg_mnemonic>"
8770   [(set_attr "type" "fsgn")
8771    (set_attr "mode" "<MODE>")])
8772
8773 (define_insn "*<code>extendsfdf2"
8774   [(set (match_operand:DF 0 "register_operand" "=f")
8775         (absneg:DF (float_extend:DF
8776                      (match_operand:SF 1 "register_operand" "0"))))]
8777   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8778   "f<absneg_mnemonic>"
8779   [(set_attr "type" "fsgn")
8780    (set_attr "mode" "DF")])
8781
8782 (define_insn "*<code>extendsfxf2"
8783   [(set (match_operand:XF 0 "register_operand" "=f")
8784         (absneg:XF (float_extend:XF
8785                      (match_operand:SF 1 "register_operand" "0"))))]
8786   "TARGET_80387"
8787   "f<absneg_mnemonic>"
8788   [(set_attr "type" "fsgn")
8789    (set_attr "mode" "XF")])
8790
8791 (define_insn "*<code>extenddfxf2"
8792   [(set (match_operand:XF 0 "register_operand" "=f")
8793         (absneg:XF (float_extend:XF
8794                      (match_operand:DF 1 "register_operand" "0"))))]
8795   "TARGET_80387"
8796   "f<absneg_mnemonic>"
8797   [(set_attr "type" "fsgn")
8798    (set_attr "mode" "XF")])
8799
8800 ;; Copysign instructions
8801
8802 (define_mode_iterator CSGNMODE [SF DF TF])
8803 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8804
8805 (define_expand "copysign<mode>3"
8806   [(match_operand:CSGNMODE 0 "register_operand" "")
8807    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8808    (match_operand:CSGNMODE 2 "register_operand" "")]
8809   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8810    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8811   "ix86_expand_copysign (operands); DONE;")
8812
8813 (define_insn_and_split "copysign<mode>3_const"
8814   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8815         (unspec:CSGNMODE
8816           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8817            (match_operand:CSGNMODE 2 "register_operand" "0")
8818            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8819           UNSPEC_COPYSIGN))]
8820   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8821    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8822   "#"
8823   "&& reload_completed"
8824   [(const_int 0)]
8825   "ix86_split_copysign_const (operands); DONE;")
8826
8827 (define_insn "copysign<mode>3_var"
8828   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8829         (unspec:CSGNMODE
8830           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8831            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8832            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8833            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8834           UNSPEC_COPYSIGN))
8835    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8836   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8837    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8838   "#")
8839
8840 (define_split
8841   [(set (match_operand:CSGNMODE 0 "register_operand" "")
8842         (unspec:CSGNMODE
8843           [(match_operand:CSGNMODE 2 "register_operand" "")
8844            (match_operand:CSGNMODE 3 "register_operand" "")
8845            (match_operand:<CSGNVMODE> 4 "" "")
8846            (match_operand:<CSGNVMODE> 5 "" "")]
8847           UNSPEC_COPYSIGN))
8848    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8849   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8850     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8851    && reload_completed"
8852   [(const_int 0)]
8853   "ix86_split_copysign_var (operands); DONE;")
8854 \f
8855 ;; One complement instructions
8856
8857 (define_expand "one_cmpl<mode>2"
8858   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8859         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8860   ""
8861   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8862
8863 (define_insn "*one_cmpl<mode>2_1"
8864   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8865         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8866   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8867   "not{<imodesuffix>}\t%0"
8868   [(set_attr "type" "negnot")
8869    (set_attr "mode" "<MODE>")])
8870
8871 ;; %%% Potential partial reg stall on alternative 1.  What to do?
8872 (define_insn "*one_cmplqi2_1"
8873   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8874         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8875   "ix86_unary_operator_ok (NOT, QImode, operands)"
8876   "@
8877    not{b}\t%0
8878    not{l}\t%k0"
8879   [(set_attr "type" "negnot")
8880    (set_attr "mode" "QI,SI")])
8881
8882 ;; ??? Currently never generated - xor is used instead.
8883 (define_insn "*one_cmplsi2_1_zext"
8884   [(set (match_operand:DI 0 "register_operand" "=r")
8885         (zero_extend:DI
8886           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8887   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8888   "not{l}\t%k0"
8889   [(set_attr "type" "negnot")
8890    (set_attr "mode" "SI")])
8891
8892 (define_insn "*one_cmpl<mode>2_2"
8893   [(set (reg FLAGS_REG)
8894         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8895                  (const_int 0)))
8896    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8897         (not:SWI (match_dup 1)))]
8898   "ix86_match_ccmode (insn, CCNOmode)
8899    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8900   "#"
8901   [(set_attr "type" "alu1")
8902    (set_attr "mode" "<MODE>")])
8903
8904 (define_split
8905   [(set (match_operand 0 "flags_reg_operand" "")
8906         (match_operator 2 "compare_operator"
8907           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8908            (const_int 0)]))
8909    (set (match_operand:SWI 1 "nonimmediate_operand" "")
8910         (not:SWI (match_dup 3)))]
8911   "ix86_match_ccmode (insn, CCNOmode)"
8912   [(parallel [(set (match_dup 0)
8913                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8914                                     (const_int 0)]))
8915               (set (match_dup 1)
8916                    (xor:SWI (match_dup 3) (const_int -1)))])])
8917
8918 ;; ??? Currently never generated - xor is used instead.
8919 (define_insn "*one_cmplsi2_2_zext"
8920   [(set (reg FLAGS_REG)
8921         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8922                  (const_int 0)))
8923    (set (match_operand:DI 0 "register_operand" "=r")
8924         (zero_extend:DI (not:SI (match_dup 1))))]
8925   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8926    && ix86_unary_operator_ok (NOT, SImode, operands)"
8927   "#"
8928   [(set_attr "type" "alu1")
8929    (set_attr "mode" "SI")])
8930
8931 (define_split
8932   [(set (match_operand 0 "flags_reg_operand" "")
8933         (match_operator 2 "compare_operator"
8934           [(not:SI (match_operand:SI 3 "register_operand" ""))
8935            (const_int 0)]))
8936    (set (match_operand:DI 1 "register_operand" "")
8937         (zero_extend:DI (not:SI (match_dup 3))))]
8938   "ix86_match_ccmode (insn, CCNOmode)"
8939   [(parallel [(set (match_dup 0)
8940                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8941                                     (const_int 0)]))
8942               (set (match_dup 1)
8943                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8944 \f
8945 ;; Shift instructions
8946
8947 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8948 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
8949 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8950 ;; from the assembler input.
8951 ;;
8952 ;; This instruction shifts the target reg/mem as usual, but instead of
8953 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
8954 ;; is a left shift double, bits are taken from the high order bits of
8955 ;; reg, else if the insn is a shift right double, bits are taken from the
8956 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
8957 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8958 ;;
8959 ;; Since sh[lr]d does not change the `reg' operand, that is done
8960 ;; separately, making all shifts emit pairs of shift double and normal
8961 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
8962 ;; support a 63 bit shift, each shift where the count is in a reg expands
8963 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8964 ;;
8965 ;; If the shift count is a constant, we need never emit more than one
8966 ;; shift pair, instead using moves and sign extension for counts greater
8967 ;; than 31.
8968
8969 (define_expand "ashl<mode>3"
8970   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8971         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8972                       (match_operand:QI 2 "nonmemory_operand" "")))]
8973   ""
8974   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8975
8976 (define_insn "*ashl<mode>3_doubleword"
8977   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8978         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8979                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8980    (clobber (reg:CC FLAGS_REG))]
8981   ""
8982   "#"
8983   [(set_attr "type" "multi")])
8984
8985 (define_split
8986   [(set (match_operand:DWI 0 "register_operand" "")
8987         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8988                     (match_operand:QI 2 "nonmemory_operand" "")))
8989    (clobber (reg:CC FLAGS_REG))]
8990   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8991   [(const_int 0)]
8992   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8993
8994 ;; By default we don't ask for a scratch register, because when DWImode
8995 ;; values are manipulated, registers are already at a premium.  But if
8996 ;; we have one handy, we won't turn it away.
8997
8998 (define_peephole2
8999   [(match_scratch:DWIH 3 "r")
9000    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9001                    (ashift:<DWI>
9002                      (match_operand:<DWI> 1 "nonmemory_operand" "")
9003                      (match_operand:QI 2 "nonmemory_operand" "")))
9004               (clobber (reg:CC FLAGS_REG))])
9005    (match_dup 3)]
9006   "TARGET_CMOVE"
9007   [(const_int 0)]
9008   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9009
9010 (define_insn "x86_64_shld"
9011   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9012         (ior:DI (ashift:DI (match_dup 0)
9013                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9014                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9015                   (minus:QI (const_int 64) (match_dup 2)))))
9016    (clobber (reg:CC FLAGS_REG))]
9017   "TARGET_64BIT"
9018   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9019   [(set_attr "type" "ishift")
9020    (set_attr "prefix_0f" "1")
9021    (set_attr "mode" "DI")
9022    (set_attr "athlon_decode" "vector")
9023    (set_attr "amdfam10_decode" "vector")
9024    (set_attr "bdver1_decode" "vector")])
9025
9026 (define_insn "x86_shld"
9027   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9028         (ior:SI (ashift:SI (match_dup 0)
9029                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9030                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9031                   (minus:QI (const_int 32) (match_dup 2)))))
9032    (clobber (reg:CC FLAGS_REG))]
9033   ""
9034   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9035   [(set_attr "type" "ishift")
9036    (set_attr "prefix_0f" "1")
9037    (set_attr "mode" "SI")
9038    (set_attr "pent_pair" "np")
9039    (set_attr "athlon_decode" "vector")
9040    (set_attr "amdfam10_decode" "vector")
9041    (set_attr "bdver1_decode" "vector")])
9042
9043 (define_expand "x86_shift<mode>_adj_1"
9044   [(set (reg:CCZ FLAGS_REG)
9045         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9046                              (match_dup 4))
9047                      (const_int 0)))
9048    (set (match_operand:SWI48 0 "register_operand" "")
9049         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9050                             (match_operand:SWI48 1 "register_operand" "")
9051                             (match_dup 0)))
9052    (set (match_dup 1)
9053         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9054                             (match_operand:SWI48 3 "register_operand" "")
9055                             (match_dup 1)))]
9056   "TARGET_CMOVE"
9057   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9058
9059 (define_expand "x86_shift<mode>_adj_2"
9060   [(use (match_operand:SWI48 0 "register_operand" ""))
9061    (use (match_operand:SWI48 1 "register_operand" ""))
9062    (use (match_operand:QI 2 "register_operand" ""))]
9063   ""
9064 {
9065   rtx label = gen_label_rtx ();
9066   rtx tmp;
9067
9068   emit_insn (gen_testqi_ccz_1 (operands[2],
9069                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9070
9071   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9072   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9073   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9074                               gen_rtx_LABEL_REF (VOIDmode, label),
9075                               pc_rtx);
9076   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9077   JUMP_LABEL (tmp) = label;
9078
9079   emit_move_insn (operands[0], operands[1]);
9080   ix86_expand_clear (operands[1]);
9081
9082   emit_label (label);
9083   LABEL_NUSES (label) = 1;
9084
9085   DONE;
9086 })
9087
9088 ;; Avoid useless masking of count operand.
9089 (define_insn_and_split "*ashl<mode>3_mask"
9090   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9091         (ashift:SWI48
9092           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9093           (subreg:QI
9094             (and:SI
9095               (match_operand:SI 2 "nonimmediate_operand" "c")
9096               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9097    (clobber (reg:CC FLAGS_REG))]
9098   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9099    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9100       == GET_MODE_BITSIZE (<MODE>mode)-1"
9101   "#"
9102   "&& 1"
9103   [(parallel [(set (match_dup 0)
9104                    (ashift:SWI48 (match_dup 1) (match_dup 2)))
9105               (clobber (reg:CC FLAGS_REG))])]
9106 {
9107   if (can_create_pseudo_p ())
9108     operands [2] = force_reg (SImode, operands[2]);
9109
9110   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9111 }
9112   [(set_attr "type" "ishift")
9113    (set_attr "mode" "<MODE>")])
9114
9115 (define_insn "*bmi2_ashl<mode>3_1"
9116   [(set (match_operand:SWI48 0 "register_operand" "=r")
9117         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9118                       (match_operand:SWI48 2 "register_operand" "r")))]
9119   "TARGET_BMI2"
9120   "shlx\t{%2, %1, %0|%0, %1, %2}"
9121   [(set_attr "type" "ishiftx")
9122    (set_attr "mode" "<MODE>")])
9123
9124 (define_insn "*ashl<mode>3_1"
9125   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9126         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9127                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9128    (clobber (reg:CC FLAGS_REG))]
9129   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9130 {
9131   switch (get_attr_type (insn))
9132     {
9133     case TYPE_LEA:
9134     case TYPE_ISHIFTX:
9135       return "#";
9136
9137     case TYPE_ALU:
9138       gcc_assert (operands[2] == const1_rtx);
9139       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9140       return "add{<imodesuffix>}\t%0, %0";
9141
9142     default:
9143       if (operands[2] == const1_rtx
9144           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9145         return "sal{<imodesuffix>}\t%0";
9146       else
9147         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9148     }
9149 }
9150   [(set_attr "isa" "*,*,bmi2")
9151    (set (attr "type")
9152      (cond [(eq_attr "alternative" "1")
9153               (const_string "lea")
9154             (eq_attr "alternative" "2")
9155               (const_string "ishiftx")
9156             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9157                       (match_operand 0 "register_operand" ""))
9158                  (match_operand 2 "const1_operand" ""))
9159               (const_string "alu")
9160            ]
9161            (const_string "ishift")))
9162    (set (attr "length_immediate")
9163      (if_then_else
9164        (ior (eq_attr "type" "alu")
9165             (and (eq_attr "type" "ishift")
9166                  (and (match_operand 2 "const1_operand" "")
9167                       (ior (match_test "TARGET_SHIFT1")
9168                            (match_test "optimize_function_for_size_p (cfun)")))))
9169        (const_string "0")
9170        (const_string "*")))
9171    (set_attr "mode" "<MODE>")])
9172
9173 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9174 (define_split
9175   [(set (match_operand:SWI48 0 "register_operand" "")
9176         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9177                       (match_operand:QI 2 "register_operand" "")))
9178    (clobber (reg:CC FLAGS_REG))]
9179   "TARGET_BMI2 && reload_completed"
9180   [(set (match_dup 0)
9181         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9182   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9183
9184 (define_insn "*bmi2_ashlsi3_1_zext"
9185   [(set (match_operand:DI 0 "register_operand" "=r")
9186         (zero_extend:DI
9187           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9188                      (match_operand:SI 2 "register_operand" "r"))))]
9189   "TARGET_64BIT && TARGET_BMI2"
9190   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9191   [(set_attr "type" "ishiftx")
9192    (set_attr "mode" "SI")])
9193
9194 (define_insn "*ashlsi3_1_zext"
9195   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9196         (zero_extend:DI
9197           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9198                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9199    (clobber (reg:CC FLAGS_REG))]
9200   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9201 {
9202   switch (get_attr_type (insn))
9203     {
9204     case TYPE_LEA:
9205     case TYPE_ISHIFTX:
9206       return "#";
9207
9208     case TYPE_ALU:
9209       gcc_assert (operands[2] == const1_rtx);
9210       return "add{l}\t%k0, %k0";
9211
9212     default:
9213       if (operands[2] == const1_rtx
9214           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9215         return "sal{l}\t%k0";
9216       else
9217         return "sal{l}\t{%2, %k0|%k0, %2}";
9218     }
9219 }
9220   [(set_attr "isa" "*,*,bmi2")
9221    (set (attr "type")
9222      (cond [(eq_attr "alternative" "1")
9223               (const_string "lea")
9224             (eq_attr "alternative" "2")
9225               (const_string "ishiftx")
9226             (and (match_test "TARGET_DOUBLE_WITH_ADD")
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" "SI")])
9241
9242 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9243 (define_split
9244   [(set (match_operand:DI 0 "register_operand" "")
9245         (zero_extend:DI
9246           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9247                      (match_operand:QI 2 "register_operand" ""))))
9248    (clobber (reg:CC FLAGS_REG))]
9249   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9250   [(set (match_dup 0)
9251         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9252   "operands[2] = gen_lowpart (SImode, operands[2]);")
9253
9254 (define_insn "*ashlhi3_1"
9255   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9256         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9257                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9258    (clobber (reg:CC FLAGS_REG))]
9259   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9260 {
9261   switch (get_attr_type (insn))
9262     {
9263     case TYPE_LEA:
9264       return "#";
9265
9266     case TYPE_ALU:
9267       gcc_assert (operands[2] == const1_rtx);
9268       return "add{w}\t%0, %0";
9269
9270     default:
9271       if (operands[2] == const1_rtx
9272           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9273         return "sal{w}\t%0";
9274       else
9275         return "sal{w}\t{%2, %0|%0, %2}";
9276     }
9277 }
9278   [(set (attr "type")
9279      (cond [(eq_attr "alternative" "1")
9280               (const_string "lea")
9281             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9282                       (match_operand 0 "register_operand" ""))
9283                  (match_operand 2 "const1_operand" ""))
9284               (const_string "alu")
9285            ]
9286            (const_string "ishift")))
9287    (set (attr "length_immediate")
9288      (if_then_else
9289        (ior (eq_attr "type" "alu")
9290             (and (eq_attr "type" "ishift")
9291                  (and (match_operand 2 "const1_operand" "")
9292                       (ior (match_test "TARGET_SHIFT1")
9293                            (match_test "optimize_function_for_size_p (cfun)")))))
9294        (const_string "0")
9295        (const_string "*")))
9296    (set_attr "mode" "HI,SI")])
9297
9298 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9299 (define_insn "*ashlqi3_1"
9300   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9301         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9302                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9303    (clobber (reg:CC FLAGS_REG))]
9304   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9305 {
9306   switch (get_attr_type (insn))
9307     {
9308     case TYPE_LEA:
9309       return "#";
9310
9311     case TYPE_ALU:
9312       gcc_assert (operands[2] == const1_rtx);
9313       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9314         return "add{l}\t%k0, %k0";
9315       else
9316         return "add{b}\t%0, %0";
9317
9318     default:
9319       if (operands[2] == const1_rtx
9320           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9321         {
9322           if (get_attr_mode (insn) == MODE_SI)
9323             return "sal{l}\t%k0";
9324           else
9325             return "sal{b}\t%0";
9326         }
9327       else
9328         {
9329           if (get_attr_mode (insn) == MODE_SI)
9330             return "sal{l}\t{%2, %k0|%k0, %2}";
9331           else
9332             return "sal{b}\t{%2, %0|%0, %2}";
9333         }
9334     }
9335 }
9336   [(set (attr "type")
9337      (cond [(eq_attr "alternative" "2")
9338               (const_string "lea")
9339             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9340                       (match_operand 0 "register_operand" ""))
9341                  (match_operand 2 "const1_operand" ""))
9342               (const_string "alu")
9343            ]
9344            (const_string "ishift")))
9345    (set (attr "length_immediate")
9346      (if_then_else
9347        (ior (eq_attr "type" "alu")
9348             (and (eq_attr "type" "ishift")
9349                  (and (match_operand 2 "const1_operand" "")
9350                       (ior (match_test "TARGET_SHIFT1")
9351                            (match_test "optimize_function_for_size_p (cfun)")))))
9352        (const_string "0")
9353        (const_string "*")))
9354    (set_attr "mode" "QI,SI,SI")])
9355
9356 (define_insn "*ashlqi3_1_slp"
9357   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9358         (ashift:QI (match_dup 0)
9359                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9360    (clobber (reg:CC FLAGS_REG))]
9361   "(optimize_function_for_size_p (cfun)
9362     || !TARGET_PARTIAL_FLAG_REG_STALL
9363     || (operands[1] == const1_rtx
9364         && (TARGET_SHIFT1
9365             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9366 {
9367   switch (get_attr_type (insn))
9368     {
9369     case TYPE_ALU:
9370       gcc_assert (operands[1] == const1_rtx);
9371       return "add{b}\t%0, %0";
9372
9373     default:
9374       if (operands[1] == const1_rtx
9375           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9376         return "sal{b}\t%0";
9377       else
9378         return "sal{b}\t{%1, %0|%0, %1}";
9379     }
9380 }
9381   [(set (attr "type")
9382      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9383                       (match_operand 0 "register_operand" ""))
9384                  (match_operand 1 "const1_operand" ""))
9385               (const_string "alu")
9386            ]
9387            (const_string "ishift1")))
9388    (set (attr "length_immediate")
9389      (if_then_else
9390        (ior (eq_attr "type" "alu")
9391             (and (eq_attr "type" "ishift1")
9392                  (and (match_operand 1 "const1_operand" "")
9393                       (ior (match_test "TARGET_SHIFT1")
9394                            (match_test "optimize_function_for_size_p (cfun)")))))
9395        (const_string "0")
9396        (const_string "*")))
9397    (set_attr "mode" "QI")])
9398
9399 ;; Convert ashift to the lea pattern to avoid flags dependency.
9400 (define_split
9401   [(set (match_operand 0 "register_operand" "")
9402         (ashift (match_operand 1 "index_register_operand" "")
9403                 (match_operand:QI 2 "const_int_operand" "")))
9404    (clobber (reg:CC FLAGS_REG))]
9405   "GET_MODE (operands[0]) == GET_MODE (operands[1])
9406    && reload_completed
9407    && true_regnum (operands[0]) != true_regnum (operands[1])"
9408   [(const_int 0)]
9409 {
9410   enum machine_mode mode = GET_MODE (operands[0]);
9411   rtx pat;
9412
9413   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9414     { 
9415       mode = SImode; 
9416       operands[0] = gen_lowpart (mode, operands[0]);
9417       operands[1] = gen_lowpart (mode, operands[1]);
9418     }
9419
9420   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9421
9422   pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9423
9424   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9425   DONE;
9426 })
9427
9428 ;; Convert ashift to the lea pattern to avoid flags dependency.
9429 (define_split
9430   [(set (match_operand:DI 0 "register_operand" "")
9431         (zero_extend:DI
9432           (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9433                      (match_operand:QI 2 "const_int_operand" ""))))
9434    (clobber (reg:CC FLAGS_REG))]
9435   "TARGET_64BIT && reload_completed
9436    && true_regnum (operands[0]) != true_regnum (operands[1])"
9437   [(set (match_dup 0)
9438         (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9439 {
9440   operands[1] = gen_lowpart (DImode, operands[1]);
9441   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9442 })
9443
9444 ;; This pattern can't accept a variable shift count, since shifts by
9445 ;; zero don't affect the flags.  We assume that shifts by constant
9446 ;; zero are optimized away.
9447 (define_insn "*ashl<mode>3_cmp"
9448   [(set (reg FLAGS_REG)
9449         (compare
9450           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9451                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9452           (const_int 0)))
9453    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9454         (ashift:SWI (match_dup 1) (match_dup 2)))]
9455   "(optimize_function_for_size_p (cfun)
9456     || !TARGET_PARTIAL_FLAG_REG_STALL
9457     || (operands[2] == const1_rtx
9458         && (TARGET_SHIFT1
9459             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9460    && ix86_match_ccmode (insn, CCGOCmode)
9461    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9462 {
9463   switch (get_attr_type (insn))
9464     {
9465     case TYPE_ALU:
9466       gcc_assert (operands[2] == const1_rtx);
9467       return "add{<imodesuffix>}\t%0, %0";
9468
9469     default:
9470       if (operands[2] == const1_rtx
9471           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9472         return "sal{<imodesuffix>}\t%0";
9473       else
9474         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9475     }
9476 }
9477   [(set (attr "type")
9478      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9479                       (match_operand 0 "register_operand" ""))
9480                  (match_operand 2 "const1_operand" ""))
9481               (const_string "alu")
9482            ]
9483            (const_string "ishift")))
9484    (set (attr "length_immediate")
9485      (if_then_else
9486        (ior (eq_attr "type" "alu")
9487             (and (eq_attr "type" "ishift")
9488                  (and (match_operand 2 "const1_operand" "")
9489                       (ior (match_test "TARGET_SHIFT1")
9490                            (match_test "optimize_function_for_size_p (cfun)")))))
9491        (const_string "0")
9492        (const_string "*")))
9493    (set_attr "mode" "<MODE>")])
9494
9495 (define_insn "*ashlsi3_cmp_zext"
9496   [(set (reg FLAGS_REG)
9497         (compare
9498           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9499                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9500           (const_int 0)))
9501    (set (match_operand:DI 0 "register_operand" "=r")
9502         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9503   "TARGET_64BIT
9504    && (optimize_function_for_size_p (cfun)
9505        || !TARGET_PARTIAL_FLAG_REG_STALL
9506        || (operands[2] == const1_rtx
9507            && (TARGET_SHIFT1
9508                || TARGET_DOUBLE_WITH_ADD)))
9509    && ix86_match_ccmode (insn, CCGOCmode)
9510    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9511 {
9512   switch (get_attr_type (insn))
9513     {
9514     case TYPE_ALU:
9515       gcc_assert (operands[2] == const1_rtx);
9516       return "add{l}\t%k0, %k0";
9517
9518     default:
9519       if (operands[2] == const1_rtx
9520           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9521         return "sal{l}\t%k0";
9522       else
9523         return "sal{l}\t{%2, %k0|%k0, %2}";
9524     }
9525 }
9526   [(set (attr "type")
9527      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9528                  (match_operand 2 "const1_operand" ""))
9529               (const_string "alu")
9530            ]
9531            (const_string "ishift")))
9532    (set (attr "length_immediate")
9533      (if_then_else
9534        (ior (eq_attr "type" "alu")
9535             (and (eq_attr "type" "ishift")
9536                  (and (match_operand 2 "const1_operand" "")
9537                       (ior (match_test "TARGET_SHIFT1")
9538                            (match_test "optimize_function_for_size_p (cfun)")))))
9539        (const_string "0")
9540        (const_string "*")))
9541    (set_attr "mode" "SI")])
9542
9543 (define_insn "*ashl<mode>3_cconly"
9544   [(set (reg FLAGS_REG)
9545         (compare
9546           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9547                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9548           (const_int 0)))
9549    (clobber (match_scratch:SWI 0 "=<r>"))]
9550   "(optimize_function_for_size_p (cfun)
9551     || !TARGET_PARTIAL_FLAG_REG_STALL
9552     || (operands[2] == const1_rtx
9553         && (TARGET_SHIFT1
9554             || TARGET_DOUBLE_WITH_ADD)))
9555    && ix86_match_ccmode (insn, CCGOCmode)"
9556 {
9557   switch (get_attr_type (insn))
9558     {
9559     case TYPE_ALU:
9560       gcc_assert (operands[2] == const1_rtx);
9561       return "add{<imodesuffix>}\t%0, %0";
9562
9563     default:
9564       if (operands[2] == const1_rtx
9565           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9566         return "sal{<imodesuffix>}\t%0";
9567       else
9568         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9569     }
9570 }
9571   [(set (attr "type")
9572      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9573                       (match_operand 0 "register_operand" ""))
9574                  (match_operand 2 "const1_operand" ""))
9575               (const_string "alu")
9576            ]
9577            (const_string "ishift")))
9578    (set (attr "length_immediate")
9579      (if_then_else
9580        (ior (eq_attr "type" "alu")
9581             (and (eq_attr "type" "ishift")
9582                  (and (match_operand 2 "const1_operand" "")
9583                       (ior (match_test "TARGET_SHIFT1")
9584                            (match_test "optimize_function_for_size_p (cfun)")))))
9585        (const_string "0")
9586        (const_string "*")))
9587    (set_attr "mode" "<MODE>")])
9588
9589 ;; See comment above `ashl<mode>3' about how this works.
9590
9591 (define_expand "<shift_insn><mode>3"
9592   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9593         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9594                            (match_operand:QI 2 "nonmemory_operand" "")))]
9595   ""
9596   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9597
9598 ;; Avoid useless masking of count operand.
9599 (define_insn_and_split "*<shift_insn><mode>3_mask"
9600   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9601         (any_shiftrt:SWI48
9602           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9603           (subreg:QI
9604             (and:SI
9605               (match_operand:SI 2 "nonimmediate_operand" "c")
9606               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9607    (clobber (reg:CC FLAGS_REG))]
9608   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9609    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9610       == GET_MODE_BITSIZE (<MODE>mode)-1"
9611   "#"
9612   "&& 1"
9613   [(parallel [(set (match_dup 0)
9614                    (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9615               (clobber (reg:CC FLAGS_REG))])]
9616 {
9617   if (can_create_pseudo_p ())
9618     operands [2] = force_reg (SImode, operands[2]);
9619
9620   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9621 }
9622   [(set_attr "type" "ishift")
9623    (set_attr "mode" "<MODE>")])
9624
9625 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9626   [(set (match_operand:DWI 0 "register_operand" "=r")
9627         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9628                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9629    (clobber (reg:CC FLAGS_REG))]
9630   ""
9631   "#"
9632   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9633   [(const_int 0)]
9634   "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9635   [(set_attr "type" "multi")])
9636
9637 ;; By default we don't ask for a scratch register, because when DWImode
9638 ;; values are manipulated, registers are already at a premium.  But if
9639 ;; we have one handy, we won't turn it away.
9640
9641 (define_peephole2
9642   [(match_scratch:DWIH 3 "r")
9643    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9644                    (any_shiftrt:<DWI>
9645                      (match_operand:<DWI> 1 "register_operand" "")
9646                      (match_operand:QI 2 "nonmemory_operand" "")))
9647               (clobber (reg:CC FLAGS_REG))])
9648    (match_dup 3)]
9649   "TARGET_CMOVE"
9650   [(const_int 0)]
9651   "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9652
9653 (define_insn "x86_64_shrd"
9654   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9655         (ior:DI (ashiftrt:DI (match_dup 0)
9656                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9657                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9658                   (minus:QI (const_int 64) (match_dup 2)))))
9659    (clobber (reg:CC FLAGS_REG))]
9660   "TARGET_64BIT"
9661   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9662   [(set_attr "type" "ishift")
9663    (set_attr "prefix_0f" "1")
9664    (set_attr "mode" "DI")
9665    (set_attr "athlon_decode" "vector")
9666    (set_attr "amdfam10_decode" "vector")
9667    (set_attr "bdver1_decode" "vector")])
9668
9669 (define_insn "x86_shrd"
9670   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9671         (ior:SI (ashiftrt:SI (match_dup 0)
9672                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9673                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9674                   (minus:QI (const_int 32) (match_dup 2)))))
9675    (clobber (reg:CC FLAGS_REG))]
9676   ""
9677   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9678   [(set_attr "type" "ishift")
9679    (set_attr "prefix_0f" "1")
9680    (set_attr "mode" "SI")
9681    (set_attr "pent_pair" "np")
9682    (set_attr "athlon_decode" "vector")
9683    (set_attr "amdfam10_decode" "vector")
9684    (set_attr "bdver1_decode" "vector")])
9685
9686 (define_insn "ashrdi3_cvt"
9687   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9688         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9689                      (match_operand:QI 2 "const_int_operand" "")))
9690    (clobber (reg:CC FLAGS_REG))]
9691   "TARGET_64BIT && INTVAL (operands[2]) == 63
9692    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9693    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9694   "@
9695    {cqto|cqo}
9696    sar{q}\t{%2, %0|%0, %2}"
9697   [(set_attr "type" "imovx,ishift")
9698    (set_attr "prefix_0f" "0,*")
9699    (set_attr "length_immediate" "0,*")
9700    (set_attr "modrm" "0,1")
9701    (set_attr "mode" "DI")])
9702
9703 (define_insn "ashrsi3_cvt"
9704   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9705         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9706                      (match_operand:QI 2 "const_int_operand" "")))
9707    (clobber (reg:CC FLAGS_REG))]
9708   "INTVAL (operands[2]) == 31
9709    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9710    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9711   "@
9712    {cltd|cdq}
9713    sar{l}\t{%2, %0|%0, %2}"
9714   [(set_attr "type" "imovx,ishift")
9715    (set_attr "prefix_0f" "0,*")
9716    (set_attr "length_immediate" "0,*")
9717    (set_attr "modrm" "0,1")
9718    (set_attr "mode" "SI")])
9719
9720 (define_insn "*ashrsi3_cvt_zext"
9721   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9722         (zero_extend:DI
9723           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9724                        (match_operand:QI 2 "const_int_operand" ""))))
9725    (clobber (reg:CC FLAGS_REG))]
9726   "TARGET_64BIT && INTVAL (operands[2]) == 31
9727    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9728    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9729   "@
9730    {cltd|cdq}
9731    sar{l}\t{%2, %k0|%k0, %2}"
9732   [(set_attr "type" "imovx,ishift")
9733    (set_attr "prefix_0f" "0,*")
9734    (set_attr "length_immediate" "0,*")
9735    (set_attr "modrm" "0,1")
9736    (set_attr "mode" "SI")])
9737
9738 (define_expand "x86_shift<mode>_adj_3"
9739   [(use (match_operand:SWI48 0 "register_operand" ""))
9740    (use (match_operand:SWI48 1 "register_operand" ""))
9741    (use (match_operand:QI 2 "register_operand" ""))]
9742   ""
9743 {
9744   rtx label = gen_label_rtx ();
9745   rtx tmp;
9746
9747   emit_insn (gen_testqi_ccz_1 (operands[2],
9748                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9749
9750   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9751   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9752   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9753                               gen_rtx_LABEL_REF (VOIDmode, label),
9754                               pc_rtx);
9755   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9756   JUMP_LABEL (tmp) = label;
9757
9758   emit_move_insn (operands[0], operands[1]);
9759   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9760                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9761   emit_label (label);
9762   LABEL_NUSES (label) = 1;
9763
9764   DONE;
9765 })
9766
9767 (define_insn "*bmi2_<shift_insn><mode>3_1"
9768   [(set (match_operand:SWI48 0 "register_operand" "=r")
9769         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9770                            (match_operand:SWI48 2 "register_operand" "r")))]
9771   "TARGET_BMI2"
9772   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9773   [(set_attr "type" "ishiftx")
9774    (set_attr "mode" "<MODE>")])
9775
9776 (define_insn "*<shift_insn><mode>3_1"
9777   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9778         (any_shiftrt:SWI48
9779           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9780           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9781    (clobber (reg:CC FLAGS_REG))]
9782   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9783 {
9784   switch (get_attr_type (insn))
9785     {
9786     case TYPE_ISHIFTX:
9787       return "#";
9788
9789     default:
9790       if (operands[2] == const1_rtx
9791           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9792         return "<shift>{<imodesuffix>}\t%0";
9793       else
9794         return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9795     }
9796 }
9797   [(set_attr "isa" "*,bmi2")
9798    (set_attr "type" "ishift,ishiftx")
9799    (set (attr "length_immediate")
9800      (if_then_else
9801        (and (match_operand 2 "const1_operand" "")
9802             (ior (match_test "TARGET_SHIFT1")
9803                  (match_test "optimize_function_for_size_p (cfun)")))
9804        (const_string "0")
9805        (const_string "*")))
9806    (set_attr "mode" "<MODE>")])
9807
9808 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9809 (define_split
9810   [(set (match_operand:SWI48 0 "register_operand" "")
9811         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9812                            (match_operand:QI 2 "register_operand" "")))
9813    (clobber (reg:CC FLAGS_REG))]
9814   "TARGET_BMI2 && reload_completed"
9815   [(set (match_dup 0)
9816         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9817   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9818
9819 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9820   [(set (match_operand:DI 0 "register_operand" "=r")
9821         (zero_extend:DI
9822           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9823                           (match_operand:SI 2 "register_operand" "r"))))]
9824   "TARGET_64BIT && TARGET_BMI2"
9825   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9826   [(set_attr "type" "ishiftx")
9827    (set_attr "mode" "SI")])
9828
9829 (define_insn "*<shift_insn>si3_1_zext"
9830   [(set (match_operand:DI 0 "register_operand" "=r,r")
9831         (zero_extend:DI
9832           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9833                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9834    (clobber (reg:CC FLAGS_REG))]
9835   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9836 {
9837   switch (get_attr_type (insn))
9838     {
9839     case TYPE_ISHIFTX:
9840       return "#";
9841
9842     default:
9843       if (operands[2] == const1_rtx
9844           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9845         return "<shift>{l}\t%k0";
9846       else
9847         return "<shift>{l}\t{%2, %k0|%k0, %2}";
9848     }
9849 }
9850   [(set_attr "isa" "*,bmi2")
9851    (set_attr "type" "ishift,ishiftx")
9852    (set (attr "length_immediate")
9853      (if_then_else
9854        (and (match_operand 2 "const1_operand" "")
9855             (ior (match_test "TARGET_SHIFT1")
9856                  (match_test "optimize_function_for_size_p (cfun)")))
9857        (const_string "0")
9858        (const_string "*")))
9859    (set_attr "mode" "SI")])
9860
9861 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9862 (define_split
9863   [(set (match_operand:DI 0 "register_operand" "")
9864         (zero_extend:DI
9865           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9866                           (match_operand:QI 2 "register_operand" ""))))
9867    (clobber (reg:CC FLAGS_REG))]
9868   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9869   [(set (match_dup 0)
9870         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9871   "operands[2] = gen_lowpart (SImode, operands[2]);")
9872
9873 (define_insn "*<shift_insn><mode>3_1"
9874   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9875         (any_shiftrt:SWI12
9876           (match_operand:SWI12 1 "nonimmediate_operand" "0")
9877           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9878    (clobber (reg:CC FLAGS_REG))]
9879   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9880 {
9881   if (operands[2] == const1_rtx
9882       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9883     return "<shift>{<imodesuffix>}\t%0";
9884   else
9885     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9886 }
9887   [(set_attr "type" "ishift")
9888    (set (attr "length_immediate")
9889      (if_then_else
9890        (and (match_operand 2 "const1_operand" "")
9891             (ior (match_test "TARGET_SHIFT1")
9892                  (match_test "optimize_function_for_size_p (cfun)")))
9893        (const_string "0")
9894        (const_string "*")))
9895    (set_attr "mode" "<MODE>")])
9896
9897 (define_insn "*<shift_insn>qi3_1_slp"
9898   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9899         (any_shiftrt:QI (match_dup 0)
9900                         (match_operand:QI 1 "nonmemory_operand" "cI")))
9901    (clobber (reg:CC FLAGS_REG))]
9902   "(optimize_function_for_size_p (cfun)
9903     || !TARGET_PARTIAL_REG_STALL
9904     || (operands[1] == const1_rtx
9905         && TARGET_SHIFT1))"
9906 {
9907   if (operands[1] == const1_rtx
9908       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9909     return "<shift>{b}\t%0";
9910   else
9911     return "<shift>{b}\t{%1, %0|%0, %1}";
9912 }
9913   [(set_attr "type" "ishift1")
9914    (set (attr "length_immediate")
9915      (if_then_else
9916        (and (match_operand 1 "const1_operand" "")
9917             (ior (match_test "TARGET_SHIFT1")
9918                  (match_test "optimize_function_for_size_p (cfun)")))
9919        (const_string "0")
9920        (const_string "*")))
9921    (set_attr "mode" "QI")])
9922
9923 ;; This pattern can't accept a variable shift count, since shifts by
9924 ;; zero don't affect the flags.  We assume that shifts by constant
9925 ;; zero are optimized away.
9926 (define_insn "*<shift_insn><mode>3_cmp"
9927   [(set (reg FLAGS_REG)
9928         (compare
9929           (any_shiftrt:SWI
9930             (match_operand:SWI 1 "nonimmediate_operand" "0")
9931             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9932           (const_int 0)))
9933    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9934         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9935   "(optimize_function_for_size_p (cfun)
9936     || !TARGET_PARTIAL_FLAG_REG_STALL
9937     || (operands[2] == const1_rtx
9938         && TARGET_SHIFT1))
9939    && ix86_match_ccmode (insn, CCGOCmode)
9940    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9941 {
9942   if (operands[2] == const1_rtx
9943       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9944     return "<shift>{<imodesuffix>}\t%0";
9945   else
9946     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9947 }
9948   [(set_attr "type" "ishift")
9949    (set (attr "length_immediate")
9950      (if_then_else
9951        (and (match_operand 2 "const1_operand" "")
9952             (ior (match_test "TARGET_SHIFT1")
9953                  (match_test "optimize_function_for_size_p (cfun)")))
9954        (const_string "0")
9955        (const_string "*")))
9956    (set_attr "mode" "<MODE>")])
9957
9958 (define_insn "*<shift_insn>si3_cmp_zext"
9959   [(set (reg FLAGS_REG)
9960         (compare
9961           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9962                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
9963           (const_int 0)))
9964    (set (match_operand:DI 0 "register_operand" "=r")
9965         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9966   "TARGET_64BIT
9967    && (optimize_function_for_size_p (cfun)
9968        || !TARGET_PARTIAL_FLAG_REG_STALL
9969        || (operands[2] == const1_rtx
9970            && TARGET_SHIFT1))
9971    && ix86_match_ccmode (insn, CCGOCmode)
9972    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9973 {
9974   if (operands[2] == const1_rtx
9975       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9976     return "<shift>{l}\t%k0";
9977   else
9978     return "<shift>{l}\t{%2, %k0|%k0, %2}";
9979 }
9980   [(set_attr "type" "ishift")
9981    (set (attr "length_immediate")
9982      (if_then_else
9983        (and (match_operand 2 "const1_operand" "")
9984             (ior (match_test "TARGET_SHIFT1")
9985                  (match_test "optimize_function_for_size_p (cfun)")))
9986        (const_string "0")
9987        (const_string "*")))
9988    (set_attr "mode" "SI")])
9989
9990 (define_insn "*<shift_insn><mode>3_cconly"
9991   [(set (reg FLAGS_REG)
9992         (compare
9993           (any_shiftrt:SWI
9994             (match_operand:SWI 1 "register_operand" "0")
9995             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9996           (const_int 0)))
9997    (clobber (match_scratch:SWI 0 "=<r>"))]
9998   "(optimize_function_for_size_p (cfun)
9999     || !TARGET_PARTIAL_FLAG_REG_STALL
10000     || (operands[2] == const1_rtx
10001         && TARGET_SHIFT1))
10002    && ix86_match_ccmode (insn, CCGOCmode)"
10003 {
10004   if (operands[2] == const1_rtx
10005       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10006     return "<shift>{<imodesuffix>}\t%0";
10007   else
10008     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10009 }
10010   [(set_attr "type" "ishift")
10011    (set (attr "length_immediate")
10012      (if_then_else
10013        (and (match_operand 2 "const1_operand" "")
10014             (ior (match_test "TARGET_SHIFT1")
10015                  (match_test "optimize_function_for_size_p (cfun)")))
10016        (const_string "0")
10017        (const_string "*")))
10018    (set_attr "mode" "<MODE>")])
10019 \f
10020 ;; Rotate instructions
10021
10022 (define_expand "<rotate_insn>ti3"
10023   [(set (match_operand:TI 0 "register_operand" "")
10024         (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10025                        (match_operand:QI 2 "nonmemory_operand" "")))]
10026   "TARGET_64BIT"
10027 {
10028   if (const_1_to_63_operand (operands[2], VOIDmode))
10029     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10030                 (operands[0], operands[1], operands[2]));
10031   else
10032     FAIL;
10033
10034   DONE;
10035 })
10036
10037 (define_expand "<rotate_insn>di3"
10038   [(set (match_operand:DI 0 "shiftdi_operand" "")
10039         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10040                        (match_operand:QI 2 "nonmemory_operand" "")))]
10041  ""
10042 {
10043   if (TARGET_64BIT)
10044     ix86_expand_binary_operator (<CODE>, DImode, operands);
10045   else if (const_1_to_31_operand (operands[2], VOIDmode))
10046     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10047                 (operands[0], operands[1], operands[2]));
10048   else
10049     FAIL;
10050
10051   DONE;
10052 })
10053
10054 (define_expand "<rotate_insn><mode>3"
10055   [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10056         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10057                             (match_operand:QI 2 "nonmemory_operand" "")))]
10058   ""
10059   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10060
10061 ;; Avoid useless masking of count operand.
10062 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10063   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10064         (any_rotate:SWI48
10065           (match_operand:SWI48 1 "nonimmediate_operand" "0")
10066           (subreg:QI
10067             (and:SI
10068               (match_operand:SI 2 "nonimmediate_operand" "c")
10069               (match_operand:SI 3 "const_int_operand" "n")) 0)))
10070    (clobber (reg:CC FLAGS_REG))]
10071   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10072    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10073       == GET_MODE_BITSIZE (<MODE>mode)-1"
10074   "#"
10075   "&& 1"
10076   [(parallel [(set (match_dup 0)
10077                    (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10078               (clobber (reg:CC FLAGS_REG))])]
10079 {
10080   if (can_create_pseudo_p ())
10081     operands [2] = force_reg (SImode, operands[2]);
10082
10083   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10084 }
10085   [(set_attr "type" "rotate")
10086    (set_attr "mode" "<MODE>")])
10087
10088 ;; Implement rotation using two double-precision
10089 ;; shift instructions and a scratch register.
10090
10091 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10092  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10093        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10094                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10095   (clobber (reg:CC FLAGS_REG))
10096   (clobber (match_scratch:DWIH 3 "=&r"))]
10097  ""
10098  "#"
10099  "reload_completed"
10100  [(set (match_dup 3) (match_dup 4))
10101   (parallel
10102    [(set (match_dup 4)
10103          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10104                    (lshiftrt:DWIH (match_dup 5)
10105                                   (minus:QI (match_dup 6) (match_dup 2)))))
10106     (clobber (reg:CC FLAGS_REG))])
10107   (parallel
10108    [(set (match_dup 5)
10109          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10110                    (lshiftrt:DWIH (match_dup 3)
10111                                   (minus:QI (match_dup 6) (match_dup 2)))))
10112     (clobber (reg:CC FLAGS_REG))])]
10113 {
10114   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10115
10116   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10117 })
10118
10119 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10120  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10121        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10122                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10123   (clobber (reg:CC FLAGS_REG))
10124   (clobber (match_scratch:DWIH 3 "=&r"))]
10125  ""
10126  "#"
10127  "reload_completed"
10128  [(set (match_dup 3) (match_dup 4))
10129   (parallel
10130    [(set (match_dup 4)
10131          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10132                    (ashift:DWIH (match_dup 5)
10133                                 (minus:QI (match_dup 6) (match_dup 2)))))
10134     (clobber (reg:CC FLAGS_REG))])
10135   (parallel
10136    [(set (match_dup 5)
10137          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10138                    (ashift:DWIH (match_dup 3)
10139                                 (minus:QI (match_dup 6) (match_dup 2)))))
10140     (clobber (reg:CC FLAGS_REG))])]
10141 {
10142   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10143
10144   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10145 })
10146
10147 (define_insn "*bmi2_rorx<mode>3_1"
10148   [(set (match_operand:SWI48 0 "register_operand" "=r")
10149         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10150                         (match_operand:QI 2 "immediate_operand" "<S>")))]
10151   "TARGET_BMI2"
10152   "rorx\t{%2, %1, %0|%0, %1, %2}"
10153   [(set_attr "type" "rotatex")
10154    (set_attr "mode" "<MODE>")])
10155
10156 (define_insn "*<rotate_insn><mode>3_1"
10157   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10158         (any_rotate:SWI48
10159           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10160           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10161    (clobber (reg:CC FLAGS_REG))]
10162   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10163 {
10164   switch (get_attr_type (insn))
10165     {
10166     case TYPE_ROTATEX:
10167       return "#";
10168
10169     default:
10170       if (operands[2] == const1_rtx
10171           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10172         return "<rotate>{<imodesuffix>}\t%0";
10173       else
10174         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10175     }
10176 }
10177   [(set_attr "isa" "*,bmi2")
10178    (set_attr "type" "rotate,rotatex")
10179    (set (attr "length_immediate")
10180      (if_then_else
10181        (and (eq_attr "type" "rotate")
10182             (and (match_operand 2 "const1_operand" "")
10183                  (ior (match_test "TARGET_SHIFT1")
10184                       (match_test "optimize_function_for_size_p (cfun)"))))
10185        (const_string "0")
10186        (const_string "*")))
10187    (set_attr "mode" "<MODE>")])
10188
10189 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10190 (define_split
10191   [(set (match_operand:SWI48 0 "register_operand" "")
10192         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10193                       (match_operand:QI 2 "immediate_operand" "")))
10194    (clobber (reg:CC FLAGS_REG))]
10195   "TARGET_BMI2 && reload_completed"
10196   [(set (match_dup 0)
10197         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10198 {
10199   operands[2]
10200     = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10201 })
10202
10203 (define_split
10204   [(set (match_operand:SWI48 0 "register_operand" "")
10205         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10206                         (match_operand:QI 2 "immediate_operand" "")))
10207    (clobber (reg:CC FLAGS_REG))]
10208   "TARGET_BMI2 && reload_completed"
10209   [(set (match_dup 0)
10210         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10211
10212 (define_insn "*bmi2_rorxsi3_1_zext"
10213   [(set (match_operand:DI 0 "register_operand" "=r")
10214         (zero_extend:DI
10215           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10216                        (match_operand:QI 2 "immediate_operand" "I"))))]
10217   "TARGET_64BIT && TARGET_BMI2"
10218   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10219   [(set_attr "type" "rotatex")
10220    (set_attr "mode" "SI")])
10221
10222 (define_insn "*<rotate_insn>si3_1_zext"
10223   [(set (match_operand:DI 0 "register_operand" "=r,r")
10224         (zero_extend:DI
10225           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10226                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10227    (clobber (reg:CC FLAGS_REG))]
10228   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10229 {
10230   switch (get_attr_type (insn))
10231     {
10232     case TYPE_ROTATEX:
10233       return "#";
10234
10235     default:
10236       if (operands[2] == const1_rtx
10237           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10238         return "<rotate>{l}\t%k0";
10239       else
10240         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10241     }
10242 }
10243   [(set_attr "isa" "*,bmi2")
10244    (set_attr "type" "rotate,rotatex")
10245    (set (attr "length_immediate")
10246      (if_then_else
10247        (and (eq_attr "type" "rotate")
10248             (and (match_operand 2 "const1_operand" "")
10249                  (ior (match_test "TARGET_SHIFT1")
10250                       (match_test "optimize_function_for_size_p (cfun)"))))
10251        (const_string "0")
10252        (const_string "*")))
10253    (set_attr "mode" "SI")])
10254
10255 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10256 (define_split
10257   [(set (match_operand:DI 0 "register_operand" "")
10258         (zero_extend:DI
10259           (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10260                      (match_operand:QI 2 "immediate_operand" ""))))
10261    (clobber (reg:CC FLAGS_REG))]
10262   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10263   [(set (match_dup 0)
10264         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10265 {
10266   operands[2]
10267     = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10268 })
10269
10270 (define_split
10271   [(set (match_operand:DI 0 "register_operand" "")
10272         (zero_extend:DI
10273           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10274                        (match_operand:QI 2 "immediate_operand" ""))))
10275    (clobber (reg:CC FLAGS_REG))]
10276   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10277   [(set (match_dup 0)
10278         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10279
10280 (define_insn "*<rotate_insn><mode>3_1"
10281   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10282         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10283                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10284    (clobber (reg:CC FLAGS_REG))]
10285   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10286 {
10287   if (operands[2] == const1_rtx
10288       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10289     return "<rotate>{<imodesuffix>}\t%0";
10290   else
10291     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10292 }
10293   [(set_attr "type" "rotate")
10294    (set (attr "length_immediate")
10295      (if_then_else
10296        (and (match_operand 2 "const1_operand" "")
10297             (ior (match_test "TARGET_SHIFT1")
10298                  (match_test "optimize_function_for_size_p (cfun)")))
10299        (const_string "0")
10300        (const_string "*")))
10301    (set_attr "mode" "<MODE>")])
10302
10303 (define_insn "*<rotate_insn>qi3_1_slp"
10304   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10305         (any_rotate:QI (match_dup 0)
10306                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10307    (clobber (reg:CC FLAGS_REG))]
10308   "(optimize_function_for_size_p (cfun)
10309     || !TARGET_PARTIAL_REG_STALL
10310     || (operands[1] == const1_rtx
10311         && TARGET_SHIFT1))"
10312 {
10313   if (operands[1] == const1_rtx
10314       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10315     return "<rotate>{b}\t%0";
10316   else
10317     return "<rotate>{b}\t{%1, %0|%0, %1}";
10318 }
10319   [(set_attr "type" "rotate1")
10320    (set (attr "length_immediate")
10321      (if_then_else
10322        (and (match_operand 1 "const1_operand" "")
10323             (ior (match_test "TARGET_SHIFT1")
10324                  (match_test "optimize_function_for_size_p (cfun)")))
10325        (const_string "0")
10326        (const_string "*")))
10327    (set_attr "mode" "QI")])
10328
10329 (define_split
10330  [(set (match_operand:HI 0 "register_operand" "")
10331        (any_rotate:HI (match_dup 0) (const_int 8)))
10332   (clobber (reg:CC FLAGS_REG))]
10333  "reload_completed
10334   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10335  [(parallel [(set (strict_low_part (match_dup 0))
10336                   (bswap:HI (match_dup 0)))
10337              (clobber (reg:CC FLAGS_REG))])])
10338 \f
10339 ;; Bit set / bit test instructions
10340
10341 (define_expand "extv"
10342   [(set (match_operand:SI 0 "register_operand" "")
10343         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10344                          (match_operand:SI 2 "const8_operand" "")
10345                          (match_operand:SI 3 "const8_operand" "")))]
10346   ""
10347 {
10348   /* Handle extractions from %ah et al.  */
10349   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10350     FAIL;
10351
10352   /* From mips.md: extract_bit_field doesn't verify that our source
10353      matches the predicate, so check it again here.  */
10354   if (! ext_register_operand (operands[1], VOIDmode))
10355     FAIL;
10356 })
10357
10358 (define_expand "extzv"
10359   [(set (match_operand:SI 0 "register_operand" "")
10360         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10361                          (match_operand:SI 2 "const8_operand" "")
10362                          (match_operand:SI 3 "const8_operand" "")))]
10363   ""
10364 {
10365   /* Handle extractions from %ah et al.  */
10366   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10367     FAIL;
10368
10369   /* From mips.md: extract_bit_field doesn't verify that our source
10370      matches the predicate, so check it again here.  */
10371   if (! ext_register_operand (operands[1], VOIDmode))
10372     FAIL;
10373 })
10374
10375 (define_expand "insv"
10376   [(set (zero_extract (match_operand 0 "register_operand" "")
10377                       (match_operand 1 "const_int_operand" "")
10378                       (match_operand 2 "const_int_operand" ""))
10379         (match_operand 3 "register_operand" ""))]
10380   ""
10381 {
10382   rtx (*gen_mov_insv_1) (rtx, rtx);
10383
10384   if (ix86_expand_pinsr (operands))
10385     DONE;
10386
10387   /* Handle insertions to %ah et al.  */
10388   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10389     FAIL;
10390
10391   /* From mips.md: insert_bit_field doesn't verify that our source
10392      matches the predicate, so check it again here.  */
10393   if (! ext_register_operand (operands[0], VOIDmode))
10394     FAIL;
10395
10396   gen_mov_insv_1 = (TARGET_64BIT
10397                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10398
10399   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10400   DONE;
10401 })
10402
10403 ;; %%% bts, btr, btc, bt.
10404 ;; In general these instructions are *slow* when applied to memory,
10405 ;; since they enforce atomic operation.  When applied to registers,
10406 ;; it depends on the cpu implementation.  They're never faster than
10407 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10408 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10409 ;; within the instruction itself, so operating on bits in the high
10410 ;; 32-bits of a register becomes easier.
10411 ;;
10412 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10413 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10414 ;; negdf respectively, so they can never be disabled entirely.
10415
10416 (define_insn "*btsq"
10417   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10418                          (const_int 1)
10419                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10420         (const_int 1))
10421    (clobber (reg:CC FLAGS_REG))]
10422   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10423   "bts{q}\t{%1, %0|%0, %1}"
10424   [(set_attr "type" "alu1")
10425    (set_attr "prefix_0f" "1")
10426    (set_attr "mode" "DI")])
10427
10428 (define_insn "*btrq"
10429   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10430                          (const_int 1)
10431                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10432         (const_int 0))
10433    (clobber (reg:CC FLAGS_REG))]
10434   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10435   "btr{q}\t{%1, %0|%0, %1}"
10436   [(set_attr "type" "alu1")
10437    (set_attr "prefix_0f" "1")
10438    (set_attr "mode" "DI")])
10439
10440 (define_insn "*btcq"
10441   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10442                          (const_int 1)
10443                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10444         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10445    (clobber (reg:CC FLAGS_REG))]
10446   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10447   "btc{q}\t{%1, %0|%0, %1}"
10448   [(set_attr "type" "alu1")
10449    (set_attr "prefix_0f" "1")
10450    (set_attr "mode" "DI")])
10451
10452 ;; Allow Nocona to avoid these instructions if a register is available.
10453
10454 (define_peephole2
10455   [(match_scratch:DI 2 "r")
10456    (parallel [(set (zero_extract:DI
10457                      (match_operand:DI 0 "register_operand" "")
10458                      (const_int 1)
10459                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10460                    (const_int 1))
10461               (clobber (reg:CC FLAGS_REG))])]
10462   "TARGET_64BIT && !TARGET_USE_BT"
10463   [(const_int 0)]
10464 {
10465   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10466   rtx op1;
10467
10468   if (HOST_BITS_PER_WIDE_INT >= 64)
10469     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10470   else if (i < HOST_BITS_PER_WIDE_INT)
10471     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10472   else
10473     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10474
10475   op1 = immed_double_const (lo, hi, DImode);
10476   if (i >= 31)
10477     {
10478       emit_move_insn (operands[2], op1);
10479       op1 = operands[2];
10480     }
10481
10482   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10483   DONE;
10484 })
10485
10486 (define_peephole2
10487   [(match_scratch:DI 2 "r")
10488    (parallel [(set (zero_extract:DI
10489                      (match_operand:DI 0 "register_operand" "")
10490                      (const_int 1)
10491                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10492                    (const_int 0))
10493               (clobber (reg:CC FLAGS_REG))])]
10494   "TARGET_64BIT && !TARGET_USE_BT"
10495   [(const_int 0)]
10496 {
10497   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10498   rtx op1;
10499
10500   if (HOST_BITS_PER_WIDE_INT >= 64)
10501     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10502   else if (i < HOST_BITS_PER_WIDE_INT)
10503     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10504   else
10505     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10506
10507   op1 = immed_double_const (~lo, ~hi, DImode);
10508   if (i >= 32)
10509     {
10510       emit_move_insn (operands[2], op1);
10511       op1 = operands[2];
10512     }
10513
10514   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10515   DONE;
10516 })
10517
10518 (define_peephole2
10519   [(match_scratch:DI 2 "r")
10520    (parallel [(set (zero_extract:DI
10521                      (match_operand:DI 0 "register_operand" "")
10522                      (const_int 1)
10523                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10524               (not:DI (zero_extract:DI
10525                         (match_dup 0) (const_int 1) (match_dup 1))))
10526               (clobber (reg:CC FLAGS_REG))])]
10527   "TARGET_64BIT && !TARGET_USE_BT"
10528   [(const_int 0)]
10529 {
10530   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10531   rtx op1;
10532
10533   if (HOST_BITS_PER_WIDE_INT >= 64)
10534     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10535   else if (i < HOST_BITS_PER_WIDE_INT)
10536     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10537   else
10538     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10539
10540   op1 = immed_double_const (lo, hi, DImode);
10541   if (i >= 31)
10542     {
10543       emit_move_insn (operands[2], op1);
10544       op1 = operands[2];
10545     }
10546
10547   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10548   DONE;
10549 })
10550
10551 (define_insn "*bt<mode>"
10552   [(set (reg:CCC FLAGS_REG)
10553         (compare:CCC
10554           (zero_extract:SWI48
10555             (match_operand:SWI48 0 "register_operand" "r")
10556             (const_int 1)
10557             (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10558           (const_int 0)))]
10559   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10560   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10561   [(set_attr "type" "alu1")
10562    (set_attr "prefix_0f" "1")
10563    (set_attr "mode" "<MODE>")])
10564 \f
10565 ;; Store-flag instructions.
10566
10567 ;; For all sCOND expanders, also expand the compare or test insn that
10568 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10569
10570 (define_insn_and_split "*setcc_di_1"
10571   [(set (match_operand:DI 0 "register_operand" "=q")
10572         (match_operator:DI 1 "ix86_comparison_operator"
10573           [(reg FLAGS_REG) (const_int 0)]))]
10574   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10575   "#"
10576   "&& reload_completed"
10577   [(set (match_dup 2) (match_dup 1))
10578    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10579 {
10580   PUT_MODE (operands[1], QImode);
10581   operands[2] = gen_lowpart (QImode, operands[0]);
10582 })
10583
10584 (define_insn_and_split "*setcc_si_1_and"
10585   [(set (match_operand:SI 0 "register_operand" "=q")
10586         (match_operator:SI 1 "ix86_comparison_operator"
10587           [(reg FLAGS_REG) (const_int 0)]))
10588    (clobber (reg:CC FLAGS_REG))]
10589   "!TARGET_PARTIAL_REG_STALL
10590    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10591   "#"
10592   "&& reload_completed"
10593   [(set (match_dup 2) (match_dup 1))
10594    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10595               (clobber (reg:CC FLAGS_REG))])]
10596 {
10597   PUT_MODE (operands[1], QImode);
10598   operands[2] = gen_lowpart (QImode, operands[0]);
10599 })
10600
10601 (define_insn_and_split "*setcc_si_1_movzbl"
10602   [(set (match_operand:SI 0 "register_operand" "=q")
10603         (match_operator:SI 1 "ix86_comparison_operator"
10604           [(reg FLAGS_REG) (const_int 0)]))]
10605   "!TARGET_PARTIAL_REG_STALL
10606    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10607   "#"
10608   "&& reload_completed"
10609   [(set (match_dup 2) (match_dup 1))
10610    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10611 {
10612   PUT_MODE (operands[1], QImode);
10613   operands[2] = gen_lowpart (QImode, operands[0]);
10614 })
10615
10616 (define_insn "*setcc_qi"
10617   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10618         (match_operator:QI 1 "ix86_comparison_operator"
10619           [(reg FLAGS_REG) (const_int 0)]))]
10620   ""
10621   "set%C1\t%0"
10622   [(set_attr "type" "setcc")
10623    (set_attr "mode" "QI")])
10624
10625 (define_insn "*setcc_qi_slp"
10626   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10627         (match_operator:QI 1 "ix86_comparison_operator"
10628           [(reg FLAGS_REG) (const_int 0)]))]
10629   ""
10630   "set%C1\t%0"
10631   [(set_attr "type" "setcc")
10632    (set_attr "mode" "QI")])
10633
10634 ;; In general it is not safe to assume too much about CCmode registers,
10635 ;; so simplify-rtx stops when it sees a second one.  Under certain
10636 ;; conditions this is safe on x86, so help combine not create
10637 ;;
10638 ;;      seta    %al
10639 ;;      testb   %al, %al
10640 ;;      sete    %al
10641
10642 (define_split
10643   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10644         (ne:QI (match_operator 1 "ix86_comparison_operator"
10645                  [(reg FLAGS_REG) (const_int 0)])
10646             (const_int 0)))]
10647   ""
10648   [(set (match_dup 0) (match_dup 1))]
10649   "PUT_MODE (operands[1], QImode);")
10650
10651 (define_split
10652   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10653         (ne:QI (match_operator 1 "ix86_comparison_operator"
10654                  [(reg FLAGS_REG) (const_int 0)])
10655             (const_int 0)))]
10656   ""
10657   [(set (match_dup 0) (match_dup 1))]
10658   "PUT_MODE (operands[1], QImode);")
10659
10660 (define_split
10661   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10662         (eq:QI (match_operator 1 "ix86_comparison_operator"
10663                  [(reg FLAGS_REG) (const_int 0)])
10664             (const_int 0)))]
10665   ""
10666   [(set (match_dup 0) (match_dup 1))]
10667 {
10668   rtx new_op1 = copy_rtx (operands[1]);
10669   operands[1] = new_op1;
10670   PUT_MODE (new_op1, QImode);
10671   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10672                                              GET_MODE (XEXP (new_op1, 0))));
10673
10674   /* Make sure that (a) the CCmode we have for the flags is strong
10675      enough for the reversed compare or (b) we have a valid FP compare.  */
10676   if (! ix86_comparison_operator (new_op1, VOIDmode))
10677     FAIL;
10678 })
10679
10680 (define_split
10681   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10682         (eq:QI (match_operator 1 "ix86_comparison_operator"
10683                  [(reg FLAGS_REG) (const_int 0)])
10684             (const_int 0)))]
10685   ""
10686   [(set (match_dup 0) (match_dup 1))]
10687 {
10688   rtx new_op1 = copy_rtx (operands[1]);
10689   operands[1] = new_op1;
10690   PUT_MODE (new_op1, QImode);
10691   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10692                                              GET_MODE (XEXP (new_op1, 0))));
10693
10694   /* Make sure that (a) the CCmode we have for the flags is strong
10695      enough for the reversed compare or (b) we have a valid FP compare.  */
10696   if (! ix86_comparison_operator (new_op1, VOIDmode))
10697     FAIL;
10698 })
10699
10700 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10701 ;; subsequent logical operations are used to imitate conditional moves.
10702 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10703 ;; it directly.
10704
10705 (define_insn "setcc_<mode>_sse"
10706   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10707         (match_operator:MODEF 3 "sse_comparison_operator"
10708           [(match_operand:MODEF 1 "register_operand" "0,x")
10709            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10710   "SSE_FLOAT_MODE_P (<MODE>mode)"
10711   "@
10712    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10713    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10714   [(set_attr "isa" "noavx,avx")
10715    (set_attr "type" "ssecmp")
10716    (set_attr "length_immediate" "1")
10717    (set_attr "prefix" "orig,vex")
10718    (set_attr "mode" "<MODE>")])
10719 \f
10720 ;; Basic conditional jump instructions.
10721 ;; We ignore the overflow flag for signed branch instructions.
10722
10723 (define_insn "*jcc_1"
10724   [(set (pc)
10725         (if_then_else (match_operator 1 "ix86_comparison_operator"
10726                                       [(reg FLAGS_REG) (const_int 0)])
10727                       (label_ref (match_operand 0 "" ""))
10728                       (pc)))]
10729   ""
10730   "%+j%C1\t%l0"
10731   [(set_attr "type" "ibr")
10732    (set_attr "modrm" "0")
10733    (set (attr "length")
10734            (if_then_else (and (ge (minus (match_dup 0) (pc))
10735                                   (const_int -126))
10736                               (lt (minus (match_dup 0) (pc))
10737                                   (const_int 128)))
10738              (const_int 2)
10739              (const_int 6)))])
10740
10741 (define_insn "*jcc_2"
10742   [(set (pc)
10743         (if_then_else (match_operator 1 "ix86_comparison_operator"
10744                                       [(reg FLAGS_REG) (const_int 0)])
10745                       (pc)
10746                       (label_ref (match_operand 0 "" ""))))]
10747   ""
10748   "%+j%c1\t%l0"
10749   [(set_attr "type" "ibr")
10750    (set_attr "modrm" "0")
10751    (set (attr "length")
10752            (if_then_else (and (ge (minus (match_dup 0) (pc))
10753                                   (const_int -126))
10754                               (lt (minus (match_dup 0) (pc))
10755                                   (const_int 128)))
10756              (const_int 2)
10757              (const_int 6)))])
10758
10759 ;; In general it is not safe to assume too much about CCmode registers,
10760 ;; so simplify-rtx stops when it sees a second one.  Under certain
10761 ;; conditions this is safe on x86, so help combine not create
10762 ;;
10763 ;;      seta    %al
10764 ;;      testb   %al, %al
10765 ;;      je      Lfoo
10766
10767 (define_split
10768   [(set (pc)
10769         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10770                                       [(reg FLAGS_REG) (const_int 0)])
10771                           (const_int 0))
10772                       (label_ref (match_operand 1 "" ""))
10773                       (pc)))]
10774   ""
10775   [(set (pc)
10776         (if_then_else (match_dup 0)
10777                       (label_ref (match_dup 1))
10778                       (pc)))]
10779   "PUT_MODE (operands[0], VOIDmode);")
10780
10781 (define_split
10782   [(set (pc)
10783         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10784                                       [(reg FLAGS_REG) (const_int 0)])
10785                           (const_int 0))
10786                       (label_ref (match_operand 1 "" ""))
10787                       (pc)))]
10788   ""
10789   [(set (pc)
10790         (if_then_else (match_dup 0)
10791                       (label_ref (match_dup 1))
10792                       (pc)))]
10793 {
10794   rtx new_op0 = copy_rtx (operands[0]);
10795   operands[0] = new_op0;
10796   PUT_MODE (new_op0, VOIDmode);
10797   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10798                                              GET_MODE (XEXP (new_op0, 0))));
10799
10800   /* Make sure that (a) the CCmode we have for the flags is strong
10801      enough for the reversed compare or (b) we have a valid FP compare.  */
10802   if (! ix86_comparison_operator (new_op0, VOIDmode))
10803     FAIL;
10804 })
10805
10806 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10807 ;; pass generates from shift insn with QImode operand.  Actually, the mode
10808 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10809 ;; appropriate modulo of the bit offset value.
10810
10811 (define_insn_and_split "*jcc_bt<mode>"
10812   [(set (pc)
10813         (if_then_else (match_operator 0 "bt_comparison_operator"
10814                         [(zero_extract:SWI48
10815                            (match_operand:SWI48 1 "register_operand" "r")
10816                            (const_int 1)
10817                            (zero_extend:SI
10818                              (match_operand:QI 2 "register_operand" "r")))
10819                          (const_int 0)])
10820                       (label_ref (match_operand 3 "" ""))
10821                       (pc)))
10822    (clobber (reg:CC FLAGS_REG))]
10823   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10824   "#"
10825   "&& 1"
10826   [(set (reg:CCC FLAGS_REG)
10827         (compare:CCC
10828           (zero_extract:SWI48
10829             (match_dup 1)
10830             (const_int 1)
10831             (match_dup 2))
10832           (const_int 0)))
10833    (set (pc)
10834         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10835                       (label_ref (match_dup 3))
10836                       (pc)))]
10837 {
10838   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10839
10840   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10841 })
10842
10843 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10844 ;; also for DImode, this is what combine produces.
10845 (define_insn_and_split "*jcc_bt<mode>_mask"
10846   [(set (pc)
10847         (if_then_else (match_operator 0 "bt_comparison_operator"
10848                         [(zero_extract:SWI48
10849                            (match_operand:SWI48 1 "register_operand" "r")
10850                            (const_int 1)
10851                            (and:SI
10852                              (match_operand:SI 2 "register_operand" "r")
10853                              (match_operand:SI 3 "const_int_operand" "n")))])
10854                       (label_ref (match_operand 4 "" ""))
10855                       (pc)))
10856    (clobber (reg:CC FLAGS_REG))]
10857   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10858    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10859       == GET_MODE_BITSIZE (<MODE>mode)-1"
10860   "#"
10861   "&& 1"
10862   [(set (reg:CCC FLAGS_REG)
10863         (compare:CCC
10864           (zero_extract:SWI48
10865             (match_dup 1)
10866             (const_int 1)
10867             (match_dup 2))
10868           (const_int 0)))
10869    (set (pc)
10870         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10871                       (label_ref (match_dup 4))
10872                       (pc)))]
10873 {
10874   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10875
10876   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10877 })
10878
10879 (define_insn_and_split "*jcc_btsi_1"
10880   [(set (pc)
10881         (if_then_else (match_operator 0 "bt_comparison_operator"
10882                         [(and:SI
10883                            (lshiftrt:SI
10884                              (match_operand:SI 1 "register_operand" "r")
10885                              (match_operand:QI 2 "register_operand" "r"))
10886                            (const_int 1))
10887                          (const_int 0)])
10888                       (label_ref (match_operand 3 "" ""))
10889                       (pc)))
10890    (clobber (reg:CC FLAGS_REG))]
10891   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10892   "#"
10893   "&& 1"
10894   [(set (reg:CCC FLAGS_REG)
10895         (compare:CCC
10896           (zero_extract:SI
10897             (match_dup 1)
10898             (const_int 1)
10899             (match_dup 2))
10900           (const_int 0)))
10901    (set (pc)
10902         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10903                       (label_ref (match_dup 3))
10904                       (pc)))]
10905 {
10906   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10907
10908   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10909 })
10910
10911 ;; avoid useless masking of bit offset operand
10912 (define_insn_and_split "*jcc_btsi_mask_1"
10913   [(set (pc)
10914         (if_then_else
10915           (match_operator 0 "bt_comparison_operator"
10916             [(and:SI
10917                (lshiftrt:SI
10918                  (match_operand:SI 1 "register_operand" "r")
10919                  (subreg:QI
10920                    (and:SI
10921                      (match_operand:SI 2 "register_operand" "r")
10922                      (match_operand:SI 3 "const_int_operand" "n")) 0))
10923                (const_int 1))
10924              (const_int 0)])
10925           (label_ref (match_operand 4 "" ""))
10926           (pc)))
10927    (clobber (reg:CC FLAGS_REG))]
10928   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10929    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10930   "#"
10931   "&& 1"
10932   [(set (reg:CCC FLAGS_REG)
10933         (compare:CCC
10934           (zero_extract:SI
10935             (match_dup 1)
10936             (const_int 1)
10937             (match_dup 2))
10938           (const_int 0)))
10939    (set (pc)
10940         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10941                       (label_ref (match_dup 4))
10942                       (pc)))]
10943   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10944
10945 ;; Define combination compare-and-branch fp compare instructions to help
10946 ;; combine.
10947
10948 (define_insn "*fp_jcc_1_387"
10949   [(set (pc)
10950         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10951                         [(match_operand 1 "register_operand" "f")
10952                          (match_operand 2 "nonimmediate_operand" "fm")])
10953           (label_ref (match_operand 3 "" ""))
10954           (pc)))
10955    (clobber (reg:CCFP FPSR_REG))
10956    (clobber (reg:CCFP FLAGS_REG))
10957    (clobber (match_scratch:HI 4 "=a"))]
10958   "TARGET_80387
10959    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10960    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10961    && SELECT_CC_MODE (GET_CODE (operands[0]),
10962                       operands[1], operands[2]) == CCFPmode
10963    && !TARGET_CMOVE"
10964   "#")
10965
10966 (define_insn "*fp_jcc_1r_387"
10967   [(set (pc)
10968         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10969                         [(match_operand 1 "register_operand" "f")
10970                          (match_operand 2 "nonimmediate_operand" "fm")])
10971           (pc)
10972           (label_ref (match_operand 3 "" ""))))
10973    (clobber (reg:CCFP FPSR_REG))
10974    (clobber (reg:CCFP FLAGS_REG))
10975    (clobber (match_scratch:HI 4 "=a"))]
10976   "TARGET_80387
10977    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10978    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10979    && SELECT_CC_MODE (GET_CODE (operands[0]),
10980                       operands[1], operands[2]) == CCFPmode
10981    && !TARGET_CMOVE"
10982   "#")
10983
10984 (define_insn "*fp_jcc_2_387"
10985   [(set (pc)
10986         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10987                         [(match_operand 1 "register_operand" "f")
10988                          (match_operand 2 "register_operand" "f")])
10989           (label_ref (match_operand 3 "" ""))
10990           (pc)))
10991    (clobber (reg:CCFP FPSR_REG))
10992    (clobber (reg:CCFP FLAGS_REG))
10993    (clobber (match_scratch:HI 4 "=a"))]
10994   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10995    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10996    && !TARGET_CMOVE"
10997   "#")
10998
10999 (define_insn "*fp_jcc_2r_387"
11000   [(set (pc)
11001         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11002                         [(match_operand 1 "register_operand" "f")
11003                          (match_operand 2 "register_operand" "f")])
11004           (pc)
11005           (label_ref (match_operand 3 "" ""))))
11006    (clobber (reg:CCFP FPSR_REG))
11007    (clobber (reg:CCFP FLAGS_REG))
11008    (clobber (match_scratch:HI 4 "=a"))]
11009   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11010    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11011    && !TARGET_CMOVE"
11012   "#")
11013
11014 (define_insn "*fp_jcc_3_387"
11015   [(set (pc)
11016         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11017                         [(match_operand 1 "register_operand" "f")
11018                          (match_operand 2 "const0_operand" "")])
11019           (label_ref (match_operand 3 "" ""))
11020           (pc)))
11021    (clobber (reg:CCFP FPSR_REG))
11022    (clobber (reg:CCFP FLAGS_REG))
11023    (clobber (match_scratch:HI 4 "=a"))]
11024   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11025    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11026    && SELECT_CC_MODE (GET_CODE (operands[0]),
11027                       operands[1], operands[2]) == CCFPmode
11028    && !TARGET_CMOVE"
11029   "#")
11030
11031 (define_split
11032   [(set (pc)
11033         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11034                         [(match_operand 1 "register_operand" "")
11035                          (match_operand 2 "nonimmediate_operand" "")])
11036           (match_operand 3 "" "")
11037           (match_operand 4 "" "")))
11038    (clobber (reg:CCFP FPSR_REG))
11039    (clobber (reg:CCFP FLAGS_REG))]
11040   "reload_completed"
11041   [(const_int 0)]
11042 {
11043   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11044                         operands[3], operands[4], NULL_RTX, NULL_RTX);
11045   DONE;
11046 })
11047
11048 (define_split
11049   [(set (pc)
11050         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11051                         [(match_operand 1 "register_operand" "")
11052                          (match_operand 2 "general_operand" "")])
11053           (match_operand 3 "" "")
11054           (match_operand 4 "" "")))
11055    (clobber (reg:CCFP FPSR_REG))
11056    (clobber (reg:CCFP FLAGS_REG))
11057    (clobber (match_scratch:HI 5 "=a"))]
11058   "reload_completed"
11059   [(const_int 0)]
11060 {
11061   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11062                         operands[3], operands[4], operands[5], NULL_RTX);
11063   DONE;
11064 })
11065
11066 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11067 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11068 ;; with a precedence over other operators and is always put in the first
11069 ;; place. Swap condition and operands to match ficom instruction.
11070
11071 (define_insn "*fp_jcc_4_<mode>_387"
11072   [(set (pc)
11073         (if_then_else
11074           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11075             [(match_operator 1 "float_operator"
11076               [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11077              (match_operand 3 "register_operand" "f,f")])
11078           (label_ref (match_operand 4 "" ""))
11079           (pc)))
11080    (clobber (reg:CCFP FPSR_REG))
11081    (clobber (reg:CCFP FLAGS_REG))
11082    (clobber (match_scratch:HI 5 "=a,a"))]
11083   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11084    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11085    && GET_MODE (operands[1]) == GET_MODE (operands[3])
11086    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11087    && !TARGET_CMOVE"
11088   "#")
11089
11090 (define_split
11091   [(set (pc)
11092         (if_then_else
11093           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11094             [(match_operator 1 "float_operator"
11095               [(match_operand:SWI24 2 "memory_operand" "")])
11096              (match_operand 3 "register_operand" "")])
11097           (match_operand 4 "" "")
11098           (match_operand 5 "" "")))
11099    (clobber (reg:CCFP FPSR_REG))
11100    (clobber (reg:CCFP FLAGS_REG))
11101    (clobber (match_scratch:HI 6 "=a"))]
11102   "reload_completed"
11103   [(const_int 0)]
11104 {
11105   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11106
11107   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11108                         operands[3], operands[7],
11109                         operands[4], operands[5], operands[6], NULL_RTX);
11110   DONE;
11111 })
11112
11113 ;; %%% Kill this when reload knows how to do it.
11114 (define_split
11115   [(set (pc)
11116         (if_then_else
11117           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11118             [(match_operator 1 "float_operator"
11119               [(match_operand:SWI24 2 "register_operand" "")])
11120              (match_operand 3 "register_operand" "")])
11121           (match_operand 4 "" "")
11122           (match_operand 5 "" "")))
11123    (clobber (reg:CCFP FPSR_REG))
11124    (clobber (reg:CCFP FLAGS_REG))
11125    (clobber (match_scratch:HI 6 "=a"))]
11126   "reload_completed"
11127   [(const_int 0)]
11128 {
11129   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11130   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11131
11132   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11133                         operands[3], operands[7],
11134                         operands[4], operands[5], operands[6], operands[2]);
11135   DONE;
11136 })
11137 \f
11138 ;; Unconditional and other jump instructions
11139
11140 (define_insn "jump"
11141   [(set (pc)
11142         (label_ref (match_operand 0 "" "")))]
11143   ""
11144   "jmp\t%l0"
11145   [(set_attr "type" "ibr")
11146    (set (attr "length")
11147            (if_then_else (and (ge (minus (match_dup 0) (pc))
11148                                   (const_int -126))
11149                               (lt (minus (match_dup 0) (pc))
11150                                   (const_int 128)))
11151              (const_int 2)
11152              (const_int 5)))
11153    (set_attr "modrm" "0")])
11154
11155 (define_expand "indirect_jump"
11156   [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11157
11158 (define_insn "*indirect_jump"
11159   [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11160   ""
11161   "jmp\t%A0"
11162   [(set_attr "type" "ibr")
11163    (set_attr "length_immediate" "0")])
11164
11165 (define_expand "tablejump"
11166   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11167               (use (label_ref (match_operand 1 "" "")))])]
11168   ""
11169 {
11170   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11171      relative.  Convert the relative address to an absolute address.  */
11172   if (flag_pic)
11173     {
11174       rtx op0, op1;
11175       enum rtx_code code;
11176
11177       /* We can't use @GOTOFF for text labels on VxWorks;
11178          see gotoff_operand.  */
11179       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11180         {
11181           code = PLUS;
11182           op0 = operands[0];
11183           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11184         }
11185       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11186         {
11187           code = PLUS;
11188           op0 = operands[0];
11189           op1 = pic_offset_table_rtx;
11190         }
11191       else
11192         {
11193           code = MINUS;
11194           op0 = pic_offset_table_rtx;
11195           op1 = operands[0];
11196         }
11197
11198       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11199                                          OPTAB_DIRECT);
11200     }
11201   else if (TARGET_X32)
11202     operands[0] = convert_memory_address (Pmode, operands[0]);
11203 })
11204
11205 (define_insn "*tablejump_1"
11206   [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11207    (use (label_ref (match_operand 1 "" "")))]
11208   ""
11209   "jmp\t%A0"
11210   [(set_attr "type" "ibr")
11211    (set_attr "length_immediate" "0")])
11212 \f
11213 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11214
11215 (define_peephole2
11216   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11217    (set (match_operand:QI 1 "register_operand" "")
11218         (match_operator:QI 2 "ix86_comparison_operator"
11219           [(reg FLAGS_REG) (const_int 0)]))
11220    (set (match_operand 3 "q_regs_operand" "")
11221         (zero_extend (match_dup 1)))]
11222   "(peep2_reg_dead_p (3, operands[1])
11223     || operands_match_p (operands[1], operands[3]))
11224    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11225   [(set (match_dup 4) (match_dup 0))
11226    (set (strict_low_part (match_dup 5))
11227         (match_dup 2))]
11228 {
11229   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11230   operands[5] = gen_lowpart (QImode, operands[3]);
11231   ix86_expand_clear (operands[3]);
11232 })
11233
11234 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11235
11236 (define_peephole2
11237   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11238    (set (match_operand:QI 1 "register_operand" "")
11239         (match_operator:QI 2 "ix86_comparison_operator"
11240           [(reg FLAGS_REG) (const_int 0)]))
11241    (parallel [(set (match_operand 3 "q_regs_operand" "")
11242                    (zero_extend (match_dup 1)))
11243               (clobber (reg:CC FLAGS_REG))])]
11244   "(peep2_reg_dead_p (3, operands[1])
11245     || operands_match_p (operands[1], operands[3]))
11246    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11247   [(set (match_dup 4) (match_dup 0))
11248    (set (strict_low_part (match_dup 5))
11249         (match_dup 2))]
11250 {
11251   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11252   operands[5] = gen_lowpart (QImode, operands[3]);
11253   ix86_expand_clear (operands[3]);
11254 })
11255 \f
11256 ;; Call instructions.
11257
11258 ;; The predicates normally associated with named expanders are not properly
11259 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11260 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11261
11262 ;; P6 processors will jump to the address after the decrement when %esp
11263 ;; is used as a call operand, so they will execute return address as a code.
11264 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11265
11266 ;; Register constraint for call instruction.
11267 (define_mode_attr c [(SI "l") (DI "r")])
11268
11269 ;; Call subroutine returning no value.
11270
11271 (define_expand "call"
11272   [(call (match_operand:QI 0 "" "")
11273          (match_operand 1 "" ""))
11274    (use (match_operand 2 "" ""))]
11275   ""
11276 {
11277   ix86_expand_call (NULL, operands[0], operands[1],
11278                     operands[2], NULL, false);
11279   DONE;
11280 })
11281
11282 (define_expand "sibcall"
11283   [(call (match_operand:QI 0 "" "")
11284          (match_operand 1 "" ""))
11285    (use (match_operand 2 "" ""))]
11286   ""
11287 {
11288   ix86_expand_call (NULL, operands[0], operands[1],
11289                     operands[2], NULL, true);
11290   DONE;
11291 })
11292
11293 (define_insn_and_split "*call_vzeroupper"
11294   [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11295          (match_operand 1 "" ""))
11296    (unspec [(match_operand 2 "const_int_operand" "")]
11297            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11298   "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11299   "#"
11300   "&& reload_completed"
11301   [(const_int 0)]
11302   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11303   [(set_attr "type" "call")])
11304
11305 (define_insn "*call"
11306   [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11307          (match_operand 1 "" ""))]
11308   "!SIBLING_CALL_P (insn)"
11309   "* return ix86_output_call_insn (insn, operands[0]);"
11310   [(set_attr "type" "call")])
11311
11312 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11313   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11314          (match_operand 1 "" ""))
11315    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11316    (clobber (reg:TI XMM6_REG))
11317    (clobber (reg:TI XMM7_REG))
11318    (clobber (reg:TI XMM8_REG))
11319    (clobber (reg:TI XMM9_REG))
11320    (clobber (reg:TI XMM10_REG))
11321    (clobber (reg:TI XMM11_REG))
11322    (clobber (reg:TI XMM12_REG))
11323    (clobber (reg:TI XMM13_REG))
11324    (clobber (reg:TI XMM14_REG))
11325    (clobber (reg:TI XMM15_REG))
11326    (clobber (reg:DI SI_REG))
11327    (clobber (reg:DI DI_REG))
11328    (unspec [(match_operand 2 "const_int_operand" "")]
11329            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11330   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11331   "#"
11332   "&& reload_completed"
11333   [(const_int 0)]
11334   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11335   [(set_attr "type" "call")])
11336
11337 (define_insn "*call_rex64_ms_sysv"
11338   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11339          (match_operand 1 "" ""))
11340    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11341    (clobber (reg:TI XMM6_REG))
11342    (clobber (reg:TI XMM7_REG))
11343    (clobber (reg:TI XMM8_REG))
11344    (clobber (reg:TI XMM9_REG))
11345    (clobber (reg:TI XMM10_REG))
11346    (clobber (reg:TI XMM11_REG))
11347    (clobber (reg:TI XMM12_REG))
11348    (clobber (reg:TI XMM13_REG))
11349    (clobber (reg:TI XMM14_REG))
11350    (clobber (reg:TI XMM15_REG))
11351    (clobber (reg:DI SI_REG))
11352    (clobber (reg:DI DI_REG))]
11353   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11354   "* return ix86_output_call_insn (insn, operands[0]);"
11355   [(set_attr "type" "call")])
11356
11357 (define_insn_and_split "*sibcall_vzeroupper"
11358   [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11359          (match_operand 1 "" ""))
11360    (unspec [(match_operand 2 "const_int_operand" "")]
11361            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11362   "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11363   "#"
11364   "&& reload_completed"
11365   [(const_int 0)]
11366   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11367   [(set_attr "type" "call")])
11368
11369 (define_insn "*sibcall"
11370   [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11371          (match_operand 1 "" ""))]
11372   "SIBLING_CALL_P (insn)"
11373   "* return ix86_output_call_insn (insn, operands[0]);"
11374   [(set_attr "type" "call")])
11375
11376 (define_expand "call_pop"
11377   [(parallel [(call (match_operand:QI 0 "" "")
11378                     (match_operand:SI 1 "" ""))
11379               (set (reg:SI SP_REG)
11380                    (plus:SI (reg:SI SP_REG)
11381                             (match_operand:SI 3 "" "")))])]
11382   "!TARGET_64BIT"
11383 {
11384   ix86_expand_call (NULL, operands[0], operands[1],
11385                     operands[2], operands[3], false);
11386   DONE;
11387 })
11388
11389 (define_insn_and_split "*call_pop_vzeroupper"
11390   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11391          (match_operand:SI 1 "" ""))
11392    (set (reg:SI SP_REG)
11393         (plus:SI (reg:SI SP_REG)
11394                  (match_operand:SI 2 "immediate_operand" "i")))
11395    (unspec [(match_operand 3 "const_int_operand" "")]
11396            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11397   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11398   "#"
11399   "&& reload_completed"
11400   [(const_int 0)]
11401   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11402   [(set_attr "type" "call")])
11403
11404 (define_insn "*call_pop"
11405   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11406          (match_operand 1 "" ""))
11407    (set (reg:SI SP_REG)
11408         (plus:SI (reg:SI SP_REG)
11409                  (match_operand:SI 2 "immediate_operand" "i")))]
11410   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11411   "* return ix86_output_call_insn (insn, operands[0]);"
11412   [(set_attr "type" "call")])
11413
11414 (define_insn_and_split "*sibcall_pop_vzeroupper"
11415   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11416          (match_operand 1 "" ""))
11417    (set (reg:SI SP_REG)
11418         (plus:SI (reg:SI SP_REG)
11419                  (match_operand:SI 2 "immediate_operand" "i")))
11420    (unspec [(match_operand 3 "const_int_operand" "")]
11421            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11422   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11423   "#"
11424   "&& reload_completed"
11425   [(const_int 0)]
11426   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11427   [(set_attr "type" "call")])
11428
11429 (define_insn "*sibcall_pop"
11430   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11431          (match_operand 1 "" ""))
11432    (set (reg:SI SP_REG)
11433         (plus:SI (reg:SI SP_REG)
11434                  (match_operand:SI 2 "immediate_operand" "i")))]
11435   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11436   "* return ix86_output_call_insn (insn, operands[0]);"
11437   [(set_attr "type" "call")])
11438
11439 ;; Call subroutine, returning value in operand 0
11440
11441 (define_expand "call_value"
11442   [(set (match_operand 0 "" "")
11443         (call (match_operand:QI 1 "" "")
11444               (match_operand 2 "" "")))
11445    (use (match_operand 3 "" ""))]
11446   ""
11447 {
11448   ix86_expand_call (operands[0], operands[1], operands[2],
11449                     operands[3], NULL, false);
11450   DONE;
11451 })
11452
11453 (define_expand "sibcall_value"
11454   [(set (match_operand 0 "" "")
11455         (call (match_operand:QI 1 "" "")
11456               (match_operand 2 "" "")))
11457    (use (match_operand 3 "" ""))]
11458   ""
11459 {
11460   ix86_expand_call (operands[0], operands[1], operands[2],
11461                     operands[3], NULL, true);
11462   DONE;
11463 })
11464
11465 (define_insn_and_split "*call_value_vzeroupper"
11466   [(set (match_operand 0 "" "")
11467         (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11468               (match_operand 2 "" "")))
11469    (unspec [(match_operand 3 "const_int_operand" "")]
11470            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11471   "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11472   "#"
11473   "&& reload_completed"
11474   [(const_int 0)]
11475   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11476   [(set_attr "type" "callv")])
11477
11478 (define_insn "*call_value"
11479   [(set (match_operand 0 "" "")
11480         (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11481               (match_operand 2 "" "")))]
11482   "!SIBLING_CALL_P (insn)"
11483   "* return ix86_output_call_insn (insn, operands[1]);"
11484   [(set_attr "type" "callv")])
11485
11486 (define_insn_and_split "*sibcall_value_vzeroupper"
11487   [(set (match_operand 0 "" "")
11488         (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11489               (match_operand 2 "" "")))
11490    (unspec [(match_operand 3 "const_int_operand" "")]
11491            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11492   "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11493   "#"
11494   "&& reload_completed"
11495   [(const_int 0)]
11496   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11497   [(set_attr "type" "callv")])
11498
11499 (define_insn "*sibcall_value"
11500   [(set (match_operand 0 "" "")
11501         (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11502               (match_operand 2 "" "")))]
11503   "SIBLING_CALL_P (insn)"
11504   "* return ix86_output_call_insn (insn, operands[1]);"
11505   [(set_attr "type" "callv")])
11506
11507 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11508   [(set (match_operand 0 "" "")
11509         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11510               (match_operand 2 "" "")))
11511    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11512    (clobber (reg:TI XMM6_REG))
11513    (clobber (reg:TI XMM7_REG))
11514    (clobber (reg:TI XMM8_REG))
11515    (clobber (reg:TI XMM9_REG))
11516    (clobber (reg:TI XMM10_REG))
11517    (clobber (reg:TI XMM11_REG))
11518    (clobber (reg:TI XMM12_REG))
11519    (clobber (reg:TI XMM13_REG))
11520    (clobber (reg:TI XMM14_REG))
11521    (clobber (reg:TI XMM15_REG))
11522    (clobber (reg:DI SI_REG))
11523    (clobber (reg:DI DI_REG))
11524    (unspec [(match_operand 3 "const_int_operand" "")]
11525            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11526   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11527   "#"
11528   "&& reload_completed"
11529   [(const_int 0)]
11530   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11531   [(set_attr "type" "callv")])
11532
11533 (define_insn "*call_value_rex64_ms_sysv"
11534   [(set (match_operand 0 "" "")
11535         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11536               (match_operand 2 "" "")))
11537    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11538    (clobber (reg:TI XMM6_REG))
11539    (clobber (reg:TI XMM7_REG))
11540    (clobber (reg:TI XMM8_REG))
11541    (clobber (reg:TI XMM9_REG))
11542    (clobber (reg:TI XMM10_REG))
11543    (clobber (reg:TI XMM11_REG))
11544    (clobber (reg:TI XMM12_REG))
11545    (clobber (reg:TI XMM13_REG))
11546    (clobber (reg:TI XMM14_REG))
11547    (clobber (reg:TI XMM15_REG))
11548    (clobber (reg:DI SI_REG))
11549    (clobber (reg:DI DI_REG))]
11550   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11551   "* return ix86_output_call_insn (insn, operands[1]);"
11552   [(set_attr "type" "callv")])
11553
11554 (define_expand "call_value_pop"
11555   [(parallel [(set (match_operand 0 "" "")
11556                    (call (match_operand:QI 1 "" "")
11557                          (match_operand:SI 2 "" "")))
11558               (set (reg:SI SP_REG)
11559                    (plus:SI (reg:SI SP_REG)
11560                             (match_operand:SI 4 "" "")))])]
11561   "!TARGET_64BIT"
11562 {
11563   ix86_expand_call (operands[0], operands[1], operands[2],
11564                     operands[3], operands[4], false);
11565   DONE;
11566 })
11567
11568 (define_insn_and_split "*call_value_pop_vzeroupper"
11569   [(set (match_operand 0 "" "")
11570         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11571               (match_operand 2 "" "")))
11572    (set (reg:SI SP_REG)
11573         (plus:SI (reg:SI SP_REG)
11574                  (match_operand:SI 3 "immediate_operand" "i")))
11575    (unspec [(match_operand 4 "const_int_operand" "")]
11576            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11577   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11578   "#"
11579   "&& reload_completed"
11580   [(const_int 0)]
11581   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11582   [(set_attr "type" "callv")])
11583
11584 (define_insn "*call_value_pop"
11585   [(set (match_operand 0 "" "")
11586         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11587               (match_operand 2 "" "")))
11588    (set (reg:SI SP_REG)
11589         (plus:SI (reg:SI SP_REG)
11590                  (match_operand:SI 3 "immediate_operand" "i")))]
11591   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11592   "* return ix86_output_call_insn (insn, operands[1]);"
11593   [(set_attr "type" "callv")])
11594
11595 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11596   [(set (match_operand 0 "" "")
11597         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11598               (match_operand 2 "" "")))
11599    (set (reg:SI SP_REG)
11600         (plus:SI (reg:SI SP_REG)
11601                  (match_operand:SI 3 "immediate_operand" "i")))
11602    (unspec [(match_operand 4 "const_int_operand" "")]
11603            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11604   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11605   "#"
11606   "&& reload_completed"
11607   [(const_int 0)]
11608   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11609   [(set_attr "type" "callv")])
11610
11611 (define_insn "*sibcall_value_pop"
11612   [(set (match_operand 0 "" "")
11613         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11614               (match_operand 2 "" "")))
11615    (set (reg:SI SP_REG)
11616         (plus:SI (reg:SI SP_REG)
11617                  (match_operand:SI 3 "immediate_operand" "i")))]
11618   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11619   "* return ix86_output_call_insn (insn, operands[1]);"
11620   [(set_attr "type" "callv")])
11621
11622 ;; Call subroutine returning any type.
11623
11624 (define_expand "untyped_call"
11625   [(parallel [(call (match_operand 0 "" "")
11626                     (const_int 0))
11627               (match_operand 1 "" "")
11628               (match_operand 2 "" "")])]
11629   ""
11630 {
11631   int i;
11632
11633   /* In order to give reg-stack an easier job in validating two
11634      coprocessor registers as containing a possible return value,
11635      simply pretend the untyped call returns a complex long double
11636      value. 
11637
11638      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11639      and should have the default ABI.  */
11640
11641   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11642                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11643                     operands[0], const0_rtx,
11644                     GEN_INT ((TARGET_64BIT
11645                               ? (ix86_abi == SYSV_ABI
11646                                  ? X86_64_SSE_REGPARM_MAX
11647                                  : X86_64_MS_SSE_REGPARM_MAX)
11648                               : X86_32_SSE_REGPARM_MAX)
11649                              - 1),
11650                     NULL, false);
11651
11652   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11653     {
11654       rtx set = XVECEXP (operands[2], 0, i);
11655       emit_move_insn (SET_DEST (set), SET_SRC (set));
11656     }
11657
11658   /* The optimizer does not know that the call sets the function value
11659      registers we stored in the result block.  We avoid problems by
11660      claiming that all hard registers are used and clobbered at this
11661      point.  */
11662   emit_insn (gen_blockage ());
11663
11664   DONE;
11665 })
11666 \f
11667 ;; Prologue and epilogue instructions
11668
11669 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11670 ;; all of memory.  This blocks insns from being moved across this point.
11671
11672 (define_insn "blockage"
11673   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11674   ""
11675   ""
11676   [(set_attr "length" "0")])
11677
11678 ;; Do not schedule instructions accessing memory across this point.
11679
11680 (define_expand "memory_blockage"
11681   [(set (match_dup 0)
11682         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11683   ""
11684 {
11685   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11686   MEM_VOLATILE_P (operands[0]) = 1;
11687 })
11688
11689 (define_insn "*memory_blockage"
11690   [(set (match_operand:BLK 0 "" "")
11691         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11692   ""
11693   ""
11694   [(set_attr "length" "0")])
11695
11696 ;; As USE insns aren't meaningful after reload, this is used instead
11697 ;; to prevent deleting instructions setting registers for PIC code
11698 (define_insn "prologue_use"
11699   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11700   ""
11701   ""
11702   [(set_attr "length" "0")])
11703
11704 ;; Insn emitted into the body of a function to return from a function.
11705 ;; This is only done if the function's epilogue is known to be simple.
11706 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11707
11708 (define_expand "return"
11709   [(simple_return)]
11710   "ix86_can_use_return_insn_p ()"
11711 {
11712   ix86_maybe_emit_epilogue_vzeroupper ();
11713   if (crtl->args.pops_args)
11714     {
11715       rtx popc = GEN_INT (crtl->args.pops_args);
11716       emit_jump_insn (gen_simple_return_pop_internal (popc));
11717       DONE;
11718     }
11719 })
11720
11721 ;; We need to disable this for TARGET_SEH, as otherwise
11722 ;; shrink-wrapped prologue gets enabled too.  This might exceed
11723 ;; the maximum size of prologue in unwind information.
11724
11725 (define_expand "simple_return"
11726   [(simple_return)]
11727   "!TARGET_SEH"
11728 {
11729   ix86_maybe_emit_epilogue_vzeroupper ();
11730   if (crtl->args.pops_args)
11731     {
11732       rtx popc = GEN_INT (crtl->args.pops_args);
11733       emit_jump_insn (gen_simple_return_pop_internal (popc));
11734       DONE;
11735     }
11736 })
11737
11738 (define_insn "simple_return_internal"
11739   [(simple_return)]
11740   "reload_completed"
11741   "ret"
11742   [(set_attr "length" "1")
11743    (set_attr "atom_unit" "jeu")
11744    (set_attr "length_immediate" "0")
11745    (set_attr "modrm" "0")])
11746
11747 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11748 ;; instruction Athlon and K8 have.
11749
11750 (define_insn "simple_return_internal_long"
11751   [(simple_return)
11752    (unspec [(const_int 0)] UNSPEC_REP)]
11753   "reload_completed"
11754   "rep\;ret"
11755   [(set_attr "length" "2")
11756    (set_attr "atom_unit" "jeu")
11757    (set_attr "length_immediate" "0")
11758    (set_attr "prefix_rep" "1")
11759    (set_attr "modrm" "0")])
11760
11761 (define_insn "simple_return_pop_internal"
11762   [(simple_return)
11763    (use (match_operand:SI 0 "const_int_operand" ""))]
11764   "reload_completed"
11765   "ret\t%0"
11766   [(set_attr "length" "3")
11767    (set_attr "atom_unit" "jeu")
11768    (set_attr "length_immediate" "2")
11769    (set_attr "modrm" "0")])
11770
11771 (define_insn "simple_return_indirect_internal"
11772   [(simple_return)
11773    (use (match_operand:SI 0 "register_operand" "r"))]
11774   "reload_completed"
11775   "jmp\t%A0"
11776   [(set_attr "type" "ibr")
11777    (set_attr "length_immediate" "0")])
11778
11779 (define_insn "nop"
11780   [(const_int 0)]
11781   ""
11782   "nop"
11783   [(set_attr "length" "1")
11784    (set_attr "length_immediate" "0")
11785    (set_attr "modrm" "0")])
11786
11787 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
11788 (define_insn "nops"
11789   [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11790                     UNSPECV_NOPS)]
11791   "reload_completed"
11792 {
11793   int num = INTVAL (operands[0]);
11794
11795   gcc_assert (num >= 1 && num <= 8);
11796
11797   while (num--)
11798     fputs ("\tnop\n", asm_out_file);
11799
11800   return "";
11801 }
11802   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11803    (set_attr "length_immediate" "0")
11804    (set_attr "modrm" "0")])
11805
11806 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11807 ;; branch prediction penalty for the third jump in a 16-byte
11808 ;; block on K8.
11809
11810 (define_insn "pad"
11811   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11812   ""
11813 {
11814 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11815   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11816 #else
11817   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11818      The align insn is used to avoid 3 jump instructions in the row to improve
11819      branch prediction and the benefits hardly outweigh the cost of extra 8
11820      nops on the average inserted by full alignment pseudo operation.  */
11821 #endif
11822   return "";
11823 }
11824   [(set_attr "length" "16")])
11825
11826 (define_expand "prologue"
11827   [(const_int 0)]
11828   ""
11829   "ix86_expand_prologue (); DONE;")
11830
11831 (define_insn "set_got"
11832   [(set (match_operand:SI 0 "register_operand" "=r")
11833         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11834    (clobber (reg:CC FLAGS_REG))]
11835   "!TARGET_64BIT"
11836   "* return output_set_got (operands[0], NULL_RTX);"
11837   [(set_attr "type" "multi")
11838    (set_attr "length" "12")])
11839
11840 (define_insn "set_got_labelled"
11841   [(set (match_operand:SI 0 "register_operand" "=r")
11842         (unspec:SI [(label_ref (match_operand 1 "" ""))]
11843          UNSPEC_SET_GOT))
11844    (clobber (reg:CC FLAGS_REG))]
11845   "!TARGET_64BIT"
11846   "* return output_set_got (operands[0], operands[1]);"
11847   [(set_attr "type" "multi")
11848    (set_attr "length" "12")])
11849
11850 (define_insn "set_got_rex64"
11851   [(set (match_operand:DI 0 "register_operand" "=r")
11852         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11853   "TARGET_64BIT"
11854   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11855   [(set_attr "type" "lea")
11856    (set_attr "length_address" "4")
11857    (set_attr "mode" "DI")])
11858
11859 (define_insn "set_rip_rex64"
11860   [(set (match_operand:DI 0 "register_operand" "=r")
11861         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11862   "TARGET_64BIT"
11863   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11864   [(set_attr "type" "lea")
11865    (set_attr "length_address" "4")
11866    (set_attr "mode" "DI")])
11867
11868 (define_insn "set_got_offset_rex64"
11869   [(set (match_operand:DI 0 "register_operand" "=r")
11870         (unspec:DI
11871           [(label_ref (match_operand 1 "" ""))]
11872           UNSPEC_SET_GOT_OFFSET))]
11873   "TARGET_LP64"
11874   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11875   [(set_attr "type" "imov")
11876    (set_attr "length_immediate" "0")
11877    (set_attr "length_address" "8")
11878    (set_attr "mode" "DI")])
11879
11880 (define_expand "epilogue"
11881   [(const_int 0)]
11882   ""
11883   "ix86_expand_epilogue (1); DONE;")
11884
11885 (define_expand "sibcall_epilogue"
11886   [(const_int 0)]
11887   ""
11888   "ix86_expand_epilogue (0); DONE;")
11889
11890 (define_expand "eh_return"
11891   [(use (match_operand 0 "register_operand" ""))]
11892   ""
11893 {
11894   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11895
11896   /* Tricky bit: we write the address of the handler to which we will
11897      be returning into someone else's stack frame, one word below the
11898      stack address we wish to restore.  */
11899   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11900   tmp = plus_constant (tmp, -UNITS_PER_WORD);
11901   tmp = gen_rtx_MEM (Pmode, tmp);
11902   emit_move_insn (tmp, ra);
11903
11904   emit_jump_insn (gen_eh_return_internal ());
11905   emit_barrier ();
11906   DONE;
11907 })
11908
11909 (define_insn_and_split "eh_return_internal"
11910   [(eh_return)]
11911   ""
11912   "#"
11913   "epilogue_completed"
11914   [(const_int 0)]
11915   "ix86_expand_epilogue (2); DONE;")
11916
11917 (define_insn "leave"
11918   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11919    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11920    (clobber (mem:BLK (scratch)))]
11921   "!TARGET_64BIT"
11922   "leave"
11923   [(set_attr "type" "leave")])
11924
11925 (define_insn "leave_rex64"
11926   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11927    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11928    (clobber (mem:BLK (scratch)))]
11929   "TARGET_64BIT"
11930   "leave"
11931   [(set_attr "type" "leave")])
11932 \f
11933 ;; Handle -fsplit-stack.
11934
11935 (define_expand "split_stack_prologue"
11936   [(const_int 0)]
11937   ""
11938 {
11939   ix86_expand_split_stack_prologue ();
11940   DONE;
11941 })
11942
11943 ;; In order to support the call/return predictor, we use a return
11944 ;; instruction which the middle-end doesn't see.
11945 (define_insn "split_stack_return"
11946   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11947                      UNSPECV_SPLIT_STACK_RETURN)]
11948   ""
11949 {
11950   if (operands[0] == const0_rtx)
11951     return "ret";
11952   else
11953     return "ret\t%0";
11954 }
11955   [(set_attr "atom_unit" "jeu")
11956    (set_attr "modrm" "0")
11957    (set (attr "length")
11958         (if_then_else (match_operand:SI 0 "const0_operand" "")
11959                       (const_int 1)
11960                       (const_int 3)))
11961    (set (attr "length_immediate")
11962         (if_then_else (match_operand:SI 0 "const0_operand" "")
11963                       (const_int 0)
11964                       (const_int 2)))])
11965
11966 ;; If there are operand 0 bytes available on the stack, jump to
11967 ;; operand 1.
11968
11969 (define_expand "split_stack_space_check"
11970   [(set (pc) (if_then_else
11971               (ltu (minus (reg SP_REG)
11972                           (match_operand 0 "register_operand" ""))
11973                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11974               (label_ref (match_operand 1 "" ""))
11975               (pc)))]
11976   ""
11977 {
11978   rtx reg, size, limit;
11979
11980   reg = gen_reg_rtx (Pmode);
11981   size = force_reg (Pmode, operands[0]);
11982   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11983   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11984                           UNSPEC_STACK_CHECK);
11985   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11986   ix86_expand_branch (GEU, reg, limit, operands[1]);
11987
11988   DONE;
11989 })
11990 \f
11991 ;; Bit manipulation instructions.
11992
11993 (define_expand "ffs<mode>2"
11994   [(set (match_dup 2) (const_int -1))
11995    (parallel [(set (reg:CCZ FLAGS_REG)
11996                    (compare:CCZ
11997                      (match_operand:SWI48 1 "nonimmediate_operand" "")
11998                      (const_int 0)))
11999               (set (match_operand:SWI48 0 "register_operand" "")
12000                    (ctz:SWI48 (match_dup 1)))])
12001    (set (match_dup 0) (if_then_else:SWI48
12002                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
12003                         (match_dup 2)
12004                         (match_dup 0)))
12005    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12006               (clobber (reg:CC FLAGS_REG))])]
12007   ""
12008 {
12009   if (<MODE>mode == SImode && !TARGET_CMOVE)
12010     {
12011       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12012       DONE;
12013     }
12014   operands[2] = gen_reg_rtx (<MODE>mode);
12015 })
12016
12017 (define_insn_and_split "ffssi2_no_cmove"
12018   [(set (match_operand:SI 0 "register_operand" "=r")
12019         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12020    (clobber (match_scratch:SI 2 "=&q"))
12021    (clobber (reg:CC FLAGS_REG))]
12022   "!TARGET_CMOVE"
12023   "#"
12024   "&& reload_completed"
12025   [(parallel [(set (reg:CCZ FLAGS_REG)
12026                    (compare:CCZ (match_dup 1) (const_int 0)))
12027               (set (match_dup 0) (ctz:SI (match_dup 1)))])
12028    (set (strict_low_part (match_dup 3))
12029         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12030    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12031               (clobber (reg:CC FLAGS_REG))])
12032    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12033               (clobber (reg:CC FLAGS_REG))])
12034    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12035               (clobber (reg:CC FLAGS_REG))])]
12036 {
12037   operands[3] = gen_lowpart (QImode, operands[2]);
12038   ix86_expand_clear (operands[2]);
12039 })
12040
12041 (define_insn "*ffs<mode>_1"
12042   [(set (reg:CCZ FLAGS_REG)
12043         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12044                      (const_int 0)))
12045    (set (match_operand:SWI48 0 "register_operand" "=r")
12046         (ctz:SWI48 (match_dup 1)))]
12047   ""
12048   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12049   [(set_attr "type" "alu1")
12050    (set_attr "prefix_0f" "1")
12051    (set_attr "mode" "<MODE>")])
12052
12053 (define_insn "ctz<mode>2"
12054   [(set (match_operand:SWI248 0 "register_operand" "=r")
12055         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12056    (clobber (reg:CC FLAGS_REG))]
12057   ""
12058 {
12059   if (TARGET_BMI)
12060     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12061   else
12062     return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12063 }
12064   [(set_attr "type" "alu1")
12065    (set_attr "prefix_0f" "1")
12066    (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12067    (set_attr "mode" "<MODE>")])
12068
12069 (define_expand "clz<mode>2"
12070   [(parallel
12071      [(set (match_operand:SWI248 0 "register_operand" "")
12072            (minus:SWI248
12073              (match_dup 2)
12074              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12075       (clobber (reg:CC FLAGS_REG))])
12076    (parallel
12077      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12078       (clobber (reg:CC FLAGS_REG))])]
12079   ""
12080 {
12081   if (TARGET_LZCNT)
12082     {
12083       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12084       DONE;
12085     }
12086   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12087 })
12088
12089 (define_insn "clz<mode>2_lzcnt"
12090   [(set (match_operand:SWI248 0 "register_operand" "=r")
12091         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12092    (clobber (reg:CC FLAGS_REG))]
12093   "TARGET_LZCNT"
12094   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12095   [(set_attr "prefix_rep" "1")
12096    (set_attr "type" "bitmanip")
12097    (set_attr "mode" "<MODE>")])
12098
12099 ;; BMI instructions.
12100 (define_insn "*bmi_andn_<mode>"
12101   [(set (match_operand:SWI48 0 "register_operand" "=r")
12102         (and:SWI48
12103           (not:SWI48
12104             (match_operand:SWI48 1 "register_operand" "r"))
12105             (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12106    (clobber (reg:CC FLAGS_REG))]
12107   "TARGET_BMI"
12108   "andn\t{%2, %1, %0|%0, %1, %2}"
12109   [(set_attr "type" "bitmanip")
12110    (set_attr "mode" "<MODE>")])
12111
12112 (define_insn "bmi_bextr_<mode>"
12113   [(set (match_operand:SWI48 0 "register_operand" "=r")
12114         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12115                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12116                        UNSPEC_BEXTR))
12117    (clobber (reg:CC FLAGS_REG))]
12118   "TARGET_BMI"
12119   "bextr\t{%2, %1, %0|%0, %1, %2}"
12120   [(set_attr "type" "bitmanip")
12121    (set_attr "mode" "<MODE>")])
12122
12123 (define_insn "*bmi_blsi_<mode>"
12124   [(set (match_operand:SWI48 0 "register_operand" "=r")
12125         (and:SWI48
12126           (neg:SWI48
12127             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12128           (match_dup 1)))
12129    (clobber (reg:CC FLAGS_REG))]
12130   "TARGET_BMI"
12131   "blsi\t{%1, %0|%0, %1}"
12132   [(set_attr "type" "bitmanip")
12133    (set_attr "mode" "<MODE>")])
12134
12135 (define_insn "*bmi_blsmsk_<mode>"
12136   [(set (match_operand:SWI48 0 "register_operand" "=r")
12137         (xor:SWI48
12138           (plus:SWI48
12139             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12140             (const_int -1))
12141           (match_dup 1)))
12142    (clobber (reg:CC FLAGS_REG))]
12143   "TARGET_BMI"
12144   "blsmsk\t{%1, %0|%0, %1}"
12145   [(set_attr "type" "bitmanip")
12146    (set_attr "mode" "<MODE>")])
12147
12148 (define_insn "*bmi_blsr_<mode>"
12149   [(set (match_operand:SWI48 0 "register_operand" "=r")
12150         (and:SWI48
12151           (plus:SWI48
12152             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12153             (const_int -1))
12154           (match_dup 1)))
12155    (clobber (reg:CC FLAGS_REG))]
12156    "TARGET_BMI"
12157    "blsr\t{%1, %0|%0, %1}"
12158   [(set_attr "type" "bitmanip")
12159    (set_attr "mode" "<MODE>")])
12160
12161 ;; BMI2 instructions.
12162 (define_insn "bmi2_bzhi_<mode>3"
12163   [(set (match_operand:SWI48 0 "register_operand" "=r")
12164         (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12165                    (lshiftrt:SWI48 (const_int -1)
12166                                    (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12167    (clobber (reg:CC FLAGS_REG))]
12168   "TARGET_BMI2"
12169   "bzhi\t{%2, %1, %0|%0, %1, %2}"
12170   [(set_attr "type" "bitmanip")
12171    (set_attr "prefix" "vex")
12172    (set_attr "mode" "<MODE>")])
12173
12174 (define_insn "bmi2_pdep_<mode>3"
12175   [(set (match_operand:SWI48 0 "register_operand" "=r")
12176         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12177                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12178                        UNSPEC_PDEP))]
12179   "TARGET_BMI2"
12180   "pdep\t{%2, %1, %0|%0, %1, %2}"
12181   [(set_attr "type" "bitmanip")
12182    (set_attr "prefix" "vex")
12183    (set_attr "mode" "<MODE>")])
12184
12185 (define_insn "bmi2_pext_<mode>3"
12186   [(set (match_operand:SWI48 0 "register_operand" "=r")
12187         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12188                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12189                        UNSPEC_PEXT))]
12190   "TARGET_BMI2"
12191   "pext\t{%2, %1, %0|%0, %1, %2}"
12192   [(set_attr "type" "bitmanip")
12193    (set_attr "prefix" "vex")
12194    (set_attr "mode" "<MODE>")])
12195
12196 ;; TBM instructions.
12197 (define_insn "tbm_bextri_<mode>"
12198   [(set (match_operand:SWI48 0 "register_operand" "=r")
12199         (zero_extract:SWI48
12200           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12201           (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12202           (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12203    (clobber (reg:CC FLAGS_REG))]
12204    "TARGET_TBM"
12205 {
12206   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12207   return "bextr\t{%2, %1, %0|%0, %1, %2}";
12208 }
12209   [(set_attr "type" "bitmanip")
12210    (set_attr "mode" "<MODE>")])
12211
12212 (define_insn "*tbm_blcfill_<mode>"
12213   [(set (match_operand:SWI48 0 "register_operand" "=r")
12214         (and:SWI48
12215           (plus:SWI48
12216             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12217             (const_int 1))
12218           (match_dup 1)))
12219    (clobber (reg:CC FLAGS_REG))]
12220    "TARGET_TBM"
12221    "blcfill\t{%1, %0|%0, %1}"
12222   [(set_attr "type" "bitmanip")
12223    (set_attr "mode" "<MODE>")])
12224
12225 (define_insn "*tbm_blci_<mode>"
12226   [(set (match_operand:SWI48 0 "register_operand" "=r")
12227         (ior:SWI48
12228           (not:SWI48
12229             (plus:SWI48
12230               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12231               (const_int 1)))
12232           (match_dup 1)))
12233    (clobber (reg:CC FLAGS_REG))]
12234    "TARGET_TBM"
12235    "blci\t{%1, %0|%0, %1}"
12236   [(set_attr "type" "bitmanip")
12237    (set_attr "mode" "<MODE>")])
12238
12239 (define_insn "*tbm_blcic_<mode>"
12240   [(set (match_operand:SWI48 0 "register_operand" "=r")
12241         (and:SWI48
12242           (plus:SWI48
12243             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12244             (const_int 1))
12245           (not:SWI48
12246             (match_dup 1))))
12247    (clobber (reg:CC FLAGS_REG))]
12248    "TARGET_TBM"
12249    "blcic\t{%1, %0|%0, %1}"
12250   [(set_attr "type" "bitmanip")
12251    (set_attr "mode" "<MODE>")])
12252
12253 (define_insn "*tbm_blcmsk_<mode>"
12254   [(set (match_operand:SWI48 0 "register_operand" "=r")
12255         (xor:SWI48
12256           (plus:SWI48
12257             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12258             (const_int 1))
12259           (match_dup 1)))
12260    (clobber (reg:CC FLAGS_REG))]
12261    "TARGET_TBM"
12262    "blcmsk\t{%1, %0|%0, %1}"
12263   [(set_attr "type" "bitmanip")
12264    (set_attr "mode" "<MODE>")])
12265
12266 (define_insn "*tbm_blcs_<mode>"
12267   [(set (match_operand:SWI48 0 "register_operand" "=r")
12268         (ior:SWI48
12269           (plus:SWI48
12270             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12271             (const_int 1))
12272           (match_dup 1)))
12273    (clobber (reg:CC FLAGS_REG))]
12274    "TARGET_TBM"
12275    "blcs\t{%1, %0|%0, %1}"
12276   [(set_attr "type" "bitmanip")
12277    (set_attr "mode" "<MODE>")])
12278
12279 (define_insn "*tbm_blsfill_<mode>"
12280   [(set (match_operand:SWI48 0 "register_operand" "=r")
12281         (ior:SWI48
12282           (plus:SWI48
12283             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12284             (const_int -1))
12285           (match_dup 1)))
12286    (clobber (reg:CC FLAGS_REG))]
12287    "TARGET_TBM"
12288    "blsfill\t{%1, %0|%0, %1}"
12289   [(set_attr "type" "bitmanip")
12290    (set_attr "mode" "<MODE>")])
12291
12292 (define_insn "*tbm_blsic_<mode>"
12293   [(set (match_operand:SWI48 0 "register_operand" "=r")
12294         (ior:SWI48
12295           (plus:SWI48
12296             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12297             (const_int -1))
12298           (not:SWI48
12299             (match_dup 1))))
12300    (clobber (reg:CC FLAGS_REG))]
12301    "TARGET_TBM"
12302    "blsic\t{%1, %0|%0, %1}"
12303   [(set_attr "type" "bitmanip")
12304    (set_attr "mode" "<MODE>")])
12305
12306 (define_insn "*tbm_t1mskc_<mode>"
12307   [(set (match_operand:SWI48 0 "register_operand" "=r")
12308         (ior:SWI48
12309           (plus:SWI48
12310             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12311             (const_int 1))
12312           (not:SWI48
12313             (match_dup 1))))
12314    (clobber (reg:CC FLAGS_REG))]
12315    "TARGET_TBM"
12316    "t1mskc\t{%1, %0|%0, %1}"
12317   [(set_attr "type" "bitmanip")
12318    (set_attr "mode" "<MODE>")])
12319
12320 (define_insn "*tbm_tzmsk_<mode>"
12321   [(set (match_operand:SWI48 0 "register_operand" "=r")
12322         (and:SWI48
12323           (plus:SWI48
12324             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12325             (const_int -1))
12326           (not:SWI48
12327             (match_dup 1))))
12328    (clobber (reg:CC FLAGS_REG))]
12329    "TARGET_TBM"
12330    "tzmsk\t{%1, %0|%0, %1}"
12331   [(set_attr "type" "bitmanip")
12332    (set_attr "mode" "<MODE>")])
12333
12334 (define_insn "bsr_rex64"
12335   [(set (match_operand:DI 0 "register_operand" "=r")
12336         (minus:DI (const_int 63)
12337                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12338    (clobber (reg:CC FLAGS_REG))]
12339   "TARGET_64BIT"
12340   "bsr{q}\t{%1, %0|%0, %1}"
12341   [(set_attr "type" "alu1")
12342    (set_attr "prefix_0f" "1")
12343    (set_attr "mode" "DI")])
12344
12345 (define_insn "bsr"
12346   [(set (match_operand:SI 0 "register_operand" "=r")
12347         (minus:SI (const_int 31)
12348                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12349    (clobber (reg:CC FLAGS_REG))]
12350   ""
12351   "bsr{l}\t{%1, %0|%0, %1}"
12352   [(set_attr "type" "alu1")
12353    (set_attr "prefix_0f" "1")
12354    (set_attr "mode" "SI")])
12355
12356 (define_insn "*bsrhi"
12357   [(set (match_operand:HI 0 "register_operand" "=r")
12358         (minus:HI (const_int 15)
12359                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12360    (clobber (reg:CC FLAGS_REG))]
12361   ""
12362   "bsr{w}\t{%1, %0|%0, %1}"
12363   [(set_attr "type" "alu1")
12364    (set_attr "prefix_0f" "1")
12365    (set_attr "mode" "HI")])
12366
12367 (define_insn "popcount<mode>2"
12368   [(set (match_operand:SWI248 0 "register_operand" "=r")
12369         (popcount:SWI248
12370           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12371    (clobber (reg:CC FLAGS_REG))]
12372   "TARGET_POPCNT"
12373 {
12374 #if TARGET_MACHO
12375   return "popcnt\t{%1, %0|%0, %1}";
12376 #else
12377   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12378 #endif
12379 }
12380   [(set_attr "prefix_rep" "1")
12381    (set_attr "type" "bitmanip")
12382    (set_attr "mode" "<MODE>")])
12383
12384 (define_insn "*popcount<mode>2_cmp"
12385   [(set (reg FLAGS_REG)
12386         (compare
12387           (popcount:SWI248
12388             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12389           (const_int 0)))
12390    (set (match_operand:SWI248 0 "register_operand" "=r")
12391         (popcount:SWI248 (match_dup 1)))]
12392   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12393 {
12394 #if TARGET_MACHO
12395   return "popcnt\t{%1, %0|%0, %1}";
12396 #else
12397   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12398 #endif
12399 }
12400   [(set_attr "prefix_rep" "1")
12401    (set_attr "type" "bitmanip")
12402    (set_attr "mode" "<MODE>")])
12403
12404 (define_insn "*popcountsi2_cmp_zext"
12405   [(set (reg FLAGS_REG)
12406         (compare
12407           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12408           (const_int 0)))
12409    (set (match_operand:DI 0 "register_operand" "=r")
12410         (zero_extend:DI(popcount:SI (match_dup 1))))]
12411   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12412 {
12413 #if TARGET_MACHO
12414   return "popcnt\t{%1, %0|%0, %1}";
12415 #else
12416   return "popcnt{l}\t{%1, %0|%0, %1}";
12417 #endif
12418 }
12419   [(set_attr "prefix_rep" "1")
12420    (set_attr "type" "bitmanip")
12421    (set_attr "mode" "SI")])
12422
12423 (define_expand "bswap<mode>2"
12424   [(set (match_operand:SWI48 0 "register_operand" "")
12425         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12426   ""
12427 {
12428   if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12429     {
12430       rtx x = operands[0];
12431
12432       emit_move_insn (x, operands[1]);
12433       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12434       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12435       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12436       DONE;
12437     }
12438 })
12439
12440 (define_insn "*bswap<mode>2_movbe"
12441   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12442         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12443   "TARGET_MOVBE
12444    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12445   "@
12446     bswap\t%0
12447     movbe\t{%1, %0|%0, %1}
12448     movbe\t{%1, %0|%0, %1}"
12449   [(set_attr "type" "bitmanip,imov,imov")
12450    (set_attr "modrm" "0,1,1")
12451    (set_attr "prefix_0f" "*,1,1")
12452    (set_attr "prefix_extra" "*,1,1")
12453    (set_attr "mode" "<MODE>")])
12454
12455 (define_insn "*bswap<mode>2_1"
12456   [(set (match_operand:SWI48 0 "register_operand" "=r")
12457         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12458   "TARGET_BSWAP"
12459   "bswap\t%0"
12460   [(set_attr "type" "bitmanip")
12461    (set_attr "modrm" "0")
12462    (set_attr "mode" "<MODE>")])
12463
12464 (define_insn "*bswaphi_lowpart_1"
12465   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12466         (bswap:HI (match_dup 0)))
12467    (clobber (reg:CC FLAGS_REG))]
12468   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12469   "@
12470     xchg{b}\t{%h0, %b0|%b0, %h0}
12471     rol{w}\t{$8, %0|%0, 8}"
12472   [(set_attr "length" "2,4")
12473    (set_attr "mode" "QI,HI")])
12474
12475 (define_insn "bswaphi_lowpart"
12476   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12477         (bswap:HI (match_dup 0)))
12478    (clobber (reg:CC FLAGS_REG))]
12479   ""
12480   "rol{w}\t{$8, %0|%0, 8}"
12481   [(set_attr "length" "4")
12482    (set_attr "mode" "HI")])
12483
12484 (define_expand "paritydi2"
12485   [(set (match_operand:DI 0 "register_operand" "")
12486         (parity:DI (match_operand:DI 1 "register_operand" "")))]
12487   "! TARGET_POPCNT"
12488 {
12489   rtx scratch = gen_reg_rtx (QImode);
12490   rtx cond;
12491
12492   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12493                                 NULL_RTX, operands[1]));
12494
12495   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12496                          gen_rtx_REG (CCmode, FLAGS_REG),
12497                          const0_rtx);
12498   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12499
12500   if (TARGET_64BIT)
12501     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12502   else
12503     {
12504       rtx tmp = gen_reg_rtx (SImode);
12505
12506       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12507       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12508     }
12509   DONE;
12510 })
12511
12512 (define_expand "paritysi2"
12513   [(set (match_operand:SI 0 "register_operand" "")
12514         (parity:SI (match_operand:SI 1 "register_operand" "")))]
12515   "! TARGET_POPCNT"
12516 {
12517   rtx scratch = gen_reg_rtx (QImode);
12518   rtx cond;
12519
12520   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12521
12522   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12523                          gen_rtx_REG (CCmode, FLAGS_REG),
12524                          const0_rtx);
12525   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12526
12527   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12528   DONE;
12529 })
12530
12531 (define_insn_and_split "paritydi2_cmp"
12532   [(set (reg:CC FLAGS_REG)
12533         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12534                    UNSPEC_PARITY))
12535    (clobber (match_scratch:DI 0 "=r"))
12536    (clobber (match_scratch:SI 1 "=&r"))
12537    (clobber (match_scratch:HI 2 "=Q"))]
12538   "! TARGET_POPCNT"
12539   "#"
12540   "&& reload_completed"
12541   [(parallel
12542      [(set (match_dup 1)
12543            (xor:SI (match_dup 1) (match_dup 4)))
12544       (clobber (reg:CC FLAGS_REG))])
12545    (parallel
12546      [(set (reg:CC FLAGS_REG)
12547            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12548       (clobber (match_dup 1))
12549       (clobber (match_dup 2))])]
12550 {
12551   operands[4] = gen_lowpart (SImode, operands[3]);
12552
12553   if (TARGET_64BIT)
12554     {
12555       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12556       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12557     }
12558   else
12559     operands[1] = gen_highpart (SImode, operands[3]);
12560 })
12561
12562 (define_insn_and_split "paritysi2_cmp"
12563   [(set (reg:CC FLAGS_REG)
12564         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12565                    UNSPEC_PARITY))
12566    (clobber (match_scratch:SI 0 "=r"))
12567    (clobber (match_scratch:HI 1 "=&Q"))]
12568   "! TARGET_POPCNT"
12569   "#"
12570   "&& reload_completed"
12571   [(parallel
12572      [(set (match_dup 1)
12573            (xor:HI (match_dup 1) (match_dup 3)))
12574       (clobber (reg:CC FLAGS_REG))])
12575    (parallel
12576      [(set (reg:CC FLAGS_REG)
12577            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12578       (clobber (match_dup 1))])]
12579 {
12580   operands[3] = gen_lowpart (HImode, operands[2]);
12581
12582   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12583   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12584 })
12585
12586 (define_insn "*parityhi2_cmp"
12587   [(set (reg:CC FLAGS_REG)
12588         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12589                    UNSPEC_PARITY))
12590    (clobber (match_scratch:HI 0 "=Q"))]
12591   "! TARGET_POPCNT"
12592   "xor{b}\t{%h0, %b0|%b0, %h0}"
12593   [(set_attr "length" "2")
12594    (set_attr "mode" "HI")])
12595
12596 \f
12597 ;; Thread-local storage patterns for ELF.
12598 ;;
12599 ;; Note that these code sequences must appear exactly as shown
12600 ;; in order to allow linker relaxation.
12601
12602 (define_insn "*tls_global_dynamic_32_gnu"
12603   [(set (match_operand:SI 0 "register_operand" "=a")
12604         (unspec:SI
12605          [(match_operand:SI 1 "register_operand" "b")
12606           (match_operand:SI 2 "tls_symbolic_operand" "")
12607           (match_operand:SI 3 "constant_call_address_operand" "z")]
12608          UNSPEC_TLS_GD))
12609    (clobber (match_scratch:SI 4 "=d"))
12610    (clobber (match_scratch:SI 5 "=c"))
12611    (clobber (reg:CC FLAGS_REG))]
12612   "!TARGET_64BIT && TARGET_GNU_TLS"
12613 {
12614   output_asm_insn
12615     ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12616   if (TARGET_SUN_TLS)
12617 #ifdef HAVE_AS_IX86_TLSGDPLT
12618     return "call\t%a2@tlsgdplt";
12619 #else
12620     return "call\t%p3@plt";
12621 #endif
12622   return "call\t%P3";
12623 }
12624   [(set_attr "type" "multi")
12625    (set_attr "length" "12")])
12626
12627 (define_expand "tls_global_dynamic_32"
12628   [(parallel
12629     [(set (match_operand:SI 0 "register_operand" "")
12630           (unspec:SI [(match_operand:SI 2 "register_operand" "")
12631                       (match_operand:SI 1 "tls_symbolic_operand" "")
12632                       (match_operand:SI 3 "constant_call_address_operand" "")]
12633                      UNSPEC_TLS_GD))
12634      (clobber (match_scratch:SI 4 ""))
12635      (clobber (match_scratch:SI 5 ""))
12636      (clobber (reg:CC FLAGS_REG))])])
12637
12638 (define_insn "*tls_global_dynamic_64"
12639   [(set (match_operand:DI 0 "register_operand" "=a")
12640         (call:DI
12641          (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12642          (match_operand:DI 3 "" "")))
12643    (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12644               UNSPEC_TLS_GD)]
12645   "TARGET_64BIT"
12646 {
12647   if (!TARGET_X32)
12648     fputs (ASM_BYTE "0x66\n", asm_out_file);
12649   output_asm_insn
12650     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12651   fputs (ASM_SHORT "0x6666\n", asm_out_file);
12652   fputs ("\trex64\n", asm_out_file);
12653   if (TARGET_SUN_TLS)
12654     return "call\t%p2@plt";
12655   return "call\t%P2";
12656 }
12657   [(set_attr "type" "multi")
12658    (set (attr "length")
12659         (symbol_ref "TARGET_X32 ? 15 : 16"))])
12660
12661 (define_expand "tls_global_dynamic_64"
12662   [(parallel
12663     [(set (match_operand:DI 0 "register_operand" "")
12664           (call:DI
12665            (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12666            (const_int 0)))
12667      (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12668                 UNSPEC_TLS_GD)])])
12669
12670 (define_insn "*tls_local_dynamic_base_32_gnu"
12671   [(set (match_operand:SI 0 "register_operand" "=a")
12672         (unspec:SI
12673          [(match_operand:SI 1 "register_operand" "b")
12674           (match_operand:SI 2 "constant_call_address_operand" "z")]
12675          UNSPEC_TLS_LD_BASE))
12676    (clobber (match_scratch:SI 3 "=d"))
12677    (clobber (match_scratch:SI 4 "=c"))
12678    (clobber (reg:CC FLAGS_REG))]
12679   "!TARGET_64BIT && TARGET_GNU_TLS"
12680 {
12681   output_asm_insn
12682     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12683   if (TARGET_SUN_TLS)
12684 #ifdef HAVE_AS_IX86_TLSLDMPLT
12685     return "call\t%&@tlsldmplt";
12686 #else
12687     return "call\t%p2@plt";
12688 #endif
12689   return "call\t%P2";
12690 }
12691   [(set_attr "type" "multi")
12692    (set_attr "length" "11")])
12693
12694 (define_expand "tls_local_dynamic_base_32"
12695   [(parallel
12696      [(set (match_operand:SI 0 "register_operand" "")
12697            (unspec:SI
12698             [(match_operand:SI 1 "register_operand" "")
12699              (match_operand:SI 2 "constant_call_address_operand" "")]
12700             UNSPEC_TLS_LD_BASE))
12701       (clobber (match_scratch:SI 3 ""))
12702       (clobber (match_scratch:SI 4 ""))
12703       (clobber (reg:CC FLAGS_REG))])])
12704
12705 (define_insn "*tls_local_dynamic_base_64"
12706   [(set (match_operand:DI 0 "register_operand" "=a")
12707         (call:DI
12708          (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12709          (match_operand:DI 2 "" "")))
12710    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12711   "TARGET_64BIT"
12712 {
12713   output_asm_insn
12714     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12715   if (TARGET_SUN_TLS)
12716     return "call\t%p1@plt";
12717   return "call\t%P1";
12718 }
12719   [(set_attr "type" "multi")
12720    (set_attr "length" "12")])
12721
12722 (define_expand "tls_local_dynamic_base_64"
12723   [(parallel
12724      [(set (match_operand:DI 0 "register_operand" "")
12725            (call:DI
12726             (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12727             (const_int 0)))
12728       (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12729
12730 ;; Local dynamic of a single variable is a lose.  Show combine how
12731 ;; to convert that back to global dynamic.
12732
12733 (define_insn_and_split "*tls_local_dynamic_32_once"
12734   [(set (match_operand:SI 0 "register_operand" "=a")
12735         (plus:SI
12736          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12737                      (match_operand:SI 2 "constant_call_address_operand" "z")]
12738                     UNSPEC_TLS_LD_BASE)
12739          (const:SI (unspec:SI
12740                     [(match_operand:SI 3 "tls_symbolic_operand" "")]
12741                     UNSPEC_DTPOFF))))
12742    (clobber (match_scratch:SI 4 "=d"))
12743    (clobber (match_scratch:SI 5 "=c"))
12744    (clobber (reg:CC FLAGS_REG))]
12745   ""
12746   "#"
12747   ""
12748   [(parallel
12749      [(set (match_dup 0)
12750            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12751                       UNSPEC_TLS_GD))
12752       (clobber (match_dup 4))
12753       (clobber (match_dup 5))
12754       (clobber (reg:CC FLAGS_REG))])])
12755
12756 ;; Segment register for the thread base ptr load
12757 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12758
12759 ;; Load and add the thread base pointer from %<tp_seg>:0.
12760 (define_insn "*load_tp_x32"
12761   [(set (match_operand:SI 0 "register_operand" "=r")
12762         (unspec:SI [(const_int 0)] UNSPEC_TP))]
12763   "TARGET_X32"
12764   "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12765   [(set_attr "type" "imov")
12766    (set_attr "modrm" "0")
12767    (set_attr "length" "7")
12768    (set_attr "memory" "load")
12769    (set_attr "imm_disp" "false")])
12770
12771 (define_insn "*load_tp_x32_zext"
12772   [(set (match_operand:DI 0 "register_operand" "=r")
12773         (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12774   "TARGET_X32"
12775   "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12776   [(set_attr "type" "imov")
12777    (set_attr "modrm" "0")
12778    (set_attr "length" "7")
12779    (set_attr "memory" "load")
12780    (set_attr "imm_disp" "false")])
12781
12782 (define_insn "*load_tp_<mode>"
12783   [(set (match_operand:P 0 "register_operand" "=r")
12784         (unspec:P [(const_int 0)] UNSPEC_TP))]
12785   "!TARGET_X32"
12786   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12787   [(set_attr "type" "imov")
12788    (set_attr "modrm" "0")
12789    (set_attr "length" "7")
12790    (set_attr "memory" "load")
12791    (set_attr "imm_disp" "false")])
12792
12793 (define_insn "*add_tp_x32"
12794   [(set (match_operand:SI 0 "register_operand" "=r")
12795         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12796                  (match_operand:SI 1 "register_operand" "0")))
12797    (clobber (reg:CC FLAGS_REG))]
12798   "TARGET_X32"
12799   "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12800   [(set_attr "type" "alu")
12801    (set_attr "modrm" "0")
12802    (set_attr "length" "7")
12803    (set_attr "memory" "load")
12804    (set_attr "imm_disp" "false")])
12805
12806 (define_insn "*add_tp_x32_zext"
12807   [(set (match_operand:DI 0 "register_operand" "=r")
12808         (zero_extend:DI
12809           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12810                    (match_operand:SI 1 "register_operand" "0"))))
12811    (clobber (reg:CC FLAGS_REG))]
12812   "TARGET_X32"
12813   "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12814   [(set_attr "type" "alu")
12815    (set_attr "modrm" "0")
12816    (set_attr "length" "7")
12817    (set_attr "memory" "load")
12818    (set_attr "imm_disp" "false")])
12819
12820 (define_insn "*add_tp_<mode>"
12821   [(set (match_operand:P 0 "register_operand" "=r")
12822         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12823                 (match_operand:P 1 "register_operand" "0")))
12824    (clobber (reg:CC FLAGS_REG))]
12825   "!TARGET_X32"
12826   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12827   [(set_attr "type" "alu")
12828    (set_attr "modrm" "0")
12829    (set_attr "length" "7")
12830    (set_attr "memory" "load")
12831    (set_attr "imm_disp" "false")])
12832
12833 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12834 ;; %rax as destination of the initial executable code sequence.
12835 (define_insn "tls_initial_exec_64_sun"
12836   [(set (match_operand:DI 0 "register_operand" "=a")
12837         (unspec:DI
12838          [(match_operand:DI 1 "tls_symbolic_operand" "")]
12839          UNSPEC_TLS_IE_SUN))
12840    (clobber (reg:CC FLAGS_REG))]
12841   "TARGET_64BIT && TARGET_SUN_TLS"
12842 {
12843   output_asm_insn
12844     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12845   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12846 }
12847   [(set_attr "type" "multi")])
12848
12849 ;; GNU2 TLS patterns can be split.
12850
12851 (define_expand "tls_dynamic_gnu2_32"
12852   [(set (match_dup 3)
12853         (plus:SI (match_operand:SI 2 "register_operand" "")
12854                  (const:SI
12855                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12856                              UNSPEC_TLSDESC))))
12857    (parallel
12858     [(set (match_operand:SI 0 "register_operand" "")
12859           (unspec:SI [(match_dup 1) (match_dup 3)
12860                       (match_dup 2) (reg:SI SP_REG)]
12861                       UNSPEC_TLSDESC))
12862      (clobber (reg:CC FLAGS_REG))])]
12863   "!TARGET_64BIT && TARGET_GNU2_TLS"
12864 {
12865   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12866   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12867 })
12868
12869 (define_insn "*tls_dynamic_gnu2_lea_32"
12870   [(set (match_operand:SI 0 "register_operand" "=r")
12871         (plus:SI (match_operand:SI 1 "register_operand" "b")
12872                  (const:SI
12873                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12874                               UNSPEC_TLSDESC))))]
12875   "!TARGET_64BIT && TARGET_GNU2_TLS"
12876   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
12877   [(set_attr "type" "lea")
12878    (set_attr "mode" "SI")
12879    (set_attr "length" "6")
12880    (set_attr "length_address" "4")])
12881
12882 (define_insn "*tls_dynamic_gnu2_call_32"
12883   [(set (match_operand:SI 0 "register_operand" "=a")
12884         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12885                     (match_operand:SI 2 "register_operand" "0")
12886                     ;; we have to make sure %ebx still points to the GOT
12887                     (match_operand:SI 3 "register_operand" "b")
12888                     (reg:SI SP_REG)]
12889                    UNSPEC_TLSDESC))
12890    (clobber (reg:CC FLAGS_REG))]
12891   "!TARGET_64BIT && TARGET_GNU2_TLS"
12892   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12893   [(set_attr "type" "call")
12894    (set_attr "length" "2")
12895    (set_attr "length_address" "0")])
12896
12897 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12898   [(set (match_operand:SI 0 "register_operand" "=&a")
12899         (plus:SI
12900          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12901                      (match_operand:SI 4 "" "")
12902                      (match_operand:SI 2 "register_operand" "b")
12903                      (reg:SI SP_REG)]
12904                     UNSPEC_TLSDESC)
12905          (const:SI (unspec:SI
12906                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
12907                     UNSPEC_DTPOFF))))
12908    (clobber (reg:CC FLAGS_REG))]
12909   "!TARGET_64BIT && TARGET_GNU2_TLS"
12910   "#"
12911   ""
12912   [(set (match_dup 0) (match_dup 5))]
12913 {
12914   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12915   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12916 })
12917
12918 (define_expand "tls_dynamic_gnu2_64"
12919   [(set (match_dup 2)
12920         (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12921                    UNSPEC_TLSDESC))
12922    (parallel
12923     [(set (match_operand:DI 0 "register_operand" "")
12924           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12925                      UNSPEC_TLSDESC))
12926      (clobber (reg:CC FLAGS_REG))])]
12927   "TARGET_64BIT && TARGET_GNU2_TLS"
12928 {
12929   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12930   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12931 })
12932
12933 (define_insn "*tls_dynamic_gnu2_lea_64"
12934   [(set (match_operand:DI 0 "register_operand" "=r")
12935         (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12936                    UNSPEC_TLSDESC))]
12937   "TARGET_64BIT && TARGET_GNU2_TLS"
12938   "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
12939   [(set_attr "type" "lea")
12940    (set_attr "mode" "DI")
12941    (set_attr "length" "7")
12942    (set_attr "length_address" "4")])
12943
12944 (define_insn "*tls_dynamic_gnu2_call_64"
12945   [(set (match_operand:DI 0 "register_operand" "=a")
12946         (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12947                     (match_operand:DI 2 "register_operand" "0")
12948                     (reg:DI SP_REG)]
12949                    UNSPEC_TLSDESC))
12950    (clobber (reg:CC FLAGS_REG))]
12951   "TARGET_64BIT && TARGET_GNU2_TLS"
12952   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12953   [(set_attr "type" "call")
12954    (set_attr "length" "2")
12955    (set_attr "length_address" "0")])
12956
12957 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12958   [(set (match_operand:DI 0 "register_operand" "=&a")
12959         (plus:DI
12960          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12961                      (match_operand:DI 3 "" "")
12962                      (reg:DI SP_REG)]
12963                     UNSPEC_TLSDESC)
12964          (const:DI (unspec:DI
12965                     [(match_operand 1 "tls_symbolic_operand" "")]
12966                     UNSPEC_DTPOFF))))
12967    (clobber (reg:CC FLAGS_REG))]
12968   "TARGET_64BIT && TARGET_GNU2_TLS"
12969   "#"
12970   ""
12971   [(set (match_dup 0) (match_dup 4))]
12972 {
12973   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12974   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12975 })
12976 \f
12977 ;; These patterns match the binary 387 instructions for addM3, subM3,
12978 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
12979 ;; SFmode.  The first is the normal insn, the second the same insn but
12980 ;; with one operand a conversion, and the third the same insn but with
12981 ;; the other operand a conversion.  The conversion may be SFmode or
12982 ;; SImode if the target mode DFmode, but only SImode if the target mode
12983 ;; is SFmode.
12984
12985 ;; Gcc is slightly more smart about handling normal two address instructions
12986 ;; so use special patterns for add and mull.
12987
12988 (define_insn "*fop_<mode>_comm_mixed"
12989   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12990         (match_operator:MODEF 3 "binary_fp_operator"
12991           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12992            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12993   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12994    && COMMUTATIVE_ARITH_P (operands[3])
12995    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12996   "* return output_387_binary_op (insn, operands);"
12997   [(set (attr "type")
12998         (if_then_else (eq_attr "alternative" "1,2")
12999            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13000               (const_string "ssemul")
13001               (const_string "sseadd"))
13002            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13003               (const_string "fmul")
13004               (const_string "fop"))))
13005    (set_attr "isa" "*,noavx,avx")
13006    (set_attr "prefix" "orig,orig,vex")
13007    (set_attr "mode" "<MODE>")])
13008
13009 (define_insn "*fop_<mode>_comm_sse"
13010   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13011         (match_operator:MODEF 3 "binary_fp_operator"
13012           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13013            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13014   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13015    && COMMUTATIVE_ARITH_P (operands[3])
13016    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13017   "* return output_387_binary_op (insn, operands);"
13018   [(set (attr "type")
13019         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13020            (const_string "ssemul")
13021            (const_string "sseadd")))
13022    (set_attr "isa" "noavx,avx")
13023    (set_attr "prefix" "orig,vex")
13024    (set_attr "mode" "<MODE>")])
13025
13026 (define_insn "*fop_<mode>_comm_i387"
13027   [(set (match_operand:MODEF 0 "register_operand" "=f")
13028         (match_operator:MODEF 3 "binary_fp_operator"
13029           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13030            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13031   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13032    && COMMUTATIVE_ARITH_P (operands[3])
13033    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13034   "* return output_387_binary_op (insn, operands);"
13035   [(set (attr "type")
13036         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13037            (const_string "fmul")
13038            (const_string "fop")))
13039    (set_attr "mode" "<MODE>")])
13040
13041 (define_insn "*fop_<mode>_1_mixed"
13042   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13043         (match_operator:MODEF 3 "binary_fp_operator"
13044           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13045            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13046   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13047    && !COMMUTATIVE_ARITH_P (operands[3])
13048    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13049   "* return output_387_binary_op (insn, operands);"
13050   [(set (attr "type")
13051         (cond [(and (eq_attr "alternative" "2,3")
13052                     (match_operand:MODEF 3 "mult_operator" ""))
13053                  (const_string "ssemul")
13054                (and (eq_attr "alternative" "2,3")
13055                     (match_operand:MODEF 3 "div_operator" ""))
13056                  (const_string "ssediv")
13057                (eq_attr "alternative" "2,3")
13058                  (const_string "sseadd")
13059                (match_operand:MODEF 3 "mult_operator" "")
13060                  (const_string "fmul")
13061                (match_operand:MODEF 3 "div_operator" "")
13062                  (const_string "fdiv")
13063               ]
13064               (const_string "fop")))
13065    (set_attr "isa" "*,*,noavx,avx")
13066    (set_attr "prefix" "orig,orig,orig,vex")
13067    (set_attr "mode" "<MODE>")])
13068
13069 (define_insn "*rcpsf2_sse"
13070   [(set (match_operand:SF 0 "register_operand" "=x")
13071         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13072                    UNSPEC_RCP))]
13073   "TARGET_SSE_MATH"
13074   "%vrcpss\t{%1, %d0|%d0, %1}"
13075   [(set_attr "type" "sse")
13076    (set_attr "atom_sse_attr" "rcp")
13077    (set_attr "prefix" "maybe_vex")
13078    (set_attr "mode" "SF")])
13079
13080 (define_insn "*fop_<mode>_1_sse"
13081   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13082         (match_operator:MODEF 3 "binary_fp_operator"
13083           [(match_operand:MODEF 1 "register_operand" "0,x")
13084            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13085   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13086    && !COMMUTATIVE_ARITH_P (operands[3])"
13087   "* return output_387_binary_op (insn, operands);"
13088   [(set (attr "type")
13089         (cond [(match_operand:MODEF 3 "mult_operator" "")
13090                  (const_string "ssemul")
13091                (match_operand:MODEF 3 "div_operator" "")
13092                  (const_string "ssediv")
13093               ]
13094               (const_string "sseadd")))
13095    (set_attr "isa" "noavx,avx")
13096    (set_attr "prefix" "orig,vex")
13097    (set_attr "mode" "<MODE>")])
13098
13099 ;; This pattern is not fully shadowed by the pattern above.
13100 (define_insn "*fop_<mode>_1_i387"
13101   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13102         (match_operator:MODEF 3 "binary_fp_operator"
13103           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13104            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13105   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13106    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13107    && !COMMUTATIVE_ARITH_P (operands[3])
13108    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13109   "* return output_387_binary_op (insn, operands);"
13110   [(set (attr "type")
13111         (cond [(match_operand:MODEF 3 "mult_operator" "")
13112                  (const_string "fmul")
13113                (match_operand:MODEF 3 "div_operator" "")
13114                  (const_string "fdiv")
13115               ]
13116               (const_string "fop")))
13117    (set_attr "mode" "<MODE>")])
13118
13119 ;; ??? Add SSE splitters for these!
13120 (define_insn "*fop_<MODEF:mode>_2_i387"
13121   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13122         (match_operator:MODEF 3 "binary_fp_operator"
13123           [(float:MODEF
13124              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13125            (match_operand:MODEF 2 "register_operand" "0,0")]))]
13126   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13127    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13128    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13129   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13130   [(set (attr "type")
13131         (cond [(match_operand:MODEF 3 "mult_operator" "")
13132                  (const_string "fmul")
13133                (match_operand:MODEF 3 "div_operator" "")
13134                  (const_string "fdiv")
13135               ]
13136               (const_string "fop")))
13137    (set_attr "fp_int_src" "true")
13138    (set_attr "mode" "<SWI24:MODE>")])
13139
13140 (define_insn "*fop_<MODEF:mode>_3_i387"
13141   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13142         (match_operator:MODEF 3 "binary_fp_operator"
13143           [(match_operand:MODEF 1 "register_operand" "0,0")
13144            (float:MODEF
13145              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13146   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13147    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13148    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13149   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13150   [(set (attr "type")
13151         (cond [(match_operand:MODEF 3 "mult_operator" "")
13152                  (const_string "fmul")
13153                (match_operand:MODEF 3 "div_operator" "")
13154                  (const_string "fdiv")
13155               ]
13156               (const_string "fop")))
13157    (set_attr "fp_int_src" "true")
13158    (set_attr "mode" "<MODE>")])
13159
13160 (define_insn "*fop_df_4_i387"
13161   [(set (match_operand:DF 0 "register_operand" "=f,f")
13162         (match_operator:DF 3 "binary_fp_operator"
13163            [(float_extend:DF
13164              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13165             (match_operand:DF 2 "register_operand" "0,f")]))]
13166   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13167    && !(TARGET_SSE2 && TARGET_SSE_MATH)
13168    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13169   "* return output_387_binary_op (insn, operands);"
13170   [(set (attr "type")
13171         (cond [(match_operand:DF 3 "mult_operator" "")
13172                  (const_string "fmul")
13173                (match_operand:DF 3 "div_operator" "")
13174                  (const_string "fdiv")
13175               ]
13176               (const_string "fop")))
13177    (set_attr "mode" "SF")])
13178
13179 (define_insn "*fop_df_5_i387"
13180   [(set (match_operand:DF 0 "register_operand" "=f,f")
13181         (match_operator:DF 3 "binary_fp_operator"
13182           [(match_operand:DF 1 "register_operand" "0,f")
13183            (float_extend:DF
13184             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13185   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13186    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13187   "* return output_387_binary_op (insn, operands);"
13188   [(set (attr "type")
13189         (cond [(match_operand:DF 3 "mult_operator" "")
13190                  (const_string "fmul")
13191                (match_operand:DF 3 "div_operator" "")
13192                  (const_string "fdiv")
13193               ]
13194               (const_string "fop")))
13195    (set_attr "mode" "SF")])
13196
13197 (define_insn "*fop_df_6_i387"
13198   [(set (match_operand:DF 0 "register_operand" "=f,f")
13199         (match_operator:DF 3 "binary_fp_operator"
13200           [(float_extend:DF
13201             (match_operand:SF 1 "register_operand" "0,f"))
13202            (float_extend:DF
13203             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13204   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13205    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13206   "* return output_387_binary_op (insn, operands);"
13207   [(set (attr "type")
13208         (cond [(match_operand:DF 3 "mult_operator" "")
13209                  (const_string "fmul")
13210                (match_operand:DF 3 "div_operator" "")
13211                  (const_string "fdiv")
13212               ]
13213               (const_string "fop")))
13214    (set_attr "mode" "SF")])
13215
13216 (define_insn "*fop_xf_comm_i387"
13217   [(set (match_operand:XF 0 "register_operand" "=f")
13218         (match_operator:XF 3 "binary_fp_operator"
13219                         [(match_operand:XF 1 "register_operand" "%0")
13220                          (match_operand:XF 2 "register_operand" "f")]))]
13221   "TARGET_80387
13222    && COMMUTATIVE_ARITH_P (operands[3])"
13223   "* return output_387_binary_op (insn, operands);"
13224   [(set (attr "type")
13225         (if_then_else (match_operand:XF 3 "mult_operator" "")
13226            (const_string "fmul")
13227            (const_string "fop")))
13228    (set_attr "mode" "XF")])
13229
13230 (define_insn "*fop_xf_1_i387"
13231   [(set (match_operand:XF 0 "register_operand" "=f,f")
13232         (match_operator:XF 3 "binary_fp_operator"
13233                         [(match_operand:XF 1 "register_operand" "0,f")
13234                          (match_operand:XF 2 "register_operand" "f,0")]))]
13235   "TARGET_80387
13236    && !COMMUTATIVE_ARITH_P (operands[3])"
13237   "* return output_387_binary_op (insn, operands);"
13238   [(set (attr "type")
13239         (cond [(match_operand:XF 3 "mult_operator" "")
13240                  (const_string "fmul")
13241                (match_operand:XF 3 "div_operator" "")
13242                  (const_string "fdiv")
13243               ]
13244               (const_string "fop")))
13245    (set_attr "mode" "XF")])
13246
13247 (define_insn "*fop_xf_2_i387"
13248   [(set (match_operand:XF 0 "register_operand" "=f,f")
13249         (match_operator:XF 3 "binary_fp_operator"
13250           [(float:XF
13251              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13252            (match_operand:XF 2 "register_operand" "0,0")]))]
13253   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13254   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13255   [(set (attr "type")
13256         (cond [(match_operand:XF 3 "mult_operator" "")
13257                  (const_string "fmul")
13258                (match_operand:XF 3 "div_operator" "")
13259                  (const_string "fdiv")
13260               ]
13261               (const_string "fop")))
13262    (set_attr "fp_int_src" "true")
13263    (set_attr "mode" "<MODE>")])
13264
13265 (define_insn "*fop_xf_3_i387"
13266   [(set (match_operand:XF 0 "register_operand" "=f,f")
13267         (match_operator:XF 3 "binary_fp_operator"
13268           [(match_operand:XF 1 "register_operand" "0,0")
13269            (float:XF
13270              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13271   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13272   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13273   [(set (attr "type")
13274         (cond [(match_operand:XF 3 "mult_operator" "")
13275                  (const_string "fmul")
13276                (match_operand:XF 3 "div_operator" "")
13277                  (const_string "fdiv")
13278               ]
13279               (const_string "fop")))
13280    (set_attr "fp_int_src" "true")
13281    (set_attr "mode" "<MODE>")])
13282
13283 (define_insn "*fop_xf_4_i387"
13284   [(set (match_operand:XF 0 "register_operand" "=f,f")
13285         (match_operator:XF 3 "binary_fp_operator"
13286            [(float_extend:XF
13287               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13288             (match_operand:XF 2 "register_operand" "0,f")]))]
13289   "TARGET_80387"
13290   "* return output_387_binary_op (insn, operands);"
13291   [(set (attr "type")
13292         (cond [(match_operand:XF 3 "mult_operator" "")
13293                  (const_string "fmul")
13294                (match_operand:XF 3 "div_operator" "")
13295                  (const_string "fdiv")
13296               ]
13297               (const_string "fop")))
13298    (set_attr "mode" "<MODE>")])
13299
13300 (define_insn "*fop_xf_5_i387"
13301   [(set (match_operand:XF 0 "register_operand" "=f,f")
13302         (match_operator:XF 3 "binary_fp_operator"
13303           [(match_operand:XF 1 "register_operand" "0,f")
13304            (float_extend:XF
13305              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13306   "TARGET_80387"
13307   "* return output_387_binary_op (insn, operands);"
13308   [(set (attr "type")
13309         (cond [(match_operand:XF 3 "mult_operator" "")
13310                  (const_string "fmul")
13311                (match_operand:XF 3 "div_operator" "")
13312                  (const_string "fdiv")
13313               ]
13314               (const_string "fop")))
13315    (set_attr "mode" "<MODE>")])
13316
13317 (define_insn "*fop_xf_6_i387"
13318   [(set (match_operand:XF 0 "register_operand" "=f,f")
13319         (match_operator:XF 3 "binary_fp_operator"
13320           [(float_extend:XF
13321              (match_operand:MODEF 1 "register_operand" "0,f"))
13322            (float_extend:XF
13323              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13324   "TARGET_80387"
13325   "* return output_387_binary_op (insn, operands);"
13326   [(set (attr "type")
13327         (cond [(match_operand:XF 3 "mult_operator" "")
13328                  (const_string "fmul")
13329                (match_operand:XF 3 "div_operator" "")
13330                  (const_string "fdiv")
13331               ]
13332               (const_string "fop")))
13333    (set_attr "mode" "<MODE>")])
13334
13335 (define_split
13336   [(set (match_operand 0 "register_operand" "")
13337         (match_operator 3 "binary_fp_operator"
13338            [(float (match_operand:SWI24 1 "register_operand" ""))
13339             (match_operand 2 "register_operand" "")]))]
13340   "reload_completed
13341    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13342    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13343   [(const_int 0)]
13344 {
13345   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13346   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13347   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13348                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13349                                           GET_MODE (operands[3]),
13350                                           operands[4],
13351                                           operands[2])));
13352   ix86_free_from_memory (GET_MODE (operands[1]));
13353   DONE;
13354 })
13355
13356 (define_split
13357   [(set (match_operand 0 "register_operand" "")
13358         (match_operator 3 "binary_fp_operator"
13359            [(match_operand 1 "register_operand" "")
13360             (float (match_operand:SWI24 2 "register_operand" ""))]))]
13361   "reload_completed
13362    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13363    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13364   [(const_int 0)]
13365 {
13366   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13367   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13368   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13369                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13370                                           GET_MODE (operands[3]),
13371                                           operands[1],
13372                                           operands[4])));
13373   ix86_free_from_memory (GET_MODE (operands[2]));
13374   DONE;
13375 })
13376 \f
13377 ;; FPU special functions.
13378
13379 ;; This pattern implements a no-op XFmode truncation for
13380 ;; all fancy i386 XFmode math functions.
13381
13382 (define_insn "truncxf<mode>2_i387_noop_unspec"
13383   [(set (match_operand:MODEF 0 "register_operand" "=f")
13384         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13385         UNSPEC_TRUNC_NOOP))]
13386   "TARGET_USE_FANCY_MATH_387"
13387   "* return output_387_reg_move (insn, operands);"
13388   [(set_attr "type" "fmov")
13389    (set_attr "mode" "<MODE>")])
13390
13391 (define_insn "sqrtxf2"
13392   [(set (match_operand:XF 0 "register_operand" "=f")
13393         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13394   "TARGET_USE_FANCY_MATH_387"
13395   "fsqrt"
13396   [(set_attr "type" "fpspc")
13397    (set_attr "mode" "XF")
13398    (set_attr "athlon_decode" "direct")
13399    (set_attr "amdfam10_decode" "direct")
13400    (set_attr "bdver1_decode" "direct")])
13401
13402 (define_insn "sqrt_extend<mode>xf2_i387"
13403   [(set (match_operand:XF 0 "register_operand" "=f")
13404         (sqrt:XF
13405           (float_extend:XF
13406             (match_operand:MODEF 1 "register_operand" "0"))))]
13407   "TARGET_USE_FANCY_MATH_387"
13408   "fsqrt"
13409   [(set_attr "type" "fpspc")
13410    (set_attr "mode" "XF")
13411    (set_attr "athlon_decode" "direct")
13412    (set_attr "amdfam10_decode" "direct")
13413    (set_attr "bdver1_decode" "direct")])
13414
13415 (define_insn "*rsqrtsf2_sse"
13416   [(set (match_operand:SF 0 "register_operand" "=x")
13417         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13418                    UNSPEC_RSQRT))]
13419   "TARGET_SSE_MATH"
13420   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13421   [(set_attr "type" "sse")
13422    (set_attr "atom_sse_attr" "rcp")
13423    (set_attr "prefix" "maybe_vex")
13424    (set_attr "mode" "SF")])
13425
13426 (define_expand "rsqrtsf2"
13427   [(set (match_operand:SF 0 "register_operand" "")
13428         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13429                    UNSPEC_RSQRT))]
13430   "TARGET_SSE_MATH"
13431 {
13432   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13433   DONE;
13434 })
13435
13436 (define_insn "*sqrt<mode>2_sse"
13437   [(set (match_operand:MODEF 0 "register_operand" "=x")
13438         (sqrt:MODEF
13439           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13440   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13441   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13442   [(set_attr "type" "sse")
13443    (set_attr "atom_sse_attr" "sqrt")
13444    (set_attr "prefix" "maybe_vex")
13445    (set_attr "mode" "<MODE>")
13446    (set_attr "athlon_decode" "*")
13447    (set_attr "amdfam10_decode" "*")
13448    (set_attr "bdver1_decode" "*")])
13449
13450 (define_expand "sqrt<mode>2"
13451   [(set (match_operand:MODEF 0 "register_operand" "")
13452         (sqrt:MODEF
13453           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13454   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13455    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13456 {
13457   if (<MODE>mode == SFmode
13458       && TARGET_SSE_MATH
13459       && TARGET_RECIP_SQRT
13460       && !optimize_function_for_size_p (cfun)
13461       && flag_finite_math_only && !flag_trapping_math
13462       && flag_unsafe_math_optimizations)
13463     {
13464       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13465       DONE;
13466     }
13467
13468   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13469     {
13470       rtx op0 = gen_reg_rtx (XFmode);
13471       rtx op1 = force_reg (<MODE>mode, operands[1]);
13472
13473       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13474       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13475       DONE;
13476    }
13477 })
13478
13479 (define_insn "fpremxf4_i387"
13480   [(set (match_operand:XF 0 "register_operand" "=f")
13481         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13482                     (match_operand:XF 3 "register_operand" "1")]
13483                    UNSPEC_FPREM_F))
13484    (set (match_operand:XF 1 "register_operand" "=u")
13485         (unspec:XF [(match_dup 2) (match_dup 3)]
13486                    UNSPEC_FPREM_U))
13487    (set (reg:CCFP FPSR_REG)
13488         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13489                      UNSPEC_C2_FLAG))]
13490   "TARGET_USE_FANCY_MATH_387"
13491   "fprem"
13492   [(set_attr "type" "fpspc")
13493    (set_attr "mode" "XF")])
13494
13495 (define_expand "fmodxf3"
13496   [(use (match_operand:XF 0 "register_operand" ""))
13497    (use (match_operand:XF 1 "general_operand" ""))
13498    (use (match_operand:XF 2 "general_operand" ""))]
13499   "TARGET_USE_FANCY_MATH_387"
13500 {
13501   rtx label = gen_label_rtx ();
13502
13503   rtx op1 = gen_reg_rtx (XFmode);
13504   rtx op2 = gen_reg_rtx (XFmode);
13505
13506   emit_move_insn (op2, operands[2]);
13507   emit_move_insn (op1, operands[1]);
13508
13509   emit_label (label);
13510   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13511   ix86_emit_fp_unordered_jump (label);
13512   LABEL_NUSES (label) = 1;
13513
13514   emit_move_insn (operands[0], op1);
13515   DONE;
13516 })
13517
13518 (define_expand "fmod<mode>3"
13519   [(use (match_operand:MODEF 0 "register_operand" ""))
13520    (use (match_operand:MODEF 1 "general_operand" ""))
13521    (use (match_operand:MODEF 2 "general_operand" ""))]
13522   "TARGET_USE_FANCY_MATH_387"
13523 {
13524   rtx (*gen_truncxf) (rtx, rtx);
13525
13526   rtx label = gen_label_rtx ();
13527
13528   rtx op1 = gen_reg_rtx (XFmode);
13529   rtx op2 = gen_reg_rtx (XFmode);
13530
13531   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13532   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13533
13534   emit_label (label);
13535   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13536   ix86_emit_fp_unordered_jump (label);
13537   LABEL_NUSES (label) = 1;
13538
13539   /* Truncate the result properly for strict SSE math.  */
13540   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13541       && !TARGET_MIX_SSE_I387)
13542     gen_truncxf = gen_truncxf<mode>2;
13543   else
13544     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13545
13546   emit_insn (gen_truncxf (operands[0], op1));
13547   DONE;
13548 })
13549
13550 (define_insn "fprem1xf4_i387"
13551   [(set (match_operand:XF 0 "register_operand" "=f")
13552         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13553                     (match_operand:XF 3 "register_operand" "1")]
13554                    UNSPEC_FPREM1_F))
13555    (set (match_operand:XF 1 "register_operand" "=u")
13556         (unspec:XF [(match_dup 2) (match_dup 3)]
13557                    UNSPEC_FPREM1_U))
13558    (set (reg:CCFP FPSR_REG)
13559         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13560                      UNSPEC_C2_FLAG))]
13561   "TARGET_USE_FANCY_MATH_387"
13562   "fprem1"
13563   [(set_attr "type" "fpspc")
13564    (set_attr "mode" "XF")])
13565
13566 (define_expand "remainderxf3"
13567   [(use (match_operand:XF 0 "register_operand" ""))
13568    (use (match_operand:XF 1 "general_operand" ""))
13569    (use (match_operand:XF 2 "general_operand" ""))]
13570   "TARGET_USE_FANCY_MATH_387"
13571 {
13572   rtx label = gen_label_rtx ();
13573
13574   rtx op1 = gen_reg_rtx (XFmode);
13575   rtx op2 = gen_reg_rtx (XFmode);
13576
13577   emit_move_insn (op2, operands[2]);
13578   emit_move_insn (op1, operands[1]);
13579
13580   emit_label (label);
13581   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13582   ix86_emit_fp_unordered_jump (label);
13583   LABEL_NUSES (label) = 1;
13584
13585   emit_move_insn (operands[0], op1);
13586   DONE;
13587 })
13588
13589 (define_expand "remainder<mode>3"
13590   [(use (match_operand:MODEF 0 "register_operand" ""))
13591    (use (match_operand:MODEF 1 "general_operand" ""))
13592    (use (match_operand:MODEF 2 "general_operand" ""))]
13593   "TARGET_USE_FANCY_MATH_387"
13594 {
13595   rtx (*gen_truncxf) (rtx, rtx);
13596
13597   rtx label = gen_label_rtx ();
13598
13599   rtx op1 = gen_reg_rtx (XFmode);
13600   rtx op2 = gen_reg_rtx (XFmode);
13601
13602   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13603   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13604
13605   emit_label (label);
13606
13607   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13608   ix86_emit_fp_unordered_jump (label);
13609   LABEL_NUSES (label) = 1;
13610
13611   /* Truncate the result properly for strict SSE math.  */
13612   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13613       && !TARGET_MIX_SSE_I387)
13614     gen_truncxf = gen_truncxf<mode>2;
13615   else
13616     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13617
13618   emit_insn (gen_truncxf (operands[0], op1));
13619   DONE;
13620 })
13621
13622 (define_insn "*sinxf2_i387"
13623   [(set (match_operand:XF 0 "register_operand" "=f")
13624         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13625   "TARGET_USE_FANCY_MATH_387
13626    && flag_unsafe_math_optimizations"
13627   "fsin"
13628   [(set_attr "type" "fpspc")
13629    (set_attr "mode" "XF")])
13630
13631 (define_insn "*sin_extend<mode>xf2_i387"
13632   [(set (match_operand:XF 0 "register_operand" "=f")
13633         (unspec:XF [(float_extend:XF
13634                       (match_operand:MODEF 1 "register_operand" "0"))]
13635                    UNSPEC_SIN))]
13636   "TARGET_USE_FANCY_MATH_387
13637    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13638        || TARGET_MIX_SSE_I387)
13639    && flag_unsafe_math_optimizations"
13640   "fsin"
13641   [(set_attr "type" "fpspc")
13642    (set_attr "mode" "XF")])
13643
13644 (define_insn "*cosxf2_i387"
13645   [(set (match_operand:XF 0 "register_operand" "=f")
13646         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13647   "TARGET_USE_FANCY_MATH_387
13648    && flag_unsafe_math_optimizations"
13649   "fcos"
13650   [(set_attr "type" "fpspc")
13651    (set_attr "mode" "XF")])
13652
13653 (define_insn "*cos_extend<mode>xf2_i387"
13654   [(set (match_operand:XF 0 "register_operand" "=f")
13655         (unspec:XF [(float_extend:XF
13656                       (match_operand:MODEF 1 "register_operand" "0"))]
13657                    UNSPEC_COS))]
13658   "TARGET_USE_FANCY_MATH_387
13659    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13660        || TARGET_MIX_SSE_I387)
13661    && flag_unsafe_math_optimizations"
13662   "fcos"
13663   [(set_attr "type" "fpspc")
13664    (set_attr "mode" "XF")])
13665
13666 ;; When sincos pattern is defined, sin and cos builtin functions will be
13667 ;; expanded to sincos pattern with one of its outputs left unused.
13668 ;; CSE pass will figure out if two sincos patterns can be combined,
13669 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13670 ;; depending on the unused output.
13671
13672 (define_insn "sincosxf3"
13673   [(set (match_operand:XF 0 "register_operand" "=f")
13674         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13675                    UNSPEC_SINCOS_COS))
13676    (set (match_operand:XF 1 "register_operand" "=u")
13677         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13678   "TARGET_USE_FANCY_MATH_387
13679    && flag_unsafe_math_optimizations"
13680   "fsincos"
13681   [(set_attr "type" "fpspc")
13682    (set_attr "mode" "XF")])
13683
13684 (define_split
13685   [(set (match_operand:XF 0 "register_operand" "")
13686         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13687                    UNSPEC_SINCOS_COS))
13688    (set (match_operand:XF 1 "register_operand" "")
13689         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13690   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13691    && can_create_pseudo_p ()"
13692   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13693
13694 (define_split
13695   [(set (match_operand:XF 0 "register_operand" "")
13696         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13697                    UNSPEC_SINCOS_COS))
13698    (set (match_operand:XF 1 "register_operand" "")
13699         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13700   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13701    && can_create_pseudo_p ()"
13702   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13703
13704 (define_insn "sincos_extend<mode>xf3_i387"
13705   [(set (match_operand:XF 0 "register_operand" "=f")
13706         (unspec:XF [(float_extend:XF
13707                       (match_operand:MODEF 2 "register_operand" "0"))]
13708                    UNSPEC_SINCOS_COS))
13709    (set (match_operand:XF 1 "register_operand" "=u")
13710         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13711   "TARGET_USE_FANCY_MATH_387
13712    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13713        || TARGET_MIX_SSE_I387)
13714    && flag_unsafe_math_optimizations"
13715   "fsincos"
13716   [(set_attr "type" "fpspc")
13717    (set_attr "mode" "XF")])
13718
13719 (define_split
13720   [(set (match_operand:XF 0 "register_operand" "")
13721         (unspec:XF [(float_extend:XF
13722                       (match_operand:MODEF 2 "register_operand" ""))]
13723                    UNSPEC_SINCOS_COS))
13724    (set (match_operand:XF 1 "register_operand" "")
13725         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13726   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13727    && can_create_pseudo_p ()"
13728   [(set (match_dup 1)
13729         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13730
13731 (define_split
13732   [(set (match_operand:XF 0 "register_operand" "")
13733         (unspec:XF [(float_extend:XF
13734                       (match_operand:MODEF 2 "register_operand" ""))]
13735                    UNSPEC_SINCOS_COS))
13736    (set (match_operand:XF 1 "register_operand" "")
13737         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13738   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13739    && can_create_pseudo_p ()"
13740   [(set (match_dup 0)
13741         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13742
13743 (define_expand "sincos<mode>3"
13744   [(use (match_operand:MODEF 0 "register_operand" ""))
13745    (use (match_operand:MODEF 1 "register_operand" ""))
13746    (use (match_operand:MODEF 2 "register_operand" ""))]
13747   "TARGET_USE_FANCY_MATH_387
13748    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13749        || TARGET_MIX_SSE_I387)
13750    && flag_unsafe_math_optimizations"
13751 {
13752   rtx op0 = gen_reg_rtx (XFmode);
13753   rtx op1 = gen_reg_rtx (XFmode);
13754
13755   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13756   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13757   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13758   DONE;
13759 })
13760
13761 (define_insn "fptanxf4_i387"
13762   [(set (match_operand:XF 0 "register_operand" "=f")
13763         (match_operand:XF 3 "const_double_operand" "F"))
13764    (set (match_operand:XF 1 "register_operand" "=u")
13765         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13766                    UNSPEC_TAN))]
13767   "TARGET_USE_FANCY_MATH_387
13768    && flag_unsafe_math_optimizations
13769    && standard_80387_constant_p (operands[3]) == 2"
13770   "fptan"
13771   [(set_attr "type" "fpspc")
13772    (set_attr "mode" "XF")])
13773
13774 (define_insn "fptan_extend<mode>xf4_i387"
13775   [(set (match_operand:MODEF 0 "register_operand" "=f")
13776         (match_operand:MODEF 3 "const_double_operand" "F"))
13777    (set (match_operand:XF 1 "register_operand" "=u")
13778         (unspec:XF [(float_extend:XF
13779                       (match_operand:MODEF 2 "register_operand" "0"))]
13780                    UNSPEC_TAN))]
13781   "TARGET_USE_FANCY_MATH_387
13782    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13783        || TARGET_MIX_SSE_I387)
13784    && flag_unsafe_math_optimizations
13785    && standard_80387_constant_p (operands[3]) == 2"
13786   "fptan"
13787   [(set_attr "type" "fpspc")
13788    (set_attr "mode" "XF")])
13789
13790 (define_expand "tanxf2"
13791   [(use (match_operand:XF 0 "register_operand" ""))
13792    (use (match_operand:XF 1 "register_operand" ""))]
13793   "TARGET_USE_FANCY_MATH_387
13794    && flag_unsafe_math_optimizations"
13795 {
13796   rtx one = gen_reg_rtx (XFmode);
13797   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13798
13799   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13800   DONE;
13801 })
13802
13803 (define_expand "tan<mode>2"
13804   [(use (match_operand:MODEF 0 "register_operand" ""))
13805    (use (match_operand:MODEF 1 "register_operand" ""))]
13806   "TARGET_USE_FANCY_MATH_387
13807    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13808        || TARGET_MIX_SSE_I387)
13809    && flag_unsafe_math_optimizations"
13810 {
13811   rtx op0 = gen_reg_rtx (XFmode);
13812
13813   rtx one = gen_reg_rtx (<MODE>mode);
13814   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13815
13816   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13817                                              operands[1], op2));
13818   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13819   DONE;
13820 })
13821
13822 (define_insn "*fpatanxf3_i387"
13823   [(set (match_operand:XF 0 "register_operand" "=f")
13824         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13825                     (match_operand:XF 2 "register_operand" "u")]
13826                    UNSPEC_FPATAN))
13827    (clobber (match_scratch:XF 3 "=2"))]
13828   "TARGET_USE_FANCY_MATH_387
13829    && flag_unsafe_math_optimizations"
13830   "fpatan"
13831   [(set_attr "type" "fpspc")
13832    (set_attr "mode" "XF")])
13833
13834 (define_insn "fpatan_extend<mode>xf3_i387"
13835   [(set (match_operand:XF 0 "register_operand" "=f")
13836         (unspec:XF [(float_extend:XF
13837                       (match_operand:MODEF 1 "register_operand" "0"))
13838                     (float_extend:XF
13839                       (match_operand:MODEF 2 "register_operand" "u"))]
13840                    UNSPEC_FPATAN))
13841    (clobber (match_scratch:XF 3 "=2"))]
13842   "TARGET_USE_FANCY_MATH_387
13843    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13844        || TARGET_MIX_SSE_I387)
13845    && flag_unsafe_math_optimizations"
13846   "fpatan"
13847   [(set_attr "type" "fpspc")
13848    (set_attr "mode" "XF")])
13849
13850 (define_expand "atan2xf3"
13851   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13852                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
13853                                (match_operand:XF 1 "register_operand" "")]
13854                               UNSPEC_FPATAN))
13855               (clobber (match_scratch:XF 3 ""))])]
13856   "TARGET_USE_FANCY_MATH_387
13857    && flag_unsafe_math_optimizations")
13858
13859 (define_expand "atan2<mode>3"
13860   [(use (match_operand:MODEF 0 "register_operand" ""))
13861    (use (match_operand:MODEF 1 "register_operand" ""))
13862    (use (match_operand:MODEF 2 "register_operand" ""))]
13863   "TARGET_USE_FANCY_MATH_387
13864    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13865        || TARGET_MIX_SSE_I387)
13866    && flag_unsafe_math_optimizations"
13867 {
13868   rtx op0 = gen_reg_rtx (XFmode);
13869
13870   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13871   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13872   DONE;
13873 })
13874
13875 (define_expand "atanxf2"
13876   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13877                    (unspec:XF [(match_dup 2)
13878                                (match_operand:XF 1 "register_operand" "")]
13879                               UNSPEC_FPATAN))
13880               (clobber (match_scratch:XF 3 ""))])]
13881   "TARGET_USE_FANCY_MATH_387
13882    && flag_unsafe_math_optimizations"
13883 {
13884   operands[2] = gen_reg_rtx (XFmode);
13885   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13886 })
13887
13888 (define_expand "atan<mode>2"
13889   [(use (match_operand:MODEF 0 "register_operand" ""))
13890    (use (match_operand:MODEF 1 "register_operand" ""))]
13891   "TARGET_USE_FANCY_MATH_387
13892    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13893        || TARGET_MIX_SSE_I387)
13894    && flag_unsafe_math_optimizations"
13895 {
13896   rtx op0 = gen_reg_rtx (XFmode);
13897
13898   rtx op2 = gen_reg_rtx (<MODE>mode);
13899   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13900
13901   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13902   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13903   DONE;
13904 })
13905
13906 (define_expand "asinxf2"
13907   [(set (match_dup 2)
13908         (mult:XF (match_operand:XF 1 "register_operand" "")
13909                  (match_dup 1)))
13910    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13911    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13912    (parallel [(set (match_operand:XF 0 "register_operand" "")
13913                    (unspec:XF [(match_dup 5) (match_dup 1)]
13914                               UNSPEC_FPATAN))
13915               (clobber (match_scratch:XF 6 ""))])]
13916   "TARGET_USE_FANCY_MATH_387
13917    && flag_unsafe_math_optimizations"
13918 {
13919   int i;
13920
13921   if (optimize_insn_for_size_p ())
13922     FAIL;
13923
13924   for (i = 2; i < 6; i++)
13925     operands[i] = gen_reg_rtx (XFmode);
13926
13927   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13928 })
13929
13930 (define_expand "asin<mode>2"
13931   [(use (match_operand:MODEF 0 "register_operand" ""))
13932    (use (match_operand:MODEF 1 "general_operand" ""))]
13933  "TARGET_USE_FANCY_MATH_387
13934    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13935        || TARGET_MIX_SSE_I387)
13936    && flag_unsafe_math_optimizations"
13937 {
13938   rtx op0 = gen_reg_rtx (XFmode);
13939   rtx op1 = gen_reg_rtx (XFmode);
13940
13941   if (optimize_insn_for_size_p ())
13942     FAIL;
13943
13944   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13945   emit_insn (gen_asinxf2 (op0, op1));
13946   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13947   DONE;
13948 })
13949
13950 (define_expand "acosxf2"
13951   [(set (match_dup 2)
13952         (mult:XF (match_operand:XF 1 "register_operand" "")
13953                  (match_dup 1)))
13954    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13955    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13956    (parallel [(set (match_operand:XF 0 "register_operand" "")
13957                    (unspec:XF [(match_dup 1) (match_dup 5)]
13958                               UNSPEC_FPATAN))
13959               (clobber (match_scratch:XF 6 ""))])]
13960   "TARGET_USE_FANCY_MATH_387
13961    && flag_unsafe_math_optimizations"
13962 {
13963   int i;
13964
13965   if (optimize_insn_for_size_p ())
13966     FAIL;
13967
13968   for (i = 2; i < 6; i++)
13969     operands[i] = gen_reg_rtx (XFmode);
13970
13971   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13972 })
13973
13974 (define_expand "acos<mode>2"
13975   [(use (match_operand:MODEF 0 "register_operand" ""))
13976    (use (match_operand:MODEF 1 "general_operand" ""))]
13977  "TARGET_USE_FANCY_MATH_387
13978    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13979        || TARGET_MIX_SSE_I387)
13980    && flag_unsafe_math_optimizations"
13981 {
13982   rtx op0 = gen_reg_rtx (XFmode);
13983   rtx op1 = gen_reg_rtx (XFmode);
13984
13985   if (optimize_insn_for_size_p ())
13986     FAIL;
13987
13988   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13989   emit_insn (gen_acosxf2 (op0, op1));
13990   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13991   DONE;
13992 })
13993
13994 (define_insn "fyl2xxf3_i387"
13995   [(set (match_operand:XF 0 "register_operand" "=f")
13996         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13997                     (match_operand:XF 2 "register_operand" "u")]
13998                    UNSPEC_FYL2X))
13999    (clobber (match_scratch:XF 3 "=2"))]
14000   "TARGET_USE_FANCY_MATH_387
14001    && flag_unsafe_math_optimizations"
14002   "fyl2x"
14003   [(set_attr "type" "fpspc")
14004    (set_attr "mode" "XF")])
14005
14006 (define_insn "fyl2x_extend<mode>xf3_i387"
14007   [(set (match_operand:XF 0 "register_operand" "=f")
14008         (unspec:XF [(float_extend:XF
14009                       (match_operand:MODEF 1 "register_operand" "0"))
14010                     (match_operand:XF 2 "register_operand" "u")]
14011                    UNSPEC_FYL2X))
14012    (clobber (match_scratch:XF 3 "=2"))]
14013   "TARGET_USE_FANCY_MATH_387
14014    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14015        || TARGET_MIX_SSE_I387)
14016    && flag_unsafe_math_optimizations"
14017   "fyl2x"
14018   [(set_attr "type" "fpspc")
14019    (set_attr "mode" "XF")])
14020
14021 (define_expand "logxf2"
14022   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14023                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14024                                (match_dup 2)] UNSPEC_FYL2X))
14025               (clobber (match_scratch:XF 3 ""))])]
14026   "TARGET_USE_FANCY_MATH_387
14027    && flag_unsafe_math_optimizations"
14028 {
14029   operands[2] = gen_reg_rtx (XFmode);
14030   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14031 })
14032
14033 (define_expand "log<mode>2"
14034   [(use (match_operand:MODEF 0 "register_operand" ""))
14035    (use (match_operand:MODEF 1 "register_operand" ""))]
14036   "TARGET_USE_FANCY_MATH_387
14037    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14038        || TARGET_MIX_SSE_I387)
14039    && flag_unsafe_math_optimizations"
14040 {
14041   rtx op0 = gen_reg_rtx (XFmode);
14042
14043   rtx op2 = gen_reg_rtx (XFmode);
14044   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14045
14046   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14047   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14048   DONE;
14049 })
14050
14051 (define_expand "log10xf2"
14052   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14053                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14054                                (match_dup 2)] UNSPEC_FYL2X))
14055               (clobber (match_scratch:XF 3 ""))])]
14056   "TARGET_USE_FANCY_MATH_387
14057    && flag_unsafe_math_optimizations"
14058 {
14059   operands[2] = gen_reg_rtx (XFmode);
14060   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14061 })
14062
14063 (define_expand "log10<mode>2"
14064   [(use (match_operand:MODEF 0 "register_operand" ""))
14065    (use (match_operand:MODEF 1 "register_operand" ""))]
14066   "TARGET_USE_FANCY_MATH_387
14067    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14068        || TARGET_MIX_SSE_I387)
14069    && flag_unsafe_math_optimizations"
14070 {
14071   rtx op0 = gen_reg_rtx (XFmode);
14072
14073   rtx op2 = gen_reg_rtx (XFmode);
14074   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14075
14076   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14077   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14078   DONE;
14079 })
14080
14081 (define_expand "log2xf2"
14082   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14083                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14084                                (match_dup 2)] UNSPEC_FYL2X))
14085               (clobber (match_scratch:XF 3 ""))])]
14086   "TARGET_USE_FANCY_MATH_387
14087    && flag_unsafe_math_optimizations"
14088 {
14089   operands[2] = gen_reg_rtx (XFmode);
14090   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14091 })
14092
14093 (define_expand "log2<mode>2"
14094   [(use (match_operand:MODEF 0 "register_operand" ""))
14095    (use (match_operand:MODEF 1 "register_operand" ""))]
14096   "TARGET_USE_FANCY_MATH_387
14097    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14098        || TARGET_MIX_SSE_I387)
14099    && flag_unsafe_math_optimizations"
14100 {
14101   rtx op0 = gen_reg_rtx (XFmode);
14102
14103   rtx op2 = gen_reg_rtx (XFmode);
14104   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14105
14106   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14107   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14108   DONE;
14109 })
14110
14111 (define_insn "fyl2xp1xf3_i387"
14112   [(set (match_operand:XF 0 "register_operand" "=f")
14113         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14114                     (match_operand:XF 2 "register_operand" "u")]
14115                    UNSPEC_FYL2XP1))
14116    (clobber (match_scratch:XF 3 "=2"))]
14117   "TARGET_USE_FANCY_MATH_387
14118    && flag_unsafe_math_optimizations"
14119   "fyl2xp1"
14120   [(set_attr "type" "fpspc")
14121    (set_attr "mode" "XF")])
14122
14123 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14124   [(set (match_operand:XF 0 "register_operand" "=f")
14125         (unspec:XF [(float_extend:XF
14126                       (match_operand:MODEF 1 "register_operand" "0"))
14127                     (match_operand:XF 2 "register_operand" "u")]
14128                    UNSPEC_FYL2XP1))
14129    (clobber (match_scratch:XF 3 "=2"))]
14130   "TARGET_USE_FANCY_MATH_387
14131    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14132        || TARGET_MIX_SSE_I387)
14133    && flag_unsafe_math_optimizations"
14134   "fyl2xp1"
14135   [(set_attr "type" "fpspc")
14136    (set_attr "mode" "XF")])
14137
14138 (define_expand "log1pxf2"
14139   [(use (match_operand:XF 0 "register_operand" ""))
14140    (use (match_operand:XF 1 "register_operand" ""))]
14141   "TARGET_USE_FANCY_MATH_387
14142    && flag_unsafe_math_optimizations"
14143 {
14144   if (optimize_insn_for_size_p ())
14145     FAIL;
14146
14147   ix86_emit_i387_log1p (operands[0], operands[1]);
14148   DONE;
14149 })
14150
14151 (define_expand "log1p<mode>2"
14152   [(use (match_operand:MODEF 0 "register_operand" ""))
14153    (use (match_operand:MODEF 1 "register_operand" ""))]
14154   "TARGET_USE_FANCY_MATH_387
14155    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14156        || TARGET_MIX_SSE_I387)
14157    && flag_unsafe_math_optimizations"
14158 {
14159   rtx op0;
14160
14161   if (optimize_insn_for_size_p ())
14162     FAIL;
14163
14164   op0 = gen_reg_rtx (XFmode);
14165
14166   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14167
14168   ix86_emit_i387_log1p (op0, operands[1]);
14169   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14170   DONE;
14171 })
14172
14173 (define_insn "fxtractxf3_i387"
14174   [(set (match_operand:XF 0 "register_operand" "=f")
14175         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14176                    UNSPEC_XTRACT_FRACT))
14177    (set (match_operand:XF 1 "register_operand" "=u")
14178         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14179   "TARGET_USE_FANCY_MATH_387
14180    && flag_unsafe_math_optimizations"
14181   "fxtract"
14182   [(set_attr "type" "fpspc")
14183    (set_attr "mode" "XF")])
14184
14185 (define_insn "fxtract_extend<mode>xf3_i387"
14186   [(set (match_operand:XF 0 "register_operand" "=f")
14187         (unspec:XF [(float_extend:XF
14188                       (match_operand:MODEF 2 "register_operand" "0"))]
14189                    UNSPEC_XTRACT_FRACT))
14190    (set (match_operand:XF 1 "register_operand" "=u")
14191         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
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   "fxtract"
14197   [(set_attr "type" "fpspc")
14198    (set_attr "mode" "XF")])
14199
14200 (define_expand "logbxf2"
14201   [(parallel [(set (match_dup 2)
14202                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14203                               UNSPEC_XTRACT_FRACT))
14204               (set (match_operand:XF 0 "register_operand" "")
14205                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14206   "TARGET_USE_FANCY_MATH_387
14207    && flag_unsafe_math_optimizations"
14208   "operands[2] = gen_reg_rtx (XFmode);")
14209
14210 (define_expand "logb<mode>2"
14211   [(use (match_operand:MODEF 0 "register_operand" ""))
14212    (use (match_operand:MODEF 1 "register_operand" ""))]
14213   "TARGET_USE_FANCY_MATH_387
14214    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14215        || TARGET_MIX_SSE_I387)
14216    && flag_unsafe_math_optimizations"
14217 {
14218   rtx op0 = gen_reg_rtx (XFmode);
14219   rtx op1 = gen_reg_rtx (XFmode);
14220
14221   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14222   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14223   DONE;
14224 })
14225
14226 (define_expand "ilogbxf2"
14227   [(use (match_operand:SI 0 "register_operand" ""))
14228    (use (match_operand:XF 1 "register_operand" ""))]
14229   "TARGET_USE_FANCY_MATH_387
14230    && flag_unsafe_math_optimizations"
14231 {
14232   rtx op0, op1;
14233
14234   if (optimize_insn_for_size_p ())
14235     FAIL;
14236
14237   op0 = gen_reg_rtx (XFmode);
14238   op1 = gen_reg_rtx (XFmode);
14239
14240   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14241   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14242   DONE;
14243 })
14244
14245 (define_expand "ilogb<mode>2"
14246   [(use (match_operand:SI 0 "register_operand" ""))
14247    (use (match_operand:MODEF 1 "register_operand" ""))]
14248   "TARGET_USE_FANCY_MATH_387
14249    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14250        || TARGET_MIX_SSE_I387)
14251    && flag_unsafe_math_optimizations"
14252 {
14253   rtx op0, op1;
14254
14255   if (optimize_insn_for_size_p ())
14256     FAIL;
14257
14258   op0 = gen_reg_rtx (XFmode);
14259   op1 = gen_reg_rtx (XFmode);
14260
14261   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14262   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14263   DONE;
14264 })
14265
14266 (define_insn "*f2xm1xf2_i387"
14267   [(set (match_operand:XF 0 "register_operand" "=f")
14268         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14269                    UNSPEC_F2XM1))]
14270   "TARGET_USE_FANCY_MATH_387
14271    && flag_unsafe_math_optimizations"
14272   "f2xm1"
14273   [(set_attr "type" "fpspc")
14274    (set_attr "mode" "XF")])
14275
14276 (define_insn "*fscalexf4_i387"
14277   [(set (match_operand:XF 0 "register_operand" "=f")
14278         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14279                     (match_operand:XF 3 "register_operand" "1")]
14280                    UNSPEC_FSCALE_FRACT))
14281    (set (match_operand:XF 1 "register_operand" "=u")
14282         (unspec:XF [(match_dup 2) (match_dup 3)]
14283                    UNSPEC_FSCALE_EXP))]
14284   "TARGET_USE_FANCY_MATH_387
14285    && flag_unsafe_math_optimizations"
14286   "fscale"
14287   [(set_attr "type" "fpspc")
14288    (set_attr "mode" "XF")])
14289
14290 (define_expand "expNcorexf3"
14291   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14292                                (match_operand:XF 2 "register_operand" "")))
14293    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14294    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14295    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14296    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14297    (parallel [(set (match_operand:XF 0 "register_operand" "")
14298                    (unspec:XF [(match_dup 8) (match_dup 4)]
14299                               UNSPEC_FSCALE_FRACT))
14300               (set (match_dup 9)
14301                    (unspec:XF [(match_dup 8) (match_dup 4)]
14302                               UNSPEC_FSCALE_EXP))])]
14303   "TARGET_USE_FANCY_MATH_387
14304    && flag_unsafe_math_optimizations"
14305 {
14306   int i;
14307
14308   if (optimize_insn_for_size_p ())
14309     FAIL;
14310
14311   for (i = 3; i < 10; i++)
14312     operands[i] = gen_reg_rtx (XFmode);
14313
14314   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14315 })
14316
14317 (define_expand "expxf2"
14318   [(use (match_operand:XF 0 "register_operand" ""))
14319    (use (match_operand:XF 1 "register_operand" ""))]
14320   "TARGET_USE_FANCY_MATH_387
14321    && flag_unsafe_math_optimizations"
14322 {
14323   rtx op2;
14324
14325   if (optimize_insn_for_size_p ())
14326     FAIL;
14327
14328   op2 = gen_reg_rtx (XFmode);
14329   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14330
14331   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14332   DONE;
14333 })
14334
14335 (define_expand "exp<mode>2"
14336   [(use (match_operand:MODEF 0 "register_operand" ""))
14337    (use (match_operand:MODEF 1 "general_operand" ""))]
14338  "TARGET_USE_FANCY_MATH_387
14339    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14340        || TARGET_MIX_SSE_I387)
14341    && flag_unsafe_math_optimizations"
14342 {
14343   rtx op0, op1;
14344
14345   if (optimize_insn_for_size_p ())
14346     FAIL;
14347
14348   op0 = gen_reg_rtx (XFmode);
14349   op1 = gen_reg_rtx (XFmode);
14350
14351   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14352   emit_insn (gen_expxf2 (op0, op1));
14353   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14354   DONE;
14355 })
14356
14357 (define_expand "exp10xf2"
14358   [(use (match_operand:XF 0 "register_operand" ""))
14359    (use (match_operand:XF 1 "register_operand" ""))]
14360   "TARGET_USE_FANCY_MATH_387
14361    && flag_unsafe_math_optimizations"
14362 {
14363   rtx op2;
14364
14365   if (optimize_insn_for_size_p ())
14366     FAIL;
14367
14368   op2 = gen_reg_rtx (XFmode);
14369   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14370
14371   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14372   DONE;
14373 })
14374
14375 (define_expand "exp10<mode>2"
14376   [(use (match_operand:MODEF 0 "register_operand" ""))
14377    (use (match_operand:MODEF 1 "general_operand" ""))]
14378  "TARGET_USE_FANCY_MATH_387
14379    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14380        || TARGET_MIX_SSE_I387)
14381    && flag_unsafe_math_optimizations"
14382 {
14383   rtx op0, op1;
14384
14385   if (optimize_insn_for_size_p ())
14386     FAIL;
14387
14388   op0 = gen_reg_rtx (XFmode);
14389   op1 = gen_reg_rtx (XFmode);
14390
14391   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14392   emit_insn (gen_exp10xf2 (op0, op1));
14393   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14394   DONE;
14395 })
14396
14397 (define_expand "exp2xf2"
14398   [(use (match_operand:XF 0 "register_operand" ""))
14399    (use (match_operand:XF 1 "register_operand" ""))]
14400   "TARGET_USE_FANCY_MATH_387
14401    && flag_unsafe_math_optimizations"
14402 {
14403   rtx op2;
14404
14405   if (optimize_insn_for_size_p ())
14406     FAIL;
14407
14408   op2 = gen_reg_rtx (XFmode);
14409   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14410
14411   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14412   DONE;
14413 })
14414
14415 (define_expand "exp2<mode>2"
14416   [(use (match_operand:MODEF 0 "register_operand" ""))
14417    (use (match_operand:MODEF 1 "general_operand" ""))]
14418  "TARGET_USE_FANCY_MATH_387
14419    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14420        || TARGET_MIX_SSE_I387)
14421    && flag_unsafe_math_optimizations"
14422 {
14423   rtx op0, op1;
14424
14425   if (optimize_insn_for_size_p ())
14426     FAIL;
14427
14428   op0 = gen_reg_rtx (XFmode);
14429   op1 = gen_reg_rtx (XFmode);
14430
14431   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14432   emit_insn (gen_exp2xf2 (op0, op1));
14433   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14434   DONE;
14435 })
14436
14437 (define_expand "expm1xf2"
14438   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14439                                (match_dup 2)))
14440    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14441    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14442    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14443    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14444    (parallel [(set (match_dup 7)
14445                    (unspec:XF [(match_dup 6) (match_dup 4)]
14446                               UNSPEC_FSCALE_FRACT))
14447               (set (match_dup 8)
14448                    (unspec:XF [(match_dup 6) (match_dup 4)]
14449                               UNSPEC_FSCALE_EXP))])
14450    (parallel [(set (match_dup 10)
14451                    (unspec:XF [(match_dup 9) (match_dup 8)]
14452                               UNSPEC_FSCALE_FRACT))
14453               (set (match_dup 11)
14454                    (unspec:XF [(match_dup 9) (match_dup 8)]
14455                               UNSPEC_FSCALE_EXP))])
14456    (set (match_dup 12) (minus:XF (match_dup 10)
14457                                  (float_extend:XF (match_dup 13))))
14458    (set (match_operand:XF 0 "register_operand" "")
14459         (plus:XF (match_dup 12) (match_dup 7)))]
14460   "TARGET_USE_FANCY_MATH_387
14461    && flag_unsafe_math_optimizations"
14462 {
14463   int i;
14464
14465   if (optimize_insn_for_size_p ())
14466     FAIL;
14467
14468   for (i = 2; i < 13; i++)
14469     operands[i] = gen_reg_rtx (XFmode);
14470
14471   operands[13]
14472     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14473
14474   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14475 })
14476
14477 (define_expand "expm1<mode>2"
14478   [(use (match_operand:MODEF 0 "register_operand" ""))
14479    (use (match_operand:MODEF 1 "general_operand" ""))]
14480  "TARGET_USE_FANCY_MATH_387
14481    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14482        || TARGET_MIX_SSE_I387)
14483    && flag_unsafe_math_optimizations"
14484 {
14485   rtx op0, op1;
14486
14487   if (optimize_insn_for_size_p ())
14488     FAIL;
14489
14490   op0 = gen_reg_rtx (XFmode);
14491   op1 = gen_reg_rtx (XFmode);
14492
14493   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14494   emit_insn (gen_expm1xf2 (op0, op1));
14495   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14496   DONE;
14497 })
14498
14499 (define_expand "ldexpxf3"
14500   [(set (match_dup 3)
14501         (float:XF (match_operand:SI 2 "register_operand" "")))
14502    (parallel [(set (match_operand:XF 0 " register_operand" "")
14503                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14504                                (match_dup 3)]
14505                               UNSPEC_FSCALE_FRACT))
14506               (set (match_dup 4)
14507                    (unspec:XF [(match_dup 1) (match_dup 3)]
14508                               UNSPEC_FSCALE_EXP))])]
14509   "TARGET_USE_FANCY_MATH_387
14510    && flag_unsafe_math_optimizations"
14511 {
14512   if (optimize_insn_for_size_p ())
14513     FAIL;
14514
14515   operands[3] = gen_reg_rtx (XFmode);
14516   operands[4] = gen_reg_rtx (XFmode);
14517 })
14518
14519 (define_expand "ldexp<mode>3"
14520   [(use (match_operand:MODEF 0 "register_operand" ""))
14521    (use (match_operand:MODEF 1 "general_operand" ""))
14522    (use (match_operand:SI 2 "register_operand" ""))]
14523  "TARGET_USE_FANCY_MATH_387
14524    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14525        || TARGET_MIX_SSE_I387)
14526    && flag_unsafe_math_optimizations"
14527 {
14528   rtx op0, op1;
14529
14530   if (optimize_insn_for_size_p ())
14531     FAIL;
14532
14533   op0 = gen_reg_rtx (XFmode);
14534   op1 = gen_reg_rtx (XFmode);
14535
14536   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14537   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14538   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14539   DONE;
14540 })
14541
14542 (define_expand "scalbxf3"
14543   [(parallel [(set (match_operand:XF 0 " register_operand" "")
14544                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14545                                (match_operand:XF 2 "register_operand" "")]
14546                               UNSPEC_FSCALE_FRACT))
14547               (set (match_dup 3)
14548                    (unspec:XF [(match_dup 1) (match_dup 2)]
14549                               UNSPEC_FSCALE_EXP))])]
14550   "TARGET_USE_FANCY_MATH_387
14551    && flag_unsafe_math_optimizations"
14552 {
14553   if (optimize_insn_for_size_p ())
14554     FAIL;
14555
14556   operands[3] = gen_reg_rtx (XFmode);
14557 })
14558
14559 (define_expand "scalb<mode>3"
14560   [(use (match_operand:MODEF 0 "register_operand" ""))
14561    (use (match_operand:MODEF 1 "general_operand" ""))
14562    (use (match_operand:MODEF 2 "general_operand" ""))]
14563  "TARGET_USE_FANCY_MATH_387
14564    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14565        || TARGET_MIX_SSE_I387)
14566    && flag_unsafe_math_optimizations"
14567 {
14568   rtx op0, op1, op2;
14569
14570   if (optimize_insn_for_size_p ())
14571     FAIL;
14572
14573   op0 = gen_reg_rtx (XFmode);
14574   op1 = gen_reg_rtx (XFmode);
14575   op2 = gen_reg_rtx (XFmode);
14576
14577   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14578   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14579   emit_insn (gen_scalbxf3 (op0, op1, op2));
14580   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14581   DONE;
14582 })
14583
14584 (define_expand "significandxf2"
14585   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14586                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14587                               UNSPEC_XTRACT_FRACT))
14588               (set (match_dup 2)
14589                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14590   "TARGET_USE_FANCY_MATH_387
14591    && flag_unsafe_math_optimizations"
14592   "operands[2] = gen_reg_rtx (XFmode);")
14593
14594 (define_expand "significand<mode>2"
14595   [(use (match_operand:MODEF 0 "register_operand" ""))
14596    (use (match_operand:MODEF 1 "register_operand" ""))]
14597   "TARGET_USE_FANCY_MATH_387
14598    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14599        || TARGET_MIX_SSE_I387)
14600    && flag_unsafe_math_optimizations"
14601 {
14602   rtx op0 = gen_reg_rtx (XFmode);
14603   rtx op1 = gen_reg_rtx (XFmode);
14604
14605   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14606   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14607   DONE;
14608 })
14609 \f
14610
14611 (define_insn "sse4_1_round<mode>2"
14612   [(set (match_operand:MODEF 0 "register_operand" "=x")
14613         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14614                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14615                       UNSPEC_ROUND))]
14616   "TARGET_ROUND"
14617   "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14618   [(set_attr "type" "ssecvt")
14619    (set_attr "prefix_extra" "1")
14620    (set_attr "prefix" "maybe_vex")
14621    (set_attr "mode" "<MODE>")])
14622
14623 (define_insn "rintxf2"
14624   [(set (match_operand:XF 0 "register_operand" "=f")
14625         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14626                    UNSPEC_FRNDINT))]
14627   "TARGET_USE_FANCY_MATH_387
14628    && flag_unsafe_math_optimizations"
14629   "frndint"
14630   [(set_attr "type" "fpspc")
14631    (set_attr "mode" "XF")])
14632
14633 (define_expand "rint<mode>2"
14634   [(use (match_operand:MODEF 0 "register_operand" ""))
14635    (use (match_operand:MODEF 1 "register_operand" ""))]
14636   "(TARGET_USE_FANCY_MATH_387
14637     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14638         || TARGET_MIX_SSE_I387)
14639     && flag_unsafe_math_optimizations)
14640    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14641        && !flag_trapping_math)"
14642 {
14643   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14644       && !flag_trapping_math)
14645     {
14646       if (TARGET_ROUND)
14647         emit_insn (gen_sse4_1_round<mode>2
14648                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14649       else if (optimize_insn_for_size_p ())
14650         FAIL;
14651       else
14652         ix86_expand_rint (operands[0], operands[1]);
14653     }
14654   else
14655     {
14656       rtx op0 = gen_reg_rtx (XFmode);
14657       rtx op1 = gen_reg_rtx (XFmode);
14658
14659       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14660       emit_insn (gen_rintxf2 (op0, op1));
14661
14662       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14663     }
14664   DONE;
14665 })
14666
14667 (define_expand "round<mode>2"
14668   [(match_operand:X87MODEF 0 "register_operand" "")
14669    (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14670   "(TARGET_USE_FANCY_MATH_387
14671     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14672         || TARGET_MIX_SSE_I387)
14673     && flag_unsafe_math_optimizations)
14674    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14675        && !flag_trapping_math && !flag_rounding_math)"
14676 {
14677   if (optimize_insn_for_size_p ())
14678     FAIL;
14679
14680   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14681       && !flag_trapping_math && !flag_rounding_math)
14682     {
14683       if (TARGET_ROUND)
14684         {
14685           operands[1] = force_reg (<MODE>mode, operands[1]);
14686           ix86_expand_round_sse4 (operands[0], operands[1]);
14687         }
14688       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14689         ix86_expand_round (operands[0], operands[1]);
14690       else
14691         ix86_expand_rounddf_32 (operands[0], operands[1]);
14692     }
14693   else
14694     {
14695       operands[1] = force_reg (<MODE>mode, operands[1]);
14696       ix86_emit_i387_round (operands[0], operands[1]);
14697     }
14698   DONE;
14699 })
14700
14701 (define_insn_and_split "*fistdi2_1"
14702   [(set (match_operand:DI 0 "nonimmediate_operand" "")
14703         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14704                    UNSPEC_FIST))]
14705   "TARGET_USE_FANCY_MATH_387
14706    && can_create_pseudo_p ()"
14707   "#"
14708   "&& 1"
14709   [(const_int 0)]
14710 {
14711   if (memory_operand (operands[0], VOIDmode))
14712     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14713   else
14714     {
14715       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14716       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14717                                          operands[2]));
14718     }
14719   DONE;
14720 }
14721   [(set_attr "type" "fpspc")
14722    (set_attr "mode" "DI")])
14723
14724 (define_insn "fistdi2"
14725   [(set (match_operand:DI 0 "memory_operand" "=m")
14726         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14727                    UNSPEC_FIST))
14728    (clobber (match_scratch:XF 2 "=&1f"))]
14729   "TARGET_USE_FANCY_MATH_387"
14730   "* return output_fix_trunc (insn, operands, false);"
14731   [(set_attr "type" "fpspc")
14732    (set_attr "mode" "DI")])
14733
14734 (define_insn "fistdi2_with_temp"
14735   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14736         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14737                    UNSPEC_FIST))
14738    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14739    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14740   "TARGET_USE_FANCY_MATH_387"
14741   "#"
14742   [(set_attr "type" "fpspc")
14743    (set_attr "mode" "DI")])
14744
14745 (define_split
14746   [(set (match_operand:DI 0 "register_operand" "")
14747         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14748                    UNSPEC_FIST))
14749    (clobber (match_operand:DI 2 "memory_operand" ""))
14750    (clobber (match_scratch 3 ""))]
14751   "reload_completed"
14752   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14753               (clobber (match_dup 3))])
14754    (set (match_dup 0) (match_dup 2))])
14755
14756 (define_split
14757   [(set (match_operand:DI 0 "memory_operand" "")
14758         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14759                    UNSPEC_FIST))
14760    (clobber (match_operand:DI 2 "memory_operand" ""))
14761    (clobber (match_scratch 3 ""))]
14762   "reload_completed"
14763   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14764               (clobber (match_dup 3))])])
14765
14766 (define_insn_and_split "*fist<mode>2_1"
14767   [(set (match_operand:SWI24 0 "register_operand" "")
14768         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14769                       UNSPEC_FIST))]
14770   "TARGET_USE_FANCY_MATH_387
14771    && can_create_pseudo_p ()"
14772   "#"
14773   "&& 1"
14774   [(const_int 0)]
14775 {
14776   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14777   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14778                                         operands[2]));
14779   DONE;
14780 }
14781   [(set_attr "type" "fpspc")
14782    (set_attr "mode" "<MODE>")])
14783
14784 (define_insn "fist<mode>2"
14785   [(set (match_operand:SWI24 0 "memory_operand" "=m")
14786         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14787                       UNSPEC_FIST))]
14788   "TARGET_USE_FANCY_MATH_387"
14789   "* return output_fix_trunc (insn, operands, false);"
14790   [(set_attr "type" "fpspc")
14791    (set_attr "mode" "<MODE>")])
14792
14793 (define_insn "fist<mode>2_with_temp"
14794   [(set (match_operand:SWI24 0 "register_operand" "=r")
14795         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14796                       UNSPEC_FIST))
14797    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14798   "TARGET_USE_FANCY_MATH_387"
14799   "#"
14800   [(set_attr "type" "fpspc")
14801    (set_attr "mode" "<MODE>")])
14802
14803 (define_split
14804   [(set (match_operand:SWI24 0 "register_operand" "")
14805         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14806                       UNSPEC_FIST))
14807    (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14808   "reload_completed"
14809   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14810    (set (match_dup 0) (match_dup 2))])
14811
14812 (define_split
14813   [(set (match_operand:SWI24 0 "memory_operand" "")
14814         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14815                       UNSPEC_FIST))
14816    (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14817   "reload_completed"
14818   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14819
14820 (define_expand "lrintxf<mode>2"
14821   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14822      (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14823                      UNSPEC_FIST))]
14824   "TARGET_USE_FANCY_MATH_387")
14825
14826 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14827   [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14828      (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14829                         UNSPEC_FIX_NOTRUNC))]
14830   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14831    && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14832
14833 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14834   [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14835    (match_operand:X87MODEF 1 "register_operand" "")]
14836   "(TARGET_USE_FANCY_MATH_387
14837     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14838         || TARGET_MIX_SSE_I387)
14839     && flag_unsafe_math_optimizations)
14840    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14841        && <SWI248x:MODE>mode != HImode 
14842        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14843        && !flag_trapping_math && !flag_rounding_math)"
14844 {
14845   if (optimize_insn_for_size_p ())
14846     FAIL;
14847
14848   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14849       && <SWI248x:MODE>mode != HImode
14850       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14851       && !flag_trapping_math && !flag_rounding_math)
14852     ix86_expand_lround (operands[0], operands[1]);
14853   else
14854     ix86_emit_i387_round (operands[0], operands[1]);
14855   DONE;
14856 })
14857
14858 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14859 (define_insn_and_split "frndintxf2_floor"
14860   [(set (match_operand:XF 0 "register_operand" "")
14861         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14862          UNSPEC_FRNDINT_FLOOR))
14863    (clobber (reg:CC FLAGS_REG))]
14864   "TARGET_USE_FANCY_MATH_387
14865    && flag_unsafe_math_optimizations
14866    && can_create_pseudo_p ()"
14867   "#"
14868   "&& 1"
14869   [(const_int 0)]
14870 {
14871   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14872
14873   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14874   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14875
14876   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14877                                         operands[2], operands[3]));
14878   DONE;
14879 }
14880   [(set_attr "type" "frndint")
14881    (set_attr "i387_cw" "floor")
14882    (set_attr "mode" "XF")])
14883
14884 (define_insn "frndintxf2_floor_i387"
14885   [(set (match_operand:XF 0 "register_operand" "=f")
14886         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14887          UNSPEC_FRNDINT_FLOOR))
14888    (use (match_operand:HI 2 "memory_operand" "m"))
14889    (use (match_operand:HI 3 "memory_operand" "m"))]
14890   "TARGET_USE_FANCY_MATH_387
14891    && flag_unsafe_math_optimizations"
14892   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14893   [(set_attr "type" "frndint")
14894    (set_attr "i387_cw" "floor")
14895    (set_attr "mode" "XF")])
14896
14897 (define_expand "floorxf2"
14898   [(use (match_operand:XF 0 "register_operand" ""))
14899    (use (match_operand:XF 1 "register_operand" ""))]
14900   "TARGET_USE_FANCY_MATH_387
14901    && flag_unsafe_math_optimizations"
14902 {
14903   if (optimize_insn_for_size_p ())
14904     FAIL;
14905   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14906   DONE;
14907 })
14908
14909 (define_expand "floor<mode>2"
14910   [(use (match_operand:MODEF 0 "register_operand" ""))
14911    (use (match_operand:MODEF 1 "register_operand" ""))]
14912   "(TARGET_USE_FANCY_MATH_387
14913     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14914         || TARGET_MIX_SSE_I387)
14915     && flag_unsafe_math_optimizations)
14916    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14917        && !flag_trapping_math)"
14918 {
14919   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14920       && !flag_trapping_math)
14921     {
14922       if (TARGET_ROUND)
14923         emit_insn (gen_sse4_1_round<mode>2
14924                    (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14925       else if (optimize_insn_for_size_p ())
14926         FAIL;
14927       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14928         ix86_expand_floorceil (operands[0], operands[1], true);
14929       else
14930         ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14931     }
14932   else
14933     {
14934       rtx op0, op1;
14935
14936       if (optimize_insn_for_size_p ())
14937         FAIL;
14938
14939       op0 = gen_reg_rtx (XFmode);
14940       op1 = gen_reg_rtx (XFmode);
14941       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14942       emit_insn (gen_frndintxf2_floor (op0, op1));
14943
14944       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14945     }
14946   DONE;
14947 })
14948
14949 (define_insn_and_split "*fist<mode>2_floor_1"
14950   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14951         (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14952                         UNSPEC_FIST_FLOOR))
14953    (clobber (reg:CC FLAGS_REG))]
14954   "TARGET_USE_FANCY_MATH_387
14955    && flag_unsafe_math_optimizations
14956    && can_create_pseudo_p ()"
14957   "#"
14958   "&& 1"
14959   [(const_int 0)]
14960 {
14961   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14962
14963   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14964   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14965   if (memory_operand (operands[0], VOIDmode))
14966     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14967                                       operands[2], operands[3]));
14968   else
14969     {
14970       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14971       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14972                                                   operands[2], operands[3],
14973                                                   operands[4]));
14974     }
14975   DONE;
14976 }
14977   [(set_attr "type" "fistp")
14978    (set_attr "i387_cw" "floor")
14979    (set_attr "mode" "<MODE>")])
14980
14981 (define_insn "fistdi2_floor"
14982   [(set (match_operand:DI 0 "memory_operand" "=m")
14983         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14984                    UNSPEC_FIST_FLOOR))
14985    (use (match_operand:HI 2 "memory_operand" "m"))
14986    (use (match_operand:HI 3 "memory_operand" "m"))
14987    (clobber (match_scratch:XF 4 "=&1f"))]
14988   "TARGET_USE_FANCY_MATH_387
14989    && flag_unsafe_math_optimizations"
14990   "* return output_fix_trunc (insn, operands, false);"
14991   [(set_attr "type" "fistp")
14992    (set_attr "i387_cw" "floor")
14993    (set_attr "mode" "DI")])
14994
14995 (define_insn "fistdi2_floor_with_temp"
14996   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14997         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14998                    UNSPEC_FIST_FLOOR))
14999    (use (match_operand:HI 2 "memory_operand" "m,m"))
15000    (use (match_operand:HI 3 "memory_operand" "m,m"))
15001    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15002    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15003   "TARGET_USE_FANCY_MATH_387
15004    && flag_unsafe_math_optimizations"
15005   "#"
15006   [(set_attr "type" "fistp")
15007    (set_attr "i387_cw" "floor")
15008    (set_attr "mode" "DI")])
15009
15010 (define_split
15011   [(set (match_operand:DI 0 "register_operand" "")
15012         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15013                    UNSPEC_FIST_FLOOR))
15014    (use (match_operand:HI 2 "memory_operand" ""))
15015    (use (match_operand:HI 3 "memory_operand" ""))
15016    (clobber (match_operand:DI 4 "memory_operand" ""))
15017    (clobber (match_scratch 5 ""))]
15018   "reload_completed"
15019   [(parallel [(set (match_dup 4)
15020                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15021               (use (match_dup 2))
15022               (use (match_dup 3))
15023               (clobber (match_dup 5))])
15024    (set (match_dup 0) (match_dup 4))])
15025
15026 (define_split
15027   [(set (match_operand:DI 0 "memory_operand" "")
15028         (unspec:DI [(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:DI 4 "memory_operand" ""))
15033    (clobber (match_scratch 5 ""))]
15034   "reload_completed"
15035   [(parallel [(set (match_dup 0)
15036                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15037               (use (match_dup 2))
15038               (use (match_dup 3))
15039               (clobber (match_dup 5))])])
15040
15041 (define_insn "fist<mode>2_floor"
15042   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15043         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15044                       UNSPEC_FIST_FLOOR))
15045    (use (match_operand:HI 2 "memory_operand" "m"))
15046    (use (match_operand:HI 3 "memory_operand" "m"))]
15047   "TARGET_USE_FANCY_MATH_387
15048    && flag_unsafe_math_optimizations"
15049   "* return output_fix_trunc (insn, operands, false);"
15050   [(set_attr "type" "fistp")
15051    (set_attr "i387_cw" "floor")
15052    (set_attr "mode" "<MODE>")])
15053
15054 (define_insn "fist<mode>2_floor_with_temp"
15055   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15056         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15057                       UNSPEC_FIST_FLOOR))
15058    (use (match_operand:HI 2 "memory_operand" "m,m"))
15059    (use (match_operand:HI 3 "memory_operand" "m,m"))
15060    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15061   "TARGET_USE_FANCY_MATH_387
15062    && flag_unsafe_math_optimizations"
15063   "#"
15064   [(set_attr "type" "fistp")
15065    (set_attr "i387_cw" "floor")
15066    (set_attr "mode" "<MODE>")])
15067
15068 (define_split
15069   [(set (match_operand:SWI24 0 "register_operand" "")
15070         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15071                       UNSPEC_FIST_FLOOR))
15072    (use (match_operand:HI 2 "memory_operand" ""))
15073    (use (match_operand:HI 3 "memory_operand" ""))
15074    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15075   "reload_completed"
15076   [(parallel [(set (match_dup 4)
15077                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15078               (use (match_dup 2))
15079               (use (match_dup 3))])
15080    (set (match_dup 0) (match_dup 4))])
15081
15082 (define_split
15083   [(set (match_operand:SWI24 0 "memory_operand" "")
15084         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15085                       UNSPEC_FIST_FLOOR))
15086    (use (match_operand:HI 2 "memory_operand" ""))
15087    (use (match_operand:HI 3 "memory_operand" ""))
15088    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15089   "reload_completed"
15090   [(parallel [(set (match_dup 0)
15091                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15092               (use (match_dup 2))
15093               (use (match_dup 3))])])
15094
15095 (define_expand "lfloorxf<mode>2"
15096   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15097                    (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15098                                    UNSPEC_FIST_FLOOR))
15099               (clobber (reg:CC FLAGS_REG))])]
15100   "TARGET_USE_FANCY_MATH_387
15101    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15102    && flag_unsafe_math_optimizations")
15103
15104 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15105   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15106    (match_operand:MODEF 1 "register_operand" "")]
15107   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15108    && !flag_trapping_math"
15109 {
15110   if (TARGET_64BIT && optimize_insn_for_size_p ())
15111     FAIL;
15112   ix86_expand_lfloorceil (operands[0], operands[1], true);
15113   DONE;
15114 })
15115
15116 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15117 (define_insn_and_split "frndintxf2_ceil"
15118   [(set (match_operand:XF 0 "register_operand" "")
15119         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15120          UNSPEC_FRNDINT_CEIL))
15121    (clobber (reg:CC FLAGS_REG))]
15122   "TARGET_USE_FANCY_MATH_387
15123    && flag_unsafe_math_optimizations
15124    && can_create_pseudo_p ()"
15125   "#"
15126   "&& 1"
15127   [(const_int 0)]
15128 {
15129   ix86_optimize_mode_switching[I387_CEIL] = 1;
15130
15131   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15132   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15133
15134   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15135                                        operands[2], operands[3]));
15136   DONE;
15137 }
15138   [(set_attr "type" "frndint")
15139    (set_attr "i387_cw" "ceil")
15140    (set_attr "mode" "XF")])
15141
15142 (define_insn "frndintxf2_ceil_i387"
15143   [(set (match_operand:XF 0 "register_operand" "=f")
15144         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15145          UNSPEC_FRNDINT_CEIL))
15146    (use (match_operand:HI 2 "memory_operand" "m"))
15147    (use (match_operand:HI 3 "memory_operand" "m"))]
15148   "TARGET_USE_FANCY_MATH_387
15149    && flag_unsafe_math_optimizations"
15150   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15151   [(set_attr "type" "frndint")
15152    (set_attr "i387_cw" "ceil")
15153    (set_attr "mode" "XF")])
15154
15155 (define_expand "ceilxf2"
15156   [(use (match_operand:XF 0 "register_operand" ""))
15157    (use (match_operand:XF 1 "register_operand" ""))]
15158   "TARGET_USE_FANCY_MATH_387
15159    && flag_unsafe_math_optimizations"
15160 {
15161   if (optimize_insn_for_size_p ())
15162     FAIL;
15163   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15164   DONE;
15165 })
15166
15167 (define_expand "ceil<mode>2"
15168   [(use (match_operand:MODEF 0 "register_operand" ""))
15169    (use (match_operand:MODEF 1 "register_operand" ""))]
15170   "(TARGET_USE_FANCY_MATH_387
15171     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15172         || TARGET_MIX_SSE_I387)
15173     && flag_unsafe_math_optimizations)
15174    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15175        && !flag_trapping_math)"
15176 {
15177   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15178       && !flag_trapping_math)
15179     {
15180       if (TARGET_ROUND)
15181         emit_insn (gen_sse4_1_round<mode>2
15182                    (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15183       else if (optimize_insn_for_size_p ())
15184         FAIL;
15185       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15186         ix86_expand_floorceil (operands[0], operands[1], false);
15187       else
15188         ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15189     }
15190   else
15191     {
15192       rtx op0, op1;
15193
15194       if (optimize_insn_for_size_p ())
15195         FAIL;
15196
15197       op0 = gen_reg_rtx (XFmode);
15198       op1 = gen_reg_rtx (XFmode);
15199       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15200       emit_insn (gen_frndintxf2_ceil (op0, op1));
15201
15202       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15203     }
15204   DONE;
15205 })
15206
15207 (define_insn_and_split "*fist<mode>2_ceil_1"
15208   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15209         (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15210                         UNSPEC_FIST_CEIL))
15211    (clobber (reg:CC FLAGS_REG))]
15212   "TARGET_USE_FANCY_MATH_387
15213    && flag_unsafe_math_optimizations
15214    && can_create_pseudo_p ()"
15215   "#"
15216   "&& 1"
15217   [(const_int 0)]
15218 {
15219   ix86_optimize_mode_switching[I387_CEIL] = 1;
15220
15221   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15222   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15223   if (memory_operand (operands[0], VOIDmode))
15224     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15225                                      operands[2], operands[3]));
15226   else
15227     {
15228       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15229       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15230                                                  operands[2], operands[3],
15231                                                  operands[4]));
15232     }
15233   DONE;
15234 }
15235   [(set_attr "type" "fistp")
15236    (set_attr "i387_cw" "ceil")
15237    (set_attr "mode" "<MODE>")])
15238
15239 (define_insn "fistdi2_ceil"
15240   [(set (match_operand:DI 0 "memory_operand" "=m")
15241         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15242                    UNSPEC_FIST_CEIL))
15243    (use (match_operand:HI 2 "memory_operand" "m"))
15244    (use (match_operand:HI 3 "memory_operand" "m"))
15245    (clobber (match_scratch:XF 4 "=&1f"))]
15246   "TARGET_USE_FANCY_MATH_387
15247    && flag_unsafe_math_optimizations"
15248   "* return output_fix_trunc (insn, operands, false);"
15249   [(set_attr "type" "fistp")
15250    (set_attr "i387_cw" "ceil")
15251    (set_attr "mode" "DI")])
15252
15253 (define_insn "fistdi2_ceil_with_temp"
15254   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15255         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15256                    UNSPEC_FIST_CEIL))
15257    (use (match_operand:HI 2 "memory_operand" "m,m"))
15258    (use (match_operand:HI 3 "memory_operand" "m,m"))
15259    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15260    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15261   "TARGET_USE_FANCY_MATH_387
15262    && flag_unsafe_math_optimizations"
15263   "#"
15264   [(set_attr "type" "fistp")
15265    (set_attr "i387_cw" "ceil")
15266    (set_attr "mode" "DI")])
15267
15268 (define_split
15269   [(set (match_operand:DI 0 "register_operand" "")
15270         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15271                    UNSPEC_FIST_CEIL))
15272    (use (match_operand:HI 2 "memory_operand" ""))
15273    (use (match_operand:HI 3 "memory_operand" ""))
15274    (clobber (match_operand:DI 4 "memory_operand" ""))
15275    (clobber (match_scratch 5 ""))]
15276   "reload_completed"
15277   [(parallel [(set (match_dup 4)
15278                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15279               (use (match_dup 2))
15280               (use (match_dup 3))
15281               (clobber (match_dup 5))])
15282    (set (match_dup 0) (match_dup 4))])
15283
15284 (define_split
15285   [(set (match_operand:DI 0 "memory_operand" "")
15286         (unspec:DI [(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:DI 4 "memory_operand" ""))
15291    (clobber (match_scratch 5 ""))]
15292   "reload_completed"
15293   [(parallel [(set (match_dup 0)
15294                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15295               (use (match_dup 2))
15296               (use (match_dup 3))
15297               (clobber (match_dup 5))])])
15298
15299 (define_insn "fist<mode>2_ceil"
15300   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15301         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15302                       UNSPEC_FIST_CEIL))
15303    (use (match_operand:HI 2 "memory_operand" "m"))
15304    (use (match_operand:HI 3 "memory_operand" "m"))]
15305   "TARGET_USE_FANCY_MATH_387
15306    && flag_unsafe_math_optimizations"
15307   "* return output_fix_trunc (insn, operands, false);"
15308   [(set_attr "type" "fistp")
15309    (set_attr "i387_cw" "ceil")
15310    (set_attr "mode" "<MODE>")])
15311
15312 (define_insn "fist<mode>2_ceil_with_temp"
15313   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15314         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15315                       UNSPEC_FIST_CEIL))
15316    (use (match_operand:HI 2 "memory_operand" "m,m"))
15317    (use (match_operand:HI 3 "memory_operand" "m,m"))
15318    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15319   "TARGET_USE_FANCY_MATH_387
15320    && flag_unsafe_math_optimizations"
15321   "#"
15322   [(set_attr "type" "fistp")
15323    (set_attr "i387_cw" "ceil")
15324    (set_attr "mode" "<MODE>")])
15325
15326 (define_split
15327   [(set (match_operand:SWI24 0 "register_operand" "")
15328         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15329                       UNSPEC_FIST_CEIL))
15330    (use (match_operand:HI 2 "memory_operand" ""))
15331    (use (match_operand:HI 3 "memory_operand" ""))
15332    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15333   "reload_completed"
15334   [(parallel [(set (match_dup 4)
15335                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15336               (use (match_dup 2))
15337               (use (match_dup 3))])
15338    (set (match_dup 0) (match_dup 4))])
15339
15340 (define_split
15341   [(set (match_operand:SWI24 0 "memory_operand" "")
15342         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15343                       UNSPEC_FIST_CEIL))
15344    (use (match_operand:HI 2 "memory_operand" ""))
15345    (use (match_operand:HI 3 "memory_operand" ""))
15346    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15347   "reload_completed"
15348   [(parallel [(set (match_dup 0)
15349                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15350               (use (match_dup 2))
15351               (use (match_dup 3))])])
15352
15353 (define_expand "lceilxf<mode>2"
15354   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15355                    (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15356                                    UNSPEC_FIST_CEIL))
15357               (clobber (reg:CC FLAGS_REG))])]
15358   "TARGET_USE_FANCY_MATH_387
15359    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15360    && flag_unsafe_math_optimizations")
15361
15362 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15363   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15364    (match_operand:MODEF 1 "register_operand" "")]
15365   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15366    && !flag_trapping_math"
15367 {
15368   ix86_expand_lfloorceil (operands[0], operands[1], false);
15369   DONE;
15370 })
15371
15372 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15373 (define_insn_and_split "frndintxf2_trunc"
15374   [(set (match_operand:XF 0 "register_operand" "")
15375         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15376          UNSPEC_FRNDINT_TRUNC))
15377    (clobber (reg:CC FLAGS_REG))]
15378   "TARGET_USE_FANCY_MATH_387
15379    && flag_unsafe_math_optimizations
15380    && can_create_pseudo_p ()"
15381   "#"
15382   "&& 1"
15383   [(const_int 0)]
15384 {
15385   ix86_optimize_mode_switching[I387_TRUNC] = 1;
15386
15387   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15388   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15389
15390   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15391                                         operands[2], operands[3]));
15392   DONE;
15393 }
15394   [(set_attr "type" "frndint")
15395    (set_attr "i387_cw" "trunc")
15396    (set_attr "mode" "XF")])
15397
15398 (define_insn "frndintxf2_trunc_i387"
15399   [(set (match_operand:XF 0 "register_operand" "=f")
15400         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15401          UNSPEC_FRNDINT_TRUNC))
15402    (use (match_operand:HI 2 "memory_operand" "m"))
15403    (use (match_operand:HI 3 "memory_operand" "m"))]
15404   "TARGET_USE_FANCY_MATH_387
15405    && flag_unsafe_math_optimizations"
15406   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15407   [(set_attr "type" "frndint")
15408    (set_attr "i387_cw" "trunc")
15409    (set_attr "mode" "XF")])
15410
15411 (define_expand "btruncxf2"
15412   [(use (match_operand:XF 0 "register_operand" ""))
15413    (use (match_operand:XF 1 "register_operand" ""))]
15414   "TARGET_USE_FANCY_MATH_387
15415    && flag_unsafe_math_optimizations"
15416 {
15417   if (optimize_insn_for_size_p ())
15418     FAIL;
15419   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15420   DONE;
15421 })
15422
15423 (define_expand "btrunc<mode>2"
15424   [(use (match_operand:MODEF 0 "register_operand" ""))
15425    (use (match_operand:MODEF 1 "register_operand" ""))]
15426   "(TARGET_USE_FANCY_MATH_387
15427     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15428         || TARGET_MIX_SSE_I387)
15429     && flag_unsafe_math_optimizations)
15430    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15431        && !flag_trapping_math)"
15432 {
15433   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15434       && !flag_trapping_math)
15435     {
15436       if (TARGET_ROUND)
15437         emit_insn (gen_sse4_1_round<mode>2
15438                    (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15439       else if (optimize_insn_for_size_p ())
15440         FAIL;
15441       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15442         ix86_expand_trunc (operands[0], operands[1]);
15443       else
15444         ix86_expand_truncdf_32 (operands[0], operands[1]);
15445     }
15446   else
15447     {
15448       rtx op0, op1;
15449
15450       if (optimize_insn_for_size_p ())
15451         FAIL;
15452
15453       op0 = gen_reg_rtx (XFmode);
15454       op1 = gen_reg_rtx (XFmode);
15455       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15456       emit_insn (gen_frndintxf2_trunc (op0, op1));
15457
15458       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15459     }
15460   DONE;
15461 })
15462
15463 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15464 (define_insn_and_split "frndintxf2_mask_pm"
15465   [(set (match_operand:XF 0 "register_operand" "")
15466         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15467          UNSPEC_FRNDINT_MASK_PM))
15468    (clobber (reg:CC FLAGS_REG))]
15469   "TARGET_USE_FANCY_MATH_387
15470    && flag_unsafe_math_optimizations
15471    && can_create_pseudo_p ()"
15472   "#"
15473   "&& 1"
15474   [(const_int 0)]
15475 {
15476   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15477
15478   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15479   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15480
15481   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15482                                           operands[2], operands[3]));
15483   DONE;
15484 }
15485   [(set_attr "type" "frndint")
15486    (set_attr "i387_cw" "mask_pm")
15487    (set_attr "mode" "XF")])
15488
15489 (define_insn "frndintxf2_mask_pm_i387"
15490   [(set (match_operand:XF 0 "register_operand" "=f")
15491         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15492          UNSPEC_FRNDINT_MASK_PM))
15493    (use (match_operand:HI 2 "memory_operand" "m"))
15494    (use (match_operand:HI 3 "memory_operand" "m"))]
15495   "TARGET_USE_FANCY_MATH_387
15496    && flag_unsafe_math_optimizations"
15497   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15498   [(set_attr "type" "frndint")
15499    (set_attr "i387_cw" "mask_pm")
15500    (set_attr "mode" "XF")])
15501
15502 (define_expand "nearbyintxf2"
15503   [(use (match_operand:XF 0 "register_operand" ""))
15504    (use (match_operand:XF 1 "register_operand" ""))]
15505   "TARGET_USE_FANCY_MATH_387
15506    && flag_unsafe_math_optimizations"
15507 {
15508   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15509   DONE;
15510 })
15511
15512 (define_expand "nearbyint<mode>2"
15513   [(use (match_operand:MODEF 0 "register_operand" ""))
15514    (use (match_operand:MODEF 1 "register_operand" ""))]
15515   "TARGET_USE_FANCY_MATH_387
15516    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15517        || TARGET_MIX_SSE_I387)
15518    && flag_unsafe_math_optimizations"
15519 {
15520   rtx op0 = gen_reg_rtx (XFmode);
15521   rtx op1 = gen_reg_rtx (XFmode);
15522
15523   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15524   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15525
15526   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15527   DONE;
15528 })
15529
15530 (define_insn "fxam<mode>2_i387"
15531   [(set (match_operand:HI 0 "register_operand" "=a")
15532         (unspec:HI
15533           [(match_operand:X87MODEF 1 "register_operand" "f")]
15534           UNSPEC_FXAM))]
15535   "TARGET_USE_FANCY_MATH_387"
15536   "fxam\n\tfnstsw\t%0"
15537   [(set_attr "type" "multi")
15538    (set_attr "length" "4")
15539    (set_attr "unit" "i387")
15540    (set_attr "mode" "<MODE>")])
15541
15542 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15543   [(set (match_operand:HI 0 "register_operand" "")
15544         (unspec:HI
15545           [(match_operand:MODEF 1 "memory_operand" "")]
15546           UNSPEC_FXAM_MEM))]
15547   "TARGET_USE_FANCY_MATH_387
15548    && can_create_pseudo_p ()"
15549   "#"
15550   "&& 1"
15551   [(set (match_dup 2)(match_dup 1))
15552    (set (match_dup 0)
15553         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15554 {
15555   operands[2] = gen_reg_rtx (<MODE>mode);
15556
15557   MEM_VOLATILE_P (operands[1]) = 1;
15558 }
15559   [(set_attr "type" "multi")
15560    (set_attr "unit" "i387")
15561    (set_attr "mode" "<MODE>")])
15562
15563 (define_expand "isinfxf2"
15564   [(use (match_operand:SI 0 "register_operand" ""))
15565    (use (match_operand:XF 1 "register_operand" ""))]
15566   "TARGET_USE_FANCY_MATH_387
15567    && TARGET_C99_FUNCTIONS"
15568 {
15569   rtx mask = GEN_INT (0x45);
15570   rtx val = GEN_INT (0x05);
15571
15572   rtx cond;
15573
15574   rtx scratch = gen_reg_rtx (HImode);
15575   rtx res = gen_reg_rtx (QImode);
15576
15577   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15578
15579   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15580   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15581   cond = gen_rtx_fmt_ee (EQ, QImode,
15582                          gen_rtx_REG (CCmode, FLAGS_REG),
15583                          const0_rtx);
15584   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15585   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15586   DONE;
15587 })
15588
15589 (define_expand "isinf<mode>2"
15590   [(use (match_operand:SI 0 "register_operand" ""))
15591    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15592   "TARGET_USE_FANCY_MATH_387
15593    && TARGET_C99_FUNCTIONS
15594    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15595 {
15596   rtx mask = GEN_INT (0x45);
15597   rtx val = GEN_INT (0x05);
15598
15599   rtx cond;
15600
15601   rtx scratch = gen_reg_rtx (HImode);
15602   rtx res = gen_reg_rtx (QImode);
15603
15604   /* Remove excess precision by forcing value through memory. */
15605   if (memory_operand (operands[1], VOIDmode))
15606     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15607   else
15608     {
15609       rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15610
15611       emit_move_insn (temp, operands[1]);
15612       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15613     }
15614
15615   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15616   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15617   cond = gen_rtx_fmt_ee (EQ, QImode,
15618                          gen_rtx_REG (CCmode, FLAGS_REG),
15619                          const0_rtx);
15620   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15621   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15622   DONE;
15623 })
15624
15625 (define_expand "signbitxf2"
15626   [(use (match_operand:SI 0 "register_operand" ""))
15627    (use (match_operand:XF 1 "register_operand" ""))]
15628   "TARGET_USE_FANCY_MATH_387"
15629 {
15630   rtx scratch = gen_reg_rtx (HImode);
15631
15632   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15633   emit_insn (gen_andsi3 (operands[0],
15634              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15635   DONE;
15636 })
15637
15638 (define_insn "movmsk_df"
15639   [(set (match_operand:SI 0 "register_operand" "=r")
15640         (unspec:SI
15641           [(match_operand:DF 1 "register_operand" "x")]
15642           UNSPEC_MOVMSK))]
15643   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15644   "%vmovmskpd\t{%1, %0|%0, %1}"
15645   [(set_attr "type" "ssemov")
15646    (set_attr "prefix" "maybe_vex")
15647    (set_attr "mode" "DF")])
15648
15649 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15650 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15651 (define_expand "signbitdf2"
15652   [(use (match_operand:SI 0 "register_operand" ""))
15653    (use (match_operand:DF 1 "register_operand" ""))]
15654   "TARGET_USE_FANCY_MATH_387
15655    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15656 {
15657   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15658     {
15659       emit_insn (gen_movmsk_df (operands[0], operands[1]));
15660       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15661     }
15662   else
15663     {
15664       rtx scratch = gen_reg_rtx (HImode);
15665
15666       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15667       emit_insn (gen_andsi3 (operands[0],
15668                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15669     }
15670   DONE;
15671 })
15672
15673 (define_expand "signbitsf2"
15674   [(use (match_operand:SI 0 "register_operand" ""))
15675    (use (match_operand:SF 1 "register_operand" ""))]
15676   "TARGET_USE_FANCY_MATH_387
15677    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15678 {
15679   rtx scratch = gen_reg_rtx (HImode);
15680
15681   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15682   emit_insn (gen_andsi3 (operands[0],
15683              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15684   DONE;
15685 })
15686 \f
15687 ;; Block operation instructions
15688
15689 (define_insn "cld"
15690   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15691   ""
15692   "cld"
15693   [(set_attr "length" "1")
15694    (set_attr "length_immediate" "0")
15695    (set_attr "modrm" "0")])
15696
15697 (define_expand "movmem<mode>"
15698   [(use (match_operand:BLK 0 "memory_operand" ""))
15699    (use (match_operand:BLK 1 "memory_operand" ""))
15700    (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15701    (use (match_operand:SWI48 3 "const_int_operand" ""))
15702    (use (match_operand:SI 4 "const_int_operand" ""))
15703    (use (match_operand:SI 5 "const_int_operand" ""))]
15704   ""
15705 {
15706  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15707                          operands[4], operands[5]))
15708    DONE;
15709  else
15710    FAIL;
15711 })
15712
15713 ;; Most CPUs don't like single string operations
15714 ;; Handle this case here to simplify previous expander.
15715
15716 (define_expand "strmov"
15717   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15718    (set (match_operand 1 "memory_operand" "") (match_dup 4))
15719    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15720               (clobber (reg:CC FLAGS_REG))])
15721    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15722               (clobber (reg:CC FLAGS_REG))])]
15723   ""
15724 {
15725   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15726
15727   /* If .md ever supports :P for Pmode, these can be directly
15728      in the pattern above.  */
15729   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15730   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15731
15732   /* Can't use this if the user has appropriated esi or edi.  */
15733   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15734       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15735     {
15736       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15737                                       operands[2], operands[3],
15738                                       operands[5], operands[6]));
15739       DONE;
15740     }
15741
15742   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15743 })
15744
15745 (define_expand "strmov_singleop"
15746   [(parallel [(set (match_operand 1 "memory_operand" "")
15747                    (match_operand 3 "memory_operand" ""))
15748               (set (match_operand 0 "register_operand" "")
15749                    (match_operand 4 "" ""))
15750               (set (match_operand 2 "register_operand" "")
15751                    (match_operand 5 "" ""))])]
15752   ""
15753   "ix86_current_function_needs_cld = 1;")
15754
15755 (define_insn "*strmovdi_rex_1"
15756   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15757         (mem:DI (match_operand:DI 3 "register_operand" "1")))
15758    (set (match_operand:DI 0 "register_operand" "=D")
15759         (plus:DI (match_dup 2)
15760                  (const_int 8)))
15761    (set (match_operand:DI 1 "register_operand" "=S")
15762         (plus:DI (match_dup 3)
15763                  (const_int 8)))]
15764   "TARGET_64BIT
15765    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15766   "movsq"
15767   [(set_attr "type" "str")
15768    (set_attr "memory" "both")
15769    (set_attr "mode" "DI")])
15770
15771 (define_insn "*strmovsi_1"
15772   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15773         (mem:SI (match_operand:P 3 "register_operand" "1")))
15774    (set (match_operand:P 0 "register_operand" "=D")
15775         (plus:P (match_dup 2)
15776                 (const_int 4)))
15777    (set (match_operand:P 1 "register_operand" "=S")
15778         (plus:P (match_dup 3)
15779                 (const_int 4)))]
15780   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15781   "movs{l|d}"
15782   [(set_attr "type" "str")
15783    (set_attr "memory" "both")
15784    (set_attr "mode" "SI")])
15785
15786 (define_insn "*strmovhi_1"
15787   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15788         (mem:HI (match_operand:P 3 "register_operand" "1")))
15789    (set (match_operand:P 0 "register_operand" "=D")
15790         (plus:P (match_dup 2)
15791                 (const_int 2)))
15792    (set (match_operand:P 1 "register_operand" "=S")
15793         (plus:P (match_dup 3)
15794                 (const_int 2)))]
15795   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15796   "movsw"
15797   [(set_attr "type" "str")
15798    (set_attr "memory" "both")
15799    (set_attr "mode" "HI")])
15800
15801 (define_insn "*strmovqi_1"
15802   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15803         (mem:QI (match_operand:P 3 "register_operand" "1")))
15804    (set (match_operand:P 0 "register_operand" "=D")
15805         (plus:P (match_dup 2)
15806                 (const_int 1)))
15807    (set (match_operand:P 1 "register_operand" "=S")
15808         (plus:P (match_dup 3)
15809                 (const_int 1)))]
15810   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15811   "movsb"
15812   [(set_attr "type" "str")
15813    (set_attr "memory" "both")
15814    (set (attr "prefix_rex")
15815         (if_then_else
15816           (match_test "<P:MODE>mode == DImode")
15817           (const_string "0")
15818           (const_string "*")))
15819    (set_attr "mode" "QI")])
15820
15821 (define_expand "rep_mov"
15822   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15823               (set (match_operand 0 "register_operand" "")
15824                    (match_operand 5 "" ""))
15825               (set (match_operand 2 "register_operand" "")
15826                    (match_operand 6 "" ""))
15827               (set (match_operand 1 "memory_operand" "")
15828                    (match_operand 3 "memory_operand" ""))
15829               (use (match_dup 4))])]
15830   ""
15831   "ix86_current_function_needs_cld = 1;")
15832
15833 (define_insn "*rep_movdi_rex64"
15834   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15835    (set (match_operand:DI 0 "register_operand" "=D")
15836         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15837                             (const_int 3))
15838                  (match_operand:DI 3 "register_operand" "0")))
15839    (set (match_operand:DI 1 "register_operand" "=S")
15840         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15841                  (match_operand:DI 4 "register_operand" "1")))
15842    (set (mem:BLK (match_dup 3))
15843         (mem:BLK (match_dup 4)))
15844    (use (match_dup 5))]
15845   "TARGET_64BIT
15846    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15847   "rep{%;} movsq"
15848   [(set_attr "type" "str")
15849    (set_attr "prefix_rep" "1")
15850    (set_attr "memory" "both")
15851    (set_attr "mode" "DI")])
15852
15853 (define_insn "*rep_movsi"
15854   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15855    (set (match_operand:P 0 "register_operand" "=D")
15856         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15857                           (const_int 2))
15858                  (match_operand:P 3 "register_operand" "0")))
15859    (set (match_operand:P 1 "register_operand" "=S")
15860         (plus:P (ashift:P (match_dup 5) (const_int 2))
15861                 (match_operand:P 4 "register_operand" "1")))
15862    (set (mem:BLK (match_dup 3))
15863         (mem:BLK (match_dup 4)))
15864    (use (match_dup 5))]
15865   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15866   "rep{%;} movs{l|d}"
15867   [(set_attr "type" "str")
15868    (set_attr "prefix_rep" "1")
15869    (set_attr "memory" "both")
15870    (set_attr "mode" "SI")])
15871
15872 (define_insn "*rep_movqi"
15873   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15874    (set (match_operand:P 0 "register_operand" "=D")
15875         (plus:P (match_operand:P 3 "register_operand" "0")
15876                 (match_operand:P 5 "register_operand" "2")))
15877    (set (match_operand:P 1 "register_operand" "=S")
15878         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15879    (set (mem:BLK (match_dup 3))
15880         (mem:BLK (match_dup 4)))
15881    (use (match_dup 5))]
15882   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15883   "rep{%;} movsb"
15884   [(set_attr "type" "str")
15885    (set_attr "prefix_rep" "1")
15886    (set_attr "memory" "both")
15887    (set_attr "mode" "QI")])
15888
15889 (define_expand "setmem<mode>"
15890    [(use (match_operand:BLK 0 "memory_operand" ""))
15891     (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15892     (use (match_operand:QI 2 "nonmemory_operand" ""))
15893     (use (match_operand 3 "const_int_operand" ""))
15894     (use (match_operand:SI 4 "const_int_operand" ""))
15895     (use (match_operand:SI 5 "const_int_operand" ""))]
15896   ""
15897 {
15898  if (ix86_expand_setmem (operands[0], operands[1],
15899                          operands[2], operands[3],
15900                          operands[4], operands[5]))
15901    DONE;
15902  else
15903    FAIL;
15904 })
15905
15906 ;; Most CPUs don't like single string operations
15907 ;; Handle this case here to simplify previous expander.
15908
15909 (define_expand "strset"
15910   [(set (match_operand 1 "memory_operand" "")
15911         (match_operand 2 "register_operand" ""))
15912    (parallel [(set (match_operand 0 "register_operand" "")
15913                    (match_dup 3))
15914               (clobber (reg:CC FLAGS_REG))])]
15915   ""
15916 {
15917   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15918     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15919
15920   /* If .md ever supports :P for Pmode, this can be directly
15921      in the pattern above.  */
15922   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15923                               GEN_INT (GET_MODE_SIZE (GET_MODE
15924                                                       (operands[2]))));
15925   /* Can't use this if the user has appropriated eax or edi.  */
15926   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15927       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15928     {
15929       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15930                                       operands[3]));
15931       DONE;
15932     }
15933 })
15934
15935 (define_expand "strset_singleop"
15936   [(parallel [(set (match_operand 1 "memory_operand" "")
15937                    (match_operand 2 "register_operand" ""))
15938               (set (match_operand 0 "register_operand" "")
15939                    (match_operand 3 "" ""))])]
15940   ""
15941   "ix86_current_function_needs_cld = 1;")
15942
15943 (define_insn "*strsetdi_rex_1"
15944   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15945         (match_operand:DI 2 "register_operand" "a"))
15946    (set (match_operand:DI 0 "register_operand" "=D")
15947         (plus:DI (match_dup 1)
15948                  (const_int 8)))]
15949   "TARGET_64BIT
15950    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15951   "stosq"
15952   [(set_attr "type" "str")
15953    (set_attr "memory" "store")
15954    (set_attr "mode" "DI")])
15955
15956 (define_insn "*strsetsi_1"
15957   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15958         (match_operand:SI 2 "register_operand" "a"))
15959    (set (match_operand:P 0 "register_operand" "=D")
15960         (plus:P (match_dup 1)
15961                 (const_int 4)))]
15962   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15963   "stos{l|d}"
15964   [(set_attr "type" "str")
15965    (set_attr "memory" "store")
15966    (set_attr "mode" "SI")])
15967
15968 (define_insn "*strsethi_1"
15969   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15970         (match_operand:HI 2 "register_operand" "a"))
15971    (set (match_operand:P 0 "register_operand" "=D")
15972         (plus:P (match_dup 1)
15973                 (const_int 2)))]
15974   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15975   "stosw"
15976   [(set_attr "type" "str")
15977    (set_attr "memory" "store")
15978    (set_attr "mode" "HI")])
15979
15980 (define_insn "*strsetqi_1"
15981   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15982         (match_operand:QI 2 "register_operand" "a"))
15983    (set (match_operand:P 0 "register_operand" "=D")
15984         (plus:P (match_dup 1)
15985                 (const_int 1)))]
15986   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15987   "stosb"
15988   [(set_attr "type" "str")
15989    (set_attr "memory" "store")
15990    (set (attr "prefix_rex")
15991         (if_then_else
15992           (match_test "<P:MODE>mode == DImode")
15993           (const_string "0")
15994           (const_string "*")))
15995    (set_attr "mode" "QI")])
15996
15997 (define_expand "rep_stos"
15998   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15999               (set (match_operand 0 "register_operand" "")
16000                    (match_operand 4 "" ""))
16001               (set (match_operand 2 "memory_operand" "") (const_int 0))
16002               (use (match_operand 3 "register_operand" ""))
16003               (use (match_dup 1))])]
16004   ""
16005   "ix86_current_function_needs_cld = 1;")
16006
16007 (define_insn "*rep_stosdi_rex64"
16008   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16009    (set (match_operand:DI 0 "register_operand" "=D")
16010         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16011                             (const_int 3))
16012                  (match_operand:DI 3 "register_operand" "0")))
16013    (set (mem:BLK (match_dup 3))
16014         (const_int 0))
16015    (use (match_operand:DI 2 "register_operand" "a"))
16016    (use (match_dup 4))]
16017   "TARGET_64BIT
16018    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16019   "rep{%;} stosq"
16020   [(set_attr "type" "str")
16021    (set_attr "prefix_rep" "1")
16022    (set_attr "memory" "store")
16023    (set_attr "mode" "DI")])
16024
16025 (define_insn "*rep_stossi"
16026   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16027    (set (match_operand:P 0 "register_operand" "=D")
16028         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16029                           (const_int 2))
16030                  (match_operand:P 3 "register_operand" "0")))
16031    (set (mem:BLK (match_dup 3))
16032         (const_int 0))
16033    (use (match_operand:SI 2 "register_operand" "a"))
16034    (use (match_dup 4))]
16035   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16036   "rep{%;} stos{l|d}"
16037   [(set_attr "type" "str")
16038    (set_attr "prefix_rep" "1")
16039    (set_attr "memory" "store")
16040    (set_attr "mode" "SI")])
16041
16042 (define_insn "*rep_stosqi"
16043   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16044    (set (match_operand:P 0 "register_operand" "=D")
16045         (plus:P (match_operand:P 3 "register_operand" "0")
16046                 (match_operand:P 4 "register_operand" "1")))
16047    (set (mem:BLK (match_dup 3))
16048         (const_int 0))
16049    (use (match_operand:QI 2 "register_operand" "a"))
16050    (use (match_dup 4))]
16051   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16052   "rep{%;} stosb"
16053   [(set_attr "type" "str")
16054    (set_attr "prefix_rep" "1")
16055    (set_attr "memory" "store")
16056    (set (attr "prefix_rex")
16057         (if_then_else
16058           (match_test "<P:MODE>mode == DImode")
16059           (const_string "0")
16060           (const_string "*")))
16061    (set_attr "mode" "QI")])
16062
16063 (define_expand "cmpstrnsi"
16064   [(set (match_operand:SI 0 "register_operand" "")
16065         (compare:SI (match_operand:BLK 1 "general_operand" "")
16066                     (match_operand:BLK 2 "general_operand" "")))
16067    (use (match_operand 3 "general_operand" ""))
16068    (use (match_operand 4 "immediate_operand" ""))]
16069   ""
16070 {
16071   rtx addr1, addr2, out, outlow, count, countreg, align;
16072
16073   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16074     FAIL;
16075
16076   /* Can't use this if the user has appropriated ecx, esi or edi.  */
16077   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16078     FAIL;
16079
16080   out = operands[0];
16081   if (!REG_P (out))
16082     out = gen_reg_rtx (SImode);
16083
16084   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16085   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16086   if (addr1 != XEXP (operands[1], 0))
16087     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16088   if (addr2 != XEXP (operands[2], 0))
16089     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16090
16091   count = operands[3];
16092   countreg = ix86_zero_extend_to_Pmode (count);
16093
16094   /* %%% Iff we are testing strict equality, we can use known alignment
16095      to good advantage.  This may be possible with combine, particularly
16096      once cc0 is dead.  */
16097   align = operands[4];
16098
16099   if (CONST_INT_P (count))
16100     {
16101       if (INTVAL (count) == 0)
16102         {
16103           emit_move_insn (operands[0], const0_rtx);
16104           DONE;
16105         }
16106       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16107                                      operands[1], operands[2]));
16108     }
16109   else
16110     {
16111       rtx (*gen_cmp) (rtx, rtx);
16112
16113       gen_cmp = (TARGET_64BIT
16114                  ? gen_cmpdi_1 : gen_cmpsi_1);
16115
16116       emit_insn (gen_cmp (countreg, countreg));
16117       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16118                                   operands[1], operands[2]));
16119     }
16120
16121   outlow = gen_lowpart (QImode, out);
16122   emit_insn (gen_cmpintqi (outlow));
16123   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16124
16125   if (operands[0] != out)
16126     emit_move_insn (operands[0], out);
16127
16128   DONE;
16129 })
16130
16131 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16132
16133 (define_expand "cmpintqi"
16134   [(set (match_dup 1)
16135         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16136    (set (match_dup 2)
16137         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16138    (parallel [(set (match_operand:QI 0 "register_operand" "")
16139                    (minus:QI (match_dup 1)
16140                              (match_dup 2)))
16141               (clobber (reg:CC FLAGS_REG))])]
16142   ""
16143 {
16144   operands[1] = gen_reg_rtx (QImode);
16145   operands[2] = gen_reg_rtx (QImode);
16146 })
16147
16148 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16149 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16150
16151 (define_expand "cmpstrnqi_nz_1"
16152   [(parallel [(set (reg:CC FLAGS_REG)
16153                    (compare:CC (match_operand 4 "memory_operand" "")
16154                                (match_operand 5 "memory_operand" "")))
16155               (use (match_operand 2 "register_operand" ""))
16156               (use (match_operand:SI 3 "immediate_operand" ""))
16157               (clobber (match_operand 0 "register_operand" ""))
16158               (clobber (match_operand 1 "register_operand" ""))
16159               (clobber (match_dup 2))])]
16160   ""
16161   "ix86_current_function_needs_cld = 1;")
16162
16163 (define_insn "*cmpstrnqi_nz_1"
16164   [(set (reg:CC FLAGS_REG)
16165         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16166                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16167    (use (match_operand:P 6 "register_operand" "2"))
16168    (use (match_operand:SI 3 "immediate_operand" "i"))
16169    (clobber (match_operand:P 0 "register_operand" "=S"))
16170    (clobber (match_operand:P 1 "register_operand" "=D"))
16171    (clobber (match_operand:P 2 "register_operand" "=c"))]
16172   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16173   "repz{%;} cmpsb"
16174   [(set_attr "type" "str")
16175    (set_attr "mode" "QI")
16176    (set (attr "prefix_rex")
16177         (if_then_else
16178           (match_test "<P:MODE>mode == DImode")
16179           (const_string "0")
16180           (const_string "*")))
16181    (set_attr "prefix_rep" "1")])
16182
16183 ;; The same, but the count is not known to not be zero.
16184
16185 (define_expand "cmpstrnqi_1"
16186   [(parallel [(set (reg:CC FLAGS_REG)
16187                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16188                                      (const_int 0))
16189                   (compare:CC (match_operand 4 "memory_operand" "")
16190                               (match_operand 5 "memory_operand" ""))
16191                   (const_int 0)))
16192               (use (match_operand:SI 3 "immediate_operand" ""))
16193               (use (reg:CC FLAGS_REG))
16194               (clobber (match_operand 0 "register_operand" ""))
16195               (clobber (match_operand 1 "register_operand" ""))
16196               (clobber (match_dup 2))])]
16197   ""
16198   "ix86_current_function_needs_cld = 1;")
16199
16200 (define_insn "*cmpstrnqi_1"
16201   [(set (reg:CC FLAGS_REG)
16202         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16203                              (const_int 0))
16204           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16205                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
16206           (const_int 0)))
16207    (use (match_operand:SI 3 "immediate_operand" "i"))
16208    (use (reg:CC FLAGS_REG))
16209    (clobber (match_operand:P 0 "register_operand" "=S"))
16210    (clobber (match_operand:P 1 "register_operand" "=D"))
16211    (clobber (match_operand:P 2 "register_operand" "=c"))]
16212   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16213   "repz{%;} cmpsb"
16214   [(set_attr "type" "str")
16215    (set_attr "mode" "QI")
16216    (set (attr "prefix_rex")
16217         (if_then_else
16218           (match_test "<P:MODE>mode == DImode")
16219           (const_string "0")
16220           (const_string "*")))
16221    (set_attr "prefix_rep" "1")])
16222
16223 (define_expand "strlen<mode>"
16224   [(set (match_operand:P 0 "register_operand" "")
16225         (unspec:P [(match_operand:BLK 1 "general_operand" "")
16226                    (match_operand:QI 2 "immediate_operand" "")
16227                    (match_operand 3 "immediate_operand" "")]
16228                   UNSPEC_SCAS))]
16229   ""
16230 {
16231  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16232    DONE;
16233  else
16234    FAIL;
16235 })
16236
16237 (define_expand "strlenqi_1"
16238   [(parallel [(set (match_operand 0 "register_operand" "")
16239                    (match_operand 2 "" ""))
16240               (clobber (match_operand 1 "register_operand" ""))
16241               (clobber (reg:CC FLAGS_REG))])]
16242   ""
16243   "ix86_current_function_needs_cld = 1;")
16244
16245 (define_insn "*strlenqi_1"
16246   [(set (match_operand:P 0 "register_operand" "=&c")
16247         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16248                    (match_operand:QI 2 "register_operand" "a")
16249                    (match_operand:P 3 "immediate_operand" "i")
16250                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16251    (clobber (match_operand:P 1 "register_operand" "=D"))
16252    (clobber (reg:CC FLAGS_REG))]
16253   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16254   "repnz{%;} scasb"
16255   [(set_attr "type" "str")
16256    (set_attr "mode" "QI")
16257    (set (attr "prefix_rex")
16258         (if_then_else
16259           (match_test "<P:MODE>mode == DImode")
16260           (const_string "0")
16261           (const_string "*")))
16262    (set_attr "prefix_rep" "1")])
16263
16264 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
16265 ;; handled in combine, but it is not currently up to the task.
16266 ;; When used for their truth value, the cmpstrn* expanders generate
16267 ;; code like this:
16268 ;;
16269 ;;   repz cmpsb
16270 ;;   seta       %al
16271 ;;   setb       %dl
16272 ;;   cmpb       %al, %dl
16273 ;;   jcc        label
16274 ;;
16275 ;; The intermediate three instructions are unnecessary.
16276
16277 ;; This one handles cmpstrn*_nz_1...
16278 (define_peephole2
16279   [(parallel[
16280      (set (reg:CC FLAGS_REG)
16281           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16282                       (mem:BLK (match_operand 5 "register_operand" ""))))
16283      (use (match_operand 6 "register_operand" ""))
16284      (use (match_operand:SI 3 "immediate_operand" ""))
16285      (clobber (match_operand 0 "register_operand" ""))
16286      (clobber (match_operand 1 "register_operand" ""))
16287      (clobber (match_operand 2 "register_operand" ""))])
16288    (set (match_operand:QI 7 "register_operand" "")
16289         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16290    (set (match_operand:QI 8 "register_operand" "")
16291         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16292    (set (reg FLAGS_REG)
16293         (compare (match_dup 7) (match_dup 8)))
16294   ]
16295   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16296   [(parallel[
16297      (set (reg:CC FLAGS_REG)
16298           (compare:CC (mem:BLK (match_dup 4))
16299                       (mem:BLK (match_dup 5))))
16300      (use (match_dup 6))
16301      (use (match_dup 3))
16302      (clobber (match_dup 0))
16303      (clobber (match_dup 1))
16304      (clobber (match_dup 2))])])
16305
16306 ;; ...and this one handles cmpstrn*_1.
16307 (define_peephole2
16308   [(parallel[
16309      (set (reg:CC FLAGS_REG)
16310           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16311                                (const_int 0))
16312             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16313                         (mem:BLK (match_operand 5 "register_operand" "")))
16314             (const_int 0)))
16315      (use (match_operand:SI 3 "immediate_operand" ""))
16316      (use (reg:CC FLAGS_REG))
16317      (clobber (match_operand 0 "register_operand" ""))
16318      (clobber (match_operand 1 "register_operand" ""))
16319      (clobber (match_operand 2 "register_operand" ""))])
16320    (set (match_operand:QI 7 "register_operand" "")
16321         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16322    (set (match_operand:QI 8 "register_operand" "")
16323         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16324    (set (reg FLAGS_REG)
16325         (compare (match_dup 7) (match_dup 8)))
16326   ]
16327   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16328   [(parallel[
16329      (set (reg:CC FLAGS_REG)
16330           (if_then_else:CC (ne (match_dup 6)
16331                                (const_int 0))
16332             (compare:CC (mem:BLK (match_dup 4))
16333                         (mem:BLK (match_dup 5)))
16334             (const_int 0)))
16335      (use (match_dup 3))
16336      (use (reg:CC FLAGS_REG))
16337      (clobber (match_dup 0))
16338      (clobber (match_dup 1))
16339      (clobber (match_dup 2))])])
16340 \f
16341 ;; Conditional move instructions.
16342
16343 (define_expand "mov<mode>cc"
16344   [(set (match_operand:SWIM 0 "register_operand" "")
16345         (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16346                            (match_operand:SWIM 2 "<general_operand>" "")
16347                            (match_operand:SWIM 3 "<general_operand>" "")))]
16348   ""
16349   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16350
16351 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16352 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16353 ;; So just document what we're doing explicitly.
16354
16355 (define_expand "x86_mov<mode>cc_0_m1"
16356   [(parallel
16357     [(set (match_operand:SWI48 0 "register_operand" "")
16358           (if_then_else:SWI48
16359             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16360              [(match_operand 1 "flags_reg_operand" "")
16361               (const_int 0)])
16362             (const_int -1)
16363             (const_int 0)))
16364      (clobber (reg:CC FLAGS_REG))])])
16365
16366 (define_insn "*x86_mov<mode>cc_0_m1"
16367   [(set (match_operand:SWI48 0 "register_operand" "=r")
16368         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16369                              [(reg FLAGS_REG) (const_int 0)])
16370           (const_int -1)
16371           (const_int 0)))
16372    (clobber (reg:CC FLAGS_REG))]
16373   ""
16374   "sbb{<imodesuffix>}\t%0, %0"
16375   ; Since we don't have the proper number of operands for an alu insn,
16376   ; fill in all the blanks.
16377   [(set_attr "type" "alu")
16378    (set_attr "use_carry" "1")
16379    (set_attr "pent_pair" "pu")
16380    (set_attr "memory" "none")
16381    (set_attr "imm_disp" "false")
16382    (set_attr "mode" "<MODE>")
16383    (set_attr "length_immediate" "0")])
16384
16385 (define_insn "*x86_mov<mode>cc_0_m1_se"
16386   [(set (match_operand:SWI48 0 "register_operand" "=r")
16387         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16388                              [(reg FLAGS_REG) (const_int 0)])
16389                             (const_int 1)
16390                             (const_int 0)))
16391    (clobber (reg:CC FLAGS_REG))]
16392   ""
16393   "sbb{<imodesuffix>}\t%0, %0"
16394   [(set_attr "type" "alu")
16395    (set_attr "use_carry" "1")
16396    (set_attr "pent_pair" "pu")
16397    (set_attr "memory" "none")
16398    (set_attr "imm_disp" "false")
16399    (set_attr "mode" "<MODE>")
16400    (set_attr "length_immediate" "0")])
16401
16402 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16403   [(set (match_operand:SWI48 0 "register_operand" "=r")
16404         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16405                     [(reg FLAGS_REG) (const_int 0)])))
16406    (clobber (reg:CC FLAGS_REG))]
16407   ""
16408   "sbb{<imodesuffix>}\t%0, %0"
16409   [(set_attr "type" "alu")
16410    (set_attr "use_carry" "1")
16411    (set_attr "pent_pair" "pu")
16412    (set_attr "memory" "none")
16413    (set_attr "imm_disp" "false")
16414    (set_attr "mode" "<MODE>")
16415    (set_attr "length_immediate" "0")])
16416
16417 (define_insn "*mov<mode>cc_noc"
16418   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16419         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16420                                [(reg FLAGS_REG) (const_int 0)])
16421           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16422           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16423   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16424   "@
16425    cmov%O2%C1\t{%2, %0|%0, %2}
16426    cmov%O2%c1\t{%3, %0|%0, %3}"
16427   [(set_attr "type" "icmov")
16428    (set_attr "mode" "<MODE>")])
16429
16430 (define_insn "*movqicc_noc"
16431   [(set (match_operand:QI 0 "register_operand" "=r,r")
16432         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16433                            [(reg FLAGS_REG) (const_int 0)])
16434                       (match_operand:QI 2 "register_operand" "r,0")
16435                       (match_operand:QI 3 "register_operand" "0,r")))]
16436   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16437   "#"
16438   [(set_attr "type" "icmov")
16439    (set_attr "mode" "QI")])
16440
16441 (define_split
16442   [(set (match_operand 0 "register_operand")
16443         (if_then_else (match_operator 1 "ix86_comparison_operator"
16444                         [(reg FLAGS_REG) (const_int 0)])
16445                       (match_operand 2 "register_operand")
16446                       (match_operand 3 "register_operand")))]
16447   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16448    && (GET_MODE (operands[0]) == QImode
16449        || GET_MODE (operands[0]) == HImode)
16450    && reload_completed"
16451   [(set (match_dup 0)
16452         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16453 {
16454   operands[0] = gen_lowpart (SImode, operands[0]);
16455   operands[2] = gen_lowpart (SImode, operands[2]);
16456   operands[3] = gen_lowpart (SImode, operands[3]);
16457 })
16458
16459 (define_expand "mov<mode>cc"
16460   [(set (match_operand:X87MODEF 0 "register_operand" "")
16461         (if_then_else:X87MODEF
16462           (match_operand 1 "ix86_fp_comparison_operator" "")
16463           (match_operand:X87MODEF 2 "register_operand" "")
16464           (match_operand:X87MODEF 3 "register_operand" "")))]
16465   "(TARGET_80387 && TARGET_CMOVE)
16466    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16467   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16468
16469 (define_insn "*movxfcc_1"
16470   [(set (match_operand:XF 0 "register_operand" "=f,f")
16471         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16472                                 [(reg FLAGS_REG) (const_int 0)])
16473                       (match_operand:XF 2 "register_operand" "f,0")
16474                       (match_operand:XF 3 "register_operand" "0,f")))]
16475   "TARGET_80387 && TARGET_CMOVE"
16476   "@
16477    fcmov%F1\t{%2, %0|%0, %2}
16478    fcmov%f1\t{%3, %0|%0, %3}"
16479   [(set_attr "type" "fcmov")
16480    (set_attr "mode" "XF")])
16481
16482 (define_insn "*movdfcc_1_rex64"
16483   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16484         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16485                                 [(reg FLAGS_REG) (const_int 0)])
16486                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16487                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16488   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16489    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16490   "@
16491    fcmov%F1\t{%2, %0|%0, %2}
16492    fcmov%f1\t{%3, %0|%0, %3}
16493    cmov%O2%C1\t{%2, %0|%0, %2}
16494    cmov%O2%c1\t{%3, %0|%0, %3}"
16495   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16496    (set_attr "mode" "DF,DF,DI,DI")])
16497
16498 (define_insn "*movdfcc_1"
16499   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16500         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16501                                 [(reg FLAGS_REG) (const_int 0)])
16502                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16503                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16504   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16505    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16506   "@
16507    fcmov%F1\t{%2, %0|%0, %2}
16508    fcmov%f1\t{%3, %0|%0, %3}
16509    #
16510    #"
16511   [(set_attr "type" "fcmov,fcmov,multi,multi")
16512    (set_attr "mode" "DF,DF,DI,DI")])
16513
16514 (define_split
16515   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16516         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16517                                 [(reg FLAGS_REG) (const_int 0)])
16518                       (match_operand:DF 2 "nonimmediate_operand")
16519                       (match_operand:DF 3 "nonimmediate_operand")))]
16520   "!TARGET_64BIT && reload_completed"
16521   [(set (match_dup 2)
16522         (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16523    (set (match_dup 3)
16524         (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16525 {
16526   split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16527   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16528 })
16529
16530 (define_insn "*movsfcc_1_387"
16531   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16532         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16533                                 [(reg FLAGS_REG) (const_int 0)])
16534                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16535                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16536   "TARGET_80387 && TARGET_CMOVE
16537    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16538   "@
16539    fcmov%F1\t{%2, %0|%0, %2}
16540    fcmov%f1\t{%3, %0|%0, %3}
16541    cmov%O2%C1\t{%2, %0|%0, %2}
16542    cmov%O2%c1\t{%3, %0|%0, %3}"
16543   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16544    (set_attr "mode" "SF,SF,SI,SI")])
16545
16546 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16547 ;; the scalar versions to have only XMM registers as operands.
16548
16549 ;; XOP conditional move
16550 (define_insn "*xop_pcmov_<mode>"
16551   [(set (match_operand:MODEF 0 "register_operand" "=x")
16552         (if_then_else:MODEF
16553           (match_operand:MODEF 1 "register_operand" "x")
16554           (match_operand:MODEF 2 "register_operand" "x")
16555           (match_operand:MODEF 3 "register_operand" "x")))]
16556   "TARGET_XOP"
16557   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16558   [(set_attr "type" "sse4arg")])
16559
16560 ;; These versions of the min/max patterns are intentionally ignorant of
16561 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16562 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16563 ;; are undefined in this condition, we're certain this is correct.
16564
16565 (define_insn "<code><mode>3"
16566   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16567         (smaxmin:MODEF
16568           (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16569           (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16570   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16571   "@
16572    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16573    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16574   [(set_attr "isa" "noavx,avx")
16575    (set_attr "prefix" "orig,vex")
16576    (set_attr "type" "sseadd")
16577    (set_attr "mode" "<MODE>")])
16578
16579 ;; These versions of the min/max patterns implement exactly the operations
16580 ;;   min = (op1 < op2 ? op1 : op2)
16581 ;;   max = (!(op1 < op2) ? op1 : op2)
16582 ;; Their operands are not commutative, and thus they may be used in the
16583 ;; presence of -0.0 and NaN.
16584
16585 (define_insn "*ieee_smin<mode>3"
16586   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16587         (unspec:MODEF
16588           [(match_operand:MODEF 1 "register_operand" "0,x")
16589            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16590          UNSPEC_IEEE_MIN))]
16591   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16592   "@
16593    min<ssemodesuffix>\t{%2, %0|%0, %2}
16594    vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16595   [(set_attr "isa" "noavx,avx")
16596    (set_attr "prefix" "orig,vex")
16597    (set_attr "type" "sseadd")
16598    (set_attr "mode" "<MODE>")])
16599
16600 (define_insn "*ieee_smax<mode>3"
16601   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16602         (unspec:MODEF
16603           [(match_operand:MODEF 1 "register_operand" "0,x")
16604            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16605          UNSPEC_IEEE_MAX))]
16606   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16607   "@
16608    max<ssemodesuffix>\t{%2, %0|%0, %2}
16609    vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16610   [(set_attr "isa" "noavx,avx")
16611    (set_attr "prefix" "orig,vex")
16612    (set_attr "type" "sseadd")
16613    (set_attr "mode" "<MODE>")])
16614
16615 ;; Make two stack loads independent:
16616 ;;   fld aa              fld aa
16617 ;;   fld %st(0)     ->   fld bb
16618 ;;   fmul bb             fmul %st(1), %st
16619 ;;
16620 ;; Actually we only match the last two instructions for simplicity.
16621 (define_peephole2
16622   [(set (match_operand 0 "fp_register_operand" "")
16623         (match_operand 1 "fp_register_operand" ""))
16624    (set (match_dup 0)
16625         (match_operator 2 "binary_fp_operator"
16626            [(match_dup 0)
16627             (match_operand 3 "memory_operand" "")]))]
16628   "REGNO (operands[0]) != REGNO (operands[1])"
16629   [(set (match_dup 0) (match_dup 3))
16630    (set (match_dup 0) (match_dup 4))]
16631
16632   ;; The % modifier is not operational anymore in peephole2's, so we have to
16633   ;; swap the operands manually in the case of addition and multiplication.
16634 {
16635   rtx op0, op1;
16636
16637   if (COMMUTATIVE_ARITH_P (operands[2]))
16638     op0 = operands[0], op1 = operands[1];
16639   else
16640     op0 = operands[1], op1 = operands[0];
16641
16642   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16643                                 GET_MODE (operands[2]),
16644                                 op0, op1);
16645 })
16646
16647 ;; Conditional addition patterns
16648 (define_expand "add<mode>cc"
16649   [(match_operand:SWI 0 "register_operand" "")
16650    (match_operand 1 "ordered_comparison_operator" "")
16651    (match_operand:SWI 2 "register_operand" "")
16652    (match_operand:SWI 3 "const_int_operand" "")]
16653   ""
16654   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16655 \f
16656 ;; Misc patterns (?)
16657
16658 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16659 ;; Otherwise there will be nothing to keep
16660 ;;
16661 ;; [(set (reg ebp) (reg esp))]
16662 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16663 ;;  (clobber (eflags)]
16664 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16665 ;;
16666 ;; in proper program order.
16667
16668 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16669   [(set (match_operand:P 0 "register_operand" "=r,r")
16670         (plus:P (match_operand:P 1 "register_operand" "0,r")
16671                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16672    (clobber (reg:CC FLAGS_REG))
16673    (clobber (mem:BLK (scratch)))]
16674   ""
16675 {
16676   switch (get_attr_type (insn))
16677     {
16678     case TYPE_IMOV:
16679       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16680
16681     case TYPE_ALU:
16682       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16683       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16684         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16685
16686       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16687
16688     default:
16689       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16690       return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16691     }
16692 }
16693   [(set (attr "type")
16694         (cond [(and (eq_attr "alternative" "0")
16695                     (not (match_test "TARGET_OPT_AGU")))
16696                  (const_string "alu")
16697                (match_operand:<MODE> 2 "const0_operand" "")
16698                  (const_string "imov")
16699               ]
16700               (const_string "lea")))
16701    (set (attr "length_immediate")
16702         (cond [(eq_attr "type" "imov")
16703                  (const_string "0")
16704                (and (eq_attr "type" "alu")
16705                     (match_operand 2 "const128_operand" ""))
16706                  (const_string "1")
16707               ]
16708               (const_string "*")))
16709    (set_attr "mode" "<MODE>")])
16710
16711 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16712   [(set (match_operand:P 0 "register_operand" "=r")
16713         (minus:P (match_operand:P 1 "register_operand" "0")
16714                  (match_operand:P 2 "register_operand" "r")))
16715    (clobber (reg:CC FLAGS_REG))
16716    (clobber (mem:BLK (scratch)))]
16717   ""
16718   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16719   [(set_attr "type" "alu")
16720    (set_attr "mode" "<MODE>")])
16721
16722 (define_insn "allocate_stack_worker_probe_<mode>"
16723   [(set (match_operand:P 0 "register_operand" "=a")
16724         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16725                             UNSPECV_STACK_PROBE))
16726    (clobber (reg:CC FLAGS_REG))]
16727   "ix86_target_stack_probe ()"
16728   "call\t___chkstk_ms"
16729   [(set_attr "type" "multi")
16730    (set_attr "length" "5")])
16731
16732 (define_expand "allocate_stack"
16733   [(match_operand 0 "register_operand" "")
16734    (match_operand 1 "general_operand" "")]
16735   "ix86_target_stack_probe ()"
16736 {
16737   rtx x;
16738
16739 #ifndef CHECK_STACK_LIMIT
16740 #define CHECK_STACK_LIMIT 0
16741 #endif
16742
16743   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16744       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16745     {
16746       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16747                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16748       if (x != stack_pointer_rtx)
16749         emit_move_insn (stack_pointer_rtx, x);
16750     }
16751   else
16752     {
16753       x = copy_to_mode_reg (Pmode, operands[1]);
16754       if (TARGET_64BIT)
16755         emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16756       else
16757         emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16758       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16759                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16760       if (x != stack_pointer_rtx)
16761         emit_move_insn (stack_pointer_rtx, x);
16762     }
16763
16764   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16765   DONE;
16766 })
16767
16768 ;; Use IOR for stack probes, this is shorter.
16769 (define_expand "probe_stack"
16770   [(match_operand 0 "memory_operand" "")]
16771   ""
16772 {
16773   rtx (*gen_ior3) (rtx, rtx, rtx);
16774
16775   gen_ior3 = (GET_MODE (operands[0]) == DImode
16776               ? gen_iordi3 : gen_iorsi3);
16777
16778   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16779   DONE;
16780 })
16781
16782 (define_insn "adjust_stack_and_probe<mode>"
16783   [(set (match_operand:P 0 "register_operand" "=r")
16784         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16785                             UNSPECV_PROBE_STACK_RANGE))
16786    (set (reg:P SP_REG)
16787         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16788    (clobber (reg:CC FLAGS_REG))
16789    (clobber (mem:BLK (scratch)))]
16790   ""
16791   "* return output_adjust_stack_and_probe (operands[0]);"
16792   [(set_attr "type" "multi")])
16793
16794 (define_insn "probe_stack_range<mode>"
16795   [(set (match_operand:P 0 "register_operand" "=r")
16796         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16797                             (match_operand:P 2 "const_int_operand" "n")]
16798                             UNSPECV_PROBE_STACK_RANGE))
16799    (clobber (reg:CC FLAGS_REG))]
16800   ""
16801   "* return output_probe_stack_range (operands[0], operands[2]);"
16802   [(set_attr "type" "multi")])
16803
16804 (define_expand "builtin_setjmp_receiver"
16805   [(label_ref (match_operand 0 "" ""))]
16806   "!TARGET_64BIT && flag_pic"
16807 {
16808 #if TARGET_MACHO
16809   if (TARGET_MACHO)
16810     {
16811       rtx xops[3];
16812       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16813       rtx label_rtx = gen_label_rtx ();
16814       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16815       xops[0] = xops[1] = picreg;
16816       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16817       ix86_expand_binary_operator (MINUS, SImode, xops);
16818     }
16819   else
16820 #endif
16821     emit_insn (gen_set_got (pic_offset_table_rtx));
16822   DONE;
16823 })
16824 \f
16825 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16826
16827 (define_split
16828   [(set (match_operand 0 "register_operand" "")
16829         (match_operator 3 "promotable_binary_operator"
16830            [(match_operand 1 "register_operand" "")
16831             (match_operand 2 "aligned_operand" "")]))
16832    (clobber (reg:CC FLAGS_REG))]
16833   "! TARGET_PARTIAL_REG_STALL && reload_completed
16834    && ((GET_MODE (operands[0]) == HImode
16835         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16836             /* ??? next two lines just !satisfies_constraint_K (...) */
16837             || !CONST_INT_P (operands[2])
16838             || satisfies_constraint_K (operands[2])))
16839        || (GET_MODE (operands[0]) == QImode
16840            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16841   [(parallel [(set (match_dup 0)
16842                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16843               (clobber (reg:CC FLAGS_REG))])]
16844 {
16845   operands[0] = gen_lowpart (SImode, operands[0]);
16846   operands[1] = gen_lowpart (SImode, operands[1]);
16847   if (GET_CODE (operands[3]) != ASHIFT)
16848     operands[2] = gen_lowpart (SImode, operands[2]);
16849   PUT_MODE (operands[3], SImode);
16850 })
16851
16852 ; Promote the QImode tests, as i386 has encoding of the AND
16853 ; instruction with 32-bit sign-extended immediate and thus the
16854 ; instruction size is unchanged, except in the %eax case for
16855 ; which it is increased by one byte, hence the ! optimize_size.
16856 (define_split
16857   [(set (match_operand 0 "flags_reg_operand" "")
16858         (match_operator 2 "compare_operator"
16859           [(and (match_operand 3 "aligned_operand" "")
16860                 (match_operand 4 "const_int_operand" ""))
16861            (const_int 0)]))
16862    (set (match_operand 1 "register_operand" "")
16863         (and (match_dup 3) (match_dup 4)))]
16864   "! TARGET_PARTIAL_REG_STALL && reload_completed
16865    && optimize_insn_for_speed_p ()
16866    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16867        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16868    /* Ensure that the operand will remain sign-extended immediate.  */
16869    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16870   [(parallel [(set (match_dup 0)
16871                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16872                                     (const_int 0)]))
16873               (set (match_dup 1)
16874                    (and:SI (match_dup 3) (match_dup 4)))])]
16875 {
16876   operands[4]
16877     = gen_int_mode (INTVAL (operands[4])
16878                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16879   operands[1] = gen_lowpart (SImode, operands[1]);
16880   operands[3] = gen_lowpart (SImode, operands[3]);
16881 })
16882
16883 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16884 ; the TEST instruction with 32-bit sign-extended immediate and thus
16885 ; the instruction size would at least double, which is not what we
16886 ; want even with ! optimize_size.
16887 (define_split
16888   [(set (match_operand 0 "flags_reg_operand" "")
16889         (match_operator 1 "compare_operator"
16890           [(and (match_operand:HI 2 "aligned_operand" "")
16891                 (match_operand:HI 3 "const_int_operand" ""))
16892            (const_int 0)]))]
16893   "! TARGET_PARTIAL_REG_STALL && reload_completed
16894    && ! TARGET_FAST_PREFIX
16895    && optimize_insn_for_speed_p ()
16896    /* Ensure that the operand will remain sign-extended immediate.  */
16897    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16898   [(set (match_dup 0)
16899         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16900                          (const_int 0)]))]
16901 {
16902   operands[3]
16903     = gen_int_mode (INTVAL (operands[3])
16904                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16905   operands[2] = gen_lowpart (SImode, operands[2]);
16906 })
16907
16908 (define_split
16909   [(set (match_operand 0 "register_operand" "")
16910         (neg (match_operand 1 "register_operand" "")))
16911    (clobber (reg:CC FLAGS_REG))]
16912   "! TARGET_PARTIAL_REG_STALL && reload_completed
16913    && (GET_MODE (operands[0]) == HImode
16914        || (GET_MODE (operands[0]) == QImode
16915            && (TARGET_PROMOTE_QImode
16916                || optimize_insn_for_size_p ())))"
16917   [(parallel [(set (match_dup 0)
16918                    (neg:SI (match_dup 1)))
16919               (clobber (reg:CC FLAGS_REG))])]
16920 {
16921   operands[0] = gen_lowpart (SImode, operands[0]);
16922   operands[1] = gen_lowpart (SImode, operands[1]);
16923 })
16924
16925 (define_split
16926   [(set (match_operand 0 "register_operand" "")
16927         (not (match_operand 1 "register_operand" "")))]
16928   "! TARGET_PARTIAL_REG_STALL && reload_completed
16929    && (GET_MODE (operands[0]) == HImode
16930        || (GET_MODE (operands[0]) == QImode
16931            && (TARGET_PROMOTE_QImode
16932                || optimize_insn_for_size_p ())))"
16933   [(set (match_dup 0)
16934         (not:SI (match_dup 1)))]
16935 {
16936   operands[0] = gen_lowpart (SImode, operands[0]);
16937   operands[1] = gen_lowpart (SImode, operands[1]);
16938 })
16939 \f
16940 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
16941 ;; transform a complex memory operation into two memory to register operations.
16942
16943 ;; Don't push memory operands
16944 (define_peephole2
16945   [(set (match_operand:SWI 0 "push_operand" "")
16946         (match_operand:SWI 1 "memory_operand" ""))
16947    (match_scratch:SWI 2 "<r>")]
16948   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16949    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16950   [(set (match_dup 2) (match_dup 1))
16951    (set (match_dup 0) (match_dup 2))])
16952
16953 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16954 ;; SImode pushes.
16955 (define_peephole2
16956   [(set (match_operand:SF 0 "push_operand" "")
16957         (match_operand:SF 1 "memory_operand" ""))
16958    (match_scratch:SF 2 "r")]
16959   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16960    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16961   [(set (match_dup 2) (match_dup 1))
16962    (set (match_dup 0) (match_dup 2))])
16963
16964 ;; Don't move an immediate directly to memory when the instruction
16965 ;; gets too big.
16966 (define_peephole2
16967   [(match_scratch:SWI124 1 "<r>")
16968    (set (match_operand:SWI124 0 "memory_operand" "")
16969         (const_int 0))]
16970   "optimize_insn_for_speed_p ()
16971    && !TARGET_USE_MOV0
16972    && TARGET_SPLIT_LONG_MOVES
16973    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16974    && peep2_regno_dead_p (0, FLAGS_REG)"
16975   [(parallel [(set (match_dup 2) (const_int 0))
16976               (clobber (reg:CC FLAGS_REG))])
16977    (set (match_dup 0) (match_dup 1))]
16978   "operands[2] = gen_lowpart (SImode, operands[1]);")
16979
16980 (define_peephole2
16981   [(match_scratch:SWI124 2 "<r>")
16982    (set (match_operand:SWI124 0 "memory_operand" "")
16983         (match_operand:SWI124 1 "immediate_operand" ""))]
16984   "optimize_insn_for_speed_p ()
16985    && TARGET_SPLIT_LONG_MOVES
16986    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16987   [(set (match_dup 2) (match_dup 1))
16988    (set (match_dup 0) (match_dup 2))])
16989
16990 ;; Don't compare memory with zero, load and use a test instead.
16991 (define_peephole2
16992   [(set (match_operand 0 "flags_reg_operand" "")
16993         (match_operator 1 "compare_operator"
16994           [(match_operand:SI 2 "memory_operand" "")
16995            (const_int 0)]))
16996    (match_scratch:SI 3 "r")]
16997   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16998   [(set (match_dup 3) (match_dup 2))
16999    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17000
17001 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17002 ;; Don't split NOTs with a displacement operand, because resulting XOR
17003 ;; will not be pairable anyway.
17004 ;;
17005 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17006 ;; represented using a modRM byte.  The XOR replacement is long decoded,
17007 ;; so this split helps here as well.
17008 ;;
17009 ;; Note: Can't do this as a regular split because we can't get proper
17010 ;; lifetime information then.
17011
17012 (define_peephole2
17013   [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
17014         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
17015   "optimize_insn_for_speed_p ()
17016    && ((TARGET_NOT_UNPAIRABLE
17017         && (!MEM_P (operands[0])
17018             || !memory_displacement_operand (operands[0], <MODE>mode)))
17019        || (TARGET_NOT_VECTORMODE
17020            && long_memory_operand (operands[0], <MODE>mode)))
17021    && peep2_regno_dead_p (0, FLAGS_REG)"
17022   [(parallel [(set (match_dup 0)
17023                    (xor:SWI124 (match_dup 1) (const_int -1)))
17024               (clobber (reg:CC FLAGS_REG))])])
17025
17026 ;; Non pairable "test imm, reg" instructions can be translated to
17027 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17028 ;; byte opcode instead of two, have a short form for byte operands),
17029 ;; so do it for other CPUs as well.  Given that the value was dead,
17030 ;; this should not create any new dependencies.  Pass on the sub-word
17031 ;; versions if we're concerned about partial register stalls.
17032
17033 (define_peephole2
17034   [(set (match_operand 0 "flags_reg_operand" "")
17035         (match_operator 1 "compare_operator"
17036           [(and:SI (match_operand:SI 2 "register_operand" "")
17037                    (match_operand:SI 3 "immediate_operand" ""))
17038            (const_int 0)]))]
17039   "ix86_match_ccmode (insn, CCNOmode)
17040    && (true_regnum (operands[2]) != AX_REG
17041        || satisfies_constraint_K (operands[3]))
17042    && peep2_reg_dead_p (1, operands[2])"
17043   [(parallel
17044      [(set (match_dup 0)
17045            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17046                             (const_int 0)]))
17047       (set (match_dup 2)
17048            (and:SI (match_dup 2) (match_dup 3)))])])
17049
17050 ;; We don't need to handle HImode case, because it will be promoted to SImode
17051 ;; on ! TARGET_PARTIAL_REG_STALL
17052
17053 (define_peephole2
17054   [(set (match_operand 0 "flags_reg_operand" "")
17055         (match_operator 1 "compare_operator"
17056           [(and:QI (match_operand:QI 2 "register_operand" "")
17057                    (match_operand:QI 3 "immediate_operand" ""))
17058            (const_int 0)]))]
17059   "! TARGET_PARTIAL_REG_STALL
17060    && ix86_match_ccmode (insn, CCNOmode)
17061    && true_regnum (operands[2]) != AX_REG
17062    && peep2_reg_dead_p (1, operands[2])"
17063   [(parallel
17064      [(set (match_dup 0)
17065            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17066                             (const_int 0)]))
17067       (set (match_dup 2)
17068            (and:QI (match_dup 2) (match_dup 3)))])])
17069
17070 (define_peephole2
17071   [(set (match_operand 0 "flags_reg_operand" "")
17072         (match_operator 1 "compare_operator"
17073           [(and:SI
17074              (zero_extract:SI
17075                (match_operand 2 "ext_register_operand" "")
17076                (const_int 8)
17077                (const_int 8))
17078              (match_operand 3 "const_int_operand" ""))
17079            (const_int 0)]))]
17080   "! TARGET_PARTIAL_REG_STALL
17081    && ix86_match_ccmode (insn, CCNOmode)
17082    && true_regnum (operands[2]) != AX_REG
17083    && peep2_reg_dead_p (1, operands[2])"
17084   [(parallel [(set (match_dup 0)
17085                    (match_op_dup 1
17086                      [(and:SI
17087                         (zero_extract:SI
17088                           (match_dup 2)
17089                           (const_int 8)
17090                           (const_int 8))
17091                         (match_dup 3))
17092                       (const_int 0)]))
17093               (set (zero_extract:SI (match_dup 2)
17094                                     (const_int 8)
17095                                     (const_int 8))
17096                    (and:SI
17097                      (zero_extract:SI
17098                        (match_dup 2)
17099                        (const_int 8)
17100                        (const_int 8))
17101                      (match_dup 3)))])])
17102
17103 ;; Don't do logical operations with memory inputs.
17104 (define_peephole2
17105   [(match_scratch:SI 2 "r")
17106    (parallel [(set (match_operand:SI 0 "register_operand" "")
17107                    (match_operator:SI 3 "arith_or_logical_operator"
17108                      [(match_dup 0)
17109                       (match_operand:SI 1 "memory_operand" "")]))
17110               (clobber (reg:CC FLAGS_REG))])]
17111   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17112   [(set (match_dup 2) (match_dup 1))
17113    (parallel [(set (match_dup 0)
17114                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17115               (clobber (reg:CC FLAGS_REG))])])
17116
17117 (define_peephole2
17118   [(match_scratch:SI 2 "r")
17119    (parallel [(set (match_operand:SI 0 "register_operand" "")
17120                    (match_operator:SI 3 "arith_or_logical_operator"
17121                      [(match_operand:SI 1 "memory_operand" "")
17122                       (match_dup 0)]))
17123               (clobber (reg:CC FLAGS_REG))])]
17124   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17125   [(set (match_dup 2) (match_dup 1))
17126    (parallel [(set (match_dup 0)
17127                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17128               (clobber (reg:CC FLAGS_REG))])])
17129
17130 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17131 ;; refers to the destination of the load!
17132
17133 (define_peephole2
17134   [(set (match_operand:SI 0 "register_operand" "")
17135         (match_operand:SI 1 "register_operand" ""))
17136    (parallel [(set (match_dup 0)
17137                    (match_operator:SI 3 "commutative_operator"
17138                      [(match_dup 0)
17139                       (match_operand:SI 2 "memory_operand" "")]))
17140               (clobber (reg:CC FLAGS_REG))])]
17141   "REGNO (operands[0]) != REGNO (operands[1])
17142    && GENERAL_REGNO_P (REGNO (operands[0]))
17143    && GENERAL_REGNO_P (REGNO (operands[1]))"
17144   [(set (match_dup 0) (match_dup 4))
17145    (parallel [(set (match_dup 0)
17146                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17147               (clobber (reg:CC FLAGS_REG))])]
17148   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17149
17150 (define_peephole2
17151   [(set (match_operand 0 "register_operand" "")
17152         (match_operand 1 "register_operand" ""))
17153    (set (match_dup 0)
17154                    (match_operator 3 "commutative_operator"
17155                      [(match_dup 0)
17156                       (match_operand 2 "memory_operand" "")]))]
17157   "REGNO (operands[0]) != REGNO (operands[1])
17158    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
17159        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17160   [(set (match_dup 0) (match_dup 2))
17161    (set (match_dup 0)
17162         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17163
17164 ; Don't do logical operations with memory outputs
17165 ;
17166 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17167 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17168 ; the same decoder scheduling characteristics as the original.
17169
17170 (define_peephole2
17171   [(match_scratch:SI 2 "r")
17172    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17173                    (match_operator:SI 3 "arith_or_logical_operator"
17174                      [(match_dup 0)
17175                       (match_operand:SI 1 "nonmemory_operand" "")]))
17176               (clobber (reg:CC FLAGS_REG))])]
17177   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17178    /* Do not split stack checking probes.  */
17179    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17180   [(set (match_dup 2) (match_dup 0))
17181    (parallel [(set (match_dup 2)
17182                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17183               (clobber (reg:CC FLAGS_REG))])
17184    (set (match_dup 0) (match_dup 2))])
17185
17186 (define_peephole2
17187   [(match_scratch:SI 2 "r")
17188    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17189                    (match_operator:SI 3 "arith_or_logical_operator"
17190                      [(match_operand:SI 1 "nonmemory_operand" "")
17191                       (match_dup 0)]))
17192               (clobber (reg:CC FLAGS_REG))])]
17193   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17194    /* Do not split stack checking probes.  */
17195    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17196   [(set (match_dup 2) (match_dup 0))
17197    (parallel [(set (match_dup 2)
17198                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17199               (clobber (reg:CC FLAGS_REG))])
17200    (set (match_dup 0) (match_dup 2))])
17201
17202 ;; Attempt to use arith or logical operations with memory outputs with
17203 ;; setting of flags.
17204 (define_peephole2
17205   [(set (match_operand:SWI 0 "register_operand" "")
17206         (match_operand:SWI 1 "memory_operand" ""))
17207    (parallel [(set (match_dup 0)
17208                    (match_operator:SWI 3 "plusminuslogic_operator"
17209                      [(match_dup 0)
17210                       (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17211               (clobber (reg:CC FLAGS_REG))])
17212    (set (match_dup 1) (match_dup 0))
17213    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17214   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17215    && peep2_reg_dead_p (4, operands[0])
17216    && !reg_overlap_mentioned_p (operands[0], operands[1])
17217    && (<MODE>mode != QImode
17218        || immediate_operand (operands[2], QImode)
17219        || q_regs_operand (operands[2], QImode))
17220    && ix86_match_ccmode (peep2_next_insn (3),
17221                          (GET_CODE (operands[3]) == PLUS
17222                           || GET_CODE (operands[3]) == MINUS)
17223                          ? CCGOCmode : CCNOmode)"
17224   [(parallel [(set (match_dup 4) (match_dup 5))
17225               (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17226                                                   (match_dup 2)]))])]
17227 {
17228   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17229   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17230                                 copy_rtx (operands[1]),
17231                                 copy_rtx (operands[2]));
17232   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17233                                  operands[5], const0_rtx);
17234 })
17235
17236 (define_peephole2
17237   [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17238                    (match_operator:SWI 2 "plusminuslogic_operator"
17239                      [(match_dup 0)
17240                       (match_operand:SWI 1 "memory_operand" "")]))
17241               (clobber (reg:CC FLAGS_REG))])
17242    (set (match_dup 1) (match_dup 0))
17243    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17244   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17245    && GET_CODE (operands[2]) != MINUS
17246    && peep2_reg_dead_p (3, operands[0])
17247    && !reg_overlap_mentioned_p (operands[0], operands[1])
17248    && ix86_match_ccmode (peep2_next_insn (2),
17249                          GET_CODE (operands[2]) == PLUS
17250                          ? CCGOCmode : CCNOmode)"
17251   [(parallel [(set (match_dup 3) (match_dup 4))
17252               (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17253                                                   (match_dup 0)]))])]
17254 {
17255   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17256   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17257                                 copy_rtx (operands[1]),
17258                                 copy_rtx (operands[0]));
17259   operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17260                                  operands[4], const0_rtx);
17261 })
17262
17263 (define_peephole2
17264   [(set (match_operand:SWI12 0 "register_operand" "")
17265         (match_operand:SWI12 1 "memory_operand" ""))
17266    (parallel [(set (match_operand:SI 4 "register_operand" "")
17267                    (match_operator:SI 3 "plusminuslogic_operator"
17268                      [(match_dup 4)
17269                       (match_operand:SI 2 "nonmemory_operand" "")]))
17270               (clobber (reg:CC FLAGS_REG))])
17271    (set (match_dup 1) (match_dup 0))
17272    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17273   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17274    && REG_P (operands[0]) && REG_P (operands[4])
17275    && REGNO (operands[0]) == REGNO (operands[4])
17276    && peep2_reg_dead_p (4, operands[0])
17277    && (<MODE>mode != QImode
17278        || immediate_operand (operands[2], SImode)
17279        || q_regs_operand (operands[2], SImode))
17280    && !reg_overlap_mentioned_p (operands[0], operands[1])
17281    && ix86_match_ccmode (peep2_next_insn (3),
17282                          (GET_CODE (operands[3]) == PLUS
17283                           || GET_CODE (operands[3]) == MINUS)
17284                          ? CCGOCmode : CCNOmode)"
17285   [(parallel [(set (match_dup 4) (match_dup 5))
17286               (set (match_dup 1) (match_dup 6))])]
17287 {
17288   operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17289   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17290   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17291                                 copy_rtx (operands[1]), operands[2]);
17292   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17293                                  operands[5], const0_rtx);
17294   operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17295                                 copy_rtx (operands[1]),
17296                                 copy_rtx (operands[2]));
17297 })
17298
17299 ;; Attempt to always use XOR for zeroing registers.
17300 (define_peephole2
17301   [(set (match_operand 0 "register_operand" "")
17302         (match_operand 1 "const0_operand" ""))]
17303   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17304    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17305    && GENERAL_REG_P (operands[0])
17306    && peep2_regno_dead_p (0, FLAGS_REG)"
17307   [(parallel [(set (match_dup 0) (const_int 0))
17308               (clobber (reg:CC FLAGS_REG))])]
17309   "operands[0] = gen_lowpart (word_mode, operands[0]);")
17310
17311 (define_peephole2
17312   [(set (strict_low_part (match_operand 0 "register_operand" ""))
17313         (const_int 0))]
17314   "(GET_MODE (operands[0]) == QImode
17315     || GET_MODE (operands[0]) == HImode)
17316    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17317    && peep2_regno_dead_p (0, FLAGS_REG)"
17318   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17319               (clobber (reg:CC FLAGS_REG))])])
17320
17321 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17322 (define_peephole2
17323   [(set (match_operand:SWI248 0 "register_operand" "")
17324         (const_int -1))]
17325   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17326    && peep2_regno_dead_p (0, FLAGS_REG)"
17327   [(parallel [(set (match_dup 0) (const_int -1))
17328               (clobber (reg:CC FLAGS_REG))])]
17329 {
17330   if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17331     operands[0] = gen_lowpart (SImode, operands[0]);
17332 })
17333
17334 ;; Attempt to convert simple lea to add/shift.
17335 ;; These can be created by move expanders.
17336
17337 (define_peephole2
17338   [(set (match_operand:SWI48 0 "register_operand" "")
17339         (plus:SWI48 (match_dup 0)
17340                     (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17341   "peep2_regno_dead_p (0, FLAGS_REG)"
17342   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17343               (clobber (reg:CC FLAGS_REG))])])
17344
17345 (define_peephole2
17346   [(set (match_operand:SI 0 "register_operand" "")
17347         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17348                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17349   "TARGET_64BIT
17350    && peep2_regno_dead_p (0, FLAGS_REG)
17351    && REGNO (operands[0]) == REGNO (operands[1])"
17352   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17353               (clobber (reg:CC FLAGS_REG))])]
17354   "operands[2] = gen_lowpart (SImode, operands[2]);")
17355
17356 (define_peephole2
17357   [(set (match_operand:SWI48 0 "register_operand" "")
17358         (mult:SWI48 (match_dup 0)
17359                     (match_operand:SWI48 1 "const_int_operand" "")))]
17360   "exact_log2 (INTVAL (operands[1])) >= 0
17361    && peep2_regno_dead_p (0, FLAGS_REG)"
17362   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17363               (clobber (reg:CC FLAGS_REG))])]
17364   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17365
17366 (define_peephole2
17367   [(set (match_operand:SI 0 "register_operand" "")
17368         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17369                    (match_operand:DI 2 "const_int_operand" "")) 0))]
17370   "TARGET_64BIT
17371    && exact_log2 (INTVAL (operands[2])) >= 0
17372    && REGNO (operands[0]) == REGNO (operands[1])
17373    && peep2_regno_dead_p (0, FLAGS_REG)"
17374   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17375               (clobber (reg:CC FLAGS_REG))])]
17376   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17377
17378 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17379 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17380 ;; On many CPUs it is also faster, since special hardware to avoid esp
17381 ;; dependencies is present.
17382
17383 ;; While some of these conversions may be done using splitters, we use
17384 ;; peepholes in order to allow combine_stack_adjustments pass to see
17385 ;; nonobfuscated RTL.
17386
17387 ;; Convert prologue esp subtractions to push.
17388 ;; We need register to push.  In order to keep verify_flow_info happy we have
17389 ;; two choices
17390 ;; - use scratch and clobber it in order to avoid dependencies
17391 ;; - use already live register
17392 ;; We can't use the second way right now, since there is no reliable way how to
17393 ;; verify that given register is live.  First choice will also most likely in
17394 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17395 ;; call clobbered registers are dead.  We may want to use base pointer as an
17396 ;; alternative when no register is available later.
17397
17398 (define_peephole2
17399   [(match_scratch:P 1 "r")
17400    (parallel [(set (reg:P SP_REG)
17401                    (plus:P (reg:P SP_REG)
17402                            (match_operand:P 0 "const_int_operand" "")))
17403               (clobber (reg:CC FLAGS_REG))
17404               (clobber (mem:BLK (scratch)))])]
17405   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17406    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17407   [(clobber (match_dup 1))
17408    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17409               (clobber (mem:BLK (scratch)))])])
17410
17411 (define_peephole2
17412   [(match_scratch:P 1 "r")
17413    (parallel [(set (reg:P SP_REG)
17414                    (plus:P (reg:P SP_REG)
17415                            (match_operand:P 0 "const_int_operand" "")))
17416               (clobber (reg:CC FLAGS_REG))
17417               (clobber (mem:BLK (scratch)))])]
17418   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17419    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17420   [(clobber (match_dup 1))
17421    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17422    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17423               (clobber (mem:BLK (scratch)))])])
17424
17425 ;; Convert esp subtractions to push.
17426 (define_peephole2
17427   [(match_scratch:P 1 "r")
17428    (parallel [(set (reg:P SP_REG)
17429                    (plus:P (reg:P SP_REG)
17430                            (match_operand:P 0 "const_int_operand" "")))
17431               (clobber (reg:CC FLAGS_REG))])]
17432   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17433    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17434   [(clobber (match_dup 1))
17435    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17436
17437 (define_peephole2
17438   [(match_scratch:P 1 "r")
17439    (parallel [(set (reg:P SP_REG)
17440                    (plus:P (reg:P SP_REG)
17441                            (match_operand:P 0 "const_int_operand" "")))
17442               (clobber (reg:CC FLAGS_REG))])]
17443   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17444    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17445   [(clobber (match_dup 1))
17446    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17447    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17448
17449 ;; Convert epilogue deallocator 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               (clobber (mem:BLK (scratch)))])]
17457   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17458    && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17459   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17460               (clobber (mem:BLK (scratch)))])])
17461
17462 ;; Two pops case is tricky, since pop causes dependency
17463 ;; on destination register.  We use two registers if available.
17464 (define_peephole2
17465   [(match_scratch:P 1 "r")
17466    (match_scratch:P 2 "r")
17467    (parallel [(set (reg:P SP_REG)
17468                    (plus:P (reg:P SP_REG)
17469                            (match_operand:P 0 "const_int_operand" "")))
17470               (clobber (reg:CC FLAGS_REG))
17471               (clobber (mem:BLK (scratch)))])]
17472   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17473    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17474   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17475               (clobber (mem:BLK (scratch)))])
17476    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17477
17478 (define_peephole2
17479   [(match_scratch:P 1 "r")
17480    (parallel [(set (reg:P SP_REG)
17481                    (plus:P (reg:P SP_REG)
17482                            (match_operand:P 0 "const_int_operand" "")))
17483               (clobber (reg:CC FLAGS_REG))
17484               (clobber (mem:BLK (scratch)))])]
17485   "optimize_insn_for_size_p ()
17486    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17487   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17488               (clobber (mem:BLK (scratch)))])
17489    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17490
17491 ;; Convert esp additions to pop.
17492 (define_peephole2
17493   [(match_scratch:P 1 "r")
17494    (parallel [(set (reg:P SP_REG)
17495                    (plus:P (reg:P SP_REG)
17496                            (match_operand:P 0 "const_int_operand" "")))
17497               (clobber (reg:CC FLAGS_REG))])]
17498   "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17499   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17500
17501 ;; Two pops case is tricky, since pop causes dependency
17502 ;; on destination register.  We use two registers if available.
17503 (define_peephole2
17504   [(match_scratch:P 1 "r")
17505    (match_scratch:P 2 "r")
17506    (parallel [(set (reg:P SP_REG)
17507                    (plus:P (reg:P SP_REG)
17508                            (match_operand:P 0 "const_int_operand" "")))
17509               (clobber (reg:CC FLAGS_REG))])]
17510   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17511   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17512    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17513
17514 (define_peephole2
17515   [(match_scratch:P 1 "r")
17516    (parallel [(set (reg:P SP_REG)
17517                    (plus:P (reg:P SP_REG)
17518                            (match_operand:P 0 "const_int_operand" "")))
17519               (clobber (reg:CC FLAGS_REG))])]
17520   "optimize_insn_for_size_p ()
17521    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17522   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17523    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17524 \f
17525 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17526 ;; required and register dies.  Similarly for 128 to -128.
17527 (define_peephole2
17528   [(set (match_operand 0 "flags_reg_operand" "")
17529         (match_operator 1 "compare_operator"
17530           [(match_operand 2 "register_operand" "")
17531            (match_operand 3 "const_int_operand" "")]))]
17532   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17533      && incdec_operand (operands[3], GET_MODE (operands[3])))
17534     || (!TARGET_FUSE_CMP_AND_BRANCH
17535         && INTVAL (operands[3]) == 128))
17536    && ix86_match_ccmode (insn, CCGCmode)
17537    && peep2_reg_dead_p (1, operands[2])"
17538   [(parallel [(set (match_dup 0)
17539                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17540               (clobber (match_dup 2))])])
17541 \f
17542 ;; Convert imul by three, five and nine into lea
17543 (define_peephole2
17544   [(parallel
17545     [(set (match_operand:SWI48 0 "register_operand" "")
17546           (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17547                       (match_operand:SWI48 2 "const359_operand" "")))
17548      (clobber (reg:CC FLAGS_REG))])]
17549   "!TARGET_PARTIAL_REG_STALL
17550    || <MODE>mode == SImode
17551    || optimize_function_for_size_p (cfun)"
17552   [(set (match_dup 0)
17553         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17554                     (match_dup 1)))]
17555   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17556
17557 (define_peephole2
17558   [(parallel
17559     [(set (match_operand:SWI48 0 "register_operand" "")
17560           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17561                       (match_operand:SWI48 2 "const359_operand" "")))
17562      (clobber (reg:CC FLAGS_REG))])]
17563   "optimize_insn_for_speed_p ()
17564    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17565   [(set (match_dup 0) (match_dup 1))
17566    (set (match_dup 0)
17567         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17568                     (match_dup 0)))]
17569   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17570
17571 ;; imul $32bit_imm, mem, reg is vector decoded, while
17572 ;; imul $32bit_imm, reg, reg is direct decoded.
17573 (define_peephole2
17574   [(match_scratch:SWI48 3 "r")
17575    (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17576                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17577                                (match_operand:SWI48 2 "immediate_operand" "")))
17578               (clobber (reg:CC FLAGS_REG))])]
17579   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17580    && !satisfies_constraint_K (operands[2])"
17581   [(set (match_dup 3) (match_dup 1))
17582    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17583               (clobber (reg:CC FLAGS_REG))])])
17584
17585 (define_peephole2
17586   [(match_scratch:SI 3 "r")
17587    (parallel [(set (match_operand:DI 0 "register_operand" "")
17588                    (zero_extend:DI
17589                      (mult:SI (match_operand:SI 1 "memory_operand" "")
17590                               (match_operand:SI 2 "immediate_operand" ""))))
17591               (clobber (reg:CC FLAGS_REG))])]
17592   "TARGET_64BIT
17593    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17594    && !satisfies_constraint_K (operands[2])"
17595   [(set (match_dup 3) (match_dup 1))
17596    (parallel [(set (match_dup 0)
17597                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17598               (clobber (reg:CC FLAGS_REG))])])
17599
17600 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17601 ;; Convert it into imul reg, reg
17602 ;; It would be better to force assembler to encode instruction using long
17603 ;; immediate, but there is apparently no way to do so.
17604 (define_peephole2
17605   [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17606                    (mult:SWI248
17607                     (match_operand:SWI248 1 "nonimmediate_operand" "")
17608                     (match_operand:SWI248 2 "const_int_operand" "")))
17609               (clobber (reg:CC FLAGS_REG))])
17610    (match_scratch:SWI248 3 "r")]
17611   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17612    && satisfies_constraint_K (operands[2])"
17613   [(set (match_dup 3) (match_dup 2))
17614    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17615               (clobber (reg:CC FLAGS_REG))])]
17616 {
17617   if (!rtx_equal_p (operands[0], operands[1]))
17618     emit_move_insn (operands[0], operands[1]);
17619 })
17620
17621 ;; After splitting up read-modify operations, array accesses with memory
17622 ;; operands might end up in form:
17623 ;;  sall    $2, %eax
17624 ;;  movl    4(%esp), %edx
17625 ;;  addl    %edx, %eax
17626 ;; instead of pre-splitting:
17627 ;;  sall    $2, %eax
17628 ;;  addl    4(%esp), %eax
17629 ;; Turn it into:
17630 ;;  movl    4(%esp), %edx
17631 ;;  leal    (%edx,%eax,4), %eax
17632
17633 (define_peephole2
17634   [(match_scratch:P 5 "r")
17635    (parallel [(set (match_operand 0 "register_operand" "")
17636                    (ashift (match_operand 1 "register_operand" "")
17637                            (match_operand 2 "const_int_operand" "")))
17638                (clobber (reg:CC FLAGS_REG))])
17639    (parallel [(set (match_operand 3 "register_operand" "")
17640                    (plus (match_dup 0)
17641                          (match_operand 4 "x86_64_general_operand" "")))
17642                    (clobber (reg:CC FLAGS_REG))])]
17643   "IN_RANGE (INTVAL (operands[2]), 1, 3)
17644    /* Validate MODE for lea.  */
17645    && ((!TARGET_PARTIAL_REG_STALL
17646         && (GET_MODE (operands[0]) == QImode
17647             || GET_MODE (operands[0]) == HImode))
17648        || GET_MODE (operands[0]) == SImode
17649        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17650    && (rtx_equal_p (operands[0], operands[3])
17651        || peep2_reg_dead_p (2, operands[0]))
17652    /* We reorder load and the shift.  */
17653    && !reg_overlap_mentioned_p (operands[0], operands[4])"
17654   [(set (match_dup 5) (match_dup 4))
17655    (set (match_dup 0) (match_dup 1))]
17656 {
17657   enum machine_mode op1mode = GET_MODE (operands[1]);
17658   enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17659   int scale = 1 << INTVAL (operands[2]);
17660   rtx index = gen_lowpart (Pmode, operands[1]);
17661   rtx base = gen_lowpart (Pmode, operands[5]);
17662   rtx dest = gen_lowpart (mode, operands[3]);
17663
17664   operands[1] = gen_rtx_PLUS (Pmode, base,
17665                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17666   operands[5] = base;
17667   if (mode != Pmode)
17668     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17669   if (op1mode != Pmode)
17670     operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17671   operands[0] = dest;
17672 })
17673 \f
17674 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17675 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17676 ;; caught for use by garbage collectors and the like.  Using an insn that
17677 ;; maps to SIGILL makes it more likely the program will rightfully die.
17678 ;; Keeping with tradition, "6" is in honor of #UD.
17679 (define_insn "trap"
17680   [(trap_if (const_int 1) (const_int 6))]
17681   ""
17682   { return ASM_SHORT "0x0b0f"; }
17683   [(set_attr "length" "2")])
17684
17685 (define_expand "prefetch"
17686   [(prefetch (match_operand 0 "address_operand" "")
17687              (match_operand:SI 1 "const_int_operand" "")
17688              (match_operand:SI 2 "const_int_operand" ""))]
17689   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17690 {
17691   int rw = INTVAL (operands[1]);
17692   int locality = INTVAL (operands[2]);
17693
17694   gcc_assert (rw == 0 || rw == 1);
17695   gcc_assert (IN_RANGE (locality, 0, 3));
17696
17697   if (TARGET_PREFETCHW && rw)
17698     operands[2] = GEN_INT (3);
17699   /* Use 3dNOW prefetch in case we are asking for write prefetch not
17700      supported by SSE counterpart or the SSE prefetch is not available
17701      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17702      of locality.  */
17703   else if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17704     operands[2] = GEN_INT (3);
17705   else
17706     operands[1] = const0_rtx;
17707 })
17708
17709 (define_insn "*prefetch_sse"
17710   [(prefetch (match_operand 0 "address_operand" "p")
17711              (const_int 0)
17712              (match_operand:SI 1 "const_int_operand" ""))]
17713   "TARGET_PREFETCH_SSE"
17714 {
17715   static const char * const patterns[4] = {
17716    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17717   };
17718
17719   int locality = INTVAL (operands[1]);
17720   gcc_assert (IN_RANGE (locality, 0, 3));
17721
17722   return patterns[locality];
17723 }
17724   [(set_attr "type" "sse")
17725    (set_attr "atom_sse_attr" "prefetch")
17726    (set (attr "length_address")
17727         (symbol_ref "memory_address_length (operands[0], false)"))
17728    (set_attr "memory" "none")])
17729
17730 (define_insn "*prefetch_3dnow"
17731   [(prefetch (match_operand 0 "address_operand" "p")
17732              (match_operand:SI 1 "const_int_operand" "n")
17733              (const_int 3))]
17734   "TARGET_3DNOW || TARGET_PREFETCHW"
17735 {
17736   if (INTVAL (operands[1]) == 0)
17737     return "prefetch\t%a0";
17738   else
17739     return "prefetchw\t%a0";
17740 }
17741   [(set_attr "type" "mmx")
17742    (set (attr "length_address")
17743         (symbol_ref "memory_address_length (operands[0], false)"))
17744    (set_attr "memory" "none")])
17745
17746 (define_expand "stack_protect_set"
17747   [(match_operand 0 "memory_operand" "")
17748    (match_operand 1 "memory_operand" "")]
17749   "!TARGET_HAS_BIONIC"
17750 {
17751   rtx (*insn)(rtx, rtx);
17752
17753 #ifdef TARGET_THREAD_SSP_OFFSET
17754   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17755   insn = (TARGET_LP64
17756           ? gen_stack_tls_protect_set_di
17757           : gen_stack_tls_protect_set_si);
17758 #else
17759   insn = (TARGET_LP64
17760           ? gen_stack_protect_set_di
17761           : gen_stack_protect_set_si);
17762 #endif
17763
17764   emit_insn (insn (operands[0], operands[1]));
17765   DONE;
17766 })
17767
17768 (define_insn "stack_protect_set_<mode>"
17769   [(set (match_operand:PTR 0 "memory_operand" "=m")
17770         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17771                     UNSPEC_SP_SET))
17772    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17773    (clobber (reg:CC FLAGS_REG))]
17774   "!TARGET_HAS_BIONIC"
17775   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17776   [(set_attr "type" "multi")])
17777
17778 (define_insn "stack_tls_protect_set_<mode>"
17779   [(set (match_operand:PTR 0 "memory_operand" "=m")
17780         (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17781                     UNSPEC_SP_TLS_SET))
17782    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17783    (clobber (reg:CC FLAGS_REG))]
17784   ""
17785   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17786   [(set_attr "type" "multi")])
17787
17788 (define_expand "stack_protect_test"
17789   [(match_operand 0 "memory_operand" "")
17790    (match_operand 1 "memory_operand" "")
17791    (match_operand 2 "" "")]
17792   "!TARGET_HAS_BIONIC"
17793 {
17794   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17795
17796   rtx (*insn)(rtx, rtx, rtx);
17797
17798 #ifdef TARGET_THREAD_SSP_OFFSET
17799   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17800   insn = (TARGET_LP64
17801           ? gen_stack_tls_protect_test_di
17802           : gen_stack_tls_protect_test_si);
17803 #else
17804   insn = (TARGET_LP64
17805           ? gen_stack_protect_test_di
17806           : gen_stack_protect_test_si);
17807 #endif
17808
17809   emit_insn (insn (flags, operands[0], operands[1]));
17810
17811   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17812                                   flags, const0_rtx, operands[2]));
17813   DONE;
17814 })
17815
17816 (define_insn "stack_protect_test_<mode>"
17817   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17818         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17819                      (match_operand:PTR 2 "memory_operand" "m")]
17820                     UNSPEC_SP_TEST))
17821    (clobber (match_scratch:PTR 3 "=&r"))]
17822   "!TARGET_HAS_BIONIC"
17823   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17824   [(set_attr "type" "multi")])
17825
17826 (define_insn "stack_tls_protect_test_<mode>"
17827   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17828         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17829                      (match_operand:PTR 2 "const_int_operand" "i")]
17830                     UNSPEC_SP_TLS_TEST))
17831    (clobber (match_scratch:PTR 3 "=r"))]
17832   ""
17833   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17834   [(set_attr "type" "multi")])
17835
17836 (define_insn "sse4_2_crc32<mode>"
17837   [(set (match_operand:SI 0 "register_operand" "=r")
17838         (unspec:SI
17839           [(match_operand:SI 1 "register_operand" "0")
17840            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17841           UNSPEC_CRC32))]
17842   "TARGET_SSE4_2 || TARGET_CRC32"
17843   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17844   [(set_attr "type" "sselog1")
17845    (set_attr "prefix_rep" "1")
17846    (set_attr "prefix_extra" "1")
17847    (set (attr "prefix_data16")
17848      (if_then_else (match_operand:HI 2 "" "")
17849        (const_string "1")
17850        (const_string "*")))
17851    (set (attr "prefix_rex")
17852      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17853        (const_string "1")
17854        (const_string "*")))
17855    (set_attr "mode" "SI")])
17856
17857 (define_insn "sse4_2_crc32di"
17858   [(set (match_operand:DI 0 "register_operand" "=r")
17859         (unspec:DI
17860           [(match_operand:DI 1 "register_operand" "0")
17861            (match_operand:DI 2 "nonimmediate_operand" "rm")]
17862           UNSPEC_CRC32))]
17863   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17864   "crc32{q}\t{%2, %0|%0, %2}"
17865   [(set_attr "type" "sselog1")
17866    (set_attr "prefix_rep" "1")
17867    (set_attr "prefix_extra" "1")
17868    (set_attr "mode" "DI")])
17869
17870 (define_expand "rdpmc"
17871   [(match_operand:DI 0 "register_operand" "")
17872    (match_operand:SI 1 "register_operand" "")]
17873   ""
17874 {
17875   rtx reg = gen_reg_rtx (DImode);
17876   rtx si;
17877
17878   /* Force operand 1 into ECX.  */
17879   rtx ecx = gen_rtx_REG (SImode, CX_REG);
17880   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17881   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17882                                 UNSPECV_RDPMC);
17883
17884   if (TARGET_64BIT)
17885     {
17886       rtvec vec = rtvec_alloc (2);
17887       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17888       rtx upper = gen_reg_rtx (DImode);
17889       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17890                                         gen_rtvec (1, const0_rtx),
17891                                         UNSPECV_RDPMC);
17892       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17893       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17894       emit_insn (load);
17895       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17896                                    NULL, 1, OPTAB_DIRECT);
17897       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17898                                  OPTAB_DIRECT);
17899     }
17900   else
17901     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17902   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17903   DONE;
17904 })
17905
17906 (define_insn "*rdpmc"
17907   [(set (match_operand:DI 0 "register_operand" "=A")
17908         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17909                             UNSPECV_RDPMC))]
17910   "!TARGET_64BIT"
17911   "rdpmc"
17912   [(set_attr "type" "other")
17913    (set_attr "length" "2")])
17914
17915 (define_insn "*rdpmc_rex64"
17916   [(set (match_operand:DI 0 "register_operand" "=a")
17917         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17918                             UNSPECV_RDPMC))
17919   (set (match_operand:DI 1 "register_operand" "=d")
17920        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17921   "TARGET_64BIT"
17922   "rdpmc"
17923   [(set_attr "type" "other")
17924    (set_attr "length" "2")])
17925
17926 (define_expand "rdtsc"
17927   [(set (match_operand:DI 0 "register_operand" "")
17928         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17929   ""
17930 {
17931   if (TARGET_64BIT)
17932     {
17933       rtvec vec = rtvec_alloc (2);
17934       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17935       rtx upper = gen_reg_rtx (DImode);
17936       rtx lower = gen_reg_rtx (DImode);
17937       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17938                                          gen_rtvec (1, const0_rtx),
17939                                          UNSPECV_RDTSC);
17940       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17941       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17942       emit_insn (load);
17943       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17944                                    NULL, 1, OPTAB_DIRECT);
17945       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17946                                    OPTAB_DIRECT);
17947       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17948       DONE;
17949     }
17950 })
17951
17952 (define_insn "*rdtsc"
17953   [(set (match_operand:DI 0 "register_operand" "=A")
17954         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17955   "!TARGET_64BIT"
17956   "rdtsc"
17957   [(set_attr "type" "other")
17958    (set_attr "length" "2")])
17959
17960 (define_insn "*rdtsc_rex64"
17961   [(set (match_operand:DI 0 "register_operand" "=a")
17962         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17963    (set (match_operand:DI 1 "register_operand" "=d")
17964         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17965   "TARGET_64BIT"
17966   "rdtsc"
17967   [(set_attr "type" "other")
17968    (set_attr "length" "2")])
17969
17970 (define_expand "rdtscp"
17971   [(match_operand:DI 0 "register_operand" "")
17972    (match_operand:SI 1 "memory_operand" "")]
17973   ""
17974 {
17975   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17976                                     gen_rtvec (1, const0_rtx),
17977                                     UNSPECV_RDTSCP);
17978   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17979                                     gen_rtvec (1, const0_rtx),
17980                                     UNSPECV_RDTSCP);
17981   rtx reg = gen_reg_rtx (DImode);
17982   rtx tmp = gen_reg_rtx (SImode);
17983
17984   if (TARGET_64BIT)
17985     {
17986       rtvec vec = rtvec_alloc (3);
17987       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17988       rtx upper = gen_reg_rtx (DImode);
17989       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17990       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17991       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17992       emit_insn (load);
17993       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17994                                    NULL, 1, OPTAB_DIRECT);
17995       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17996                                  OPTAB_DIRECT);
17997     }
17998   else
17999     {
18000       rtvec vec = rtvec_alloc (2);
18001       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18002       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18003       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18004       emit_insn (load);
18005     }
18006   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18007   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18008   DONE;
18009 })
18010
18011 (define_insn "*rdtscp"
18012   [(set (match_operand:DI 0 "register_operand" "=A")
18013         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18014    (set (match_operand:SI 1 "register_operand" "=c")
18015         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18016   "!TARGET_64BIT"
18017   "rdtscp"
18018   [(set_attr "type" "other")
18019    (set_attr "length" "3")])
18020
18021 (define_insn "*rdtscp_rex64"
18022   [(set (match_operand:DI 0 "register_operand" "=a")
18023         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18024    (set (match_operand:DI 1 "register_operand" "=d")
18025         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18026    (set (match_operand:SI 2 "register_operand" "=c")
18027         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18028   "TARGET_64BIT"
18029   "rdtscp"
18030   [(set_attr "type" "other")
18031    (set_attr "length" "3")])
18032
18033 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18034 ;;
18035 ;; LWP instructions
18036 ;;
18037 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18038
18039 (define_expand "lwp_llwpcb"
18040   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18041                     UNSPECV_LLWP_INTRINSIC)]
18042   "TARGET_LWP")
18043
18044 (define_insn "*lwp_llwpcb<mode>1"
18045   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18046                     UNSPECV_LLWP_INTRINSIC)]
18047   "TARGET_LWP"
18048   "llwpcb\t%0"
18049   [(set_attr "type" "lwp")
18050    (set_attr "mode" "<MODE>")
18051    (set_attr "length" "5")])
18052
18053 (define_expand "lwp_slwpcb"
18054   [(set (match_operand 0 "register_operand" "=r")
18055         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18056   "TARGET_LWP"
18057 {
18058   rtx (*insn)(rtx);
18059
18060   insn = (TARGET_64BIT
18061           ? gen_lwp_slwpcbdi
18062           : gen_lwp_slwpcbsi);
18063
18064   emit_insn (insn (operands[0]));
18065   DONE;
18066 })
18067
18068 (define_insn "lwp_slwpcb<mode>"
18069   [(set (match_operand:P 0 "register_operand" "=r")
18070         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18071   "TARGET_LWP"
18072   "slwpcb\t%0"
18073   [(set_attr "type" "lwp")
18074    (set_attr "mode" "<MODE>")
18075    (set_attr "length" "5")])
18076
18077 (define_expand "lwp_lwpval<mode>3"
18078   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18079                      (match_operand:SI 2 "nonimmediate_operand" "rm")
18080                      (match_operand:SI 3 "const_int_operand" "i")]
18081                     UNSPECV_LWPVAL_INTRINSIC)]
18082   "TARGET_LWP"
18083   ;; Avoid unused variable warning.
18084   "(void) operands[0];")
18085
18086 (define_insn "*lwp_lwpval<mode>3_1"
18087   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18088                      (match_operand:SI 1 "nonimmediate_operand" "rm")
18089                      (match_operand:SI 2 "const_int_operand" "i")]
18090                     UNSPECV_LWPVAL_INTRINSIC)]
18091   "TARGET_LWP"
18092   "lwpval\t{%2, %1, %0|%0, %1, %2}"
18093   [(set_attr "type" "lwp")
18094    (set_attr "mode" "<MODE>")
18095    (set (attr "length")
18096         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18097
18098 (define_expand "lwp_lwpins<mode>3"
18099   [(set (reg:CCC FLAGS_REG)
18100         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18101                               (match_operand:SI 2 "nonimmediate_operand" "rm")
18102                               (match_operand:SI 3 "const_int_operand" "i")]
18103                              UNSPECV_LWPINS_INTRINSIC))
18104    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18105         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18106   "TARGET_LWP")
18107
18108 (define_insn "*lwp_lwpins<mode>3_1"
18109   [(set (reg:CCC FLAGS_REG)
18110         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18111                               (match_operand:SI 1 "nonimmediate_operand" "rm")
18112                               (match_operand:SI 2 "const_int_operand" "i")]
18113                              UNSPECV_LWPINS_INTRINSIC))]
18114   "TARGET_LWP"
18115   "lwpins\t{%2, %1, %0|%0, %1, %2}"
18116   [(set_attr "type" "lwp")
18117    (set_attr "mode" "<MODE>")
18118    (set (attr "length")
18119         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18120
18121 (define_insn "rdfsbase<mode>"
18122   [(set (match_operand:SWI48 0 "register_operand" "=r")
18123         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18124   "TARGET_64BIT && TARGET_FSGSBASE"
18125   "rdfsbase %0"
18126   [(set_attr "type" "other")
18127    (set_attr "prefix_extra" "2")])
18128
18129 (define_insn "rdgsbase<mode>"
18130   [(set (match_operand:SWI48 0 "register_operand" "=r")
18131         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18132   "TARGET_64BIT && TARGET_FSGSBASE"
18133   "rdgsbase %0"
18134   [(set_attr "type" "other")
18135    (set_attr "prefix_extra" "2")])
18136
18137 (define_insn "wrfsbase<mode>"
18138   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18139                     UNSPECV_WRFSBASE)]
18140   "TARGET_64BIT && TARGET_FSGSBASE"
18141   "wrfsbase %0"
18142   [(set_attr "type" "other")
18143    (set_attr "prefix_extra" "2")])
18144
18145 (define_insn "wrgsbase<mode>"
18146   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18147                     UNSPECV_WRGSBASE)]
18148   "TARGET_64BIT && TARGET_FSGSBASE"
18149   "wrgsbase %0"
18150   [(set_attr "type" "other")
18151    (set_attr "prefix_extra" "2")])
18152
18153 (define_insn "rdrand<mode>_1"
18154   [(set (match_operand:SWI248 0 "register_operand" "=r")
18155         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18156    (set (reg:CCC FLAGS_REG)
18157         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18158   "TARGET_RDRND"
18159   "rdrand\t%0"
18160   [(set_attr "type" "other")
18161    (set_attr "prefix_extra" "1")])
18162
18163 (define_expand "pause"
18164   [(set (match_dup 0)
18165         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18166   ""
18167 {
18168   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18169   MEM_VOLATILE_P (operands[0]) = 1;
18170 })
18171
18172 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18173 ;; They have the same encoding.
18174 (define_insn "*pause"
18175   [(set (match_operand:BLK 0 "" "")
18176         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18177   ""
18178   "rep; nop"
18179   [(set_attr "length" "2")
18180    (set_attr "memory" "unknown")])
18181
18182 (include "mmx.md")
18183 (include "sse.md")
18184 (include "sync.md")