OSDN Git Service

c76cd6bac52c2566e468d98b9c4325c8bdfff290
[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   UNSPEC_STOS
113
114   ;; For SSE/MMX support:
115   UNSPEC_FIX_NOTRUNC
116   UNSPEC_MASKMOV
117   UNSPEC_MOVMSK
118   UNSPEC_RCP
119   UNSPEC_RSQRT
120   UNSPEC_PSADBW
121
122   ;; Generic math support
123   UNSPEC_COPYSIGN
124   UNSPEC_IEEE_MIN       ; not commutative
125   UNSPEC_IEEE_MAX       ; not commutative
126
127   ;; x87 Floating point
128   UNSPEC_SIN
129   UNSPEC_COS
130   UNSPEC_FPATAN
131   UNSPEC_FYL2X
132   UNSPEC_FYL2XP1
133   UNSPEC_FRNDINT
134   UNSPEC_FIST
135   UNSPEC_F2XM1
136   UNSPEC_TAN
137   UNSPEC_FXAM
138
139   ;; x87 Rounding
140   UNSPEC_FRNDINT_FLOOR
141   UNSPEC_FRNDINT_CEIL
142   UNSPEC_FRNDINT_TRUNC
143   UNSPEC_FRNDINT_MASK_PM
144   UNSPEC_FIST_FLOOR
145   UNSPEC_FIST_CEIL
146
147   ;; x87 Double output FP
148   UNSPEC_SINCOS_COS
149   UNSPEC_SINCOS_SIN
150   UNSPEC_XTRACT_FRACT
151   UNSPEC_XTRACT_EXP
152   UNSPEC_FSCALE_FRACT
153   UNSPEC_FSCALE_EXP
154   UNSPEC_FPREM_F
155   UNSPEC_FPREM_U
156   UNSPEC_FPREM1_F
157   UNSPEC_FPREM1_U
158
159   UNSPEC_C2_FLAG
160   UNSPEC_FXAM_MEM
161
162   ;; SSP patterns
163   UNSPEC_SP_SET
164   UNSPEC_SP_TEST
165   UNSPEC_SP_TLS_SET
166   UNSPEC_SP_TLS_TEST
167
168   ;; For ROUND support
169   UNSPEC_ROUND
170
171   ;; For CRC32 support
172   UNSPEC_CRC32
173
174   ;; For BMI support
175   UNSPEC_BEXTR
176
177   ;; For BMI2 support
178   UNSPEC_PDEP
179   UNSPEC_PEXT
180 ])
181
182 (define_c_enum "unspecv" [
183   UNSPECV_BLOCKAGE
184   UNSPECV_STACK_PROBE
185   UNSPECV_PROBE_STACK_RANGE
186   UNSPECV_ALIGN
187   UNSPECV_PROLOGUE_USE
188   UNSPECV_SPLIT_STACK_RETURN
189   UNSPECV_CLD
190   UNSPECV_NOPS
191   UNSPECV_RDTSC
192   UNSPECV_RDTSCP
193   UNSPECV_RDPMC
194   UNSPECV_LLWP_INTRINSIC
195   UNSPECV_SLWP_INTRINSIC
196   UNSPECV_LWPVAL_INTRINSIC
197   UNSPECV_LWPINS_INTRINSIC
198   UNSPECV_RDFSBASE
199   UNSPECV_RDGSBASE
200   UNSPECV_WRFSBASE
201   UNSPECV_WRGSBASE
202
203   ;; For RDRAND support
204   UNSPECV_RDRAND
205 ])
206
207 ;; Constants to represent rounding modes in the ROUND instruction
208 (define_constants
209   [(ROUND_FLOOR                 0x1)
210    (ROUND_CEIL                  0x2)
211    (ROUND_TRUNC                 0x3)
212    (ROUND_MXCSR                 0x4)
213    (ROUND_NO_EXC                0x8)
214   ])
215
216 ;; Constants to represent pcomtrue/pcomfalse variants
217 (define_constants
218   [(PCOM_FALSE                  0)
219    (PCOM_TRUE                   1)
220    (COM_FALSE_S                 2)
221    (COM_FALSE_P                 3)
222    (COM_TRUE_S                  4)
223    (COM_TRUE_P                  5)
224   ])
225
226 ;; Constants used in the XOP pperm instruction
227 (define_constants
228   [(PPERM_SRC                   0x00)   /* copy source */
229    (PPERM_INVERT                0x20)   /* invert source */
230    (PPERM_REVERSE               0x40)   /* bit reverse source */
231    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
232    (PPERM_ZERO                  0x80)   /* all 0's */
233    (PPERM_ONES                  0xa0)   /* all 1's */
234    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
235    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
236    (PPERM_SRC1                  0x00)   /* use first source byte */
237    (PPERM_SRC2                  0x10)   /* use second source byte */
238    ])
239
240 ;; Registers by name.
241 (define_constants
242   [(AX_REG                       0)
243    (DX_REG                       1)
244    (CX_REG                       2)
245    (BX_REG                       3)
246    (SI_REG                       4)
247    (DI_REG                       5)
248    (BP_REG                       6)
249    (SP_REG                       7)
250    (ST0_REG                      8)
251    (ST1_REG                      9)
252    (ST2_REG                     10)
253    (ST3_REG                     11)
254    (ST4_REG                     12)
255    (ST5_REG                     13)
256    (ST6_REG                     14)
257    (ST7_REG                     15)
258    (FLAGS_REG                   17)
259    (FPSR_REG                    18)
260    (FPCR_REG                    19)
261    (XMM0_REG                    21)
262    (XMM1_REG                    22)
263    (XMM2_REG                    23)
264    (XMM3_REG                    24)
265    (XMM4_REG                    25)
266    (XMM5_REG                    26)
267    (XMM6_REG                    27)
268    (XMM7_REG                    28)
269    (MM0_REG                     29)
270    (MM1_REG                     30)
271    (MM2_REG                     31)
272    (MM3_REG                     32)
273    (MM4_REG                     33)
274    (MM5_REG                     34)
275    (MM6_REG                     35)
276    (MM7_REG                     36)
277    (R8_REG                      37)
278    (R9_REG                      38)
279    (R10_REG                     39)
280    (R11_REG                     40)
281    (R12_REG                     41)
282    (R13_REG                     42)
283    (XMM8_REG                    45)
284    (XMM9_REG                    46)
285    (XMM10_REG                   47)
286    (XMM11_REG                   48)
287    (XMM12_REG                   49)
288    (XMM13_REG                   50)
289    (XMM14_REG                   51)
290    (XMM15_REG                   52)
291   ])
292
293 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
294 ;; from i386.c.
295
296 ;; In C guard expressions, put expressions which may be compile-time
297 ;; constants first.  This allows for better optimization.  For
298 ;; example, write "TARGET_64BIT && reload_completed", not
299 ;; "reload_completed && TARGET_64BIT".
300
301 \f
302 ;; Processor type.
303 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
304                     atom,generic64,amdfam10,bdver1,bdver2,btver1"
305   (const (symbol_ref "ix86_schedule")))
306
307 ;; A basic instruction type.  Refinements due to arguments to be
308 ;; provided in other attributes.
309 (define_attr "type"
310   "other,multi,
311    alu,alu1,negnot,imov,imovx,lea,
312    incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
313    icmp,test,ibr,setcc,icmov,
314    push,pop,call,callv,leave,
315    str,bitmanip,
316    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
317    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
318    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
319    ssemuladd,sse4arg,lwp,
320    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
321   (const_string "other"))
322
323 ;; Main data type used by the insn
324 (define_attr "mode"
325   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
326   (const_string "unknown"))
327
328 ;; The CPU unit operations uses.
329 (define_attr "unit" "integer,i387,sse,mmx,unknown"
330   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
331            (const_string "i387")
332          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
333                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
334                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
335            (const_string "sse")
336          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
337            (const_string "mmx")
338          (eq_attr "type" "other")
339            (const_string "unknown")]
340          (const_string "integer")))
341
342 ;; The (bounding maximum) length of an instruction immediate.
343 (define_attr "length_immediate" ""
344   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
345                           bitmanip,imulx")
346            (const_int 0)
347          (eq_attr "unit" "i387,sse,mmx")
348            (const_int 0)
349          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
350                           rotate,rotatex,rotate1,imul,icmp,push,pop")
351            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
352          (eq_attr "type" "imov,test")
353            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
354          (eq_attr "type" "call")
355            (if_then_else (match_operand 0 "constant_call_address_operand" "")
356              (const_int 4)
357              (const_int 0))
358          (eq_attr "type" "callv")
359            (if_then_else (match_operand 1 "constant_call_address_operand" "")
360              (const_int 4)
361              (const_int 0))
362          ;; We don't know the size before shorten_branches.  Expect
363          ;; the instruction to fit for better scheduling.
364          (eq_attr "type" "ibr")
365            (const_int 1)
366          ]
367          (symbol_ref "/* Update immediate_length and other attributes! */
368                       gcc_unreachable (),1")))
369
370 ;; The (bounding maximum) length of an instruction address.
371 (define_attr "length_address" ""
372   (cond [(eq_attr "type" "str,other,multi,fxch")
373            (const_int 0)
374          (and (eq_attr "type" "call")
375               (match_operand 0 "constant_call_address_operand" ""))
376              (const_int 0)
377          (and (eq_attr "type" "callv")
378               (match_operand 1 "constant_call_address_operand" ""))
379              (const_int 0)
380          ]
381          (symbol_ref "ix86_attr_length_address_default (insn)")))
382
383 ;; Set when length prefix is used.
384 (define_attr "prefix_data16" ""
385   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
386            (const_int 0)
387          (eq_attr "mode" "HI")
388            (const_int 1)
389          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
390            (const_int 1)
391         ]
392         (const_int 0)))
393
394 ;; Set when string REP prefix is used.
395 (define_attr "prefix_rep" ""
396   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
397            (const_int 0)
398          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
399            (const_int 1)
400         ]
401         (const_int 0)))
402
403 ;; Set when 0f opcode prefix is used.
404 (define_attr "prefix_0f" ""
405   (if_then_else
406     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
407          (eq_attr "unit" "sse,mmx"))
408     (const_int 1)
409     (const_int 0)))
410
411 ;; Set when REX opcode prefix is used.
412 (define_attr "prefix_rex" ""
413   (cond [(not (match_test "TARGET_64BIT"))
414            (const_int 0)
415          (and (eq_attr "mode" "DI")
416               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
417                    (eq_attr "unit" "!mmx")))
418            (const_int 1)
419          (and (eq_attr "mode" "QI")
420               (match_test "x86_extended_QIreg_mentioned_p (insn)"))
421            (const_int 1)
422          (match_test "x86_extended_reg_mentioned_p (insn)")
423            (const_int 1)
424          (and (eq_attr "type" "imovx")
425               (match_operand:QI 1 "ext_QIreg_operand" ""))
426            (const_int 1)
427         ]
428         (const_int 0)))
429
430 ;; There are also additional prefixes in 3DNOW, SSSE3.
431 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
432 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
433 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
434 (define_attr "prefix_extra" ""
435   (cond [(eq_attr "type" "ssemuladd,sse4arg")
436            (const_int 2)
437          (eq_attr "type" "sseiadd1,ssecvt1")
438            (const_int 1)
439         ]
440         (const_int 0)))
441
442 ;; Prefix used: original, VEX or maybe VEX.
443 (define_attr "prefix" "orig,vex,maybe_vex"
444   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
445     (const_string "vex")
446     (const_string "orig")))
447
448 ;; VEX W bit is used.
449 (define_attr "prefix_vex_w" "" (const_int 0))
450
451 ;; The length of VEX prefix
452 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
453 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
454 ;; still prefix_0f 1, with prefix_extra 1.
455 (define_attr "length_vex" ""
456   (if_then_else (and (eq_attr "prefix_0f" "1")
457                      (eq_attr "prefix_extra" "0"))
458     (if_then_else (eq_attr "prefix_vex_w" "1")
459       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
460       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
461     (if_then_else (eq_attr "prefix_vex_w" "1")
462       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
463       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
464
465 ;; Set when modrm byte is used.
466 (define_attr "modrm" ""
467   (cond [(eq_attr "type" "str,leave")
468            (const_int 0)
469          (eq_attr "unit" "i387")
470            (const_int 0)
471          (and (eq_attr "type" "incdec")
472               (and (not (match_test "TARGET_64BIT"))
473                    (ior (match_operand:SI 1 "register_operand" "")
474                         (match_operand:HI 1 "register_operand" ""))))
475            (const_int 0)
476          (and (eq_attr "type" "push")
477               (not (match_operand 1 "memory_operand" "")))
478            (const_int 0)
479          (and (eq_attr "type" "pop")
480               (not (match_operand 0 "memory_operand" "")))
481            (const_int 0)
482          (and (eq_attr "type" "imov")
483               (and (not (eq_attr "mode" "DI"))
484                    (ior (and (match_operand 0 "register_operand" "")
485                              (match_operand 1 "immediate_operand" ""))
486                         (ior (and (match_operand 0 "ax_reg_operand" "")
487                                   (match_operand 1 "memory_displacement_only_operand" ""))
488                              (and (match_operand 0 "memory_displacement_only_operand" "")
489                                   (match_operand 1 "ax_reg_operand" ""))))))
490            (const_int 0)
491          (and (eq_attr "type" "call")
492               (match_operand 0 "constant_call_address_operand" ""))
493              (const_int 0)
494          (and (eq_attr "type" "callv")
495               (match_operand 1 "constant_call_address_operand" ""))
496              (const_int 0)
497          (and (eq_attr "type" "alu,alu1,icmp,test")
498               (match_operand 0 "ax_reg_operand" ""))
499              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
500          ]
501          (const_int 1)))
502
503 ;; The (bounding maximum) length of an instruction in bytes.
504 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
505 ;; Later we may want to split them and compute proper length as for
506 ;; other insns.
507 (define_attr "length" ""
508   (cond [(eq_attr "type" "other,multi,fistp,frndint")
509            (const_int 16)
510          (eq_attr "type" "fcmp")
511            (const_int 4)
512          (eq_attr "unit" "i387")
513            (plus (const_int 2)
514                  (plus (attr "prefix_data16")
515                        (attr "length_address")))
516          (ior (eq_attr "prefix" "vex")
517               (and (eq_attr "prefix" "maybe_vex")
518                    (match_test "TARGET_AVX")))
519            (plus (attr "length_vex")
520                  (plus (attr "length_immediate")
521                        (plus (attr "modrm")
522                              (attr "length_address"))))]
523          (plus (plus (attr "modrm")
524                      (plus (attr "prefix_0f")
525                            (plus (attr "prefix_rex")
526                                  (plus (attr "prefix_extra")
527                                        (const_int 1)))))
528                (plus (attr "prefix_rep")
529                      (plus (attr "prefix_data16")
530                            (plus (attr "length_immediate")
531                                  (attr "length_address")))))))
532
533 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
534 ;; `store' if there is a simple memory reference therein, or `unknown'
535 ;; if the instruction is complex.
536
537 (define_attr "memory" "none,load,store,both,unknown"
538   (cond [(eq_attr "type" "other,multi,str,lwp")
539            (const_string "unknown")
540          (eq_attr "type" "lea,fcmov,fpspc")
541            (const_string "none")
542          (eq_attr "type" "fistp,leave")
543            (const_string "both")
544          (eq_attr "type" "frndint")
545            (const_string "load")
546          (eq_attr "type" "push")
547            (if_then_else (match_operand 1 "memory_operand" "")
548              (const_string "both")
549              (const_string "store"))
550          (eq_attr "type" "pop")
551            (if_then_else (match_operand 0 "memory_operand" "")
552              (const_string "both")
553              (const_string "load"))
554          (eq_attr "type" "setcc")
555            (if_then_else (match_operand 0 "memory_operand" "")
556              (const_string "store")
557              (const_string "none"))
558          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
559            (if_then_else (ior (match_operand 0 "memory_operand" "")
560                               (match_operand 1 "memory_operand" ""))
561              (const_string "load")
562              (const_string "none"))
563          (eq_attr "type" "ibr")
564            (if_then_else (match_operand 0 "memory_operand" "")
565              (const_string "load")
566              (const_string "none"))
567          (eq_attr "type" "call")
568            (if_then_else (match_operand 0 "constant_call_address_operand" "")
569              (const_string "none")
570              (const_string "load"))
571          (eq_attr "type" "callv")
572            (if_then_else (match_operand 1 "constant_call_address_operand" "")
573              (const_string "none")
574              (const_string "load"))
575          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
576               (match_operand 1 "memory_operand" ""))
577            (const_string "both")
578          (and (match_operand 0 "memory_operand" "")
579               (match_operand 1 "memory_operand" ""))
580            (const_string "both")
581          (match_operand 0 "memory_operand" "")
582            (const_string "store")
583          (match_operand 1 "memory_operand" "")
584            (const_string "load")
585          (and (eq_attr "type"
586                  "!alu1,negnot,ishift1,
587                    imov,imovx,icmp,test,bitmanip,
588                    fmov,fcmp,fsgn,
589                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
590                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
591               (match_operand 2 "memory_operand" ""))
592            (const_string "load")
593          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
594               (match_operand 3 "memory_operand" ""))
595            (const_string "load")
596         ]
597         (const_string "none")))
598
599 ;; Indicates if an instruction has both an immediate and a displacement.
600
601 (define_attr "imm_disp" "false,true,unknown"
602   (cond [(eq_attr "type" "other,multi")
603            (const_string "unknown")
604          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
605               (and (match_operand 0 "memory_displacement_operand" "")
606                    (match_operand 1 "immediate_operand" "")))
607            (const_string "true")
608          (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
609               (and (match_operand 0 "memory_displacement_operand" "")
610                    (match_operand 2 "immediate_operand" "")))
611            (const_string "true")
612         ]
613         (const_string "false")))
614
615 ;; Indicates if an FP operation has an integer source.
616
617 (define_attr "fp_int_src" "false,true"
618   (const_string "false"))
619
620 ;; Defines rounding mode of an FP operation.
621
622 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
623   (const_string "any"))
624
625 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
626 (define_attr "use_carry" "0,1" (const_string "0"))
627
628 ;; Define attribute to indicate unaligned ssemov insns
629 (define_attr "movu" "0,1" (const_string "0"))
630
631 ;; Used to control the "enabled" attribute on a per-instruction basis.
632 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,
633                     bmi2,fma4,fma"
634   (const_string "base"))
635
636 (define_attr "enabled" ""
637   (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
638          (eq_attr "isa" "sse2_noavx")
639            (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
640          (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
641          (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
642          (eq_attr "isa" "sse4_noavx")
643            (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
644          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
645          (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
646          (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
647          (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
648          (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
649         ]
650         (const_int 1)))
651
652 ;; Describe a user's asm statement.
653 (define_asm_attributes
654   [(set_attr "length" "128")
655    (set_attr "type" "multi")])
656
657 (define_code_iterator plusminus [plus minus])
658
659 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
660
661 ;; Base name for define_insn
662 (define_code_attr plusminus_insn
663   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
664    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
665
666 ;; Base name for insn mnemonic.
667 (define_code_attr plusminus_mnemonic
668   [(plus "add") (ss_plus "adds") (us_plus "addus")
669    (minus "sub") (ss_minus "subs") (us_minus "subus")])
670 (define_code_attr plusminus_carry_mnemonic
671   [(plus "adc") (minus "sbb")])
672
673 ;; Mark commutative operators as such in constraints.
674 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
675                         (minus "") (ss_minus "") (us_minus "")])
676
677 ;; Mapping of max and min
678 (define_code_iterator maxmin [smax smin umax umin])
679
680 ;; Mapping of signed max and min
681 (define_code_iterator smaxmin [smax smin])
682
683 ;; Mapping of unsigned max and min
684 (define_code_iterator umaxmin [umax umin])
685
686 ;; Base name for integer and FP insn mnemonic
687 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
688                               (umax "maxu") (umin "minu")])
689 (define_code_attr maxmin_float [(smax "max") (smin "min")])
690
691 ;; Mapping of logic operators
692 (define_code_iterator any_logic [and ior xor])
693 (define_code_iterator any_or [ior xor])
694
695 ;; Base name for insn mnemonic.
696 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
697
698 ;; Mapping of logic-shift operators
699 (define_code_iterator any_lshift [ashift lshiftrt])
700
701 ;; Mapping of shift-right operators
702 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
703
704 ;; Base name for define_insn
705 (define_code_attr shift_insn
706   [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
707
708 ;; Base name for insn mnemonic.
709 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
710 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
711
712 ;; Mapping of rotate operators
713 (define_code_iterator any_rotate [rotate rotatert])
714
715 ;; Base name for define_insn
716 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
717
718 ;; Base name for insn mnemonic.
719 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
720
721 ;; Mapping of abs neg operators
722 (define_code_iterator absneg [abs neg])
723
724 ;; Base name for x87 insn mnemonic.
725 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
726
727 ;; Used in signed and unsigned widening multiplications.
728 (define_code_iterator any_extend [sign_extend zero_extend])
729
730 ;; Prefix for insn menmonic.
731 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
732
733 ;; Prefix for define_insn
734 (define_code_attr u [(sign_extend "") (zero_extend "u")])
735 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
736
737 ;; All integer modes.
738 (define_mode_iterator SWI1248x [QI HI SI DI])
739
740 ;; All integer modes without QImode.
741 (define_mode_iterator SWI248x [HI SI DI])
742
743 ;; All integer modes without QImode and HImode.
744 (define_mode_iterator SWI48x [SI DI])
745
746 ;; All integer modes without SImode and DImode.
747 (define_mode_iterator SWI12 [QI HI])
748
749 ;; All integer modes without DImode.
750 (define_mode_iterator SWI124 [QI HI SI])
751
752 ;; All integer modes without QImode and DImode.
753 (define_mode_iterator SWI24 [HI SI])
754
755 ;; Single word integer modes.
756 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
757
758 ;; Single word integer modes without QImode.
759 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
760
761 ;; Single word integer modes without QImode and HImode.
762 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
763
764 ;; All math-dependant single and double word integer modes.
765 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
766                              (HI "TARGET_HIMODE_MATH")
767                              SI DI (TI "TARGET_64BIT")])
768
769 ;; Math-dependant single word integer modes.
770 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
771                             (HI "TARGET_HIMODE_MATH")
772                             SI (DI "TARGET_64BIT")])
773
774 ;; Math-dependant integer modes without DImode.
775 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
776                                (HI "TARGET_HIMODE_MATH")
777                                SI])
778
779 ;; Math-dependant single word integer modes without QImode.
780 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
781                                SI (DI "TARGET_64BIT")])
782
783 ;; Double word integer modes.
784 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
785                            (TI "TARGET_64BIT")])
786
787 ;; Double word integer modes as mode attribute.
788 (define_mode_attr DWI [(SI "DI") (DI "TI")])
789 (define_mode_attr dwi [(SI "di") (DI "ti")])
790
791 ;; Half mode for double word integer modes.
792 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
793                             (DI "TARGET_64BIT")])
794
795 ;; Instruction suffix for integer modes.
796 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
797
798 ;; Pointer size prefix for integer modes (Intel asm dialect)
799 (define_mode_attr iptrsize [(QI "BYTE")
800                             (HI "WORD")
801                             (SI "DWORD")
802                             (DI "QWORD")])
803
804 ;; Register class for integer modes.
805 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
806
807 ;; Immediate operand constraint for integer modes.
808 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
809
810 ;; General operand constraint for word modes.
811 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
812
813 ;; Immediate operand constraint for double integer modes.
814 (define_mode_attr di [(SI "nF") (DI "e")])
815
816 ;; Immediate operand constraint for shifts.
817 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
818
819 ;; General operand predicate for integer modes.
820 (define_mode_attr general_operand
821         [(QI "general_operand")
822          (HI "general_operand")
823          (SI "x86_64_general_operand")
824          (DI "x86_64_general_operand")
825          (TI "x86_64_general_operand")])
826
827 ;; General sign/zero extend operand predicate for integer modes.
828 (define_mode_attr general_szext_operand
829         [(QI "general_operand")
830          (HI "general_operand")
831          (SI "x86_64_szext_general_operand")
832          (DI "x86_64_szext_general_operand")])
833
834 ;; Immediate operand predicate for integer modes.
835 (define_mode_attr immediate_operand
836         [(QI "immediate_operand")
837          (HI "immediate_operand")
838          (SI "x86_64_immediate_operand")
839          (DI "x86_64_immediate_operand")])
840
841 ;; Nonmemory operand predicate for integer modes.
842 (define_mode_attr nonmemory_operand
843         [(QI "nonmemory_operand")
844          (HI "nonmemory_operand")
845          (SI "x86_64_nonmemory_operand")
846          (DI "x86_64_nonmemory_operand")])
847
848 ;; Operand predicate for shifts.
849 (define_mode_attr shift_operand
850         [(QI "nonimmediate_operand")
851          (HI "nonimmediate_operand")
852          (SI "nonimmediate_operand")
853          (DI "shiftdi_operand")
854          (TI "register_operand")])
855
856 ;; Operand predicate for shift argument.
857 (define_mode_attr shift_immediate_operand
858         [(QI "const_1_to_31_operand")
859          (HI "const_1_to_31_operand")
860          (SI "const_1_to_31_operand")
861          (DI "const_1_to_63_operand")])
862
863 ;; Input operand predicate for arithmetic left shifts.
864 (define_mode_attr ashl_input_operand
865         [(QI "nonimmediate_operand")
866          (HI "nonimmediate_operand")
867          (SI "nonimmediate_operand")
868          (DI "ashldi_input_operand")
869          (TI "reg_or_pm1_operand")])
870
871 ;; SSE and x87 SFmode and DFmode floating point modes
872 (define_mode_iterator MODEF [SF DF])
873
874 ;; All x87 floating point modes
875 (define_mode_iterator X87MODEF [SF DF XF])
876
877 ;; SSE instruction suffix for various modes
878 (define_mode_attr ssemodesuffix
879   [(SF "ss") (DF "sd")
880    (V8SF "ps") (V4DF "pd")
881    (V4SF "ps") (V2DF "pd")
882    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
883    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
884
885 ;; SSE vector suffix for floating point modes
886 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
887
888 ;; SSE vector mode corresponding to a scalar mode
889 (define_mode_attr ssevecmode
890   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
891
892 ;; Instruction suffix for REX 64bit operators.
893 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
894
895 ;; This mode iterator allows :P to be used for patterns that operate on
896 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
897 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
898
899 ;; This mode iterator allows :PTR to be used for patterns that operate on
900 ;; ptr_mode sized quantities.
901 (define_mode_iterator PTR
902   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
903 \f
904 ;; Scheduling descriptions
905
906 (include "pentium.md")
907 (include "ppro.md")
908 (include "k6.md")
909 (include "athlon.md")
910 (include "bdver1.md")
911 (include "geode.md")
912 (include "atom.md")
913 (include "core2.md")
914
915 \f
916 ;; Operand and operator predicates and constraints
917
918 (include "predicates.md")
919 (include "constraints.md")
920
921 \f
922 ;; Compare and branch/compare and store instructions.
923
924 (define_expand "cbranch<mode>4"
925   [(set (reg:CC FLAGS_REG)
926         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
927                     (match_operand:SDWIM 2 "<general_operand>" "")))
928    (set (pc) (if_then_else
929                (match_operator 0 "ordered_comparison_operator"
930                 [(reg:CC FLAGS_REG) (const_int 0)])
931                (label_ref (match_operand 3 "" ""))
932                (pc)))]
933   ""
934 {
935   if (MEM_P (operands[1]) && MEM_P (operands[2]))
936     operands[1] = force_reg (<MODE>mode, operands[1]);
937   ix86_expand_branch (GET_CODE (operands[0]),
938                       operands[1], operands[2], operands[3]);
939   DONE;
940 })
941
942 (define_expand "cstore<mode>4"
943   [(set (reg:CC FLAGS_REG)
944         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
945                     (match_operand:SWIM 3 "<general_operand>" "")))
946    (set (match_operand:QI 0 "register_operand" "")
947         (match_operator 1 "ordered_comparison_operator"
948           [(reg:CC FLAGS_REG) (const_int 0)]))]
949   ""
950 {
951   if (MEM_P (operands[2]) && MEM_P (operands[3]))
952     operands[2] = force_reg (<MODE>mode, operands[2]);
953   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
954                      operands[2], operands[3]);
955   DONE;
956 })
957
958 (define_expand "cmp<mode>_1"
959   [(set (reg:CC FLAGS_REG)
960         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
961                     (match_operand:SWI48 1 "<general_operand>" "")))])
962
963 (define_insn "*cmp<mode>_ccno_1"
964   [(set (reg FLAGS_REG)
965         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
966                  (match_operand:SWI 1 "const0_operand" "")))]
967   "ix86_match_ccmode (insn, CCNOmode)"
968   "@
969    test{<imodesuffix>}\t%0, %0
970    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
971   [(set_attr "type" "test,icmp")
972    (set_attr "length_immediate" "0,1")
973    (set_attr "mode" "<MODE>")])
974
975 (define_insn "*cmp<mode>_1"
976   [(set (reg FLAGS_REG)
977         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
978                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
979   "ix86_match_ccmode (insn, CCmode)"
980   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
981   [(set_attr "type" "icmp")
982    (set_attr "mode" "<MODE>")])
983
984 (define_insn "*cmp<mode>_minus_1"
985   [(set (reg FLAGS_REG)
986         (compare
987           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
988                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
989           (const_int 0)))]
990   "ix86_match_ccmode (insn, CCGOCmode)"
991   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
992   [(set_attr "type" "icmp")
993    (set_attr "mode" "<MODE>")])
994
995 (define_insn "*cmpqi_ext_1"
996   [(set (reg FLAGS_REG)
997         (compare
998           (match_operand:QI 0 "general_operand" "Qm")
999           (subreg:QI
1000             (zero_extract:SI
1001               (match_operand 1 "ext_register_operand" "Q")
1002               (const_int 8)
1003               (const_int 8)) 0)))]
1004   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1005   "cmp{b}\t{%h1, %0|%0, %h1}"
1006   [(set_attr "type" "icmp")
1007    (set_attr "mode" "QI")])
1008
1009 (define_insn "*cmpqi_ext_1_rex64"
1010   [(set (reg FLAGS_REG)
1011         (compare
1012           (match_operand:QI 0 "register_operand" "Q")
1013           (subreg:QI
1014             (zero_extract:SI
1015               (match_operand 1 "ext_register_operand" "Q")
1016               (const_int 8)
1017               (const_int 8)) 0)))]
1018   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1019   "cmp{b}\t{%h1, %0|%0, %h1}"
1020   [(set_attr "type" "icmp")
1021    (set_attr "mode" "QI")])
1022
1023 (define_insn "*cmpqi_ext_2"
1024   [(set (reg FLAGS_REG)
1025         (compare
1026           (subreg:QI
1027             (zero_extract:SI
1028               (match_operand 0 "ext_register_operand" "Q")
1029               (const_int 8)
1030               (const_int 8)) 0)
1031           (match_operand:QI 1 "const0_operand" "")))]
1032   "ix86_match_ccmode (insn, CCNOmode)"
1033   "test{b}\t%h0, %h0"
1034   [(set_attr "type" "test")
1035    (set_attr "length_immediate" "0")
1036    (set_attr "mode" "QI")])
1037
1038 (define_expand "cmpqi_ext_3"
1039   [(set (reg:CC FLAGS_REG)
1040         (compare:CC
1041           (subreg:QI
1042             (zero_extract:SI
1043               (match_operand 0 "ext_register_operand" "")
1044               (const_int 8)
1045               (const_int 8)) 0)
1046           (match_operand:QI 1 "immediate_operand" "")))])
1047
1048 (define_insn "*cmpqi_ext_3_insn"
1049   [(set (reg FLAGS_REG)
1050         (compare
1051           (subreg:QI
1052             (zero_extract:SI
1053               (match_operand 0 "ext_register_operand" "Q")
1054               (const_int 8)
1055               (const_int 8)) 0)
1056           (match_operand:QI 1 "general_operand" "Qmn")))]
1057   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1058   "cmp{b}\t{%1, %h0|%h0, %1}"
1059   [(set_attr "type" "icmp")
1060    (set_attr "modrm" "1")
1061    (set_attr "mode" "QI")])
1062
1063 (define_insn "*cmpqi_ext_3_insn_rex64"
1064   [(set (reg FLAGS_REG)
1065         (compare
1066           (subreg:QI
1067             (zero_extract:SI
1068               (match_operand 0 "ext_register_operand" "Q")
1069               (const_int 8)
1070               (const_int 8)) 0)
1071           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1072   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1073   "cmp{b}\t{%1, %h0|%h0, %1}"
1074   [(set_attr "type" "icmp")
1075    (set_attr "modrm" "1")
1076    (set_attr "mode" "QI")])
1077
1078 (define_insn "*cmpqi_ext_4"
1079   [(set (reg FLAGS_REG)
1080         (compare
1081           (subreg:QI
1082             (zero_extract:SI
1083               (match_operand 0 "ext_register_operand" "Q")
1084               (const_int 8)
1085               (const_int 8)) 0)
1086           (subreg:QI
1087             (zero_extract:SI
1088               (match_operand 1 "ext_register_operand" "Q")
1089               (const_int 8)
1090               (const_int 8)) 0)))]
1091   "ix86_match_ccmode (insn, CCmode)"
1092   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1093   [(set_attr "type" "icmp")
1094    (set_attr "mode" "QI")])
1095
1096 ;; These implement float point compares.
1097 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1098 ;; which would allow mix and match FP modes on the compares.  Which is what
1099 ;; the old patterns did, but with many more of them.
1100
1101 (define_expand "cbranchxf4"
1102   [(set (reg:CC FLAGS_REG)
1103         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1104                     (match_operand:XF 2 "nonmemory_operand" "")))
1105    (set (pc) (if_then_else
1106               (match_operator 0 "ix86_fp_comparison_operator"
1107                [(reg:CC FLAGS_REG)
1108                 (const_int 0)])
1109               (label_ref (match_operand 3 "" ""))
1110               (pc)))]
1111   "TARGET_80387"
1112 {
1113   ix86_expand_branch (GET_CODE (operands[0]),
1114                       operands[1], operands[2], operands[3]);
1115   DONE;
1116 })
1117
1118 (define_expand "cstorexf4"
1119   [(set (reg:CC FLAGS_REG)
1120         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1121                     (match_operand:XF 3 "nonmemory_operand" "")))
1122    (set (match_operand:QI 0 "register_operand" "")
1123               (match_operator 1 "ix86_fp_comparison_operator"
1124                [(reg:CC FLAGS_REG)
1125                 (const_int 0)]))]
1126   "TARGET_80387"
1127 {
1128   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1129                      operands[2], operands[3]);
1130   DONE;
1131 })
1132
1133 (define_expand "cbranch<mode>4"
1134   [(set (reg:CC FLAGS_REG)
1135         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1136                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1137    (set (pc) (if_then_else
1138               (match_operator 0 "ix86_fp_comparison_operator"
1139                [(reg:CC FLAGS_REG)
1140                 (const_int 0)])
1141               (label_ref (match_operand 3 "" ""))
1142               (pc)))]
1143   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1144 {
1145   ix86_expand_branch (GET_CODE (operands[0]),
1146                       operands[1], operands[2], operands[3]);
1147   DONE;
1148 })
1149
1150 (define_expand "cstore<mode>4"
1151   [(set (reg:CC FLAGS_REG)
1152         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1153                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1154    (set (match_operand:QI 0 "register_operand" "")
1155               (match_operator 1 "ix86_fp_comparison_operator"
1156                [(reg:CC FLAGS_REG)
1157                 (const_int 0)]))]
1158   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1159 {
1160   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1161                      operands[2], operands[3]);
1162   DONE;
1163 })
1164
1165 (define_expand "cbranchcc4"
1166   [(set (pc) (if_then_else
1167               (match_operator 0 "comparison_operator"
1168                [(match_operand 1 "flags_reg_operand" "")
1169                 (match_operand 2 "const0_operand" "")])
1170               (label_ref (match_operand 3 "" ""))
1171               (pc)))]
1172   ""
1173 {
1174   ix86_expand_branch (GET_CODE (operands[0]),
1175                       operands[1], operands[2], operands[3]);
1176   DONE;
1177 })
1178
1179 (define_expand "cstorecc4"
1180   [(set (match_operand:QI 0 "register_operand" "")
1181               (match_operator 1 "comparison_operator"
1182                [(match_operand 2 "flags_reg_operand" "")
1183                 (match_operand 3 "const0_operand" "")]))]
1184   ""
1185 {
1186   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1187                      operands[2], operands[3]);
1188   DONE;
1189 })
1190
1191
1192 ;; FP compares, step 1:
1193 ;; Set the FP condition codes.
1194 ;;
1195 ;; CCFPmode     compare with exceptions
1196 ;; CCFPUmode    compare with no exceptions
1197
1198 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1199 ;; used to manage the reg stack popping would not be preserved.
1200
1201 (define_insn "*cmpfp_0"
1202   [(set (match_operand:HI 0 "register_operand" "=a")
1203         (unspec:HI
1204           [(compare:CCFP
1205              (match_operand 1 "register_operand" "f")
1206              (match_operand 2 "const0_operand" ""))]
1207         UNSPEC_FNSTSW))]
1208   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1209    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1210   "* return output_fp_compare (insn, operands, false, false);"
1211   [(set_attr "type" "multi")
1212    (set_attr "unit" "i387")
1213    (set (attr "mode")
1214      (cond [(match_operand:SF 1 "" "")
1215               (const_string "SF")
1216             (match_operand:DF 1 "" "")
1217               (const_string "DF")
1218            ]
1219            (const_string "XF")))])
1220
1221 (define_insn_and_split "*cmpfp_0_cc"
1222   [(set (reg:CCFP FLAGS_REG)
1223         (compare:CCFP
1224           (match_operand 1 "register_operand" "f")
1225           (match_operand 2 "const0_operand" "")))
1226    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1227   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1228    && TARGET_SAHF && !TARGET_CMOVE
1229    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1230   "#"
1231   "&& reload_completed"
1232   [(set (match_dup 0)
1233         (unspec:HI
1234           [(compare:CCFP (match_dup 1)(match_dup 2))]
1235         UNSPEC_FNSTSW))
1236    (set (reg:CC FLAGS_REG)
1237         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1238   ""
1239   [(set_attr "type" "multi")
1240    (set_attr "unit" "i387")
1241    (set (attr "mode")
1242      (cond [(match_operand:SF 1 "" "")
1243               (const_string "SF")
1244             (match_operand:DF 1 "" "")
1245               (const_string "DF")
1246            ]
1247            (const_string "XF")))])
1248
1249 (define_insn "*cmpfp_xf"
1250   [(set (match_operand:HI 0 "register_operand" "=a")
1251         (unspec:HI
1252           [(compare:CCFP
1253              (match_operand:XF 1 "register_operand" "f")
1254              (match_operand:XF 2 "register_operand" "f"))]
1255           UNSPEC_FNSTSW))]
1256   "TARGET_80387"
1257   "* return output_fp_compare (insn, operands, false, false);"
1258   [(set_attr "type" "multi")
1259    (set_attr "unit" "i387")
1260    (set_attr "mode" "XF")])
1261
1262 (define_insn_and_split "*cmpfp_xf_cc"
1263   [(set (reg:CCFP FLAGS_REG)
1264         (compare:CCFP
1265           (match_operand:XF 1 "register_operand" "f")
1266           (match_operand:XF 2 "register_operand" "f")))
1267    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1268   "TARGET_80387
1269    && TARGET_SAHF && !TARGET_CMOVE"
1270   "#"
1271   "&& reload_completed"
1272   [(set (match_dup 0)
1273         (unspec:HI
1274           [(compare:CCFP (match_dup 1)(match_dup 2))]
1275         UNSPEC_FNSTSW))
1276    (set (reg:CC FLAGS_REG)
1277         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1278   ""
1279   [(set_attr "type" "multi")
1280    (set_attr "unit" "i387")
1281    (set_attr "mode" "XF")])
1282
1283 (define_insn "*cmpfp_<mode>"
1284   [(set (match_operand:HI 0 "register_operand" "=a")
1285         (unspec:HI
1286           [(compare:CCFP
1287              (match_operand:MODEF 1 "register_operand" "f")
1288              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1289           UNSPEC_FNSTSW))]
1290   "TARGET_80387"
1291   "* return output_fp_compare (insn, operands, false, false);"
1292   [(set_attr "type" "multi")
1293    (set_attr "unit" "i387")
1294    (set_attr "mode" "<MODE>")])
1295
1296 (define_insn_and_split "*cmpfp_<mode>_cc"
1297   [(set (reg:CCFP FLAGS_REG)
1298         (compare:CCFP
1299           (match_operand:MODEF 1 "register_operand" "f")
1300           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1301    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1302   "TARGET_80387
1303    && TARGET_SAHF && !TARGET_CMOVE"
1304   "#"
1305   "&& reload_completed"
1306   [(set (match_dup 0)
1307         (unspec:HI
1308           [(compare:CCFP (match_dup 1)(match_dup 2))]
1309         UNSPEC_FNSTSW))
1310    (set (reg:CC FLAGS_REG)
1311         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1312   ""
1313   [(set_attr "type" "multi")
1314    (set_attr "unit" "i387")
1315    (set_attr "mode" "<MODE>")])
1316
1317 (define_insn "*cmpfp_u"
1318   [(set (match_operand:HI 0 "register_operand" "=a")
1319         (unspec:HI
1320           [(compare:CCFPU
1321              (match_operand 1 "register_operand" "f")
1322              (match_operand 2 "register_operand" "f"))]
1323           UNSPEC_FNSTSW))]
1324   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1325    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1326   "* return output_fp_compare (insn, operands, false, true);"
1327   [(set_attr "type" "multi")
1328    (set_attr "unit" "i387")
1329    (set (attr "mode")
1330      (cond [(match_operand:SF 1 "" "")
1331               (const_string "SF")
1332             (match_operand:DF 1 "" "")
1333               (const_string "DF")
1334            ]
1335            (const_string "XF")))])
1336
1337 (define_insn_and_split "*cmpfp_u_cc"
1338   [(set (reg:CCFPU FLAGS_REG)
1339         (compare:CCFPU
1340           (match_operand 1 "register_operand" "f")
1341           (match_operand 2 "register_operand" "f")))
1342    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1343   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1344    && TARGET_SAHF && !TARGET_CMOVE
1345    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1346   "#"
1347   "&& reload_completed"
1348   [(set (match_dup 0)
1349         (unspec:HI
1350           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1351         UNSPEC_FNSTSW))
1352    (set (reg:CC FLAGS_REG)
1353         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1354   ""
1355   [(set_attr "type" "multi")
1356    (set_attr "unit" "i387")
1357    (set (attr "mode")
1358      (cond [(match_operand:SF 1 "" "")
1359               (const_string "SF")
1360             (match_operand:DF 1 "" "")
1361               (const_string "DF")
1362            ]
1363            (const_string "XF")))])
1364
1365 (define_insn "*cmpfp_<mode>"
1366   [(set (match_operand:HI 0 "register_operand" "=a")
1367         (unspec:HI
1368           [(compare:CCFP
1369              (match_operand 1 "register_operand" "f")
1370              (match_operator 3 "float_operator"
1371                [(match_operand:SWI24 2 "memory_operand" "m")]))]
1372           UNSPEC_FNSTSW))]
1373   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1374    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1375    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1376   "* return output_fp_compare (insn, operands, false, false);"
1377   [(set_attr "type" "multi")
1378    (set_attr "unit" "i387")
1379    (set_attr "fp_int_src" "true")
1380    (set_attr "mode" "<MODE>")])
1381
1382 (define_insn_and_split "*cmpfp_<mode>_cc"
1383   [(set (reg:CCFP FLAGS_REG)
1384         (compare:CCFP
1385           (match_operand 1 "register_operand" "f")
1386           (match_operator 3 "float_operator"
1387             [(match_operand:SWI24 2 "memory_operand" "m")])))
1388    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1389   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1390    && TARGET_SAHF && !TARGET_CMOVE
1391    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1392    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1393   "#"
1394   "&& reload_completed"
1395   [(set (match_dup 0)
1396         (unspec:HI
1397           [(compare:CCFP
1398              (match_dup 1)
1399              (match_op_dup 3 [(match_dup 2)]))]
1400         UNSPEC_FNSTSW))
1401    (set (reg:CC FLAGS_REG)
1402         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1403   ""
1404   [(set_attr "type" "multi")
1405    (set_attr "unit" "i387")
1406    (set_attr "fp_int_src" "true")
1407    (set_attr "mode" "<MODE>")])
1408
1409 ;; FP compares, step 2
1410 ;; Move the fpsw to ax.
1411
1412 (define_insn "x86_fnstsw_1"
1413   [(set (match_operand:HI 0 "register_operand" "=a")
1414         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1415   "TARGET_80387"
1416   "fnstsw\t%0"
1417   [(set (attr "length")
1418         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1419    (set_attr "mode" "SI")
1420    (set_attr "unit" "i387")])
1421
1422 ;; FP compares, step 3
1423 ;; Get ax into flags, general case.
1424
1425 (define_insn "x86_sahf_1"
1426   [(set (reg:CC FLAGS_REG)
1427         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1428                    UNSPEC_SAHF))]
1429   "TARGET_SAHF"
1430 {
1431 #ifndef HAVE_AS_IX86_SAHF
1432   if (TARGET_64BIT)
1433     return ASM_BYTE "0x9e";
1434   else
1435 #endif
1436   return "sahf";
1437 }
1438   [(set_attr "length" "1")
1439    (set_attr "athlon_decode" "vector")
1440    (set_attr "amdfam10_decode" "direct")
1441    (set_attr "bdver1_decode" "direct")
1442    (set_attr "mode" "SI")])
1443
1444 ;; Pentium Pro can do steps 1 through 3 in one go.
1445 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1446 ;; (these i387 instructions set flags directly)
1447 (define_insn "*cmpfp_i_mixed"
1448   [(set (reg:CCFP FLAGS_REG)
1449         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1450                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1451   "TARGET_MIX_SSE_I387
1452    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1453    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1454   "* return output_fp_compare (insn, operands, true, false);"
1455   [(set_attr "type" "fcmp,ssecomi")
1456    (set_attr "prefix" "orig,maybe_vex")
1457    (set (attr "mode")
1458      (if_then_else (match_operand:SF 1 "" "")
1459         (const_string "SF")
1460         (const_string "DF")))
1461    (set (attr "prefix_rep")
1462         (if_then_else (eq_attr "type" "ssecomi")
1463                       (const_string "0")
1464                       (const_string "*")))
1465    (set (attr "prefix_data16")
1466         (cond [(eq_attr "type" "fcmp")
1467                  (const_string "*")
1468                (eq_attr "mode" "DF")
1469                  (const_string "1")
1470               ]
1471               (const_string "0")))
1472    (set_attr "athlon_decode" "vector")
1473    (set_attr "amdfam10_decode" "direct")
1474    (set_attr "bdver1_decode" "double")])
1475
1476 (define_insn "*cmpfp_i_sse"
1477   [(set (reg:CCFP FLAGS_REG)
1478         (compare:CCFP (match_operand 0 "register_operand" "x")
1479                       (match_operand 1 "nonimmediate_operand" "xm")))]
1480   "TARGET_SSE_MATH
1481    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1482    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1483   "* return output_fp_compare (insn, operands, true, false);"
1484   [(set_attr "type" "ssecomi")
1485    (set_attr "prefix" "maybe_vex")
1486    (set (attr "mode")
1487      (if_then_else (match_operand:SF 1 "" "")
1488         (const_string "SF")
1489         (const_string "DF")))
1490    (set_attr "prefix_rep" "0")
1491    (set (attr "prefix_data16")
1492         (if_then_else (eq_attr "mode" "DF")
1493                       (const_string "1")
1494                       (const_string "0")))
1495    (set_attr "athlon_decode" "vector")
1496    (set_attr "amdfam10_decode" "direct")
1497    (set_attr "bdver1_decode" "double")])
1498
1499 (define_insn "*cmpfp_i_i387"
1500   [(set (reg:CCFP FLAGS_REG)
1501         (compare:CCFP (match_operand 0 "register_operand" "f")
1502                       (match_operand 1 "register_operand" "f")))]
1503   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1504    && TARGET_CMOVE
1505    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1506    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1507   "* return output_fp_compare (insn, operands, true, false);"
1508   [(set_attr "type" "fcmp")
1509    (set (attr "mode")
1510      (cond [(match_operand:SF 1 "" "")
1511               (const_string "SF")
1512             (match_operand:DF 1 "" "")
1513               (const_string "DF")
1514            ]
1515            (const_string "XF")))
1516    (set_attr "athlon_decode" "vector")
1517    (set_attr "amdfam10_decode" "direct")
1518    (set_attr "bdver1_decode" "double")])
1519
1520 (define_insn "*cmpfp_iu_mixed"
1521   [(set (reg:CCFPU FLAGS_REG)
1522         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1523                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1524   "TARGET_MIX_SSE_I387
1525    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1526    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1527   "* return output_fp_compare (insn, operands, true, true);"
1528   [(set_attr "type" "fcmp,ssecomi")
1529    (set_attr "prefix" "orig,maybe_vex")
1530    (set (attr "mode")
1531      (if_then_else (match_operand:SF 1 "" "")
1532         (const_string "SF")
1533         (const_string "DF")))
1534    (set (attr "prefix_rep")
1535         (if_then_else (eq_attr "type" "ssecomi")
1536                       (const_string "0")
1537                       (const_string "*")))
1538    (set (attr "prefix_data16")
1539         (cond [(eq_attr "type" "fcmp")
1540                  (const_string "*")
1541                (eq_attr "mode" "DF")
1542                  (const_string "1")
1543               ]
1544               (const_string "0")))
1545    (set_attr "athlon_decode" "vector")
1546    (set_attr "amdfam10_decode" "direct")
1547    (set_attr "bdver1_decode" "double")])
1548
1549 (define_insn "*cmpfp_iu_sse"
1550   [(set (reg:CCFPU FLAGS_REG)
1551         (compare:CCFPU (match_operand 0 "register_operand" "x")
1552                        (match_operand 1 "nonimmediate_operand" "xm")))]
1553   "TARGET_SSE_MATH
1554    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1555    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1556   "* return output_fp_compare (insn, operands, true, true);"
1557   [(set_attr "type" "ssecomi")
1558    (set_attr "prefix" "maybe_vex")
1559    (set (attr "mode")
1560      (if_then_else (match_operand:SF 1 "" "")
1561         (const_string "SF")
1562         (const_string "DF")))
1563    (set_attr "prefix_rep" "0")
1564    (set (attr "prefix_data16")
1565         (if_then_else (eq_attr "mode" "DF")
1566                       (const_string "1")
1567                       (const_string "0")))
1568    (set_attr "athlon_decode" "vector")
1569    (set_attr "amdfam10_decode" "direct")
1570    (set_attr "bdver1_decode" "double")])
1571
1572 (define_insn "*cmpfp_iu_387"
1573   [(set (reg:CCFPU FLAGS_REG)
1574         (compare:CCFPU (match_operand 0 "register_operand" "f")
1575                        (match_operand 1 "register_operand" "f")))]
1576   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1577    && TARGET_CMOVE
1578    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1579    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1580   "* return output_fp_compare (insn, operands, true, true);"
1581   [(set_attr "type" "fcmp")
1582    (set (attr "mode")
1583      (cond [(match_operand:SF 1 "" "")
1584               (const_string "SF")
1585             (match_operand:DF 1 "" "")
1586               (const_string "DF")
1587            ]
1588            (const_string "XF")))
1589    (set_attr "athlon_decode" "vector")
1590    (set_attr "amdfam10_decode" "direct")
1591    (set_attr "bdver1_decode" "direct")])
1592 \f
1593 ;; Push/pop instructions.
1594
1595 (define_insn "*push<mode>2"
1596   [(set (match_operand:DWI 0 "push_operand" "=<")
1597         (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1598   ""
1599   "#"
1600   [(set_attr "type" "multi")
1601    (set_attr "mode" "<MODE>")])
1602
1603 (define_split
1604   [(set (match_operand:TI 0 "push_operand" "")
1605         (match_operand:TI 1 "general_operand" ""))]
1606   "TARGET_64BIT && reload_completed
1607    && !SSE_REG_P (operands[1])"
1608   [(const_int 0)]
1609   "ix86_split_long_move (operands); DONE;")
1610
1611 (define_insn "*pushdi2_rex64"
1612   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1613         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1614   "TARGET_64BIT"
1615   "@
1616    push{q}\t%1
1617    #"
1618   [(set_attr "type" "push,multi")
1619    (set_attr "mode" "DI")])
1620
1621 ;; Convert impossible pushes of immediate to existing instructions.
1622 ;; First try to get scratch register and go through it.  In case this
1623 ;; fails, push sign extended lower part first and then overwrite
1624 ;; upper part by 32bit move.
1625 (define_peephole2
1626   [(match_scratch:DI 2 "r")
1627    (set (match_operand:DI 0 "push_operand" "")
1628         (match_operand:DI 1 "immediate_operand" ""))]
1629   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1630    && !x86_64_immediate_operand (operands[1], DImode)"
1631   [(set (match_dup 2) (match_dup 1))
1632    (set (match_dup 0) (match_dup 2))])
1633
1634 ;; We need to define this as both peepholer and splitter for case
1635 ;; peephole2 pass is not run.
1636 ;; "&& 1" is needed to keep it from matching the previous pattern.
1637 (define_peephole2
1638   [(set (match_operand:DI 0 "push_operand" "")
1639         (match_operand:DI 1 "immediate_operand" ""))]
1640   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1641    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1642   [(set (match_dup 0) (match_dup 1))
1643    (set (match_dup 2) (match_dup 3))]
1644 {
1645   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1646
1647   operands[1] = gen_lowpart (DImode, operands[2]);
1648   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1649                                                    GEN_INT (4)));
1650 })
1651
1652 (define_split
1653   [(set (match_operand:DI 0 "push_operand" "")
1654         (match_operand:DI 1 "immediate_operand" ""))]
1655   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1656                     ? epilogue_completed : reload_completed)
1657    && !symbolic_operand (operands[1], DImode)
1658    && !x86_64_immediate_operand (operands[1], DImode)"
1659   [(set (match_dup 0) (match_dup 1))
1660    (set (match_dup 2) (match_dup 3))]
1661 {
1662   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1663
1664   operands[1] = gen_lowpart (DImode, operands[2]);
1665   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1666                                                    GEN_INT (4)));
1667 })
1668
1669 (define_split
1670   [(set (match_operand:DI 0 "push_operand" "")
1671         (match_operand:DI 1 "general_operand" ""))]
1672   "!TARGET_64BIT && reload_completed
1673    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1674   [(const_int 0)]
1675   "ix86_split_long_move (operands); DONE;")
1676
1677 (define_insn "*pushsi2"
1678   [(set (match_operand:SI 0 "push_operand" "=<")
1679         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1680   "!TARGET_64BIT"
1681   "push{l}\t%1"
1682   [(set_attr "type" "push")
1683    (set_attr "mode" "SI")])
1684
1685 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1686 ;; "push a byte/word".  But actually we use pushl, which has the effect
1687 ;; of rounding the amount pushed up to a word.
1688
1689 ;; For TARGET_64BIT we always round up to 8 bytes.
1690 (define_insn "*push<mode>2_rex64"
1691   [(set (match_operand:SWI124 0 "push_operand" "=X")
1692         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1693   "TARGET_64BIT"
1694   "push{q}\t%q1"
1695   [(set_attr "type" "push")
1696    (set_attr "mode" "DI")])
1697
1698 (define_insn "*push<mode>2"
1699   [(set (match_operand:SWI12 0 "push_operand" "=X")
1700         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1701   "!TARGET_64BIT"
1702   "push{l}\t%k1"
1703   [(set_attr "type" "push")
1704    (set_attr "mode" "SI")])
1705
1706 (define_insn "*push<mode>2_prologue"
1707   [(set (match_operand:P 0 "push_operand" "=<")
1708         (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1709    (clobber (mem:BLK (scratch)))]
1710   ""
1711   "push{<imodesuffix>}\t%1"
1712   [(set_attr "type" "push")
1713    (set_attr "mode" "<MODE>")])
1714
1715 (define_insn "*pop<mode>1"
1716   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1717         (match_operand:P 1 "pop_operand" ">"))]
1718   ""
1719   "pop{<imodesuffix>}\t%0"
1720   [(set_attr "type" "pop")
1721    (set_attr "mode" "<MODE>")])
1722
1723 (define_insn "*pop<mode>1_epilogue"
1724   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1725         (match_operand:P 1 "pop_operand" ">"))
1726    (clobber (mem:BLK (scratch)))]
1727   ""
1728   "pop{<imodesuffix>}\t%0"
1729   [(set_attr "type" "pop")
1730    (set_attr "mode" "<MODE>")])
1731 \f
1732 ;; Move instructions.
1733
1734 (define_expand "movoi"
1735   [(set (match_operand:OI 0 "nonimmediate_operand" "")
1736         (match_operand:OI 1 "general_operand" ""))]
1737   "TARGET_AVX"
1738   "ix86_expand_move (OImode, operands); DONE;")
1739
1740 (define_expand "movti"
1741   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1742         (match_operand:TI 1 "nonimmediate_operand" ""))]
1743   "TARGET_64BIT || TARGET_SSE"
1744 {
1745   if (TARGET_64BIT)
1746     ix86_expand_move (TImode, operands);
1747   else if (push_operand (operands[0], TImode))
1748     ix86_expand_push (TImode, operands[1]);
1749   else
1750     ix86_expand_vector_move (TImode, operands);
1751   DONE;
1752 })
1753
1754 ;; This expands to what emit_move_complex would generate if we didn't
1755 ;; have a movti pattern.  Having this avoids problems with reload on
1756 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1757 ;; to have around all the time.
1758 (define_expand "movcdi"
1759   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1760         (match_operand:CDI 1 "general_operand" ""))]
1761   ""
1762 {
1763   if (push_operand (operands[0], CDImode))
1764     emit_move_complex_push (CDImode, operands[0], operands[1]);
1765   else
1766     emit_move_complex_parts (operands[0], operands[1]);
1767   DONE;
1768 })
1769
1770 (define_expand "mov<mode>"
1771   [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1772         (match_operand:SWI1248x 1 "general_operand" ""))]
1773   ""
1774   "ix86_expand_move (<MODE>mode, operands); DONE;")
1775
1776 (define_insn "*mov<mode>_xor"
1777   [(set (match_operand:SWI48 0 "register_operand" "=r")
1778         (match_operand:SWI48 1 "const0_operand" ""))
1779    (clobber (reg:CC FLAGS_REG))]
1780   "reload_completed"
1781   "xor{l}\t%k0, %k0"
1782   [(set_attr "type" "alu1")
1783    (set_attr "mode" "SI")
1784    (set_attr "length_immediate" "0")])
1785
1786 (define_insn "*mov<mode>_or"
1787   [(set (match_operand:SWI48 0 "register_operand" "=r")
1788         (match_operand:SWI48 1 "const_int_operand" ""))
1789    (clobber (reg:CC FLAGS_REG))]
1790   "reload_completed
1791    && operands[1] == constm1_rtx"
1792   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1793   [(set_attr "type" "alu1")
1794    (set_attr "mode" "<MODE>")
1795    (set_attr "length_immediate" "1")])
1796
1797 (define_insn "*movoi_internal_avx"
1798   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1799         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1800   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1801 {
1802   switch (which_alternative)
1803     {
1804     case 0:
1805       return standard_sse_constant_opcode (insn, operands[1]);
1806     case 1:
1807     case 2:
1808       if (misaligned_operand (operands[0], OImode)
1809           || misaligned_operand (operands[1], OImode))
1810         return "vmovdqu\t{%1, %0|%0, %1}";
1811       else
1812         return "vmovdqa\t{%1, %0|%0, %1}";
1813     default:
1814       gcc_unreachable ();
1815     }
1816 }
1817   [(set_attr "type" "sselog1,ssemov,ssemov")
1818    (set_attr "prefix" "vex")
1819    (set_attr "mode" "OI")])
1820
1821 (define_insn "*movti_internal_rex64"
1822   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,m")
1823         (match_operand:TI 1 "general_operand" "riFo,re,C,xm,x"))]
1824   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1825 {
1826   switch (which_alternative)
1827     {
1828     case 0:
1829     case 1:
1830       return "#";
1831     case 2:
1832       return standard_sse_constant_opcode (insn, operands[1]);
1833     case 3:
1834     case 4:
1835       /* TDmode values are passed as TImode on the stack.  Moving them
1836          to stack may result in unaligned memory access.  */
1837       if (misaligned_operand (operands[0], TImode)
1838           || misaligned_operand (operands[1], TImode))
1839         {
1840           if (get_attr_mode (insn) == MODE_V4SF)
1841             return "%vmovups\t{%1, %0|%0, %1}";
1842           else
1843             return "%vmovdqu\t{%1, %0|%0, %1}";
1844         }
1845       else
1846         {
1847           if (get_attr_mode (insn) == MODE_V4SF)
1848             return "%vmovaps\t{%1, %0|%0, %1}";
1849           else
1850             return "%vmovdqa\t{%1, %0|%0, %1}";
1851         }
1852     default:
1853       gcc_unreachable ();
1854     }
1855 }
1856   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1857    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1858    (set (attr "mode")
1859         (cond [(eq_attr "alternative" "0,1")
1860                  (const_string "DI")
1861                (ior (not (match_test "TARGET_SSE2"))
1862                     (match_test "optimize_function_for_size_p (cfun)"))
1863                  (const_string "V4SF")
1864                (and (eq_attr "alternative" "4")
1865                     (match_test "TARGET_SSE_TYPELESS_STORES"))
1866                  (const_string "V4SF")
1867                ]
1868                (const_string "TI")))])
1869
1870 (define_split
1871   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1872         (match_operand:TI 1 "general_operand" ""))]
1873   "reload_completed
1874    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1875   [(const_int 0)]
1876   "ix86_split_long_move (operands); DONE;")
1877
1878 (define_insn "*movti_internal_sse"
1879   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1880         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1881   "TARGET_SSE && !TARGET_64BIT
1882    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1883 {
1884   switch (which_alternative)
1885     {
1886     case 0:
1887       return standard_sse_constant_opcode (insn, operands[1]);
1888     case 1:
1889     case 2:
1890       /* TDmode values are passed as TImode on the stack.  Moving them
1891          to stack may result in unaligned memory access.  */
1892       if (misaligned_operand (operands[0], TImode)
1893           || misaligned_operand (operands[1], TImode))
1894         {
1895           if (get_attr_mode (insn) == MODE_V4SF)
1896             return "%vmovups\t{%1, %0|%0, %1}";
1897           else
1898             return "%vmovdqu\t{%1, %0|%0, %1}";
1899         }
1900       else
1901         {
1902           if (get_attr_mode (insn) == MODE_V4SF)
1903             return "%vmovaps\t{%1, %0|%0, %1}";
1904           else
1905             return "%vmovdqa\t{%1, %0|%0, %1}";
1906         }
1907     default:
1908       gcc_unreachable ();
1909     }
1910 }
1911   [(set_attr "type" "sselog1,ssemov,ssemov")
1912    (set_attr "prefix" "maybe_vex")
1913    (set (attr "mode")
1914         (cond [(ior (not (match_test "TARGET_SSE2"))
1915                     (match_test "optimize_function_for_size_p (cfun)"))
1916                  (const_string "V4SF")
1917                (and (eq_attr "alternative" "2")
1918                     (match_test "TARGET_SSE_TYPELESS_STORES"))
1919                  (const_string "V4SF")]
1920               (const_string "TI")))])
1921
1922 (define_insn "*movdi_internal_rex64"
1923   [(set (match_operand:DI 0 "nonimmediate_operand"
1924           "=r,r  ,r,m ,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1925         (match_operand:DI 1 "general_operand"
1926           "Z ,rem,i,re,C ,*y ,m  ,*Ym,r   ,C ,*x,*x,m ,*Yi,r   ,*Ym,*x"))]
1927   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1928 {
1929   switch (get_attr_type (insn))
1930     {
1931     case TYPE_SSECVT:
1932       if (SSE_REG_P (operands[0]))
1933         return "movq2dq\t{%1, %0|%0, %1}";
1934       else
1935         return "movdq2q\t{%1, %0|%0, %1}";
1936
1937     case TYPE_SSEMOV:
1938       if (get_attr_mode (insn) == MODE_TI)
1939         return "%vmovdqa\t{%1, %0|%0, %1}";
1940       /* Handle broken assemblers that require movd instead of movq.  */
1941       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1942         return "%vmovd\t{%1, %0|%0, %1}";
1943       else
1944         return "%vmovq\t{%1, %0|%0, %1}";
1945
1946     case TYPE_MMXMOV:
1947       /* Handle broken assemblers that require movd instead of movq.  */
1948       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1949         return "movd\t{%1, %0|%0, %1}";
1950       else
1951         return "movq\t{%1, %0|%0, %1}";
1952
1953     case TYPE_SSELOG1:
1954       return standard_sse_constant_opcode (insn, operands[1]);
1955
1956     case TYPE_MMX:
1957       return "pxor\t%0, %0";
1958
1959     case TYPE_LEA:
1960       return "lea{q}\t{%E1, %0|%0, %E1}";
1961
1962     default:
1963       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1964       if (get_attr_mode (insn) == MODE_SI)
1965         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1966       else if (which_alternative == 2)
1967         return "movabs{q}\t{%1, %0|%0, %1}";
1968       else if (ix86_use_lea_for_mov (insn, operands))
1969         return "lea{q}\t{%E1, %0|%0, %E1}";
1970       else
1971         return "mov{q}\t{%1, %0|%0, %1}";
1972     }
1973 }
1974   [(set (attr "type")
1975      (cond [(eq_attr "alternative" "4")
1976               (const_string "mmx")
1977             (eq_attr "alternative" "5,6,7,8")
1978               (const_string "mmxmov")
1979             (eq_attr "alternative" "9")
1980               (const_string "sselog1")
1981             (eq_attr "alternative" "10,11,12,13,14")
1982               (const_string "ssemov")
1983             (eq_attr "alternative" "15,16")
1984               (const_string "ssecvt")
1985             (match_operand 1 "pic_32bit_operand" "")
1986               (const_string "lea")
1987            ]
1988            (const_string "imov")))
1989    (set (attr "modrm")
1990      (if_then_else
1991        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
1992          (const_string "0")
1993          (const_string "*")))
1994    (set (attr "length_immediate")
1995      (if_then_else
1996        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
1997          (const_string "8")
1998          (const_string "*")))
1999    (set (attr "prefix_rex")
2000      (if_then_else (eq_attr "alternative" "7,8")
2001        (const_string "1")
2002        (const_string "*")))
2003    (set (attr "prefix_data16")
2004      (if_then_else (eq_attr "alternative" "10")
2005        (const_string "1")
2006        (const_string "*")))
2007    (set (attr "prefix")
2008      (if_then_else (eq_attr "alternative" "11,12,13,14,15")
2009        (const_string "maybe_vex")
2010        (const_string "orig")))
2011    (set_attr "mode" "SI,DI,DI,DI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2012
2013 ;; Reload patterns to support multi-word load/store
2014 ;; with non-offsetable address.
2015 (define_expand "reload_noff_store"
2016   [(parallel [(match_operand 0 "memory_operand" "=m")
2017               (match_operand 1 "register_operand" "r")
2018               (match_operand:DI 2 "register_operand" "=&r")])]
2019   "TARGET_64BIT"
2020 {
2021   rtx mem = operands[0];
2022   rtx addr = XEXP (mem, 0);
2023
2024   emit_move_insn (operands[2], addr);
2025   mem = replace_equiv_address_nv (mem, operands[2]);
2026
2027   emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2028   DONE;
2029 })
2030
2031 (define_expand "reload_noff_load"
2032   [(parallel [(match_operand 0 "register_operand" "=r")
2033               (match_operand 1 "memory_operand" "m")
2034               (match_operand:DI 2 "register_operand" "=r")])]
2035   "TARGET_64BIT"
2036 {
2037   rtx mem = operands[1];
2038   rtx addr = XEXP (mem, 0);
2039
2040   emit_move_insn (operands[2], addr);
2041   mem = replace_equiv_address_nv (mem, operands[2]);
2042
2043   emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2044   DONE;
2045 })
2046
2047 (define_insn "*movdi_internal"
2048   [(set (match_operand:DI 0 "nonimmediate_operand"
2049           "=r  ,o  ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2050         (match_operand:DI 1 "general_operand"
2051           "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2052   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2053 {
2054   switch (get_attr_type (insn))
2055     {
2056     case TYPE_SSECVT:
2057       if (SSE_REG_P (operands[0]))
2058         return "movq2dq\t{%1, %0|%0, %1}";
2059       else
2060         return "movdq2q\t{%1, %0|%0, %1}";
2061
2062     case TYPE_SSEMOV:
2063       switch (get_attr_mode (insn))
2064         {
2065         case MODE_TI:
2066           return "%vmovdqa\t{%1, %0|%0, %1}";
2067         case MODE_DI:
2068            return "%vmovq\t{%1, %0|%0, %1}";
2069         case MODE_V4SF:
2070           return "movaps\t{%1, %0|%0, %1}";
2071         case MODE_V2SF:
2072           return "movlps\t{%1, %0|%0, %1}";
2073         default:
2074           gcc_unreachable ();
2075         }
2076
2077     case TYPE_MMXMOV:
2078       return "movq\t{%1, %0|%0, %1}";
2079
2080     case TYPE_SSELOG1:
2081       return standard_sse_constant_opcode (insn, operands[1]);
2082
2083     case TYPE_MMX:
2084       return "pxor\t%0, %0";
2085
2086     case TYPE_MULTI:
2087       return "#";
2088
2089     default:
2090       gcc_unreachable ();
2091     }
2092 }
2093   [(set (attr "isa")
2094      (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2095               (const_string "sse2")
2096             (eq_attr "alternative" "9,10,11,12")
2097               (const_string "noavx")
2098            ]
2099            (const_string "*")))
2100    (set (attr "type")
2101      (cond [(eq_attr "alternative" "0,1")
2102               (const_string "multi")
2103             (eq_attr "alternative" "2")
2104               (const_string "mmx")
2105             (eq_attr "alternative" "3,4")
2106               (const_string "mmxmov")
2107             (eq_attr "alternative" "5,9")
2108               (const_string "sselog1")
2109             (eq_attr "alternative" "13,14")
2110               (const_string "ssecvt")
2111            ]
2112            (const_string "ssemov")))
2113    (set (attr "prefix")
2114      (if_then_else (eq_attr "alternative" "5,6,7,8")
2115        (const_string "maybe_vex")
2116        (const_string "orig")))
2117    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2118
2119 (define_split
2120   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2121         (match_operand:DI 1 "general_operand" ""))]
2122   "!TARGET_64BIT && reload_completed
2123    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2124    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2125   [(const_int 0)]
2126   "ix86_split_long_move (operands); DONE;")
2127
2128 (define_insn "*movsi_internal"
2129   [(set (match_operand:SI 0 "nonimmediate_operand"
2130                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2131         (match_operand:SI 1 "general_operand"
2132                         "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
2133   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2134 {
2135   switch (get_attr_type (insn))
2136     {
2137     case TYPE_SSELOG1:
2138       return standard_sse_constant_opcode (insn, operands[1]);
2139
2140     case TYPE_SSEMOV:
2141       switch (get_attr_mode (insn))
2142         {
2143         case MODE_TI:
2144           return "%vmovdqa\t{%1, %0|%0, %1}";
2145         case MODE_V4SF:
2146           return "%vmovaps\t{%1, %0|%0, %1}";
2147         case MODE_SI:
2148           return "%vmovd\t{%1, %0|%0, %1}";
2149         case MODE_SF:
2150           return "%vmovss\t{%1, %0|%0, %1}";
2151         default:
2152           gcc_unreachable ();
2153         }
2154
2155     case TYPE_MMX:
2156       return "pxor\t%0, %0";
2157
2158     case TYPE_MMXMOV:
2159       if (get_attr_mode (insn) == MODE_DI)
2160         return "movq\t{%1, %0|%0, %1}";
2161       return "movd\t{%1, %0|%0, %1}";
2162
2163     case TYPE_LEA:
2164       return "lea{l}\t{%E1, %0|%0, %E1}";
2165
2166     default:
2167       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2168       if (ix86_use_lea_for_mov (insn, operands))
2169         return "lea{l}\t{%E1, %0|%0, %E1}";
2170       else
2171         return "mov{l}\t{%1, %0|%0, %1}";
2172     }
2173 }
2174   [(set (attr "type")
2175      (cond [(eq_attr "alternative" "2")
2176               (const_string "mmx")
2177             (eq_attr "alternative" "3,4,5")
2178               (const_string "mmxmov")
2179             (eq_attr "alternative" "6")
2180               (const_string "sselog1")
2181             (eq_attr "alternative" "7,8,9,10,11")
2182               (const_string "ssemov")
2183             (match_operand 1 "pic_32bit_operand" "")
2184               (const_string "lea")
2185            ]
2186            (const_string "imov")))
2187    (set (attr "prefix")
2188      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2189        (const_string "orig")
2190        (const_string "maybe_vex")))
2191    (set (attr "prefix_data16")
2192      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2193        (const_string "1")
2194        (const_string "*")))
2195    (set (attr "mode")
2196      (cond [(eq_attr "alternative" "2,3")
2197               (const_string "DI")
2198             (eq_attr "alternative" "6,7")
2199               (if_then_else
2200                 (not (match_test "TARGET_SSE2"))
2201                 (const_string "V4SF")
2202                 (const_string "TI"))
2203             (and (eq_attr "alternative" "8,9,10,11")
2204                  (not (match_test "TARGET_SSE2")))
2205               (const_string "SF")
2206            ]
2207            (const_string "SI")))])
2208
2209 (define_insn "*movhi_internal"
2210   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2211         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2212   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2213 {
2214   switch (get_attr_type (insn))
2215     {
2216     case TYPE_IMOVX:
2217       /* movzwl is faster than movw on p2 due to partial word stalls,
2218          though not as fast as an aligned movl.  */
2219       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2220     default:
2221       if (get_attr_mode (insn) == MODE_SI)
2222         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2223       else
2224         return "mov{w}\t{%1, %0|%0, %1}";
2225     }
2226 }
2227   [(set (attr "type")
2228      (cond [(match_test "optimize_function_for_size_p (cfun)")
2229               (const_string "imov")
2230             (and (eq_attr "alternative" "0")
2231                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2232                       (not (match_test "TARGET_HIMODE_MATH"))))
2233               (const_string "imov")
2234             (and (eq_attr "alternative" "1,2")
2235                  (match_operand:HI 1 "aligned_operand" ""))
2236               (const_string "imov")
2237             (and (match_test "TARGET_MOVX")
2238                  (eq_attr "alternative" "0,2"))
2239               (const_string "imovx")
2240            ]
2241            (const_string "imov")))
2242     (set (attr "mode")
2243       (cond [(eq_attr "type" "imovx")
2244                (const_string "SI")
2245              (and (eq_attr "alternative" "1,2")
2246                   (match_operand:HI 1 "aligned_operand" ""))
2247                (const_string "SI")
2248              (and (eq_attr "alternative" "0")
2249                   (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2250                        (not (match_test "TARGET_HIMODE_MATH"))))
2251                (const_string "SI")
2252             ]
2253             (const_string "HI")))])
2254
2255 ;; Situation is quite tricky about when to choose full sized (SImode) move
2256 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2257 ;; partial register dependency machines (such as AMD Athlon), where QImode
2258 ;; moves issue extra dependency and for partial register stalls machines
2259 ;; that don't use QImode patterns (and QImode move cause stall on the next
2260 ;; instruction).
2261 ;;
2262 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2263 ;; register stall machines with, where we use QImode instructions, since
2264 ;; partial register stall can be caused there.  Then we use movzx.
2265 (define_insn "*movqi_internal"
2266   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2267         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2268   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2269 {
2270   switch (get_attr_type (insn))
2271     {
2272     case TYPE_IMOVX:
2273       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2274       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2275     default:
2276       if (get_attr_mode (insn) == MODE_SI)
2277         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2278       else
2279         return "mov{b}\t{%1, %0|%0, %1}";
2280     }
2281 }
2282   [(set (attr "type")
2283      (cond [(and (eq_attr "alternative" "5")
2284                  (not (match_operand:QI 1 "aligned_operand" "")))
2285               (const_string "imovx")
2286             (match_test "optimize_function_for_size_p (cfun)")
2287               (const_string "imov")
2288             (and (eq_attr "alternative" "3")
2289                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2290                       (not (match_test "TARGET_QIMODE_MATH"))))
2291               (const_string "imov")
2292             (eq_attr "alternative" "3,5")
2293               (const_string "imovx")
2294             (and (match_test "TARGET_MOVX")
2295                  (eq_attr "alternative" "2"))
2296               (const_string "imovx")
2297            ]
2298            (const_string "imov")))
2299    (set (attr "mode")
2300       (cond [(eq_attr "alternative" "3,4,5")
2301                (const_string "SI")
2302              (eq_attr "alternative" "6")
2303                (const_string "QI")
2304              (eq_attr "type" "imovx")
2305                (const_string "SI")
2306              (and (eq_attr "type" "imov")
2307                   (and (eq_attr "alternative" "0,1")
2308                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2309                             (and (not (match_test "optimize_function_for_size_p (cfun)"))
2310                                  (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2311                (const_string "SI")
2312              ;; Avoid partial register stalls when not using QImode arithmetic
2313              (and (eq_attr "type" "imov")
2314                   (and (eq_attr "alternative" "0,1")
2315                        (and (match_test "TARGET_PARTIAL_REG_STALL")
2316                             (not (match_test "TARGET_QIMODE_MATH")))))
2317                (const_string "SI")
2318            ]
2319            (const_string "QI")))])
2320
2321 ;; Stores and loads of ax to arbitrary constant address.
2322 ;; We fake an second form of instruction to force reload to load address
2323 ;; into register when rax is not available
2324 (define_insn "*movabs<mode>_1"
2325   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2326         (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2327   "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2328   "@
2329    movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2330    mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2331   [(set_attr "type" "imov")
2332    (set_attr "modrm" "0,*")
2333    (set_attr "length_address" "8,0")
2334    (set_attr "length_immediate" "0,*")
2335    (set_attr "memory" "store")
2336    (set_attr "mode" "<MODE>")])
2337
2338 (define_insn "*movabs<mode>_2"
2339   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2340         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2341   "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2342   "@
2343    movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2344    mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2345   [(set_attr "type" "imov")
2346    (set_attr "modrm" "0,*")
2347    (set_attr "length_address" "8,0")
2348    (set_attr "length_immediate" "0")
2349    (set_attr "memory" "load")
2350    (set_attr "mode" "<MODE>")])
2351
2352 (define_insn "*swap<mode>"
2353   [(set (match_operand:SWI48 0 "register_operand" "+r")
2354         (match_operand:SWI48 1 "register_operand" "+r"))
2355    (set (match_dup 1)
2356         (match_dup 0))]
2357   ""
2358   "xchg{<imodesuffix>}\t%1, %0"
2359   [(set_attr "type" "imov")
2360    (set_attr "mode" "<MODE>")
2361    (set_attr "pent_pair" "np")
2362    (set_attr "athlon_decode" "vector")
2363    (set_attr "amdfam10_decode" "double")
2364    (set_attr "bdver1_decode" "double")])
2365
2366 (define_insn "*swap<mode>_1"
2367   [(set (match_operand:SWI12 0 "register_operand" "+r")
2368         (match_operand:SWI12 1 "register_operand" "+r"))
2369    (set (match_dup 1)
2370         (match_dup 0))]
2371   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2372   "xchg{l}\t%k1, %k0"
2373   [(set_attr "type" "imov")
2374    (set_attr "mode" "SI")
2375    (set_attr "pent_pair" "np")
2376    (set_attr "athlon_decode" "vector")
2377    (set_attr "amdfam10_decode" "double")
2378    (set_attr "bdver1_decode" "double")])
2379
2380 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2381 ;; is disabled for AMDFAM10
2382 (define_insn "*swap<mode>_2"
2383   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2384         (match_operand:SWI12 1 "register_operand" "+<r>"))
2385    (set (match_dup 1)
2386         (match_dup 0))]
2387   "TARGET_PARTIAL_REG_STALL"
2388   "xchg{<imodesuffix>}\t%1, %0"
2389   [(set_attr "type" "imov")
2390    (set_attr "mode" "<MODE>")
2391    (set_attr "pent_pair" "np")
2392    (set_attr "athlon_decode" "vector")])
2393
2394 (define_expand "movstrict<mode>"
2395   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2396         (match_operand:SWI12 1 "general_operand" ""))]
2397   ""
2398 {
2399   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2400     FAIL;
2401   if (GET_CODE (operands[0]) == SUBREG
2402       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2403     FAIL;
2404   /* Don't generate memory->memory moves, go through a register */
2405   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2406     operands[1] = force_reg (<MODE>mode, operands[1]);
2407 })
2408
2409 (define_insn "*movstrict<mode>_1"
2410   [(set (strict_low_part
2411           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2412         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2413   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2414    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2415   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2416   [(set_attr "type" "imov")
2417    (set_attr "mode" "<MODE>")])
2418
2419 (define_insn "*movstrict<mode>_xor"
2420   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2421         (match_operand:SWI12 1 "const0_operand" ""))
2422    (clobber (reg:CC FLAGS_REG))]
2423   "reload_completed"
2424   "xor{<imodesuffix>}\t%0, %0"
2425   [(set_attr "type" "alu1")
2426    (set_attr "mode" "<MODE>")
2427    (set_attr "length_immediate" "0")])
2428
2429 (define_insn "*mov<mode>_extv_1"
2430   [(set (match_operand:SWI24 0 "register_operand" "=R")
2431         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2432                             (const_int 8)
2433                             (const_int 8)))]
2434   ""
2435   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2436   [(set_attr "type" "imovx")
2437    (set_attr "mode" "SI")])
2438
2439 (define_insn "*movqi_extv_1_rex64"
2440   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2441         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2442                          (const_int 8)
2443                          (const_int 8)))]
2444   "TARGET_64BIT"
2445 {
2446   switch (get_attr_type (insn))
2447     {
2448     case TYPE_IMOVX:
2449       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2450     default:
2451       return "mov{b}\t{%h1, %0|%0, %h1}";
2452     }
2453 }
2454   [(set (attr "type")
2455      (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2456                         (match_test "TARGET_MOVX"))
2457         (const_string "imovx")
2458         (const_string "imov")))
2459    (set (attr "mode")
2460      (if_then_else (eq_attr "type" "imovx")
2461         (const_string "SI")
2462         (const_string "QI")))])
2463
2464 (define_insn "*movqi_extv_1"
2465   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2466         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2467                          (const_int 8)
2468                          (const_int 8)))]
2469   "!TARGET_64BIT"
2470 {
2471   switch (get_attr_type (insn))
2472     {
2473     case TYPE_IMOVX:
2474       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2475     default:
2476       return "mov{b}\t{%h1, %0|%0, %h1}";
2477     }
2478 }
2479   [(set (attr "type")
2480      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2481                         (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2482                              (match_test "TARGET_MOVX")))
2483         (const_string "imovx")
2484         (const_string "imov")))
2485    (set (attr "mode")
2486      (if_then_else (eq_attr "type" "imovx")
2487         (const_string "SI")
2488         (const_string "QI")))])
2489
2490 (define_insn "*mov<mode>_extzv_1"
2491   [(set (match_operand:SWI48 0 "register_operand" "=R")
2492         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2493                             (const_int 8)
2494                             (const_int 8)))]
2495   ""
2496   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2497   [(set_attr "type" "imovx")
2498    (set_attr "mode" "SI")])
2499
2500 (define_insn "*movqi_extzv_2_rex64"
2501   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2502         (subreg:QI
2503           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2504                            (const_int 8)
2505                            (const_int 8)) 0))]
2506   "TARGET_64BIT"
2507 {
2508   switch (get_attr_type (insn))
2509     {
2510     case TYPE_IMOVX:
2511       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2512     default:
2513       return "mov{b}\t{%h1, %0|%0, %h1}";
2514     }
2515 }
2516   [(set (attr "type")
2517      (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2518                         (match_test "TARGET_MOVX"))
2519         (const_string "imovx")
2520         (const_string "imov")))
2521    (set (attr "mode")
2522      (if_then_else (eq_attr "type" "imovx")
2523         (const_string "SI")
2524         (const_string "QI")))])
2525
2526 (define_insn "*movqi_extzv_2"
2527   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2528         (subreg:QI
2529           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2530                            (const_int 8)
2531                            (const_int 8)) 0))]
2532   "!TARGET_64BIT"
2533 {
2534   switch (get_attr_type (insn))
2535     {
2536     case TYPE_IMOVX:
2537       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2538     default:
2539       return "mov{b}\t{%h1, %0|%0, %h1}";
2540     }
2541 }
2542   [(set (attr "type")
2543      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2544                         (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2545                              (match_test "TARGET_MOVX")))
2546         (const_string "imovx")
2547         (const_string "imov")))
2548    (set (attr "mode")
2549      (if_then_else (eq_attr "type" "imovx")
2550         (const_string "SI")
2551         (const_string "QI")))])
2552
2553 (define_expand "mov<mode>_insv_1"
2554   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2555                             (const_int 8)
2556                             (const_int 8))
2557         (match_operand:SWI48 1 "nonmemory_operand" ""))])
2558
2559 (define_insn "*mov<mode>_insv_1_rex64"
2560   [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2561                              (const_int 8)
2562                              (const_int 8))
2563         (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2564   "TARGET_64BIT"
2565 {
2566   if (CONST_INT_P (operands[1]))
2567     operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2568   return "mov{b}\t{%b1, %h0|%h0, %b1}";
2569 }
2570   [(set_attr "type" "imov")
2571    (set_attr "mode" "QI")])
2572
2573 (define_insn "*movsi_insv_1"
2574   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2575                          (const_int 8)
2576                          (const_int 8))
2577         (match_operand:SI 1 "general_operand" "Qmn"))]
2578   "!TARGET_64BIT"
2579 {
2580   if (CONST_INT_P (operands[1]))
2581     operands[1] = simplify_gen_subreg (QImode, operands[1], SImode, 0);
2582   return "mov{b}\t{%b1, %h0|%h0, %b1}";
2583 }
2584   [(set_attr "type" "imov")
2585    (set_attr "mode" "QI")])
2586
2587 (define_insn "*movqi_insv_2"
2588   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2589                          (const_int 8)
2590                          (const_int 8))
2591         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2592                      (const_int 8)))]
2593   ""
2594   "mov{b}\t{%h1, %h0|%h0, %h1}"
2595   [(set_attr "type" "imov")
2596    (set_attr "mode" "QI")])
2597 \f
2598 ;; Floating point push instructions.
2599
2600 (define_insn "*pushtf"
2601   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2602         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2603   "TARGET_SSE2"
2604 {
2605   /* This insn should be already split before reg-stack.  */
2606   gcc_unreachable ();
2607 }
2608   [(set_attr "type" "multi")
2609    (set_attr "unit" "sse,*,*")
2610    (set_attr "mode" "TF,SI,SI")])
2611
2612 ;; %%% Kill this when call knows how to work this out.
2613 (define_split
2614   [(set (match_operand:TF 0 "push_operand" "")
2615         (match_operand:TF 1 "sse_reg_operand" ""))]
2616   "TARGET_SSE2 && reload_completed"
2617   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2618    (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2619
2620 (define_insn "*pushxf"
2621   [(set (match_operand:XF 0 "push_operand" "=<,<")
2622         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2623   "optimize_function_for_speed_p (cfun)"
2624 {
2625   /* This insn should be already split before reg-stack.  */
2626   gcc_unreachable ();
2627 }
2628   [(set_attr "type" "multi")
2629    (set_attr "unit" "i387,*")
2630    (set_attr "mode" "XF,SI")])
2631
2632 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2633 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2634 ;; Pushing using integer instructions is longer except for constants
2635 ;; and direct memory references (assuming that any given constant is pushed
2636 ;; only once, but this ought to be handled elsewhere).
2637
2638 (define_insn "*pushxf_nointeger"
2639   [(set (match_operand:XF 0 "push_operand" "=<,<")
2640         (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2641   "optimize_function_for_size_p (cfun)"
2642 {
2643   /* This insn should be already split before reg-stack.  */
2644   gcc_unreachable ();
2645 }
2646   [(set_attr "type" "multi")
2647    (set_attr "unit" "i387,*")
2648    (set_attr "mode" "XF,SI")])
2649
2650 ;; %%% Kill this when call knows how to work this out.
2651 (define_split
2652   [(set (match_operand:XF 0 "push_operand" "")
2653         (match_operand:XF 1 "fp_register_operand" ""))]
2654   "reload_completed"
2655   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2656    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2657   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2658
2659 (define_insn "*pushdf_rex64"
2660   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2661         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2662   "TARGET_64BIT"
2663 {
2664   /* This insn should be already split before reg-stack.  */
2665   gcc_unreachable ();
2666 }
2667   [(set_attr "type" "multi")
2668    (set_attr "unit" "i387,*,*")
2669    (set_attr "mode" "DF,DI,DF")])
2670
2671 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2672 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2673 ;; On the average, pushdf using integers can be still shorter.
2674
2675 (define_insn "*pushdf"
2676   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2677         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2678   "!TARGET_64BIT"
2679 {
2680   /* This insn should be already split before reg-stack.  */
2681   gcc_unreachable ();
2682 }
2683   [(set_attr "isa" "*,*,sse2")
2684    (set_attr "type" "multi")
2685    (set_attr "unit" "i387,*,*")
2686    (set_attr "mode" "DF,DI,DF")])
2687
2688 ;; %%% Kill this when call knows how to work this out.
2689 (define_split
2690   [(set (match_operand:DF 0 "push_operand" "")
2691         (match_operand:DF 1 "any_fp_register_operand" ""))]
2692   "reload_completed"
2693   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2694    (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2695
2696 (define_insn "*pushsf_rex64"
2697   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2698         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2699   "TARGET_64BIT"
2700 {
2701   /* Anything else should be already split before reg-stack.  */
2702   gcc_assert (which_alternative == 1);
2703   return "push{q}\t%q1";
2704 }
2705   [(set_attr "type" "multi,push,multi")
2706    (set_attr "unit" "i387,*,*")
2707    (set_attr "mode" "SF,DI,SF")])
2708
2709 (define_insn "*pushsf"
2710   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2711         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2712   "!TARGET_64BIT"
2713 {
2714   /* Anything else should be already split before reg-stack.  */
2715   gcc_assert (which_alternative == 1);
2716   return "push{l}\t%1";
2717 }
2718   [(set_attr "type" "multi,push,multi")
2719    (set_attr "unit" "i387,*,*")
2720    (set_attr "mode" "SF,SI,SF")])
2721
2722 ;; %%% Kill this when call knows how to work this out.
2723 (define_split
2724   [(set (match_operand:SF 0 "push_operand" "")
2725         (match_operand:SF 1 "any_fp_register_operand" ""))]
2726   "reload_completed"
2727   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2728    (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2729   "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2730
2731 (define_split
2732   [(set (match_operand:SF 0 "push_operand" "")
2733         (match_operand:SF 1 "memory_operand" ""))]
2734   "reload_completed
2735    && (operands[2] = find_constant_src (insn))"
2736   [(set (match_dup 0) (match_dup 2))])
2737
2738 (define_split
2739   [(set (match_operand 0 "push_operand" "")
2740         (match_operand 1 "general_operand" ""))]
2741   "reload_completed
2742    && (GET_MODE (operands[0]) == TFmode
2743        || GET_MODE (operands[0]) == XFmode
2744        || GET_MODE (operands[0]) == DFmode)
2745    && !ANY_FP_REG_P (operands[1])"
2746   [(const_int 0)]
2747   "ix86_split_long_move (operands); DONE;")
2748 \f
2749 ;; Floating point move instructions.
2750
2751 (define_expand "movtf"
2752   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2753         (match_operand:TF 1 "nonimmediate_operand" ""))]
2754   "TARGET_64BIT || TARGET_SSE2"
2755 {
2756   ix86_expand_move (TFmode, operands);
2757   DONE;
2758 })
2759
2760 (define_expand "mov<mode>"
2761   [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2762         (match_operand:X87MODEF 1 "general_operand" ""))]
2763   ""
2764   "ix86_expand_move (<MODE>mode, operands); DONE;")
2765
2766 (define_insn "*movtf_internal_rex64"
2767   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2768         (match_operand:TF 1 "general_operand"      "xm,x,C,*roF,*r"))]
2769   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2770    && (!can_create_pseudo_p ()
2771        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2772        || GET_CODE (operands[1]) != CONST_DOUBLE
2773        || (optimize_function_for_size_p (cfun)
2774            && standard_sse_constant_p (operands[1])
2775            && !memory_operand (operands[0], TFmode))
2776        || (!TARGET_MEMORY_MISMATCH_STALL
2777            && memory_operand (operands[0], TFmode)))"
2778 {
2779   switch (which_alternative)
2780     {
2781     case 0:
2782     case 1:
2783       /* Handle misaligned load/store since we
2784          don't have movmisaligntf pattern. */
2785       if (misaligned_operand (operands[0], TFmode)
2786           || misaligned_operand (operands[1], TFmode))
2787         {
2788           if (get_attr_mode (insn) == MODE_V4SF)
2789             return "%vmovups\t{%1, %0|%0, %1}";
2790           else
2791             return "%vmovdqu\t{%1, %0|%0, %1}";
2792         }
2793       else
2794         {
2795           if (get_attr_mode (insn) == MODE_V4SF)
2796             return "%vmovaps\t{%1, %0|%0, %1}";
2797           else
2798             return "%vmovdqa\t{%1, %0|%0, %1}";
2799         }
2800
2801     case 2:
2802       return standard_sse_constant_opcode (insn, operands[1]);
2803
2804     case 3:
2805     case 4:
2806         return "#";
2807
2808     default:
2809       gcc_unreachable ();
2810     }
2811 }
2812   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2813    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2814    (set (attr "mode")
2815         (cond [(eq_attr "alternative" "0,2")
2816                  (if_then_else
2817                    (match_test "optimize_function_for_size_p (cfun)")
2818                    (const_string "V4SF")
2819                    (const_string "TI"))
2820                (eq_attr "alternative" "1")
2821                  (if_then_else
2822                    (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2823                         (match_test "optimize_function_for_size_p (cfun)"))
2824                    (const_string "V4SF")
2825                    (const_string "TI"))]
2826                (const_string "DI")))])
2827
2828 (define_insn "*movtf_internal_sse2"
2829   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x")
2830         (match_operand:TF 1 "general_operand"      "xm,x,C"))]
2831   "TARGET_SSE2 && !TARGET_64BIT
2832    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2833    && (!can_create_pseudo_p ()
2834        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2835        || GET_CODE (operands[1]) != CONST_DOUBLE
2836        || (optimize_function_for_size_p (cfun)
2837            && standard_sse_constant_p (operands[1])
2838            && !memory_operand (operands[0], TFmode))
2839        || (!TARGET_MEMORY_MISMATCH_STALL
2840            && memory_operand (operands[0], TFmode)))"
2841 {
2842   switch (which_alternative)
2843     {
2844     case 0:
2845     case 1:
2846       /* Handle misaligned load/store since we
2847          don't have movmisaligntf pattern. */
2848       if (misaligned_operand (operands[0], TFmode)
2849           || misaligned_operand (operands[1], TFmode))
2850         {
2851           if (get_attr_mode (insn) == MODE_V4SF)
2852             return "%vmovups\t{%1, %0|%0, %1}";
2853           else
2854             return "%vmovdqu\t{%1, %0|%0, %1}";
2855         }
2856       else
2857         {
2858           if (get_attr_mode (insn) == MODE_V4SF)
2859             return "%vmovaps\t{%1, %0|%0, %1}";
2860           else
2861             return "%vmovdqa\t{%1, %0|%0, %1}";
2862         }
2863
2864     case 2:
2865       return standard_sse_constant_opcode (insn, operands[1]);
2866
2867     default:
2868       gcc_unreachable ();
2869     }
2870 }
2871   [(set_attr "type" "ssemov,ssemov,sselog1")
2872    (set_attr "prefix" "maybe_vex")
2873    (set (attr "mode")
2874         (cond [(eq_attr "alternative" "0,2")
2875                  (if_then_else
2876                    (match_test "optimize_function_for_size_p (cfun)")
2877                    (const_string "V4SF")
2878                    (const_string "TI"))
2879                (eq_attr "alternative" "1")
2880                  (if_then_else
2881                    (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2882                         (match_test "optimize_function_for_size_p (cfun)"))
2883                    (const_string "V4SF")
2884                    (const_string "TI"))]
2885                (const_string "DI")))])
2886
2887 (define_insn "*movxf_internal_rex64"
2888   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2889         (match_operand:XF 1 "general_operand"      "fm,f,G,Yx*roF,Yx*rC"))]
2890   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2891    && (!can_create_pseudo_p ()
2892        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2893        || GET_CODE (operands[1]) != CONST_DOUBLE
2894        || (optimize_function_for_size_p (cfun)
2895            && standard_80387_constant_p (operands[1]) > 0
2896            && !memory_operand (operands[0], XFmode))
2897        || (!TARGET_MEMORY_MISMATCH_STALL
2898            && memory_operand (operands[0], XFmode)))"
2899 {
2900   switch (which_alternative)
2901     {
2902     case 0:
2903     case 1:
2904       return output_387_reg_move (insn, operands);
2905
2906     case 2:
2907       return standard_80387_constant_opcode (operands[1]);
2908
2909     case 3:
2910     case 4:
2911       return "#";
2912
2913     default:
2914       gcc_unreachable ();
2915     }
2916 }
2917   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2918    (set_attr "mode" "XF,XF,XF,SI,SI")])
2919
2920 ;; Possible store forwarding (partial memory) stall in alternative 4.
2921 (define_insn "*movxf_internal"
2922   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2923         (match_operand:XF 1 "general_operand"      "fm,f,G,Yx*roF,Yx*rF"))]
2924   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2925    && (!can_create_pseudo_p ()
2926        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2927        || GET_CODE (operands[1]) != CONST_DOUBLE
2928        || (optimize_function_for_size_p (cfun)
2929            && standard_80387_constant_p (operands[1]) > 0
2930            && !memory_operand (operands[0], XFmode))
2931        || (!TARGET_MEMORY_MISMATCH_STALL
2932            && memory_operand (operands[0], XFmode)))"
2933 {
2934   switch (which_alternative)
2935     {
2936     case 0:
2937     case 1:
2938       return output_387_reg_move (insn, operands);
2939
2940     case 2:
2941       return standard_80387_constant_opcode (operands[1]);
2942
2943     case 3:
2944     case 4:
2945       return "#";
2946
2947     default:
2948       gcc_unreachable ();
2949     }
2950 }
2951   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2952    (set_attr "mode" "XF,XF,XF,SI,SI")])
2953
2954 (define_insn "*movdf_internal_rex64"
2955   [(set (match_operand:DF 0 "nonimmediate_operand"
2956                 "=?Yf*f,?m   ,?Yf*f,?r,?m,?r,?r,x,x,x,m,Yi,r ")
2957         (match_operand:DF 1 "general_operand"
2958                 "Yf*fm ,Yf*f ,G    ,rm,rC,C ,F ,C,x,m,x,r ,Yi"))]
2959   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2960    && (!can_create_pseudo_p ()
2961        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2962        || GET_CODE (operands[1]) != CONST_DOUBLE
2963        || (optimize_function_for_size_p (cfun)
2964            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2965                 && standard_80387_constant_p (operands[1]) > 0)
2966                || (TARGET_SSE2 && TARGET_SSE_MATH
2967                    && standard_sse_constant_p (operands[1]))))
2968        || memory_operand (operands[0], DFmode))"
2969 {
2970   switch (which_alternative)
2971     {
2972     case 0:
2973     case 1:
2974       return output_387_reg_move (insn, operands);
2975
2976     case 2:
2977       return standard_80387_constant_opcode (operands[1]);
2978
2979     case 3:
2980     case 4:
2981       return "mov{q}\t{%1, %0|%0, %1}";
2982
2983     case 5:
2984       return "mov{l}\t{%1, %k0|%k0, %1}";
2985
2986     case 6:
2987       return "movabs{q}\t{%1, %0|%0, %1}";
2988
2989     case 7:
2990       return standard_sse_constant_opcode (insn, operands[1]);
2991
2992     case 8:
2993     case 9:
2994     case 10:
2995       switch (get_attr_mode (insn))
2996         {
2997         case MODE_V2DF:
2998           if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2999             return "%vmovapd\t{%1, %0|%0, %1}";
3000         case MODE_V4SF:
3001           return "%vmovaps\t{%1, %0|%0, %1}";
3002
3003         case MODE_DI:
3004           return "%vmovq\t{%1, %0|%0, %1}";
3005         case MODE_DF:
3006           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3007             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3008           return "%vmovsd\t{%1, %0|%0, %1}";
3009         case MODE_V1DF:
3010           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3011         case MODE_V2SF:
3012           return "%vmovlps\t{%1, %d0|%d0, %1}";
3013         default:
3014           gcc_unreachable ();
3015         }
3016
3017     case 11:
3018     case 12:
3019       /* Handle broken assemblers that require movd instead of movq.  */
3020       return "%vmovd\t{%1, %0|%0, %1}";
3021
3022     default:
3023       gcc_unreachable();
3024     }
3025 }
3026   [(set (attr "type")
3027         (cond [(eq_attr "alternative" "0,1,2")
3028                  (const_string "fmov")
3029                (eq_attr "alternative" "3,4,5,6")
3030                  (const_string "imov")
3031                (eq_attr "alternative" "7")
3032                  (const_string "sselog1")
3033               ]
3034               (const_string "ssemov")))
3035    (set (attr "modrm")
3036      (if_then_else
3037        (and (eq_attr "alternative" "6") (eq_attr "type" "imov"))
3038          (const_string "0")
3039          (const_string "*")))
3040    (set (attr "length_immediate")
3041      (if_then_else
3042        (and (eq_attr "alternative" "6") (eq_attr "type" "imov"))
3043          (const_string "8")
3044          (const_string "*")))
3045    (set (attr "prefix")
3046      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3047        (const_string "orig")
3048        (const_string "maybe_vex")))
3049    (set (attr "prefix_data16")
3050      (if_then_else (eq_attr "mode" "V1DF")
3051        (const_string "1")
3052        (const_string "*")))
3053    (set (attr "mode")
3054         (cond [(eq_attr "alternative" "0,1,2")
3055                  (const_string "DF")
3056                (eq_attr "alternative" "3,4,6,11,12")
3057                  (const_string "DI")
3058                (eq_attr "alternative" "5")
3059                  (const_string "SI")
3060
3061                /* xorps is one byte shorter.  */
3062                (eq_attr "alternative" "7")
3063                  (cond [(match_test "optimize_function_for_size_p (cfun)")
3064                           (const_string "V4SF")
3065                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3066                           (const_string "TI")
3067                        ]
3068                        (const_string "V2DF"))
3069
3070                /* For architectures resolving dependencies on
3071                   whole SSE registers use APD move to break dependency
3072                   chains, otherwise use short move to avoid extra work.
3073
3074                   movaps encodes one byte shorter.  */
3075                (eq_attr "alternative" "8")
3076                  (cond
3077                    [(match_test "optimize_function_for_size_p (cfun)")
3078                       (const_string "V4SF")
3079                     (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3080                       (const_string "V2DF")
3081                    ]
3082                    (const_string "DF"))
3083                /* For architectures resolving dependencies on register
3084                   parts we may avoid extra work to zero out upper part
3085                   of register.  */
3086                (eq_attr "alternative" "9")
3087                  (if_then_else
3088                    (match_test "TARGET_SSE_SPLIT_REGS")
3089                    (const_string "V1DF")
3090                    (const_string "DF"))
3091               ]
3092               (const_string "DF")))])
3093
3094 ;; Possible store forwarding (partial memory) stall in alternative 4.
3095 (define_insn "*movdf_internal"
3096   [(set (match_operand:DF 0 "nonimmediate_operand"
3097                 "=Yf*f,m   ,Yf*f,?Yd*r ,!o   ,x,x,x,m,*x,*x,*x,m")
3098         (match_operand:DF 1 "general_operand"
3099                 "Yf*fm,Yf*f,G   ,Yd*roF,Yd*rF,C,x,m,x,C ,*x,m ,*x"))]
3100   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3101    && (!can_create_pseudo_p ()
3102        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3103        || GET_CODE (operands[1]) != CONST_DOUBLE
3104        || (optimize_function_for_size_p (cfun)
3105            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3106                 && standard_80387_constant_p (operands[1]) > 0)
3107                || (TARGET_SSE2 && TARGET_SSE_MATH
3108                    && standard_sse_constant_p (operands[1])))
3109            && !memory_operand (operands[0], DFmode))
3110        || (!TARGET_MEMORY_MISMATCH_STALL
3111            && memory_operand (operands[0], DFmode)))"
3112 {
3113   switch (which_alternative)
3114     {
3115     case 0:
3116     case 1:
3117       return output_387_reg_move (insn, operands);
3118
3119     case 2:
3120       return standard_80387_constant_opcode (operands[1]);
3121
3122     case 3:
3123     case 4:
3124       return "#";
3125
3126     case 5:
3127     case 9:
3128       return standard_sse_constant_opcode (insn, operands[1]);
3129
3130     case 6:
3131     case 7:
3132     case 8:
3133     case 10:
3134     case 11:
3135     case 12:
3136       switch (get_attr_mode (insn))
3137         {
3138         case MODE_V2DF:
3139           if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3140             return "%vmovapd\t{%1, %0|%0, %1}";
3141         case MODE_V4SF:
3142           return "%vmovaps\t{%1, %0|%0, %1}";
3143
3144         case MODE_DI:
3145           return "%vmovq\t{%1, %0|%0, %1}";
3146         case MODE_DF:
3147           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3148             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3149           return "%vmovsd\t{%1, %0|%0, %1}";
3150         case MODE_V1DF:
3151           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3152         case MODE_V2SF:
3153           return "%vmovlps\t{%1, %d0|%d0, %1}";
3154         default:
3155           gcc_unreachable ();
3156         }
3157
3158     default:
3159       gcc_unreachable ();
3160     }
3161 }
3162   [(set (attr "isa")
3163      (if_then_else (eq_attr "alternative" "5,6,7,8")
3164        (const_string "sse2")
3165        (const_string "*")))
3166    (set (attr "type")
3167         (cond [(eq_attr "alternative" "0,1,2")
3168                  (const_string "fmov")
3169                (eq_attr "alternative" "3,4")
3170                  (const_string "multi")
3171                (eq_attr "alternative" "5,9")
3172                  (const_string "sselog1")
3173               ]
3174               (const_string "ssemov")))
3175    (set (attr "prefix")
3176      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3177        (const_string "orig")
3178        (const_string "maybe_vex")))
3179    (set (attr "prefix_data16")
3180      (if_then_else (eq_attr "mode" "V1DF")
3181        (const_string "1")
3182        (const_string "*")))
3183    (set (attr "mode")
3184         (cond [(eq_attr "alternative" "0,1,2")
3185                  (const_string "DF")
3186                (eq_attr "alternative" "3,4")
3187                  (const_string "SI")
3188
3189                /* For SSE1, we have many fewer alternatives.  */
3190                (not (match_test "TARGET_SSE2"))
3191                  (if_then_else
3192                    (eq_attr "alternative" "5,6,9,10")
3193                    (const_string "V4SF")
3194                    (const_string "V2SF"))
3195
3196                /* xorps is one byte shorter.  */
3197                (eq_attr "alternative" "5,9")
3198                  (cond [(match_test "optimize_function_for_size_p (cfun)")
3199                           (const_string "V4SF")
3200                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3201                           (const_string "TI")
3202                        ]
3203                        (const_string "V2DF"))
3204
3205                /* For architectures resolving dependencies on
3206                   whole SSE registers use APD move to break dependency
3207                   chains, otherwise use short move to avoid extra work.
3208
3209                   movaps encodes one byte shorter.  */
3210                (eq_attr "alternative" "6,10")
3211                  (cond
3212                    [(match_test "optimize_function_for_size_p (cfun)")
3213                       (const_string "V4SF")
3214                     (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3215                       (const_string "V2DF")
3216                    ]
3217                    (const_string "DF"))
3218                /* For architectures resolving dependencies on register
3219                   parts we may avoid extra work to zero out upper part
3220                   of register.  */
3221                (eq_attr "alternative" "7,11")
3222                  (if_then_else
3223                    (match_test "TARGET_SSE_SPLIT_REGS")
3224                    (const_string "V1DF")
3225                    (const_string "DF"))
3226               ]
3227               (const_string "DF")))])
3228
3229 (define_insn "*movsf_internal"
3230   [(set (match_operand:SF 0 "nonimmediate_operand"
3231           "=Yf*f,m   ,Yf*f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3232         (match_operand:SF 1 "general_operand"
3233           "Yf*fm,Yf*f,G   ,rmF,rF,C,x,m,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
3234   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3235    && (!can_create_pseudo_p ()
3236        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3237        || GET_CODE (operands[1]) != CONST_DOUBLE
3238        || (optimize_function_for_size_p (cfun)
3239            && ((!TARGET_SSE_MATH
3240                 && standard_80387_constant_p (operands[1]) > 0)
3241                || (TARGET_SSE_MATH
3242                    && standard_sse_constant_p (operands[1]))))
3243        || memory_operand (operands[0], SFmode))"
3244 {
3245   switch (which_alternative)
3246     {
3247     case 0:
3248     case 1:
3249       return output_387_reg_move (insn, operands);
3250
3251     case 2:
3252       return standard_80387_constant_opcode (operands[1]);
3253
3254     case 3:
3255     case 4:
3256       return "mov{l}\t{%1, %0|%0, %1}";
3257
3258     case 5:
3259       return standard_sse_constant_opcode (insn, operands[1]);
3260
3261     case 6:
3262       if (get_attr_mode (insn) == MODE_V4SF)
3263         return "%vmovaps\t{%1, %0|%0, %1}";
3264       if (TARGET_AVX)
3265         return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3266
3267     case 7:
3268     case 8:
3269       return "%vmovss\t{%1, %0|%0, %1}";
3270
3271     case 9:
3272     case 10:
3273     case 14:
3274     case 15:
3275       return "movd\t{%1, %0|%0, %1}";
3276
3277     case 11:
3278       return "movq\t{%1, %0|%0, %1}";
3279
3280     case 12:
3281     case 13:
3282       return "%vmovd\t{%1, %0|%0, %1}";
3283
3284     default:
3285       gcc_unreachable ();
3286     }
3287 }
3288   [(set (attr "type")
3289         (cond [(eq_attr "alternative" "0,1,2")
3290                  (const_string "fmov")
3291                (eq_attr "alternative" "3,4")
3292                  (const_string "imov")
3293                (eq_attr "alternative" "5")
3294                  (const_string "sselog1")
3295                (eq_attr "alternative" "9,10,11,14,15")
3296                  (const_string "mmxmov")
3297               ]
3298               (const_string "ssemov")))
3299    (set (attr "prefix")
3300      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3301        (const_string "maybe_vex")
3302        (const_string "orig")))
3303    (set (attr "mode")
3304         (cond [(eq_attr "alternative" "3,4,9,10")
3305                  (const_string "SI")
3306                (eq_attr "alternative" "5")
3307                  (if_then_else
3308                    (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3309                              (match_test "TARGET_SSE2"))
3310                         (not (match_test "optimize_function_for_size_p (cfun)")))
3311                    (const_string "TI")
3312                    (const_string "V4SF"))
3313                /* For architectures resolving dependencies on
3314                   whole SSE registers use APS move to break dependency
3315                   chains, otherwise use short move to avoid extra work.
3316
3317                   Do the same for architectures resolving dependencies on
3318                   the parts.  While in DF mode it is better to always handle
3319                   just register parts, the SF mode is different due to lack
3320                   of instructions to load just part of the register.  It is
3321                   better to maintain the whole registers in single format
3322                   to avoid problems on using packed logical operations.  */
3323                (eq_attr "alternative" "6")
3324                  (if_then_else
3325                    (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3326                         (match_test "TARGET_SSE_SPLIT_REGS"))
3327                    (const_string "V4SF")
3328                    (const_string "SF"))
3329                (eq_attr "alternative" "11")
3330                  (const_string "DI")]
3331                (const_string "SF")))])
3332
3333 (define_split
3334   [(set (match_operand 0 "any_fp_register_operand" "")
3335         (match_operand 1 "memory_operand" ""))]
3336   "reload_completed
3337    && (GET_MODE (operands[0]) == TFmode
3338        || GET_MODE (operands[0]) == XFmode
3339        || GET_MODE (operands[0]) == DFmode
3340        || GET_MODE (operands[0]) == SFmode)
3341    && (operands[2] = find_constant_src (insn))"
3342   [(set (match_dup 0) (match_dup 2))]
3343 {
3344   rtx c = operands[2];
3345   int r = REGNO (operands[0]);
3346
3347   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3348       || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3349     FAIL;
3350 })
3351
3352 (define_split
3353   [(set (match_operand 0 "any_fp_register_operand" "")
3354         (float_extend (match_operand 1 "memory_operand" "")))]
3355   "reload_completed
3356    && (GET_MODE (operands[0]) == TFmode
3357        || GET_MODE (operands[0]) == XFmode
3358        || GET_MODE (operands[0]) == DFmode)
3359    && (operands[2] = find_constant_src (insn))"
3360   [(set (match_dup 0) (match_dup 2))]
3361 {
3362   rtx c = operands[2];
3363   int r = REGNO (operands[0]);
3364
3365   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3366       || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3367     FAIL;
3368 })
3369
3370 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3371 (define_split
3372   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3373         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3374   "reload_completed
3375    && (standard_80387_constant_p (operands[1]) == 8
3376        || standard_80387_constant_p (operands[1]) == 9)"
3377   [(set (match_dup 0)(match_dup 1))
3378    (set (match_dup 0)
3379         (neg:X87MODEF (match_dup 0)))]
3380 {
3381   REAL_VALUE_TYPE r;
3382
3383   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3384   if (real_isnegzero (&r))
3385     operands[1] = CONST0_RTX (<MODE>mode);
3386   else
3387     operands[1] = CONST1_RTX (<MODE>mode);
3388 })
3389
3390 (define_split
3391   [(set (match_operand 0 "nonimmediate_operand" "")
3392         (match_operand 1 "general_operand" ""))]
3393   "reload_completed
3394    && (GET_MODE (operands[0]) == TFmode
3395        || GET_MODE (operands[0]) == XFmode
3396        || GET_MODE (operands[0]) == DFmode)
3397    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3398   [(const_int 0)]
3399   "ix86_split_long_move (operands); DONE;")
3400
3401 (define_insn "swapxf"
3402   [(set (match_operand:XF 0 "register_operand" "+f")
3403         (match_operand:XF 1 "register_operand" "+f"))
3404    (set (match_dup 1)
3405         (match_dup 0))]
3406   "TARGET_80387"
3407 {
3408   if (STACK_TOP_P (operands[0]))
3409     return "fxch\t%1";
3410   else
3411     return "fxch\t%0";
3412 }
3413   [(set_attr "type" "fxch")
3414    (set_attr "mode" "XF")])
3415
3416 (define_insn "*swap<mode>"
3417   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3418         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3419    (set (match_dup 1)
3420         (match_dup 0))]
3421   "TARGET_80387 || reload_completed"
3422 {
3423   if (STACK_TOP_P (operands[0]))
3424     return "fxch\t%1";
3425   else
3426     return "fxch\t%0";
3427 }
3428   [(set_attr "type" "fxch")
3429    (set_attr "mode" "<MODE>")])
3430 \f
3431 ;; Zero extension instructions
3432
3433 (define_expand "zero_extendsidi2"
3434   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3435         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3436   ""
3437 {
3438   if (!TARGET_64BIT)
3439     {
3440       emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3441       DONE;
3442     }
3443 })
3444
3445 (define_insn "*zero_extendsidi2_rex64"
3446   [(set (match_operand:DI 0 "nonimmediate_operand"  "=r,o,?*Ym,?!*y,?*Yi,*x")
3447         (zero_extend:DI
3448          (match_operand:SI 1 "nonimmediate_operand" "rm,0,r   ,m   ,r   ,m")))]
3449   "TARGET_64BIT"
3450   "@
3451    mov{l}\t{%1, %k0|%k0, %1}
3452    #
3453    movd\t{%1, %0|%0, %1}
3454    movd\t{%1, %0|%0, %1}
3455    %vmovd\t{%1, %0|%0, %1}
3456    %vmovd\t{%1, %0|%0, %1}"
3457   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3458    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3459    (set_attr "prefix_0f" "0,*,*,*,*,*")
3460    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3461
3462 (define_split
3463   [(set (match_operand:DI 0 "memory_operand" "")
3464         (zero_extend:DI (match_dup 0)))]
3465   "TARGET_64BIT"
3466   [(set (match_dup 4) (const_int 0))]
3467   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3468
3469 ;; %%% Kill me once multi-word ops are sane.
3470 (define_insn "zero_extendsidi2_1"
3471   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?!*y,?*Yi,*x")
3472         (zero_extend:DI
3473          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m   ,r   ,m")))
3474    (clobber (reg:CC FLAGS_REG))]
3475   "!TARGET_64BIT"
3476   "@
3477    #
3478    #
3479    #
3480    movd\t{%1, %0|%0, %1}
3481    movd\t{%1, %0|%0, %1}
3482    %vmovd\t{%1, %0|%0, %1}
3483    %vmovd\t{%1, %0|%0, %1}"
3484   [(set_attr "isa" "*,*,*,*,*,*,sse2")
3485    (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3486    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3487    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3488
3489 (define_split
3490   [(set (match_operand:DI 0 "register_operand" "")
3491         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3492    (clobber (reg:CC FLAGS_REG))]
3493   "!TARGET_64BIT && reload_completed
3494    && true_regnum (operands[0]) == true_regnum (operands[1])"
3495   [(set (match_dup 4) (const_int 0))]
3496   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3497
3498 (define_split
3499   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3500         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3501    (clobber (reg:CC FLAGS_REG))]
3502   "!TARGET_64BIT && reload_completed
3503    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3504   [(set (match_dup 3) (match_dup 1))
3505    (set (match_dup 4) (const_int 0))]
3506   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3507
3508 (define_insn "zero_extend<mode>di2"
3509   [(set (match_operand:DI 0 "register_operand" "=r")
3510         (zero_extend:DI
3511          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3512   "TARGET_64BIT"
3513   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3514   [(set_attr "type" "imovx")
3515    (set_attr "mode" "SI")])
3516
3517 (define_expand "zero_extendhisi2"
3518   [(set (match_operand:SI 0 "register_operand" "")
3519         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3520   ""
3521 {
3522   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3523     {
3524       operands[1] = force_reg (HImode, operands[1]);
3525       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3526       DONE;
3527     }
3528 })
3529
3530 (define_insn_and_split "zero_extendhisi2_and"
3531   [(set (match_operand:SI 0 "register_operand" "=r")
3532         (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3533    (clobber (reg:CC FLAGS_REG))]
3534   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3535   "#"
3536   "&& reload_completed"
3537   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3538               (clobber (reg:CC FLAGS_REG))])]
3539   ""
3540   [(set_attr "type" "alu1")
3541    (set_attr "mode" "SI")])
3542
3543 (define_insn "*zero_extendhisi2_movzwl"
3544   [(set (match_operand:SI 0 "register_operand" "=r")
3545         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3546   "!TARGET_ZERO_EXTEND_WITH_AND
3547    || optimize_function_for_size_p (cfun)"
3548   "movz{wl|x}\t{%1, %0|%0, %1}"
3549   [(set_attr "type" "imovx")
3550    (set_attr "mode" "SI")])
3551
3552 (define_expand "zero_extendqi<mode>2"
3553   [(parallel
3554     [(set (match_operand:SWI24 0 "register_operand" "")
3555           (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3556      (clobber (reg:CC FLAGS_REG))])])
3557
3558 (define_insn "*zero_extendqi<mode>2_and"
3559   [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3560         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3561    (clobber (reg:CC FLAGS_REG))]
3562   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3563   "#"
3564   [(set_attr "type" "alu1")
3565    (set_attr "mode" "<MODE>")])
3566
3567 ;; When source and destination does not overlap, clear destination
3568 ;; first and then do the movb
3569 (define_split
3570   [(set (match_operand:SWI24 0 "register_operand" "")
3571         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3572    (clobber (reg:CC FLAGS_REG))]
3573   "reload_completed
3574    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3575    && ANY_QI_REG_P (operands[0])
3576    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3577    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3578   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3579 {
3580   operands[2] = gen_lowpart (QImode, operands[0]);
3581   ix86_expand_clear (operands[0]);
3582 })
3583
3584 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3585   [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3586         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3587    (clobber (reg:CC FLAGS_REG))]
3588   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3589   "#"
3590   [(set_attr "type" "imovx,alu1")
3591    (set_attr "mode" "<MODE>")])
3592
3593 ;; For the movzbl case strip only the clobber
3594 (define_split
3595   [(set (match_operand:SWI24 0 "register_operand" "")
3596         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3597    (clobber (reg:CC FLAGS_REG))]
3598   "reload_completed
3599    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3600    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3601   [(set (match_dup 0)
3602         (zero_extend:SWI24 (match_dup 1)))])
3603
3604 ; zero extend to SImode to avoid partial register stalls
3605 (define_insn "*zero_extendqi<mode>2_movzbl"
3606   [(set (match_operand:SWI24 0 "register_operand" "=r")
3607         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3608   "reload_completed
3609    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3610   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3611   [(set_attr "type" "imovx")
3612    (set_attr "mode" "SI")])
3613
3614 ;; Rest is handled by single and.
3615 (define_split
3616   [(set (match_operand:SWI24 0 "register_operand" "")
3617         (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3618    (clobber (reg:CC FLAGS_REG))]
3619   "reload_completed
3620    && true_regnum (operands[0]) == true_regnum (operands[1])"
3621   [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3622               (clobber (reg:CC FLAGS_REG))])])
3623 \f
3624 ;; Sign extension instructions
3625
3626 (define_expand "extendsidi2"
3627   [(set (match_operand:DI 0 "register_operand" "")
3628         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3629   ""
3630 {
3631   if (!TARGET_64BIT)
3632     {
3633       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3634       DONE;
3635     }
3636 })
3637
3638 (define_insn "*extendsidi2_rex64"
3639   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3640         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3641   "TARGET_64BIT"
3642   "@
3643    {cltq|cdqe}
3644    movs{lq|x}\t{%1, %0|%0, %1}"
3645   [(set_attr "type" "imovx")
3646    (set_attr "mode" "DI")
3647    (set_attr "prefix_0f" "0")
3648    (set_attr "modrm" "0,1")])
3649
3650 (define_insn "extendsidi2_1"
3651   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3652         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3653    (clobber (reg:CC FLAGS_REG))
3654    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3655   "!TARGET_64BIT"
3656   "#")
3657
3658 ;; Extend to memory case when source register does die.
3659 (define_split
3660   [(set (match_operand:DI 0 "memory_operand" "")
3661         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3662    (clobber (reg:CC FLAGS_REG))
3663    (clobber (match_operand:SI 2 "register_operand" ""))]
3664   "(reload_completed
3665     && dead_or_set_p (insn, operands[1])
3666     && !reg_mentioned_p (operands[1], operands[0]))"
3667   [(set (match_dup 3) (match_dup 1))
3668    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3669               (clobber (reg:CC FLAGS_REG))])
3670    (set (match_dup 4) (match_dup 1))]
3671   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3672
3673 ;; Extend to memory case when source register does not die.
3674 (define_split
3675   [(set (match_operand:DI 0 "memory_operand" "")
3676         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3677    (clobber (reg:CC FLAGS_REG))
3678    (clobber (match_operand:SI 2 "register_operand" ""))]
3679   "reload_completed"
3680   [(const_int 0)]
3681 {
3682   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3683
3684   emit_move_insn (operands[3], operands[1]);
3685
3686   /* Generate a cltd if possible and doing so it profitable.  */
3687   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3688       && true_regnum (operands[1]) == AX_REG
3689       && true_regnum (operands[2]) == DX_REG)
3690     {
3691       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3692     }
3693   else
3694     {
3695       emit_move_insn (operands[2], operands[1]);
3696       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3697     }
3698   emit_move_insn (operands[4], operands[2]);
3699   DONE;
3700 })
3701
3702 ;; Extend to register case.  Optimize case where source and destination
3703 ;; registers match and cases where we can use cltd.
3704 (define_split
3705   [(set (match_operand:DI 0 "register_operand" "")
3706         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3707    (clobber (reg:CC FLAGS_REG))
3708    (clobber (match_scratch:SI 2 ""))]
3709   "reload_completed"
3710   [(const_int 0)]
3711 {
3712   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3713
3714   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3715     emit_move_insn (operands[3], operands[1]);
3716
3717   /* Generate a cltd if possible and doing so it profitable.  */
3718   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3719       && true_regnum (operands[3]) == AX_REG
3720       && true_regnum (operands[4]) == DX_REG)
3721     {
3722       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3723       DONE;
3724     }
3725
3726   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3727     emit_move_insn (operands[4], operands[1]);
3728
3729   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3730   DONE;
3731 })
3732
3733 (define_insn "extend<mode>di2"
3734   [(set (match_operand:DI 0 "register_operand" "=r")
3735         (sign_extend:DI
3736          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3737   "TARGET_64BIT"
3738   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3739   [(set_attr "type" "imovx")
3740    (set_attr "mode" "DI")])
3741
3742 (define_insn "extendhisi2"
3743   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3744         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3745   ""
3746 {
3747   switch (get_attr_prefix_0f (insn))
3748     {
3749     case 0:
3750       return "{cwtl|cwde}";
3751     default:
3752       return "movs{wl|x}\t{%1, %0|%0, %1}";
3753     }
3754 }
3755   [(set_attr "type" "imovx")
3756    (set_attr "mode" "SI")
3757    (set (attr "prefix_0f")
3758      ;; movsx is short decodable while cwtl is vector decoded.
3759      (if_then_else (and (eq_attr "cpu" "!k6")
3760                         (eq_attr "alternative" "0"))
3761         (const_string "0")
3762         (const_string "1")))
3763    (set (attr "modrm")
3764      (if_then_else (eq_attr "prefix_0f" "0")
3765         (const_string "0")
3766         (const_string "1")))])
3767
3768 (define_insn "*extendhisi2_zext"
3769   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3770         (zero_extend:DI
3771          (sign_extend:SI
3772           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3773   "TARGET_64BIT"
3774 {
3775   switch (get_attr_prefix_0f (insn))
3776     {
3777     case 0:
3778       return "{cwtl|cwde}";
3779     default:
3780       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3781     }
3782 }
3783   [(set_attr "type" "imovx")
3784    (set_attr "mode" "SI")
3785    (set (attr "prefix_0f")
3786      ;; movsx is short decodable while cwtl is vector decoded.
3787      (if_then_else (and (eq_attr "cpu" "!k6")
3788                         (eq_attr "alternative" "0"))
3789         (const_string "0")
3790         (const_string "1")))
3791    (set (attr "modrm")
3792      (if_then_else (eq_attr "prefix_0f" "0")
3793         (const_string "0")
3794         (const_string "1")))])
3795
3796 (define_insn "extendqisi2"
3797   [(set (match_operand:SI 0 "register_operand" "=r")
3798         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3799   ""
3800   "movs{bl|x}\t{%1, %0|%0, %1}"
3801    [(set_attr "type" "imovx")
3802     (set_attr "mode" "SI")])
3803
3804 (define_insn "*extendqisi2_zext"
3805   [(set (match_operand:DI 0 "register_operand" "=r")
3806         (zero_extend:DI
3807           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3808   "TARGET_64BIT"
3809   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3810    [(set_attr "type" "imovx")
3811     (set_attr "mode" "SI")])
3812
3813 (define_insn "extendqihi2"
3814   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3815         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3816   ""
3817 {
3818   switch (get_attr_prefix_0f (insn))
3819     {
3820     case 0:
3821       return "{cbtw|cbw}";
3822     default:
3823       return "movs{bw|x}\t{%1, %0|%0, %1}";
3824     }
3825 }
3826   [(set_attr "type" "imovx")
3827    (set_attr "mode" "HI")
3828    (set (attr "prefix_0f")
3829      ;; movsx is short decodable while cwtl is vector decoded.
3830      (if_then_else (and (eq_attr "cpu" "!k6")
3831                         (eq_attr "alternative" "0"))
3832         (const_string "0")
3833         (const_string "1")))
3834    (set (attr "modrm")
3835      (if_then_else (eq_attr "prefix_0f" "0")
3836         (const_string "0")
3837         (const_string "1")))])
3838 \f
3839 ;; Conversions between float and double.
3840
3841 ;; These are all no-ops in the model used for the 80387.
3842 ;; So just emit moves.
3843
3844 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3845 (define_split
3846   [(set (match_operand:DF 0 "push_operand" "")
3847         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3848   "reload_completed"
3849   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3850    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3851
3852 (define_split
3853   [(set (match_operand:XF 0 "push_operand" "")
3854         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3855   "reload_completed"
3856   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3857    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3858   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3859
3860 (define_expand "extendsfdf2"
3861   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3862         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3863   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3864 {
3865   /* ??? Needed for compress_float_constant since all fp constants
3866      are TARGET_LEGITIMATE_CONSTANT_P.  */
3867   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3868     {
3869       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3870           && standard_80387_constant_p (operands[1]) > 0)
3871         {
3872           operands[1] = simplify_const_unary_operation
3873             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3874           emit_move_insn_1 (operands[0], operands[1]);
3875           DONE;
3876         }
3877       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3878     }
3879 })
3880
3881 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3882    cvtss2sd:
3883       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3884       cvtps2pd xmm2,xmm1
3885    We do the conversion post reload to avoid producing of 128bit spills
3886    that might lead to ICE on 32bit target.  The sequence unlikely combine
3887    anyway.  */
3888 (define_split
3889   [(set (match_operand:DF 0 "register_operand" "")
3890         (float_extend:DF
3891           (match_operand:SF 1 "nonimmediate_operand" "")))]
3892   "TARGET_USE_VECTOR_FP_CONVERTS
3893    && optimize_insn_for_speed_p ()
3894    && reload_completed && SSE_REG_P (operands[0])"
3895    [(set (match_dup 2)
3896          (float_extend:V2DF
3897            (vec_select:V2SF
3898              (match_dup 3)
3899              (parallel [(const_int 0) (const_int 1)]))))]
3900 {
3901   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3902   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3903   /* Use movss for loading from memory, unpcklps reg, reg for registers.
3904      Try to avoid move when unpacking can be done in source.  */
3905   if (REG_P (operands[1]))
3906     {
3907       /* If it is unsafe to overwrite upper half of source, we need
3908          to move to destination and unpack there.  */
3909       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3910            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3911           && true_regnum (operands[0]) != true_regnum (operands[1]))
3912         {
3913           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3914           emit_move_insn (tmp, operands[1]);
3915         }
3916       else
3917         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3918       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3919                                              operands[3]));
3920     }
3921   else
3922     emit_insn (gen_vec_setv4sf_0 (operands[3],
3923                                   CONST0_RTX (V4SFmode), operands[1]));
3924 })
3925
3926 (define_insn "*extendsfdf2_mixed"
3927   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3928         (float_extend:DF
3929           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3930   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3931 {
3932   switch (which_alternative)
3933     {
3934     case 0:
3935     case 1:
3936       return output_387_reg_move (insn, operands);
3937
3938     case 2:
3939       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3940
3941     default:
3942       gcc_unreachable ();
3943     }
3944 }
3945   [(set_attr "type" "fmov,fmov,ssecvt")
3946    (set_attr "prefix" "orig,orig,maybe_vex")
3947    (set_attr "mode" "SF,XF,DF")])
3948
3949 (define_insn "*extendsfdf2_sse"
3950   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3951         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3952   "TARGET_SSE2 && TARGET_SSE_MATH"
3953   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3954   [(set_attr "type" "ssecvt")
3955    (set_attr "prefix" "maybe_vex")
3956    (set_attr "mode" "DF")])
3957
3958 (define_insn "*extendsfdf2_i387"
3959   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3960         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3961   "TARGET_80387"
3962   "* return output_387_reg_move (insn, operands);"
3963   [(set_attr "type" "fmov")
3964    (set_attr "mode" "SF,XF")])
3965
3966 (define_expand "extend<mode>xf2"
3967   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3968         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3969   "TARGET_80387"
3970 {
3971   /* ??? Needed for compress_float_constant since all fp constants
3972      are TARGET_LEGITIMATE_CONSTANT_P.  */
3973   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3974     {
3975       if (standard_80387_constant_p (operands[1]) > 0)
3976         {
3977           operands[1] = simplify_const_unary_operation
3978             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3979           emit_move_insn_1 (operands[0], operands[1]);
3980           DONE;
3981         }
3982       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3983     }
3984 })
3985
3986 (define_insn "*extend<mode>xf2_i387"
3987   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3988         (float_extend:XF
3989           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3990   "TARGET_80387"
3991   "* return output_387_reg_move (insn, operands);"
3992   [(set_attr "type" "fmov")
3993    (set_attr "mode" "<MODE>,XF")])
3994
3995 ;; %%% This seems bad bad news.
3996 ;; This cannot output into an f-reg because there is no way to be sure
3997 ;; of truncating in that case.  Otherwise this is just like a simple move
3998 ;; insn.  So we pretend we can output to a reg in order to get better
3999 ;; register preferencing, but we really use a stack slot.
4000
4001 ;; Conversion from DFmode to SFmode.
4002
4003 (define_expand "truncdfsf2"
4004   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4005         (float_truncate:SF
4006           (match_operand:DF 1 "nonimmediate_operand" "")))]
4007   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4008 {
4009   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4010     ;
4011   else if (flag_unsafe_math_optimizations)
4012     ;
4013   else
4014     {
4015       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4016       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4017       DONE;
4018     }
4019 })
4020
4021 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4022    cvtsd2ss:
4023       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4024       cvtpd2ps xmm2,xmm1
4025    We do the conversion post reload to avoid producing of 128bit spills
4026    that might lead to ICE on 32bit target.  The sequence unlikely combine
4027    anyway.  */
4028 (define_split
4029   [(set (match_operand:SF 0 "register_operand" "")
4030         (float_truncate:SF
4031           (match_operand:DF 1 "nonimmediate_operand" "")))]
4032   "TARGET_USE_VECTOR_FP_CONVERTS
4033    && optimize_insn_for_speed_p ()
4034    && reload_completed && SSE_REG_P (operands[0])"
4035    [(set (match_dup 2)
4036          (vec_concat:V4SF
4037            (float_truncate:V2SF
4038              (match_dup 4))
4039            (match_dup 3)))]
4040 {
4041   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4042   operands[3] = CONST0_RTX (V2SFmode);
4043   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4044   /* Use movsd for loading from memory, unpcklpd for registers.
4045      Try to avoid move when unpacking can be done in source, or SSE3
4046      movddup is available.  */
4047   if (REG_P (operands[1]))
4048     {
4049       if (!TARGET_SSE3
4050           && true_regnum (operands[0]) != true_regnum (operands[1])
4051           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4052               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4053         {
4054           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4055           emit_move_insn (tmp, operands[1]);
4056           operands[1] = tmp;
4057         }
4058       else if (!TARGET_SSE3)
4059         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4060       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4061     }
4062   else
4063     emit_insn (gen_sse2_loadlpd (operands[4],
4064                                  CONST0_RTX (V2DFmode), operands[1]));
4065 })
4066
4067 (define_expand "truncdfsf2_with_temp"
4068   [(parallel [(set (match_operand:SF 0 "" "")
4069                    (float_truncate:SF (match_operand:DF 1 "" "")))
4070               (clobber (match_operand:SF 2 "" ""))])])
4071
4072 (define_insn "*truncdfsf_fast_mixed"
4073   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4074         (float_truncate:SF
4075           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4076   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4077 {
4078   switch (which_alternative)
4079     {
4080     case 0:
4081       return output_387_reg_move (insn, operands);
4082     case 1:
4083       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4084     default:
4085       gcc_unreachable ();
4086     }
4087 }
4088   [(set_attr "type" "fmov,ssecvt")
4089    (set_attr "prefix" "orig,maybe_vex")
4090    (set_attr "mode" "SF")])
4091
4092 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4093 ;; because nothing we do here is unsafe.
4094 (define_insn "*truncdfsf_fast_sse"
4095   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4096         (float_truncate:SF
4097           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4098   "TARGET_SSE2 && TARGET_SSE_MATH"
4099   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4100   [(set_attr "type" "ssecvt")
4101    (set_attr "prefix" "maybe_vex")
4102    (set_attr "mode" "SF")])
4103
4104 (define_insn "*truncdfsf_fast_i387"
4105   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4106         (float_truncate:SF
4107           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4108   "TARGET_80387 && flag_unsafe_math_optimizations"
4109   "* return output_387_reg_move (insn, operands);"
4110   [(set_attr "type" "fmov")
4111    (set_attr "mode" "SF")])
4112
4113 (define_insn "*truncdfsf_mixed"
4114   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,x ,?f,?x,?*r")
4115         (float_truncate:SF
4116           (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4117    (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
4118   "TARGET_MIX_SSE_I387"
4119 {
4120   switch (which_alternative)
4121     {
4122     case 0:
4123       return output_387_reg_move (insn, operands);
4124     case 1:
4125       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4126
4127     default:
4128       return "#";
4129     }
4130 }
4131   [(set_attr "isa" "*,sse2,*,*,*")
4132    (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4133    (set_attr "unit" "*,*,i387,i387,i387")
4134    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4135    (set_attr "mode" "SF")])
4136
4137 (define_insn "*truncdfsf_i387"
4138   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4139         (float_truncate:SF
4140           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4141    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4142   "TARGET_80387"
4143 {
4144   switch (which_alternative)
4145     {
4146     case 0:
4147       return output_387_reg_move (insn, operands);
4148
4149     default:
4150       return "#";
4151     }
4152 }
4153   [(set_attr "type" "fmov,multi,multi,multi")
4154    (set_attr "unit" "*,i387,i387,i387")
4155    (set_attr "mode" "SF")])
4156
4157 (define_insn "*truncdfsf2_i387_1"
4158   [(set (match_operand:SF 0 "memory_operand" "=m")
4159         (float_truncate:SF
4160           (match_operand:DF 1 "register_operand" "f")))]
4161   "TARGET_80387
4162    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4163    && !TARGET_MIX_SSE_I387"
4164   "* return output_387_reg_move (insn, operands);"
4165   [(set_attr "type" "fmov")
4166    (set_attr "mode" "SF")])
4167
4168 (define_split
4169   [(set (match_operand:SF 0 "register_operand" "")
4170         (float_truncate:SF
4171          (match_operand:DF 1 "fp_register_operand" "")))
4172    (clobber (match_operand 2 "" ""))]
4173   "reload_completed"
4174   [(set (match_dup 2) (match_dup 1))
4175    (set (match_dup 0) (match_dup 2))]
4176   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4177
4178 ;; Conversion from XFmode to {SF,DF}mode
4179
4180 (define_expand "truncxf<mode>2"
4181   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4182                    (float_truncate:MODEF
4183                      (match_operand:XF 1 "register_operand" "")))
4184               (clobber (match_dup 2))])]
4185   "TARGET_80387"
4186 {
4187   if (flag_unsafe_math_optimizations)
4188     {
4189       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4190       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4191       if (reg != operands[0])
4192         emit_move_insn (operands[0], reg);
4193       DONE;
4194     }
4195   else
4196     operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4197 })
4198
4199 (define_insn "*truncxfsf2_mixed"
4200   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4201         (float_truncate:SF
4202           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4203    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4204   "TARGET_80387"
4205 {
4206   gcc_assert (!which_alternative);
4207   return output_387_reg_move (insn, operands);
4208 }
4209   [(set_attr "type" "fmov,multi,multi,multi")
4210    (set_attr "unit" "*,i387,i387,i387")
4211    (set_attr "mode" "SF")])
4212
4213 (define_insn "*truncxfdf2_mixed"
4214   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4215         (float_truncate:DF
4216           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4217    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4218   "TARGET_80387"
4219 {
4220   gcc_assert (!which_alternative);
4221   return output_387_reg_move (insn, operands);
4222 }
4223   [(set_attr "isa" "*,*,sse2,*")
4224    (set_attr "type" "fmov,multi,multi,multi")
4225    (set_attr "unit" "*,i387,i387,i387")
4226    (set_attr "mode" "DF")])
4227
4228 (define_insn "truncxf<mode>2_i387_noop"
4229   [(set (match_operand:MODEF 0 "register_operand" "=f")
4230         (float_truncate:MODEF
4231           (match_operand:XF 1 "register_operand" "f")))]
4232   "TARGET_80387 && flag_unsafe_math_optimizations"
4233   "* return output_387_reg_move (insn, operands);"
4234   [(set_attr "type" "fmov")
4235    (set_attr "mode" "<MODE>")])
4236
4237 (define_insn "*truncxf<mode>2_i387"
4238   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4239         (float_truncate:MODEF
4240           (match_operand:XF 1 "register_operand" "f")))]
4241   "TARGET_80387"
4242   "* return output_387_reg_move (insn, operands);"
4243   [(set_attr "type" "fmov")
4244    (set_attr "mode" "<MODE>")])
4245
4246 (define_split
4247   [(set (match_operand:MODEF 0 "register_operand" "")
4248         (float_truncate:MODEF
4249           (match_operand:XF 1 "register_operand" "")))
4250    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4251   "TARGET_80387 && reload_completed"
4252   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4253    (set (match_dup 0) (match_dup 2))])
4254
4255 (define_split
4256   [(set (match_operand:MODEF 0 "memory_operand" "")
4257         (float_truncate:MODEF
4258           (match_operand:XF 1 "register_operand" "")))
4259    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4260   "TARGET_80387"
4261   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4262 \f
4263 ;; Signed conversion to DImode.
4264
4265 (define_expand "fix_truncxfdi2"
4266   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4267                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4268               (clobber (reg:CC FLAGS_REG))])]
4269   "TARGET_80387"
4270 {
4271   if (TARGET_FISTTP)
4272    {
4273      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4274      DONE;
4275    }
4276 })
4277
4278 (define_expand "fix_trunc<mode>di2"
4279   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4280                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4281               (clobber (reg:CC FLAGS_REG))])]
4282   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4283 {
4284   if (TARGET_FISTTP
4285       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4286    {
4287      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4288      DONE;
4289    }
4290   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4291    {
4292      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4293      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4294      if (out != operands[0])
4295         emit_move_insn (operands[0], out);
4296      DONE;
4297    }
4298 })
4299
4300 ;; Signed conversion to SImode.
4301
4302 (define_expand "fix_truncxfsi2"
4303   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4304                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4305               (clobber (reg:CC FLAGS_REG))])]
4306   "TARGET_80387"
4307 {
4308   if (TARGET_FISTTP)
4309    {
4310      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4311      DONE;
4312    }
4313 })
4314
4315 (define_expand "fix_trunc<mode>si2"
4316   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4317                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4318               (clobber (reg:CC FLAGS_REG))])]
4319   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4320 {
4321   if (TARGET_FISTTP
4322       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4323    {
4324      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4325      DONE;
4326    }
4327   if (SSE_FLOAT_MODE_P (<MODE>mode))
4328    {
4329      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4330      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4331      if (out != operands[0])
4332         emit_move_insn (operands[0], out);
4333      DONE;
4334    }
4335 })
4336
4337 ;; Signed conversion to HImode.
4338
4339 (define_expand "fix_trunc<mode>hi2"
4340   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4341                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4342               (clobber (reg:CC FLAGS_REG))])]
4343   "TARGET_80387
4344    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4345 {
4346   if (TARGET_FISTTP)
4347    {
4348      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4349      DONE;
4350    }
4351 })
4352
4353 ;; Unsigned conversion to SImode.
4354
4355 (define_expand "fixuns_trunc<mode>si2"
4356   [(parallel
4357     [(set (match_operand:SI 0 "register_operand" "")
4358           (unsigned_fix:SI
4359             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4360      (use (match_dup 2))
4361      (clobber (match_scratch:<ssevecmode> 3 ""))
4362      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4363   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4364 {
4365   enum machine_mode mode = <MODE>mode;
4366   enum machine_mode vecmode = <ssevecmode>mode;
4367   REAL_VALUE_TYPE TWO31r;
4368   rtx two31;
4369
4370   if (optimize_insn_for_size_p ())
4371     FAIL;
4372
4373   real_ldexp (&TWO31r, &dconst1, 31);
4374   two31 = const_double_from_real_value (TWO31r, mode);
4375   two31 = ix86_build_const_vector (vecmode, true, two31);
4376   operands[2] = force_reg (vecmode, two31);
4377 })
4378
4379 (define_insn_and_split "*fixuns_trunc<mode>_1"
4380   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4381         (unsigned_fix:SI
4382           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4383    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4384    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4385    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4386   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4387    && optimize_function_for_speed_p (cfun)"
4388   "#"
4389   "&& reload_completed"
4390   [(const_int 0)]
4391 {
4392   ix86_split_convert_uns_si_sse (operands);
4393   DONE;
4394 })
4395
4396 ;; Unsigned conversion to HImode.
4397 ;; Without these patterns, we'll try the unsigned SI conversion which
4398 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4399
4400 (define_expand "fixuns_trunc<mode>hi2"
4401   [(set (match_dup 2)
4402         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4403    (set (match_operand:HI 0 "nonimmediate_operand" "")
4404         (subreg:HI (match_dup 2) 0))]
4405   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4406   "operands[2] = gen_reg_rtx (SImode);")
4407
4408 ;; When SSE is available, it is always faster to use it!
4409 (define_insn "fix_trunc<mode>di_sse"
4410   [(set (match_operand:DI 0 "register_operand" "=r,r")
4411         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4412   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4413    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4414   "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4415   [(set_attr "type" "sseicvt")
4416    (set_attr "prefix" "maybe_vex")
4417    (set_attr "prefix_rex" "1")
4418    (set_attr "mode" "<MODE>")
4419    (set_attr "athlon_decode" "double,vector")
4420    (set_attr "amdfam10_decode" "double,double")
4421    (set_attr "bdver1_decode" "double,double")])
4422
4423 (define_insn "fix_trunc<mode>si_sse"
4424   [(set (match_operand:SI 0 "register_operand" "=r,r")
4425         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4426   "SSE_FLOAT_MODE_P (<MODE>mode)
4427    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4428   "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4429   [(set_attr "type" "sseicvt")
4430    (set_attr "prefix" "maybe_vex")
4431    (set_attr "mode" "<MODE>")
4432    (set_attr "athlon_decode" "double,vector")
4433    (set_attr "amdfam10_decode" "double,double")
4434    (set_attr "bdver1_decode" "double,double")])
4435
4436 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4437 (define_peephole2
4438   [(set (match_operand:MODEF 0 "register_operand" "")
4439         (match_operand:MODEF 1 "memory_operand" ""))
4440    (set (match_operand:SWI48x 2 "register_operand" "")
4441         (fix:SWI48x (match_dup 0)))]
4442   "TARGET_SHORTEN_X87_SSE
4443    && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4444    && peep2_reg_dead_p (2, operands[0])"
4445   [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4446
4447 ;; Avoid vector decoded forms of the instruction.
4448 (define_peephole2
4449   [(match_scratch:DF 2 "x")
4450    (set (match_operand:SWI48x 0 "register_operand" "")
4451         (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4452   "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4453   [(set (match_dup 2) (match_dup 1))
4454    (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4455
4456 (define_peephole2
4457   [(match_scratch:SF 2 "x")
4458    (set (match_operand:SWI48x 0 "register_operand" "")
4459         (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4460   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4461   [(set (match_dup 2) (match_dup 1))
4462    (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4463
4464 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4465   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4466         (fix:SWI248x (match_operand 1 "register_operand" "")))]
4467   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4468    && TARGET_FISTTP
4469    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4470          && (TARGET_64BIT || <MODE>mode != DImode))
4471         && TARGET_SSE_MATH)
4472    && can_create_pseudo_p ()"
4473   "#"
4474   "&& 1"
4475   [(const_int 0)]
4476 {
4477   if (memory_operand (operands[0], VOIDmode))
4478     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4479   else
4480     {
4481       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4482       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4483                                                             operands[1],
4484                                                             operands[2]));
4485     }
4486   DONE;
4487 }
4488   [(set_attr "type" "fisttp")
4489    (set_attr "mode" "<MODE>")])
4490
4491 (define_insn "fix_trunc<mode>_i387_fisttp"
4492   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4493         (fix:SWI248x (match_operand 1 "register_operand" "f")))
4494    (clobber (match_scratch:XF 2 "=&1f"))]
4495   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4496    && TARGET_FISTTP
4497    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4498          && (TARGET_64BIT || <MODE>mode != DImode))
4499         && TARGET_SSE_MATH)"
4500   "* return output_fix_trunc (insn, operands, true);"
4501   [(set_attr "type" "fisttp")
4502    (set_attr "mode" "<MODE>")])
4503
4504 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4505   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4506         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4507    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4508    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4509   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4510    && TARGET_FISTTP
4511    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4512         && (TARGET_64BIT || <MODE>mode != DImode))
4513         && TARGET_SSE_MATH)"
4514   "#"
4515   [(set_attr "type" "fisttp")
4516    (set_attr "mode" "<MODE>")])
4517
4518 (define_split
4519   [(set (match_operand:SWI248x 0 "register_operand" "")
4520         (fix:SWI248x (match_operand 1 "register_operand" "")))
4521    (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4522    (clobber (match_scratch 3 ""))]
4523   "reload_completed"
4524   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4525               (clobber (match_dup 3))])
4526    (set (match_dup 0) (match_dup 2))])
4527
4528 (define_split
4529   [(set (match_operand:SWI248x 0 "memory_operand" "")
4530         (fix:SWI248x (match_operand 1 "register_operand" "")))
4531    (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4532    (clobber (match_scratch 3 ""))]
4533   "reload_completed"
4534   [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4535               (clobber (match_dup 3))])])
4536
4537 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4538 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4539 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4540 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4541 ;; function in i386.c.
4542 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4543   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4544         (fix:SWI248x (match_operand 1 "register_operand" "")))
4545    (clobber (reg:CC FLAGS_REG))]
4546   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4547    && !TARGET_FISTTP
4548    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4549          && (TARGET_64BIT || <MODE>mode != DImode))
4550    && can_create_pseudo_p ()"
4551   "#"
4552   "&& 1"
4553   [(const_int 0)]
4554 {
4555   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4556
4557   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4558   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4559   if (memory_operand (operands[0], VOIDmode))
4560     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4561                                          operands[2], operands[3]));
4562   else
4563     {
4564       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4565       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4566                                                      operands[2], operands[3],
4567                                                      operands[4]));
4568     }
4569   DONE;
4570 }
4571   [(set_attr "type" "fistp")
4572    (set_attr "i387_cw" "trunc")
4573    (set_attr "mode" "<MODE>")])
4574
4575 (define_insn "fix_truncdi_i387"
4576   [(set (match_operand:DI 0 "memory_operand" "=m")
4577         (fix:DI (match_operand 1 "register_operand" "f")))
4578    (use (match_operand:HI 2 "memory_operand" "m"))
4579    (use (match_operand:HI 3 "memory_operand" "m"))
4580    (clobber (match_scratch:XF 4 "=&1f"))]
4581   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4582    && !TARGET_FISTTP
4583    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4584   "* return output_fix_trunc (insn, operands, false);"
4585   [(set_attr "type" "fistp")
4586    (set_attr "i387_cw" "trunc")
4587    (set_attr "mode" "DI")])
4588
4589 (define_insn "fix_truncdi_i387_with_temp"
4590   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4591         (fix:DI (match_operand 1 "register_operand" "f,f")))
4592    (use (match_operand:HI 2 "memory_operand" "m,m"))
4593    (use (match_operand:HI 3 "memory_operand" "m,m"))
4594    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4595    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4596   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4597    && !TARGET_FISTTP
4598    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4599   "#"
4600   [(set_attr "type" "fistp")
4601    (set_attr "i387_cw" "trunc")
4602    (set_attr "mode" "DI")])
4603
4604 (define_split
4605   [(set (match_operand:DI 0 "register_operand" "")
4606         (fix:DI (match_operand 1 "register_operand" "")))
4607    (use (match_operand:HI 2 "memory_operand" ""))
4608    (use (match_operand:HI 3 "memory_operand" ""))
4609    (clobber (match_operand:DI 4 "memory_operand" ""))
4610    (clobber (match_scratch 5 ""))]
4611   "reload_completed"
4612   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4613               (use (match_dup 2))
4614               (use (match_dup 3))
4615               (clobber (match_dup 5))])
4616    (set (match_dup 0) (match_dup 4))])
4617
4618 (define_split
4619   [(set (match_operand:DI 0 "memory_operand" "")
4620         (fix:DI (match_operand 1 "register_operand" "")))
4621    (use (match_operand:HI 2 "memory_operand" ""))
4622    (use (match_operand:HI 3 "memory_operand" ""))
4623    (clobber (match_operand:DI 4 "memory_operand" ""))
4624    (clobber (match_scratch 5 ""))]
4625   "reload_completed"
4626   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4627               (use (match_dup 2))
4628               (use (match_dup 3))
4629               (clobber (match_dup 5))])])
4630
4631 (define_insn "fix_trunc<mode>_i387"
4632   [(set (match_operand:SWI24 0 "memory_operand" "=m")
4633         (fix:SWI24 (match_operand 1 "register_operand" "f")))
4634    (use (match_operand:HI 2 "memory_operand" "m"))
4635    (use (match_operand:HI 3 "memory_operand" "m"))]
4636   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4637    && !TARGET_FISTTP
4638    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4639   "* return output_fix_trunc (insn, operands, false);"
4640   [(set_attr "type" "fistp")
4641    (set_attr "i387_cw" "trunc")
4642    (set_attr "mode" "<MODE>")])
4643
4644 (define_insn "fix_trunc<mode>_i387_with_temp"
4645   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4646         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4647    (use (match_operand:HI 2 "memory_operand" "m,m"))
4648    (use (match_operand:HI 3 "memory_operand" "m,m"))
4649    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4650   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4651    && !TARGET_FISTTP
4652    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4653   "#"
4654   [(set_attr "type" "fistp")
4655    (set_attr "i387_cw" "trunc")
4656    (set_attr "mode" "<MODE>")])
4657
4658 (define_split
4659   [(set (match_operand:SWI24 0 "register_operand" "")
4660         (fix:SWI24 (match_operand 1 "register_operand" "")))
4661    (use (match_operand:HI 2 "memory_operand" ""))
4662    (use (match_operand:HI 3 "memory_operand" ""))
4663    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4664   "reload_completed"
4665   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4666               (use (match_dup 2))
4667               (use (match_dup 3))])
4668    (set (match_dup 0) (match_dup 4))])
4669
4670 (define_split
4671   [(set (match_operand:SWI24 0 "memory_operand" "")
4672         (fix:SWI24 (match_operand 1 "register_operand" "")))
4673    (use (match_operand:HI 2 "memory_operand" ""))
4674    (use (match_operand:HI 3 "memory_operand" ""))
4675    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4676   "reload_completed"
4677   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4678               (use (match_dup 2))
4679               (use (match_dup 3))])])
4680
4681 (define_insn "x86_fnstcw_1"
4682   [(set (match_operand:HI 0 "memory_operand" "=m")
4683         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4684   "TARGET_80387"
4685   "fnstcw\t%0"
4686   [(set (attr "length")
4687         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4688    (set_attr "mode" "HI")
4689    (set_attr "unit" "i387")
4690    (set_attr "bdver1_decode" "vector")])
4691
4692 (define_insn "x86_fldcw_1"
4693   [(set (reg:HI FPCR_REG)
4694         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4695   "TARGET_80387"
4696   "fldcw\t%0"
4697   [(set (attr "length")
4698         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4699    (set_attr "mode" "HI")
4700    (set_attr "unit" "i387")
4701    (set_attr "athlon_decode" "vector")
4702    (set_attr "amdfam10_decode" "vector")
4703    (set_attr "bdver1_decode" "vector")])
4704 \f
4705 ;; Conversion between fixed point and floating point.
4706
4707 ;; Even though we only accept memory inputs, the backend _really_
4708 ;; wants to be able to do this between registers.
4709
4710 (define_expand "floathi<mode>2"
4711   [(set (match_operand:X87MODEF 0 "register_operand" "")
4712         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4713   "TARGET_80387
4714    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4715        || TARGET_MIX_SSE_I387)")
4716
4717 ;; Pre-reload splitter to add memory clobber to the pattern.
4718 (define_insn_and_split "*floathi<mode>2_1"
4719   [(set (match_operand:X87MODEF 0 "register_operand" "")
4720         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4721   "TARGET_80387
4722    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4723        || TARGET_MIX_SSE_I387)
4724    && can_create_pseudo_p ()"
4725   "#"
4726   "&& 1"
4727   [(parallel [(set (match_dup 0)
4728               (float:X87MODEF (match_dup 1)))
4729    (clobber (match_dup 2))])]
4730   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4731
4732 (define_insn "*floathi<mode>2_i387_with_temp"
4733   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4734         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4735   (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4736   "TARGET_80387
4737    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4738        || TARGET_MIX_SSE_I387)"
4739   "#"
4740   [(set_attr "type" "fmov,multi")
4741    (set_attr "mode" "<MODE>")
4742    (set_attr "unit" "*,i387")
4743    (set_attr "fp_int_src" "true")])
4744
4745 (define_insn "*floathi<mode>2_i387"
4746   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4747         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4748   "TARGET_80387
4749    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4750        || TARGET_MIX_SSE_I387)"
4751   "fild%Z1\t%1"
4752   [(set_attr "type" "fmov")
4753    (set_attr "mode" "<MODE>")
4754    (set_attr "fp_int_src" "true")])
4755
4756 (define_split
4757   [(set (match_operand:X87MODEF 0 "register_operand" "")
4758         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4759    (clobber (match_operand:HI 2 "memory_operand" ""))]
4760   "TARGET_80387
4761    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4762        || TARGET_MIX_SSE_I387)
4763    && reload_completed"
4764   [(set (match_dup 2) (match_dup 1))
4765    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4766
4767 (define_split
4768   [(set (match_operand:X87MODEF 0 "register_operand" "")
4769         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4770    (clobber (match_operand:HI 2 "memory_operand" ""))]
4771    "TARGET_80387
4772     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4773         || TARGET_MIX_SSE_I387)
4774     && reload_completed"
4775   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4776
4777 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4778   [(set (match_operand:X87MODEF 0 "register_operand" "")
4779         (float:X87MODEF
4780           (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4781   "TARGET_80387
4782    || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4783        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4784 {
4785   if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4786         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4787       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4788     {
4789       rtx reg = gen_reg_rtx (XFmode);
4790       rtx (*insn)(rtx, rtx);
4791
4792       emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4793
4794       if (<X87MODEF:MODE>mode == SFmode)
4795         insn = gen_truncxfsf2;
4796       else if (<X87MODEF:MODE>mode == DFmode)
4797         insn = gen_truncxfdf2;
4798       else
4799         gcc_unreachable ();
4800
4801       emit_insn (insn (operands[0], reg));
4802       DONE;
4803     }
4804 })
4805
4806 ;; Pre-reload splitter to add memory clobber to the pattern.
4807 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4808   [(set (match_operand:X87MODEF 0 "register_operand" "")
4809         (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4810   "((TARGET_80387
4811      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4812      && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4813            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4814          || TARGET_MIX_SSE_I387))
4815     || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4816         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4817         && ((<SWI48x:MODE>mode == SImode
4818              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4819              && optimize_function_for_speed_p (cfun)
4820              && flag_trapping_math)
4821             || !(TARGET_INTER_UNIT_CONVERSIONS
4822                  || optimize_function_for_size_p (cfun)))))
4823    && can_create_pseudo_p ()"
4824   "#"
4825   "&& 1"
4826   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4827               (clobber (match_dup 2))])]
4828 {
4829   operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4830
4831   /* Avoid store forwarding (partial memory) stall penalty
4832      by passing DImode value through XMM registers.  */
4833   if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4834       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4835       && optimize_function_for_speed_p (cfun))
4836     {
4837       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4838                                                             operands[1],
4839                                                             operands[2]));
4840       DONE;
4841     }
4842 })
4843
4844 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4845   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4846         (float:MODEF
4847           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4848    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4849   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4850    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4851   "#"
4852   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4853    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4854    (set_attr "unit" "*,i387,*,*,*")
4855    (set_attr "athlon_decode" "*,*,double,direct,double")
4856    (set_attr "amdfam10_decode" "*,*,vector,double,double")
4857    (set_attr "bdver1_decode" "*,*,double,direct,double")
4858    (set_attr "fp_int_src" "true")])
4859
4860 (define_insn "*floatsi<mode>2_vector_mixed"
4861   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4862         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4863   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4864    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4865   "@
4866    fild%Z1\t%1
4867    #"
4868   [(set_attr "type" "fmov,sseicvt")
4869    (set_attr "mode" "<MODE>,<ssevecmode>")
4870    (set_attr "unit" "i387,*")
4871    (set_attr "athlon_decode" "*,direct")
4872    (set_attr "amdfam10_decode" "*,double")
4873    (set_attr "bdver1_decode" "*,direct")
4874    (set_attr "fp_int_src" "true")])
4875
4876 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4877   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4878         (float:MODEF
4879           (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4880    (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4881   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4882    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4883   "#"
4884   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4885    (set_attr "mode" "<MODEF:MODE>")
4886    (set_attr "unit" "*,i387,*,*")
4887    (set_attr "athlon_decode" "*,*,double,direct")
4888    (set_attr "amdfam10_decode" "*,*,vector,double")
4889    (set_attr "bdver1_decode" "*,*,double,direct")
4890    (set_attr "fp_int_src" "true")])
4891
4892 (define_split
4893   [(set (match_operand:MODEF 0 "register_operand" "")
4894         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4895    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4896   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4897    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4898    && TARGET_INTER_UNIT_CONVERSIONS
4899    && reload_completed
4900    && (SSE_REG_P (operands[0])
4901        || (GET_CODE (operands[0]) == SUBREG
4902            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4903   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4904
4905 (define_split
4906   [(set (match_operand:MODEF 0 "register_operand" "")
4907         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4908    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4909   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4910    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4911    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4912    && reload_completed
4913    && (SSE_REG_P (operands[0])
4914        || (GET_CODE (operands[0]) == SUBREG
4915            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4916   [(set (match_dup 2) (match_dup 1))
4917    (set (match_dup 0) (float:MODEF (match_dup 2)))])
4918
4919 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4920   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4921         (float:MODEF
4922           (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4923   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4924    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4925    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4926   "@
4927    fild%Z1\t%1
4928    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4929    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4930   [(set_attr "type" "fmov,sseicvt,sseicvt")
4931    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4932    (set_attr "mode" "<MODEF:MODE>")
4933    (set (attr "prefix_rex")
4934      (if_then_else
4935        (and (eq_attr "prefix" "maybe_vex")
4936             (match_test "<SWI48x:MODE>mode == DImode"))
4937        (const_string "1")
4938        (const_string "*")))
4939    (set_attr "unit" "i387,*,*")
4940    (set_attr "athlon_decode" "*,double,direct")
4941    (set_attr "amdfam10_decode" "*,vector,double")
4942    (set_attr "bdver1_decode" "*,double,direct")
4943    (set_attr "fp_int_src" "true")])
4944
4945 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4946   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4947         (float:MODEF
4948           (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4949   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4950    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4951    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4952   "@
4953    fild%Z1\t%1
4954    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4955   [(set_attr "type" "fmov,sseicvt")
4956    (set_attr "prefix" "orig,maybe_vex")
4957    (set_attr "mode" "<MODEF:MODE>")
4958    (set (attr "prefix_rex")
4959      (if_then_else
4960        (and (eq_attr "prefix" "maybe_vex")
4961             (match_test "<SWI48x:MODE>mode == DImode"))
4962        (const_string "1")
4963        (const_string "*")))
4964    (set_attr "athlon_decode" "*,direct")
4965    (set_attr "amdfam10_decode" "*,double")
4966    (set_attr "bdver1_decode" "*,direct")
4967    (set_attr "fp_int_src" "true")])
4968
4969 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4970   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4971         (float:MODEF
4972           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4973    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4974   "TARGET_SSE2 && TARGET_SSE_MATH
4975    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4976   "#"
4977   [(set_attr "type" "sseicvt")
4978    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4979    (set_attr "athlon_decode" "double,direct,double")
4980    (set_attr "amdfam10_decode" "vector,double,double")
4981    (set_attr "bdver1_decode" "double,direct,double")
4982    (set_attr "fp_int_src" "true")])
4983
4984 (define_insn "*floatsi<mode>2_vector_sse"
4985   [(set (match_operand:MODEF 0 "register_operand" "=x")
4986         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4987   "TARGET_SSE2 && TARGET_SSE_MATH
4988    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4989   "#"
4990   [(set_attr "type" "sseicvt")
4991    (set_attr "mode" "<MODE>")
4992    (set_attr "athlon_decode" "direct")
4993    (set_attr "amdfam10_decode" "double")
4994    (set_attr "bdver1_decode" "direct")
4995    (set_attr "fp_int_src" "true")])
4996
4997 (define_split
4998   [(set (match_operand:MODEF 0 "register_operand" "")
4999         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5000    (clobber (match_operand:SI 2 "memory_operand" ""))]
5001   "TARGET_SSE2 && TARGET_SSE_MATH
5002    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5003    && reload_completed
5004    && (SSE_REG_P (operands[0])
5005        || (GET_CODE (operands[0]) == SUBREG
5006            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5007   [(const_int 0)]
5008 {
5009   rtx op1 = operands[1];
5010
5011   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5012                                      <MODE>mode, 0);
5013   if (GET_CODE (op1) == SUBREG)
5014     op1 = SUBREG_REG (op1);
5015
5016   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5017     {
5018       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5019       emit_insn (gen_sse2_loadld (operands[4],
5020                                   CONST0_RTX (V4SImode), operands[1]));
5021     }
5022   /* We can ignore possible trapping value in the
5023      high part of SSE register for non-trapping math. */
5024   else if (SSE_REG_P (op1) && !flag_trapping_math)
5025     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5026   else
5027     {
5028       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5029       emit_move_insn (operands[2], operands[1]);
5030       emit_insn (gen_sse2_loadld (operands[4],
5031                                   CONST0_RTX (V4SImode), operands[2]));
5032     }
5033   if (<ssevecmode>mode == V4SFmode)
5034     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5035   else
5036     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5037   DONE;
5038 })
5039
5040 (define_split
5041   [(set (match_operand:MODEF 0 "register_operand" "")
5042         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5043    (clobber (match_operand:SI 2 "memory_operand" ""))]
5044   "TARGET_SSE2 && TARGET_SSE_MATH
5045    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5046    && reload_completed
5047    && (SSE_REG_P (operands[0])
5048        || (GET_CODE (operands[0]) == SUBREG
5049            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5050   [(const_int 0)]
5051 {
5052   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5053                                      <MODE>mode, 0);
5054   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5055
5056   emit_insn (gen_sse2_loadld (operands[4],
5057                               CONST0_RTX (V4SImode), operands[1]));
5058   if (<ssevecmode>mode == V4SFmode)
5059     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5060   else
5061     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5062   DONE;
5063 })
5064
5065 (define_split
5066   [(set (match_operand:MODEF 0 "register_operand" "")
5067         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5068   "TARGET_SSE2 && TARGET_SSE_MATH
5069    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5070    && reload_completed
5071    && (SSE_REG_P (operands[0])
5072        || (GET_CODE (operands[0]) == SUBREG
5073            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5074   [(const_int 0)]
5075 {
5076   rtx op1 = operands[1];
5077
5078   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5079                                      <MODE>mode, 0);
5080   if (GET_CODE (op1) == SUBREG)
5081     op1 = SUBREG_REG (op1);
5082
5083   if (GENERAL_REG_P (op1))
5084     {
5085       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5086       if (TARGET_INTER_UNIT_MOVES)
5087         emit_insn (gen_sse2_loadld (operands[4],
5088                                     CONST0_RTX (V4SImode), operands[1]));
5089       else
5090         {
5091           operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5092                                               operands[1]);
5093           emit_insn (gen_sse2_loadld (operands[4],
5094                                       CONST0_RTX (V4SImode), operands[5]));
5095           ix86_free_from_memory (GET_MODE (operands[1]));
5096         }
5097     }
5098   /* We can ignore possible trapping value in the
5099      high part of SSE register for non-trapping math. */
5100   else if (SSE_REG_P (op1) && !flag_trapping_math)
5101     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5102   else
5103     gcc_unreachable ();
5104   if (<ssevecmode>mode == V4SFmode)
5105     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5106   else
5107     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5108   DONE;
5109 })
5110
5111 (define_split
5112   [(set (match_operand:MODEF 0 "register_operand" "")
5113         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5114   "TARGET_SSE2 && TARGET_SSE_MATH
5115    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5116    && reload_completed
5117    && (SSE_REG_P (operands[0])
5118        || (GET_CODE (operands[0]) == SUBREG
5119            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5120   [(const_int 0)]
5121 {
5122   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5123                                      <MODE>mode, 0);
5124   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5125
5126   emit_insn (gen_sse2_loadld (operands[4],
5127                               CONST0_RTX (V4SImode), operands[1]));
5128   if (<ssevecmode>mode == V4SFmode)
5129     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5130   else
5131     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5132   DONE;
5133 })
5134
5135 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5136   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5137         (float:MODEF
5138           (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5139   (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5140   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5141    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5142   "#"
5143   [(set_attr "type" "sseicvt")
5144    (set_attr "mode" "<MODEF:MODE>")
5145    (set_attr "athlon_decode" "double,direct")
5146    (set_attr "amdfam10_decode" "vector,double")
5147    (set_attr "bdver1_decode" "double,direct")
5148    (set_attr "fp_int_src" "true")])
5149
5150 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5151   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5152         (float:MODEF
5153           (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5154   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5155    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5156    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5157   "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5158   [(set_attr "type" "sseicvt")
5159    (set_attr "prefix" "maybe_vex")
5160    (set_attr "mode" "<MODEF:MODE>")
5161    (set (attr "prefix_rex")
5162      (if_then_else
5163        (and (eq_attr "prefix" "maybe_vex")
5164             (match_test "<SWI48x:MODE>mode == DImode"))
5165        (const_string "1")
5166        (const_string "*")))
5167    (set_attr "athlon_decode" "double,direct")
5168    (set_attr "amdfam10_decode" "vector,double")
5169    (set_attr "bdver1_decode" "double,direct")
5170    (set_attr "fp_int_src" "true")])
5171
5172 (define_split
5173   [(set (match_operand:MODEF 0 "register_operand" "")
5174         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5175    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5176   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5177    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5178    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5179    && reload_completed
5180    && (SSE_REG_P (operands[0])
5181        || (GET_CODE (operands[0]) == SUBREG
5182            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5183   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5184
5185 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5186   [(set (match_operand:MODEF 0 "register_operand" "=x")
5187         (float:MODEF
5188           (match_operand:SWI48x 1 "memory_operand" "m")))]
5189   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5190    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5191    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5192   "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5193   [(set_attr "type" "sseicvt")
5194    (set_attr "prefix" "maybe_vex")
5195    (set_attr "mode" "<MODEF:MODE>")
5196    (set (attr "prefix_rex")
5197      (if_then_else
5198        (and (eq_attr "prefix" "maybe_vex")
5199             (match_test "<SWI48x:MODE>mode == DImode"))
5200        (const_string "1")
5201        (const_string "*")))
5202    (set_attr "athlon_decode" "direct")
5203    (set_attr "amdfam10_decode" "double")
5204    (set_attr "bdver1_decode" "direct")
5205    (set_attr "fp_int_src" "true")])
5206
5207 (define_split
5208   [(set (match_operand:MODEF 0 "register_operand" "")
5209         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5210    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5211   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5212    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5213    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5214    && reload_completed
5215    && (SSE_REG_P (operands[0])
5216        || (GET_CODE (operands[0]) == SUBREG
5217            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5218   [(set (match_dup 2) (match_dup 1))
5219    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5220
5221 (define_split
5222   [(set (match_operand:MODEF 0 "register_operand" "")
5223         (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5224    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5225   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5226    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5227    && reload_completed
5228    && (SSE_REG_P (operands[0])
5229        || (GET_CODE (operands[0]) == SUBREG
5230            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5231   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5232
5233 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5234   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5235         (float:X87MODEF
5236           (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5237   (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5238   "TARGET_80387
5239    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5240   "@
5241    fild%Z1\t%1
5242    #"
5243   [(set_attr "type" "fmov,multi")
5244    (set_attr "mode" "<X87MODEF:MODE>")
5245    (set_attr "unit" "*,i387")
5246    (set_attr "fp_int_src" "true")])
5247
5248 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5249   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5250         (float:X87MODEF
5251           (match_operand:SWI48x 1 "memory_operand" "m")))]
5252   "TARGET_80387
5253    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5254   "fild%Z1\t%1"
5255   [(set_attr "type" "fmov")
5256    (set_attr "mode" "<X87MODEF:MODE>")
5257    (set_attr "fp_int_src" "true")])
5258
5259 (define_split
5260   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5261         (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5262    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5263   "TARGET_80387
5264    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5265    && reload_completed"
5266   [(set (match_dup 2) (match_dup 1))
5267    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5268
5269 (define_split
5270   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5271         (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5272    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5273   "TARGET_80387
5274    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5275    && reload_completed"
5276   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5277
5278 ;; Avoid store forwarding (partial memory) stall penalty
5279 ;; by passing DImode value through XMM registers.  */
5280
5281 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5282   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5283         (float:X87MODEF
5284           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5285    (clobber (match_scratch:V4SI 3 "=X,x"))
5286    (clobber (match_scratch:V4SI 4 "=X,x"))
5287    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5288   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5289    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5290    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5291   "#"
5292   [(set_attr "type" "multi")
5293    (set_attr "mode" "<X87MODEF:MODE>")
5294    (set_attr "unit" "i387")
5295    (set_attr "fp_int_src" "true")])
5296
5297 (define_split
5298   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5299         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5300    (clobber (match_scratch:V4SI 3 ""))
5301    (clobber (match_scratch:V4SI 4 ""))
5302    (clobber (match_operand:DI 2 "memory_operand" ""))]
5303   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5304    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5305    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5306    && reload_completed"
5307   [(set (match_dup 2) (match_dup 3))
5308    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5309 {
5310   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5311      Assemble the 64-bit DImode value in an xmm register.  */
5312   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5313                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5314   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5315                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5316   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5317                                          operands[4]));
5318
5319   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5320 })
5321
5322 (define_split
5323   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5324         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5325    (clobber (match_scratch:V4SI 3 ""))
5326    (clobber (match_scratch:V4SI 4 ""))
5327    (clobber (match_operand:DI 2 "memory_operand" ""))]
5328   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5329    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5330    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5331    && reload_completed"
5332   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5333
5334 ;; Avoid store forwarding (partial memory) stall penalty by extending
5335 ;; SImode value to DImode through XMM register instead of pushing two
5336 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5337 ;; targets benefit from this optimization. Also note that fild
5338 ;; loads from memory only.
5339
5340 (define_insn "*floatunssi<mode>2_1"
5341   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5342         (unsigned_float:X87MODEF
5343           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5344    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5345    (clobber (match_scratch:SI 3 "=X,x"))]
5346   "!TARGET_64BIT
5347    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5348    && TARGET_SSE"
5349   "#"
5350   [(set_attr "type" "multi")
5351    (set_attr "mode" "<MODE>")])
5352
5353 (define_split
5354   [(set (match_operand:X87MODEF 0 "register_operand" "")
5355         (unsigned_float:X87MODEF
5356           (match_operand:SI 1 "register_operand" "")))
5357    (clobber (match_operand:DI 2 "memory_operand" ""))
5358    (clobber (match_scratch:SI 3 ""))]
5359   "!TARGET_64BIT
5360    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5361    && TARGET_SSE
5362    && reload_completed"
5363   [(set (match_dup 2) (match_dup 1))
5364    (set (match_dup 0)
5365         (float:X87MODEF (match_dup 2)))]
5366   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5367
5368 (define_split
5369   [(set (match_operand:X87MODEF 0 "register_operand" "")
5370         (unsigned_float:X87MODEF
5371           (match_operand:SI 1 "memory_operand" "")))
5372    (clobber (match_operand:DI 2 "memory_operand" ""))
5373    (clobber (match_scratch:SI 3 ""))]
5374   "!TARGET_64BIT
5375    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5376    && TARGET_SSE
5377    && reload_completed"
5378   [(set (match_dup 2) (match_dup 3))
5379    (set (match_dup 0)
5380         (float:X87MODEF (match_dup 2)))]
5381 {
5382   emit_move_insn (operands[3], operands[1]);
5383   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5384 })
5385
5386 (define_expand "floatunssi<mode>2"
5387   [(parallel
5388      [(set (match_operand:X87MODEF 0 "register_operand" "")
5389            (unsigned_float:X87MODEF
5390              (match_operand:SI 1 "nonimmediate_operand" "")))
5391       (clobber (match_dup 2))
5392       (clobber (match_scratch:SI 3 ""))])]
5393   "!TARGET_64BIT
5394    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5395         && TARGET_SSE)
5396        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5397 {
5398   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5399     {
5400       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5401       DONE;
5402     }
5403   else
5404     operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5405 })
5406
5407 (define_expand "floatunsdisf2"
5408   [(use (match_operand:SF 0 "register_operand" ""))
5409    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5410   "TARGET_64BIT && TARGET_SSE_MATH"
5411   "x86_emit_floatuns (operands); DONE;")
5412
5413 (define_expand "floatunsdidf2"
5414   [(use (match_operand:DF 0 "register_operand" ""))
5415    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5416   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5417    && TARGET_SSE2 && TARGET_SSE_MATH"
5418 {
5419   if (TARGET_64BIT)
5420     x86_emit_floatuns (operands);
5421   else
5422     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5423   DONE;
5424 })
5425 \f
5426 ;; Load effective address instructions
5427
5428 (define_insn_and_split "*lea<mode>"
5429   [(set (match_operand:SWI48 0 "register_operand" "=r")
5430         (match_operand:SWI48 1 "lea_address_operand" "p"))]
5431   ""
5432 {
5433   rtx addr = operands[1];
5434
5435   if (SImode_address_operand (addr, VOIDmode))
5436     {
5437       gcc_assert (TARGET_64BIT);
5438       return "lea{l}\t{%E1, %k0|%k0, %E1}";
5439     }
5440   else 
5441     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5442 }
5443   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5444   [(const_int 0)]
5445 {
5446   ix86_split_lea_for_addr (operands, <MODE>mode);
5447   DONE;
5448 }
5449   [(set_attr "type" "lea")
5450    (set (attr "mode")
5451      (if_then_else
5452        (match_operand 1 "SImode_address_operand")
5453        (const_string "SI")
5454        (const_string "<MODE>")))])
5455 \f
5456 ;; Add instructions
5457
5458 (define_expand "add<mode>3"
5459   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5460         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5461                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5462   ""
5463   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5464
5465 (define_insn_and_split "*add<dwi>3_doubleword"
5466   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5467         (plus:<DWI>
5468           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5469           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5470    (clobber (reg:CC FLAGS_REG))]
5471   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5472   "#"
5473   "reload_completed"
5474   [(parallel [(set (reg:CC FLAGS_REG)
5475                    (unspec:CC [(match_dup 1) (match_dup 2)]
5476                               UNSPEC_ADD_CARRY))
5477               (set (match_dup 0)
5478                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5479    (parallel [(set (match_dup 3)
5480                    (plus:DWIH
5481                      (match_dup 4)
5482                      (plus:DWIH
5483                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5484                        (match_dup 5))))
5485               (clobber (reg:CC FLAGS_REG))])]
5486   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5487
5488 (define_insn "*add<mode>3_cc"
5489   [(set (reg:CC FLAGS_REG)
5490         (unspec:CC
5491           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5492            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5493           UNSPEC_ADD_CARRY))
5494    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5495         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5496   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5497   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5498   [(set_attr "type" "alu")
5499    (set_attr "mode" "<MODE>")])
5500
5501 (define_insn "addqi3_cc"
5502   [(set (reg:CC FLAGS_REG)
5503         (unspec:CC
5504           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5505            (match_operand:QI 2 "general_operand" "qn,qm")]
5506           UNSPEC_ADD_CARRY))
5507    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5508         (plus:QI (match_dup 1) (match_dup 2)))]
5509   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5510   "add{b}\t{%2, %0|%0, %2}"
5511   [(set_attr "type" "alu")
5512    (set_attr "mode" "QI")])
5513
5514 (define_insn "*add<mode>_1"
5515   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5516         (plus:SWI48
5517           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5518           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5519    (clobber (reg:CC FLAGS_REG))]
5520   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5521 {
5522   switch (get_attr_type (insn))
5523     {
5524     case TYPE_LEA:
5525       return "#";
5526
5527     case TYPE_INCDEC:
5528       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5529       if (operands[2] == const1_rtx)
5530         return "inc{<imodesuffix>}\t%0";
5531       else
5532         {
5533           gcc_assert (operands[2] == constm1_rtx);
5534           return "dec{<imodesuffix>}\t%0";
5535         }
5536
5537     default:
5538       /* For most processors, ADD is faster than LEA.  This alternative
5539          was added to use ADD as much as possible.  */
5540       if (which_alternative == 2)
5541         {
5542           rtx tmp;
5543           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5544         }
5545         
5546       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5547       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5548         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5549
5550       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5551     }
5552 }
5553   [(set (attr "type")
5554      (cond [(eq_attr "alternative" "3")
5555               (const_string "lea")
5556             (match_operand:SWI48 2 "incdec_operand" "")
5557               (const_string "incdec")
5558            ]
5559            (const_string "alu")))
5560    (set (attr "length_immediate")
5561       (if_then_else
5562         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5563         (const_string "1")
5564         (const_string "*")))
5565    (set_attr "mode" "<MODE>")])
5566
5567 ;; It may seem that nonimmediate operand is proper one for operand 1.
5568 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5569 ;; we take care in ix86_binary_operator_ok to not allow two memory
5570 ;; operands so proper swapping will be done in reload.  This allow
5571 ;; patterns constructed from addsi_1 to match.
5572
5573 (define_insn "addsi_1_zext"
5574   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5575         (zero_extend:DI
5576           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5577                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5578    (clobber (reg:CC FLAGS_REG))]
5579   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5580 {
5581   switch (get_attr_type (insn))
5582     {
5583     case TYPE_LEA:
5584       return "#";
5585
5586     case TYPE_INCDEC:
5587       if (operands[2] == const1_rtx)
5588         return "inc{l}\t%k0";
5589       else
5590         {
5591           gcc_assert (operands[2] == constm1_rtx);
5592           return "dec{l}\t%k0";
5593         }
5594
5595     default:
5596       /* For most processors, ADD is faster than LEA.  This alternative
5597          was added to use ADD as much as possible.  */
5598       if (which_alternative == 1)
5599         {
5600           rtx tmp;
5601           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5602         }
5603
5604       if (x86_maybe_negate_const_int (&operands[2], SImode))
5605         return "sub{l}\t{%2, %k0|%k0, %2}";
5606
5607       return "add{l}\t{%2, %k0|%k0, %2}";
5608     }
5609 }
5610   [(set (attr "type")
5611      (cond [(eq_attr "alternative" "2")
5612               (const_string "lea")
5613             (match_operand:SI 2 "incdec_operand" "")
5614               (const_string "incdec")
5615            ]
5616            (const_string "alu")))
5617    (set (attr "length_immediate")
5618       (if_then_else
5619         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5620         (const_string "1")
5621         (const_string "*")))
5622    (set_attr "mode" "SI")])
5623
5624 (define_insn "*addhi_1"
5625   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5626         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5627                  (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5628    (clobber (reg:CC FLAGS_REG))]
5629   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5630 {
5631   switch (get_attr_type (insn))
5632     {
5633     case TYPE_LEA:
5634       return "#";
5635
5636     case TYPE_INCDEC:
5637       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5638       if (operands[2] == const1_rtx)
5639         return "inc{w}\t%0";
5640       else
5641         {
5642           gcc_assert (operands[2] == constm1_rtx);
5643           return "dec{w}\t%0";
5644         }
5645
5646     default:
5647       /* For most processors, ADD is faster than LEA.  This alternative
5648          was added to use ADD as much as possible.  */
5649       if (which_alternative == 2)
5650         {
5651           rtx tmp;
5652           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5653         }
5654
5655       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5656       if (x86_maybe_negate_const_int (&operands[2], HImode))
5657         return "sub{w}\t{%2, %0|%0, %2}";
5658
5659       return "add{w}\t{%2, %0|%0, %2}";
5660     }
5661 }
5662   [(set (attr "type")
5663      (cond [(eq_attr "alternative" "3")
5664               (const_string "lea")
5665             (match_operand:HI 2 "incdec_operand" "")
5666               (const_string "incdec")
5667            ]
5668            (const_string "alu")))
5669    (set (attr "length_immediate")
5670       (if_then_else
5671         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5672         (const_string "1")
5673         (const_string "*")))
5674    (set_attr "mode" "HI,HI,HI,SI")])
5675
5676 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5677 (define_insn "*addqi_1"
5678   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5679         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5680                  (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5681    (clobber (reg:CC FLAGS_REG))]
5682   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5683 {
5684   bool widen = (which_alternative == 3 || which_alternative == 4);
5685
5686   switch (get_attr_type (insn))
5687     {
5688     case TYPE_LEA:
5689       return "#";
5690
5691     case TYPE_INCDEC:
5692       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5693       if (operands[2] == const1_rtx)
5694         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5695       else
5696         {
5697           gcc_assert (operands[2] == constm1_rtx);
5698           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5699         }
5700
5701     default:
5702       /* For most processors, ADD is faster than LEA.  These alternatives
5703          were added to use ADD as much as possible.  */
5704       if (which_alternative == 2 || which_alternative == 4)
5705         {
5706           rtx tmp;
5707           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5708         }
5709
5710       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5711       if (x86_maybe_negate_const_int (&operands[2], QImode))
5712         {
5713           if (widen)
5714             return "sub{l}\t{%2, %k0|%k0, %2}";
5715           else
5716             return "sub{b}\t{%2, %0|%0, %2}";
5717         }
5718       if (widen)
5719         return "add{l}\t{%k2, %k0|%k0, %k2}";
5720       else
5721         return "add{b}\t{%2, %0|%0, %2}";
5722     }
5723 }
5724   [(set (attr "type")
5725      (cond [(eq_attr "alternative" "5")
5726               (const_string "lea")
5727             (match_operand:QI 2 "incdec_operand" "")
5728               (const_string "incdec")
5729            ]
5730            (const_string "alu")))
5731    (set (attr "length_immediate")
5732       (if_then_else
5733         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5734         (const_string "1")
5735         (const_string "*")))
5736    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5737
5738 (define_insn "*addqi_1_slp"
5739   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5740         (plus:QI (match_dup 0)
5741                  (match_operand:QI 1 "general_operand" "qn,qm")))
5742    (clobber (reg:CC FLAGS_REG))]
5743   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5744    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5745 {
5746   switch (get_attr_type (insn))
5747     {
5748     case TYPE_INCDEC:
5749       if (operands[1] == const1_rtx)
5750         return "inc{b}\t%0";
5751       else
5752         {
5753           gcc_assert (operands[1] == constm1_rtx);
5754           return "dec{b}\t%0";
5755         }
5756
5757     default:
5758       if (x86_maybe_negate_const_int (&operands[1], QImode))
5759         return "sub{b}\t{%1, %0|%0, %1}";
5760
5761       return "add{b}\t{%1, %0|%0, %1}";
5762     }
5763 }
5764   [(set (attr "type")
5765      (if_then_else (match_operand:QI 1 "incdec_operand" "")
5766         (const_string "incdec")
5767         (const_string "alu1")))
5768    (set (attr "memory")
5769      (if_then_else (match_operand 1 "memory_operand" "")
5770         (const_string "load")
5771         (const_string "none")))
5772    (set_attr "mode" "QI")])
5773
5774 ;; Split non destructive adds if we cannot use lea.
5775 (define_split
5776   [(set (match_operand:SWI48 0 "register_operand" "")
5777         (plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5778               (match_operand:SWI48 2 "nonmemory_operand" "")))
5779    (clobber (reg:CC FLAGS_REG))]
5780   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5781   [(set (match_dup 0) (match_dup 1))
5782    (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5783               (clobber (reg:CC FLAGS_REG))])])
5784
5785 ;; Convert add to the lea pattern to avoid flags dependency.
5786 (define_split
5787   [(set (match_operand:SWI 0 "register_operand" "")
5788         (plus:SWI (match_operand:SWI 1 "register_operand" "")
5789                   (match_operand:SWI 2 "<nonmemory_operand>" "")))
5790    (clobber (reg:CC FLAGS_REG))]
5791   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5792   [(const_int 0)]
5793 {
5794   enum machine_mode mode = <MODE>mode;
5795   rtx pat;
5796
5797   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5798     { 
5799       mode = SImode; 
5800       operands[0] = gen_lowpart (mode, operands[0]);
5801       operands[1] = gen_lowpart (mode, operands[1]);
5802       operands[2] = gen_lowpart (mode, operands[2]);
5803     }
5804
5805   pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5806
5807   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5808   DONE;
5809 })
5810
5811 ;; Convert add to the lea pattern to avoid flags dependency.
5812 (define_split
5813   [(set (match_operand:DI 0 "register_operand" "")
5814         (zero_extend:DI
5815           (plus:SI (match_operand:SI 1 "register_operand" "")
5816                    (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5817    (clobber (reg:CC FLAGS_REG))]
5818   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5819   [(set (match_dup 0)
5820         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5821
5822 (define_insn "*add<mode>_2"
5823   [(set (reg FLAGS_REG)
5824         (compare
5825           (plus:SWI
5826             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5827             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5828           (const_int 0)))
5829    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5830         (plus:SWI (match_dup 1) (match_dup 2)))]
5831   "ix86_match_ccmode (insn, CCGOCmode)
5832    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5833 {
5834   switch (get_attr_type (insn))
5835     {
5836     case TYPE_INCDEC:
5837       if (operands[2] == const1_rtx)
5838         return "inc{<imodesuffix>}\t%0";
5839       else
5840         {
5841           gcc_assert (operands[2] == constm1_rtx);
5842           return "dec{<imodesuffix>}\t%0";
5843         }
5844
5845     default:
5846       if (which_alternative == 2)
5847         {
5848           rtx tmp;
5849           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5850         }
5851         
5852       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5853       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5854         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5855
5856       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5857     }
5858 }
5859   [(set (attr "type")
5860      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5861         (const_string "incdec")
5862         (const_string "alu")))
5863    (set (attr "length_immediate")
5864       (if_then_else
5865         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5866         (const_string "1")
5867         (const_string "*")))
5868    (set_attr "mode" "<MODE>")])
5869
5870 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5871 (define_insn "*addsi_2_zext"
5872   [(set (reg FLAGS_REG)
5873         (compare
5874           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5875                    (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5876           (const_int 0)))
5877    (set (match_operand:DI 0 "register_operand" "=r,r")
5878         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5879   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5880    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5881 {
5882   switch (get_attr_type (insn))
5883     {
5884     case TYPE_INCDEC:
5885       if (operands[2] == const1_rtx)
5886         return "inc{l}\t%k0";
5887       else
5888         {
5889           gcc_assert (operands[2] == constm1_rtx);
5890           return "dec{l}\t%k0";
5891         }
5892
5893     default:
5894       if (which_alternative == 1)
5895         {
5896           rtx tmp;
5897           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5898         }
5899
5900       if (x86_maybe_negate_const_int (&operands[2], SImode))
5901         return "sub{l}\t{%2, %k0|%k0, %2}";
5902
5903       return "add{l}\t{%2, %k0|%k0, %2}";
5904     }
5905 }
5906   [(set (attr "type")
5907      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5908         (const_string "incdec")
5909         (const_string "alu")))
5910    (set (attr "length_immediate")
5911       (if_then_else
5912         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5913         (const_string "1")
5914         (const_string "*")))
5915    (set_attr "mode" "SI")])
5916
5917 (define_insn "*add<mode>_3"
5918   [(set (reg FLAGS_REG)
5919         (compare
5920           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5921           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5922    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5923   "ix86_match_ccmode (insn, CCZmode)
5924    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5925 {
5926   switch (get_attr_type (insn))
5927     {
5928     case TYPE_INCDEC:
5929       if (operands[2] == const1_rtx)
5930         return "inc{<imodesuffix>}\t%0";
5931       else
5932         {
5933           gcc_assert (operands[2] == constm1_rtx);
5934           return "dec{<imodesuffix>}\t%0";
5935         }
5936
5937     default:
5938       if (which_alternative == 1)
5939         {
5940           rtx tmp;
5941           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5942         }
5943
5944       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5945       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5946         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5947
5948       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5949     }
5950 }
5951   [(set (attr "type")
5952      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5953         (const_string "incdec")
5954         (const_string "alu")))
5955    (set (attr "length_immediate")
5956       (if_then_else
5957         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5958         (const_string "1")
5959         (const_string "*")))
5960    (set_attr "mode" "<MODE>")])
5961
5962 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5963 (define_insn "*addsi_3_zext"
5964   [(set (reg FLAGS_REG)
5965         (compare
5966           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5967           (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5968    (set (match_operand:DI 0 "register_operand" "=r,r")
5969         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5970   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5971    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5972 {
5973   switch (get_attr_type (insn))
5974     {
5975     case TYPE_INCDEC:
5976       if (operands[2] == const1_rtx)
5977         return "inc{l}\t%k0";
5978       else
5979         {
5980           gcc_assert (operands[2] == constm1_rtx);
5981           return "dec{l}\t%k0";
5982         }
5983
5984     default:
5985       if (which_alternative == 1)
5986         {
5987           rtx tmp;
5988           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5989         }
5990
5991       if (x86_maybe_negate_const_int (&operands[2], SImode))
5992         return "sub{l}\t{%2, %k0|%k0, %2}";
5993
5994       return "add{l}\t{%2, %k0|%k0, %2}";
5995     }
5996 }
5997   [(set (attr "type")
5998      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5999         (const_string "incdec")
6000         (const_string "alu")))
6001    (set (attr "length_immediate")
6002       (if_then_else
6003         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6004         (const_string "1")
6005         (const_string "*")))
6006    (set_attr "mode" "SI")])
6007
6008 ; For comparisons against 1, -1 and 128, we may generate better code
6009 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6010 ; is matched then.  We can't accept general immediate, because for
6011 ; case of overflows,  the result is messed up.
6012 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6013 ; only for comparisons not depending on it.
6014
6015 (define_insn "*adddi_4"
6016   [(set (reg FLAGS_REG)
6017         (compare
6018           (match_operand:DI 1 "nonimmediate_operand" "0")
6019           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6020    (clobber (match_scratch:DI 0 "=rm"))]
6021   "TARGET_64BIT
6022    && ix86_match_ccmode (insn, CCGCmode)"
6023 {
6024   switch (get_attr_type (insn))
6025     {
6026     case TYPE_INCDEC:
6027       if (operands[2] == constm1_rtx)
6028         return "inc{q}\t%0";
6029       else
6030         {
6031           gcc_assert (operands[2] == const1_rtx);
6032           return "dec{q}\t%0";
6033         }
6034
6035     default:
6036       if (x86_maybe_negate_const_int (&operands[2], DImode))
6037         return "add{q}\t{%2, %0|%0, %2}";
6038
6039       return "sub{q}\t{%2, %0|%0, %2}";
6040     }
6041 }
6042   [(set (attr "type")
6043      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6044         (const_string "incdec")
6045         (const_string "alu")))
6046    (set (attr "length_immediate")
6047       (if_then_else
6048         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6049         (const_string "1")
6050         (const_string "*")))
6051    (set_attr "mode" "DI")])
6052
6053 ; For comparisons against 1, -1 and 128, we may generate better code
6054 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6055 ; is matched then.  We can't accept general immediate, because for
6056 ; case of overflows,  the result is messed up.
6057 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6058 ; only for comparisons not depending on it.
6059
6060 (define_insn "*add<mode>_4"
6061   [(set (reg FLAGS_REG)
6062         (compare
6063           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6064           (match_operand:SWI124 2 "const_int_operand" "n")))
6065    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6066   "ix86_match_ccmode (insn, CCGCmode)"
6067 {
6068   switch (get_attr_type (insn))
6069     {
6070     case TYPE_INCDEC:
6071       if (operands[2] == constm1_rtx)
6072         return "inc{<imodesuffix>}\t%0";
6073       else
6074         {
6075           gcc_assert (operands[2] == const1_rtx);
6076           return "dec{<imodesuffix>}\t%0";
6077         }
6078
6079     default:
6080       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6081         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6082
6083       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6084     }
6085 }
6086   [(set (attr "type")
6087      (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6088         (const_string "incdec")
6089         (const_string "alu")))
6090    (set (attr "length_immediate")
6091       (if_then_else
6092         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6093         (const_string "1")
6094         (const_string "*")))
6095    (set_attr "mode" "<MODE>")])
6096
6097 (define_insn "*add<mode>_5"
6098   [(set (reg FLAGS_REG)
6099         (compare
6100           (plus:SWI
6101             (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6102             (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6103           (const_int 0)))
6104    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6105   "ix86_match_ccmode (insn, CCGOCmode)
6106    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6107 {
6108   switch (get_attr_type (insn))
6109     {
6110     case TYPE_INCDEC:
6111       if (operands[2] == const1_rtx)
6112         return "inc{<imodesuffix>}\t%0";
6113       else
6114         {
6115           gcc_assert (operands[2] == constm1_rtx);
6116           return "dec{<imodesuffix>}\t%0";
6117         }
6118
6119     default:
6120       if (which_alternative == 1)
6121         {
6122           rtx tmp;
6123           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6124         }
6125
6126       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6127       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6128         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6129
6130       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6131     }
6132 }
6133   [(set (attr "type")
6134      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6135         (const_string "incdec")
6136         (const_string "alu")))
6137    (set (attr "length_immediate")
6138       (if_then_else
6139         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6140         (const_string "1")
6141         (const_string "*")))
6142    (set_attr "mode" "<MODE>")])
6143
6144 (define_insn "*addqi_ext_1_rex64"
6145   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6146                          (const_int 8)
6147                          (const_int 8))
6148         (plus:SI
6149           (zero_extract:SI
6150             (match_operand 1 "ext_register_operand" "0")
6151             (const_int 8)
6152             (const_int 8))
6153           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6154    (clobber (reg:CC FLAGS_REG))]
6155   "TARGET_64BIT"
6156 {
6157   switch (get_attr_type (insn))
6158     {
6159     case TYPE_INCDEC:
6160       if (operands[2] == const1_rtx)
6161         return "inc{b}\t%h0";
6162       else
6163         {
6164           gcc_assert (operands[2] == constm1_rtx);
6165           return "dec{b}\t%h0";
6166         }
6167
6168     default:
6169       return "add{b}\t{%2, %h0|%h0, %2}";
6170     }
6171 }
6172   [(set (attr "type")
6173      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6174         (const_string "incdec")
6175         (const_string "alu")))
6176    (set_attr "modrm" "1")
6177    (set_attr "mode" "QI")])
6178
6179 (define_insn "addqi_ext_1"
6180   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6181                          (const_int 8)
6182                          (const_int 8))
6183         (plus:SI
6184           (zero_extract:SI
6185             (match_operand 1 "ext_register_operand" "0")
6186             (const_int 8)
6187             (const_int 8))
6188           (match_operand:QI 2 "general_operand" "Qmn")))
6189    (clobber (reg:CC FLAGS_REG))]
6190   "!TARGET_64BIT"
6191 {
6192   switch (get_attr_type (insn))
6193     {
6194     case TYPE_INCDEC:
6195       if (operands[2] == const1_rtx)
6196         return "inc{b}\t%h0";
6197       else
6198         {
6199           gcc_assert (operands[2] == constm1_rtx);
6200           return "dec{b}\t%h0";
6201         }
6202
6203     default:
6204       return "add{b}\t{%2, %h0|%h0, %2}";
6205     }
6206 }
6207   [(set (attr "type")
6208      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6209         (const_string "incdec")
6210         (const_string "alu")))
6211    (set_attr "modrm" "1")
6212    (set_attr "mode" "QI")])
6213
6214 (define_insn "*addqi_ext_2"
6215   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6216                          (const_int 8)
6217                          (const_int 8))
6218         (plus:SI
6219           (zero_extract:SI
6220             (match_operand 1 "ext_register_operand" "%0")
6221             (const_int 8)
6222             (const_int 8))
6223           (zero_extract:SI
6224             (match_operand 2 "ext_register_operand" "Q")
6225             (const_int 8)
6226             (const_int 8))))
6227    (clobber (reg:CC FLAGS_REG))]
6228   ""
6229   "add{b}\t{%h2, %h0|%h0, %h2}"
6230   [(set_attr "type" "alu")
6231    (set_attr "mode" "QI")])
6232
6233 ;; The lea patterns for modes less than 32 bits need to be matched by
6234 ;; several insns converted to real lea by splitters.
6235
6236 (define_insn_and_split "*lea_general_1"
6237   [(set (match_operand 0 "register_operand" "=r")
6238         (plus (plus (match_operand 1 "index_register_operand" "l")
6239                     (match_operand 2 "register_operand" "r"))
6240               (match_operand 3 "immediate_operand" "i")))]
6241   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6242    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6243    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6244    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6245    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6246        || GET_MODE (operands[3]) == VOIDmode)"
6247   "#"
6248   "&& reload_completed"
6249   [(const_int 0)]
6250 {
6251   enum machine_mode mode = SImode;
6252   rtx pat;
6253
6254   operands[0] = gen_lowpart (mode, operands[0]);
6255   operands[1] = gen_lowpart (mode, operands[1]);
6256   operands[2] = gen_lowpart (mode, operands[2]);
6257   operands[3] = gen_lowpart (mode, operands[3]);
6258
6259   pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6260                       operands[3]);
6261
6262   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6263   DONE;
6264 }
6265   [(set_attr "type" "lea")
6266    (set_attr "mode" "SI")])
6267
6268 (define_insn_and_split "*lea_general_2"
6269   [(set (match_operand 0 "register_operand" "=r")
6270         (plus (mult (match_operand 1 "index_register_operand" "l")
6271                     (match_operand 2 "const248_operand" "n"))
6272               (match_operand 3 "nonmemory_operand" "ri")))]
6273   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6274    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6275    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6276    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6277        || GET_MODE (operands[3]) == VOIDmode)"
6278   "#"
6279   "&& reload_completed"
6280   [(const_int 0)]
6281 {
6282   enum machine_mode mode = SImode;
6283   rtx pat;
6284
6285   operands[0] = gen_lowpart (mode, operands[0]);
6286   operands[1] = gen_lowpart (mode, operands[1]);
6287   operands[3] = gen_lowpart (mode, operands[3]);
6288
6289   pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6290                       operands[3]);
6291
6292   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6293   DONE;
6294 }
6295   [(set_attr "type" "lea")
6296    (set_attr "mode" "SI")])
6297
6298 (define_insn_and_split "*lea_general_3"
6299   [(set (match_operand 0 "register_operand" "=r")
6300         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6301                           (match_operand 2 "const248_operand" "n"))
6302                     (match_operand 3 "register_operand" "r"))
6303               (match_operand 4 "immediate_operand" "i")))]
6304   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6305    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6306    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6307    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6308   "#"
6309   "&& reload_completed"
6310   [(const_int 0)]
6311 {
6312   enum machine_mode mode = SImode;
6313   rtx pat;
6314
6315   operands[0] = gen_lowpart (mode, operands[0]);
6316   operands[1] = gen_lowpart (mode, operands[1]);
6317   operands[3] = gen_lowpart (mode, operands[3]);
6318   operands[4] = gen_lowpart (mode, operands[4]);
6319
6320   pat = gen_rtx_PLUS (mode,
6321                       gen_rtx_PLUS (mode,
6322                                     gen_rtx_MULT (mode, operands[1],
6323                                                         operands[2]),
6324                                     operands[3]),
6325                       operands[4]);
6326
6327   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6328   DONE;
6329 }
6330   [(set_attr "type" "lea")
6331    (set_attr "mode" "SI")])
6332
6333 (define_insn_and_split "*lea_general_4"
6334   [(set (match_operand 0 "register_operand" "=r")
6335         (any_or (ashift
6336                   (match_operand 1 "index_register_operand" "l")
6337                   (match_operand 2 "const_int_operand" "n"))
6338                 (match_operand 3 "const_int_operand" "n")))]
6339   "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6340       && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6341     || GET_MODE (operands[0]) == SImode
6342     || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6343    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6344    && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6345    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6346        < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6347   "#"
6348   "&& reload_completed"
6349   [(const_int 0)]
6350 {
6351   enum machine_mode mode = GET_MODE (operands[0]);
6352   rtx pat;
6353
6354   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6355     { 
6356       mode = SImode; 
6357       operands[0] = gen_lowpart (mode, operands[0]);
6358       operands[1] = gen_lowpart (mode, operands[1]);
6359     }
6360
6361   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6362
6363   pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6364                        INTVAL (operands[3]));
6365
6366   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6367   DONE;
6368 }
6369   [(set_attr "type" "lea")
6370    (set (attr "mode")
6371       (if_then_else (match_operand:DI 0 "" "")
6372         (const_string "DI")
6373         (const_string "SI")))])
6374 \f
6375 ;; Subtract instructions
6376
6377 (define_expand "sub<mode>3"
6378   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6379         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6380                      (match_operand:SDWIM 2 "<general_operand>" "")))]
6381   ""
6382   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6383
6384 (define_insn_and_split "*sub<dwi>3_doubleword"
6385   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6386         (minus:<DWI>
6387           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6388           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6389    (clobber (reg:CC FLAGS_REG))]
6390   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6391   "#"
6392   "reload_completed"
6393   [(parallel [(set (reg:CC FLAGS_REG)
6394                    (compare:CC (match_dup 1) (match_dup 2)))
6395               (set (match_dup 0)
6396                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6397    (parallel [(set (match_dup 3)
6398                    (minus:DWIH
6399                      (match_dup 4)
6400                      (plus:DWIH
6401                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6402                        (match_dup 5))))
6403               (clobber (reg:CC FLAGS_REG))])]
6404   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6405
6406 (define_insn "*sub<mode>_1"
6407   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6408         (minus:SWI
6409           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6410           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6411    (clobber (reg:CC FLAGS_REG))]
6412   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6413   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6414   [(set_attr "type" "alu")
6415    (set_attr "mode" "<MODE>")])
6416
6417 (define_insn "*subsi_1_zext"
6418   [(set (match_operand:DI 0 "register_operand" "=r")
6419         (zero_extend:DI
6420           (minus:SI (match_operand:SI 1 "register_operand" "0")
6421                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6422    (clobber (reg:CC FLAGS_REG))]
6423   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6424   "sub{l}\t{%2, %k0|%k0, %2}"
6425   [(set_attr "type" "alu")
6426    (set_attr "mode" "SI")])
6427
6428 (define_insn "*subqi_1_slp"
6429   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6430         (minus:QI (match_dup 0)
6431                   (match_operand:QI 1 "general_operand" "qn,qm")))
6432    (clobber (reg:CC FLAGS_REG))]
6433   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6434    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6435   "sub{b}\t{%1, %0|%0, %1}"
6436   [(set_attr "type" "alu1")
6437    (set_attr "mode" "QI")])
6438
6439 (define_insn "*sub<mode>_2"
6440   [(set (reg FLAGS_REG)
6441         (compare
6442           (minus:SWI
6443             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6444             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6445           (const_int 0)))
6446    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6447         (minus:SWI (match_dup 1) (match_dup 2)))]
6448   "ix86_match_ccmode (insn, CCGOCmode)
6449    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6450   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6451   [(set_attr "type" "alu")
6452    (set_attr "mode" "<MODE>")])
6453
6454 (define_insn "*subsi_2_zext"
6455   [(set (reg FLAGS_REG)
6456         (compare
6457           (minus:SI (match_operand:SI 1 "register_operand" "0")
6458                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6459           (const_int 0)))
6460    (set (match_operand:DI 0 "register_operand" "=r")
6461         (zero_extend:DI
6462           (minus:SI (match_dup 1)
6463                     (match_dup 2))))]
6464   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6465    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6466   "sub{l}\t{%2, %k0|%k0, %2}"
6467   [(set_attr "type" "alu")
6468    (set_attr "mode" "SI")])
6469
6470 (define_insn "*sub<mode>_3"
6471   [(set (reg FLAGS_REG)
6472         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6473                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6474    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6475         (minus:SWI (match_dup 1) (match_dup 2)))]
6476   "ix86_match_ccmode (insn, CCmode)
6477    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6478   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6479   [(set_attr "type" "alu")
6480    (set_attr "mode" "<MODE>")])
6481
6482 (define_insn "*subsi_3_zext"
6483   [(set (reg FLAGS_REG)
6484         (compare (match_operand:SI 1 "register_operand" "0")
6485                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6486    (set (match_operand:DI 0 "register_operand" "=r")
6487         (zero_extend:DI
6488           (minus:SI (match_dup 1)
6489                     (match_dup 2))))]
6490   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6491    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6492   "sub{l}\t{%2, %1|%1, %2}"
6493   [(set_attr "type" "alu")
6494    (set_attr "mode" "SI")])
6495 \f
6496 ;; Add with carry and subtract with borrow
6497
6498 (define_expand "<plusminus_insn><mode>3_carry"
6499   [(parallel
6500     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6501           (plusminus:SWI
6502             (match_operand:SWI 1 "nonimmediate_operand" "")
6503             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6504                        [(match_operand 3 "flags_reg_operand" "")
6505                         (const_int 0)])
6506                       (match_operand:SWI 2 "<general_operand>" ""))))
6507      (clobber (reg:CC FLAGS_REG))])]
6508   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6509
6510 (define_insn "*<plusminus_insn><mode>3_carry"
6511   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6512         (plusminus:SWI
6513           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6514           (plus:SWI
6515             (match_operator 3 "ix86_carry_flag_operator"
6516              [(reg FLAGS_REG) (const_int 0)])
6517             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6518    (clobber (reg:CC FLAGS_REG))]
6519   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6520   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6521   [(set_attr "type" "alu")
6522    (set_attr "use_carry" "1")
6523    (set_attr "pent_pair" "pu")
6524    (set_attr "mode" "<MODE>")])
6525
6526 (define_insn "*addsi3_carry_zext"
6527   [(set (match_operand:DI 0 "register_operand" "=r")
6528         (zero_extend:DI
6529           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6530                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6531                              [(reg FLAGS_REG) (const_int 0)])
6532                             (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6533    (clobber (reg:CC FLAGS_REG))]
6534   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6535   "adc{l}\t{%2, %k0|%k0, %2}"
6536   [(set_attr "type" "alu")
6537    (set_attr "use_carry" "1")
6538    (set_attr "pent_pair" "pu")
6539    (set_attr "mode" "SI")])
6540
6541 (define_insn "*subsi3_carry_zext"
6542   [(set (match_operand:DI 0 "register_operand" "=r")
6543         (zero_extend:DI
6544           (minus:SI (match_operand:SI 1 "register_operand" "0")
6545                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6546                               [(reg FLAGS_REG) (const_int 0)])
6547                              (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6548    (clobber (reg:CC FLAGS_REG))]
6549   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6550   "sbb{l}\t{%2, %k0|%k0, %2}"
6551   [(set_attr "type" "alu")
6552    (set_attr "pent_pair" "pu")
6553    (set_attr "mode" "SI")])
6554 \f
6555 ;; Overflow setting add and subtract instructions
6556
6557 (define_insn "*add<mode>3_cconly_overflow"
6558   [(set (reg:CCC FLAGS_REG)
6559         (compare:CCC
6560           (plus:SWI
6561             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6562             (match_operand:SWI 2 "<general_operand>" "<g>"))
6563           (match_dup 1)))
6564    (clobber (match_scratch:SWI 0 "=<r>"))]
6565   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6566   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6567   [(set_attr "type" "alu")
6568    (set_attr "mode" "<MODE>")])
6569
6570 (define_insn "*sub<mode>3_cconly_overflow"
6571   [(set (reg:CCC FLAGS_REG)
6572         (compare:CCC
6573           (minus:SWI
6574             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6575             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6576           (match_dup 0)))]
6577   ""
6578   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6579   [(set_attr "type" "icmp")
6580    (set_attr "mode" "<MODE>")])
6581
6582 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6583   [(set (reg:CCC FLAGS_REG)
6584         (compare:CCC
6585             (plusminus:SWI
6586                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6587                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6588             (match_dup 1)))
6589    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6590         (plusminus:SWI (match_dup 1) (match_dup 2)))]
6591   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6592   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6593   [(set_attr "type" "alu")
6594    (set_attr "mode" "<MODE>")])
6595
6596 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6597   [(set (reg:CCC FLAGS_REG)
6598         (compare:CCC
6599           (plusminus:SI
6600             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6601             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6602           (match_dup 1)))
6603    (set (match_operand:DI 0 "register_operand" "=r")
6604         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6605   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6606   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6607   [(set_attr "type" "alu")
6608    (set_attr "mode" "SI")])
6609
6610 ;; The patterns that match these are at the end of this file.
6611
6612 (define_expand "<plusminus_insn>xf3"
6613   [(set (match_operand:XF 0 "register_operand" "")
6614         (plusminus:XF
6615           (match_operand:XF 1 "register_operand" "")
6616           (match_operand:XF 2 "register_operand" "")))]
6617   "TARGET_80387")
6618
6619 (define_expand "<plusminus_insn><mode>3"
6620   [(set (match_operand:MODEF 0 "register_operand" "")
6621         (plusminus:MODEF
6622           (match_operand:MODEF 1 "register_operand" "")
6623           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6624   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6625     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6626 \f
6627 ;; Multiply instructions
6628
6629 (define_expand "mul<mode>3"
6630   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6631                    (mult:SWIM248
6632                      (match_operand:SWIM248 1 "register_operand" "")
6633                      (match_operand:SWIM248 2 "<general_operand>" "")))
6634               (clobber (reg:CC FLAGS_REG))])])
6635
6636 (define_expand "mulqi3"
6637   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6638                    (mult:QI
6639                      (match_operand:QI 1 "register_operand" "")
6640                      (match_operand:QI 2 "nonimmediate_operand" "")))
6641               (clobber (reg:CC FLAGS_REG))])]
6642   "TARGET_QIMODE_MATH")
6643
6644 ;; On AMDFAM10
6645 ;; IMUL reg32/64, reg32/64, imm8        Direct
6646 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6647 ;; IMUL reg32/64, reg32/64, imm32       Direct
6648 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6649 ;; IMUL reg32/64, reg32/64              Direct
6650 ;; IMUL reg32/64, mem32/64              Direct
6651 ;;
6652 ;; On BDVER1, all above IMULs use DirectPath
6653
6654 (define_insn "*mul<mode>3_1"
6655   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6656         (mult:SWI48
6657           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6658           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6659    (clobber (reg:CC FLAGS_REG))]
6660   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6661   "@
6662    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6663    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6664    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6665   [(set_attr "type" "imul")
6666    (set_attr "prefix_0f" "0,0,1")
6667    (set (attr "athlon_decode")
6668         (cond [(eq_attr "cpu" "athlon")
6669                   (const_string "vector")
6670                (eq_attr "alternative" "1")
6671                   (const_string "vector")
6672                (and (eq_attr "alternative" "2")
6673                     (match_operand 1 "memory_operand" ""))
6674                   (const_string "vector")]
6675               (const_string "direct")))
6676    (set (attr "amdfam10_decode")
6677         (cond [(and (eq_attr "alternative" "0,1")
6678                     (match_operand 1 "memory_operand" ""))
6679                   (const_string "vector")]
6680               (const_string "direct")))
6681    (set_attr "bdver1_decode" "direct")
6682    (set_attr "mode" "<MODE>")])
6683
6684 (define_insn "*mulsi3_1_zext"
6685   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6686         (zero_extend:DI
6687           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6688                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6689    (clobber (reg:CC FLAGS_REG))]
6690   "TARGET_64BIT
6691    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6692   "@
6693    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6694    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6695    imul{l}\t{%2, %k0|%k0, %2}"
6696   [(set_attr "type" "imul")
6697    (set_attr "prefix_0f" "0,0,1")
6698    (set (attr "athlon_decode")
6699         (cond [(eq_attr "cpu" "athlon")
6700                   (const_string "vector")
6701                (eq_attr "alternative" "1")
6702                   (const_string "vector")
6703                (and (eq_attr "alternative" "2")
6704                     (match_operand 1 "memory_operand" ""))
6705                   (const_string "vector")]
6706               (const_string "direct")))
6707    (set (attr "amdfam10_decode")
6708         (cond [(and (eq_attr "alternative" "0,1")
6709                     (match_operand 1 "memory_operand" ""))
6710                   (const_string "vector")]
6711               (const_string "direct")))
6712    (set_attr "bdver1_decode" "direct")
6713    (set_attr "mode" "SI")])
6714
6715 ;; On AMDFAM10
6716 ;; IMUL reg16, reg16, imm8      VectorPath
6717 ;; IMUL reg16, mem16, imm8      VectorPath
6718 ;; IMUL reg16, reg16, imm16     VectorPath
6719 ;; IMUL reg16, mem16, imm16     VectorPath
6720 ;; IMUL reg16, reg16            Direct
6721 ;; IMUL reg16, mem16            Direct
6722 ;;
6723 ;; On BDVER1, all HI MULs use DoublePath
6724
6725 (define_insn "*mulhi3_1"
6726   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6727         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6728                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6729    (clobber (reg:CC FLAGS_REG))]
6730   "TARGET_HIMODE_MATH
6731    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6732   "@
6733    imul{w}\t{%2, %1, %0|%0, %1, %2}
6734    imul{w}\t{%2, %1, %0|%0, %1, %2}
6735    imul{w}\t{%2, %0|%0, %2}"
6736   [(set_attr "type" "imul")
6737    (set_attr "prefix_0f" "0,0,1")
6738    (set (attr "athlon_decode")
6739         (cond [(eq_attr "cpu" "athlon")
6740                   (const_string "vector")
6741                (eq_attr "alternative" "1,2")
6742                   (const_string "vector")]
6743               (const_string "direct")))
6744    (set (attr "amdfam10_decode")
6745         (cond [(eq_attr "alternative" "0,1")
6746                   (const_string "vector")]
6747               (const_string "direct")))
6748    (set_attr "bdver1_decode" "double")
6749    (set_attr "mode" "HI")])
6750
6751 ;;On AMDFAM10 and BDVER1
6752 ;; MUL reg8     Direct
6753 ;; MUL mem8     Direct
6754
6755 (define_insn "*mulqi3_1"
6756   [(set (match_operand:QI 0 "register_operand" "=a")
6757         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6758                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6759    (clobber (reg:CC FLAGS_REG))]
6760   "TARGET_QIMODE_MATH
6761    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6762   "mul{b}\t%2"
6763   [(set_attr "type" "imul")
6764    (set_attr "length_immediate" "0")
6765    (set (attr "athlon_decode")
6766      (if_then_else (eq_attr "cpu" "athlon")
6767         (const_string "vector")
6768         (const_string "direct")))
6769    (set_attr "amdfam10_decode" "direct")
6770    (set_attr "bdver1_decode" "direct")
6771    (set_attr "mode" "QI")])
6772
6773 (define_expand "<u>mul<mode><dwi>3"
6774   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6775                    (mult:<DWI>
6776                      (any_extend:<DWI>
6777                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
6778                      (any_extend:<DWI>
6779                        (match_operand:DWIH 2 "register_operand" ""))))
6780               (clobber (reg:CC FLAGS_REG))])])
6781
6782 (define_expand "<u>mulqihi3"
6783   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6784                    (mult:HI
6785                      (any_extend:HI
6786                        (match_operand:QI 1 "nonimmediate_operand" ""))
6787                      (any_extend:HI
6788                        (match_operand:QI 2 "register_operand" ""))))
6789               (clobber (reg:CC FLAGS_REG))])]
6790   "TARGET_QIMODE_MATH")
6791
6792 (define_insn "*bmi2_umulditi3_1"
6793   [(set (match_operand:DI 0 "register_operand" "=r")
6794         (mult:DI
6795           (match_operand:DI 2 "nonimmediate_operand" "%d")
6796           (match_operand:DI 3 "nonimmediate_operand" "rm")))
6797    (set (match_operand:DI 1 "register_operand" "=r")
6798         (truncate:DI
6799           (lshiftrt:TI
6800             (mult:TI (zero_extend:TI (match_dup 2))
6801                      (zero_extend:TI (match_dup 3)))
6802             (const_int 64))))]
6803   "TARGET_64BIT && TARGET_BMI2
6804    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6805   "mulx\t{%3, %0, %1|%1, %0, %3}"
6806   [(set_attr "type" "imulx")
6807    (set_attr "prefix" "vex")
6808    (set_attr "mode" "DI")])
6809
6810 (define_insn "*bmi2_umulsidi3_1"
6811   [(set (match_operand:SI 0 "register_operand" "=r")
6812         (mult:SI
6813           (match_operand:SI 2 "nonimmediate_operand" "%d")
6814           (match_operand:SI 3 "nonimmediate_operand" "rm")))
6815    (set (match_operand:SI 1 "register_operand" "=r")
6816         (truncate:SI
6817           (lshiftrt:DI
6818             (mult:DI (zero_extend:DI (match_dup 2))
6819                      (zero_extend:DI (match_dup 3)))
6820             (const_int 32))))]
6821   "!TARGET_64BIT && TARGET_BMI2
6822    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6823   "mulx\t{%3, %0, %1|%1, %0, %3}"
6824   [(set_attr "type" "imulx")
6825    (set_attr "prefix" "vex")
6826    (set_attr "mode" "SI")])
6827
6828 (define_insn "*umul<mode><dwi>3_1"
6829   [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6830         (mult:<DWI>
6831           (zero_extend:<DWI>
6832             (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6833           (zero_extend:<DWI>
6834             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6835    (clobber (reg:CC FLAGS_REG))]
6836   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6837   "@
6838    mul{<imodesuffix>}\t%2
6839    #"
6840   [(set_attr "isa" "*,bmi2")
6841    (set_attr "type" "imul,imulx")
6842    (set_attr "length_immediate" "0,*")
6843    (set (attr "athlon_decode")
6844         (cond [(eq_attr "alternative" "0")
6845                  (if_then_else (eq_attr "cpu" "athlon")
6846                    (const_string "vector")
6847                    (const_string "double"))]
6848               (const_string "*")))
6849    (set_attr "amdfam10_decode" "double,*")
6850    (set_attr "bdver1_decode" "direct,*")
6851    (set_attr "prefix" "orig,vex")
6852    (set_attr "mode" "<MODE>")])
6853
6854 ;; Convert mul to the mulx pattern to avoid flags dependency.
6855 (define_split
6856  [(set (match_operand:<DWI> 0 "register_operand" "")
6857        (mult:<DWI>
6858          (zero_extend:<DWI>
6859            (match_operand:DWIH 1 "register_operand" ""))
6860          (zero_extend:<DWI>
6861            (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6862   (clobber (reg:CC FLAGS_REG))]
6863  "TARGET_BMI2 && reload_completed
6864   && true_regnum (operands[1]) == DX_REG"
6865   [(parallel [(set (match_dup 3)
6866                    (mult:DWIH (match_dup 1) (match_dup 2)))
6867               (set (match_dup 4)
6868                    (truncate:DWIH
6869                      (lshiftrt:<DWI>
6870                        (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6871                                    (zero_extend:<DWI> (match_dup 2)))
6872                        (match_dup 5))))])]
6873 {
6874   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6875
6876   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6877 })
6878
6879 (define_insn "*mul<mode><dwi>3_1"
6880   [(set (match_operand:<DWI> 0 "register_operand" "=A")
6881         (mult:<DWI>
6882           (sign_extend:<DWI>
6883             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6884           (sign_extend:<DWI>
6885             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6886    (clobber (reg:CC FLAGS_REG))]
6887   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6888   "imul{<imodesuffix>}\t%2"
6889   [(set_attr "type" "imul")
6890    (set_attr "length_immediate" "0")
6891    (set (attr "athlon_decode")
6892      (if_then_else (eq_attr "cpu" "athlon")
6893         (const_string "vector")
6894         (const_string "double")))
6895    (set_attr "amdfam10_decode" "double")
6896    (set_attr "bdver1_decode" "direct")
6897    (set_attr "mode" "<MODE>")])
6898
6899 (define_insn "*<u>mulqihi3_1"
6900   [(set (match_operand:HI 0 "register_operand" "=a")
6901         (mult:HI
6902           (any_extend:HI
6903             (match_operand:QI 1 "nonimmediate_operand" "%0"))
6904           (any_extend:HI
6905             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6906    (clobber (reg:CC FLAGS_REG))]
6907   "TARGET_QIMODE_MATH
6908    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6909   "<sgnprefix>mul{b}\t%2"
6910   [(set_attr "type" "imul")
6911    (set_attr "length_immediate" "0")
6912    (set (attr "athlon_decode")
6913      (if_then_else (eq_attr "cpu" "athlon")
6914         (const_string "vector")
6915         (const_string "direct")))
6916    (set_attr "amdfam10_decode" "direct")
6917    (set_attr "bdver1_decode" "direct")
6918    (set_attr "mode" "QI")])
6919
6920 (define_expand "<s>mul<mode>3_highpart"
6921   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6922                    (truncate:SWI48
6923                      (lshiftrt:<DWI>
6924                        (mult:<DWI>
6925                          (any_extend:<DWI>
6926                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
6927                          (any_extend:<DWI>
6928                            (match_operand:SWI48 2 "register_operand" "")))
6929                        (match_dup 4))))
6930               (clobber (match_scratch:SWI48 3 ""))
6931               (clobber (reg:CC FLAGS_REG))])]
6932   ""
6933   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6934
6935 (define_insn "*<s>muldi3_highpart_1"
6936   [(set (match_operand:DI 0 "register_operand" "=d")
6937         (truncate:DI
6938           (lshiftrt:TI
6939             (mult:TI
6940               (any_extend:TI
6941                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6942               (any_extend:TI
6943                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6944             (const_int 64))))
6945    (clobber (match_scratch:DI 3 "=1"))
6946    (clobber (reg:CC FLAGS_REG))]
6947   "TARGET_64BIT
6948    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6949   "<sgnprefix>mul{q}\t%2"
6950   [(set_attr "type" "imul")
6951    (set_attr "length_immediate" "0")
6952    (set (attr "athlon_decode")
6953      (if_then_else (eq_attr "cpu" "athlon")
6954         (const_string "vector")
6955         (const_string "double")))
6956    (set_attr "amdfam10_decode" "double")
6957    (set_attr "bdver1_decode" "direct")
6958    (set_attr "mode" "DI")])
6959
6960 (define_insn "*<s>mulsi3_highpart_1"
6961   [(set (match_operand:SI 0 "register_operand" "=d")
6962         (truncate:SI
6963           (lshiftrt:DI
6964             (mult:DI
6965               (any_extend:DI
6966                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6967               (any_extend:DI
6968                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6969             (const_int 32))))
6970    (clobber (match_scratch:SI 3 "=1"))
6971    (clobber (reg:CC FLAGS_REG))]
6972   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6973   "<sgnprefix>mul{l}\t%2"
6974   [(set_attr "type" "imul")
6975    (set_attr "length_immediate" "0")
6976    (set (attr "athlon_decode")
6977      (if_then_else (eq_attr "cpu" "athlon")
6978         (const_string "vector")
6979         (const_string "double")))
6980    (set_attr "amdfam10_decode" "double")
6981    (set_attr "bdver1_decode" "direct")
6982    (set_attr "mode" "SI")])
6983
6984 (define_insn "*<s>mulsi3_highpart_zext"
6985   [(set (match_operand:DI 0 "register_operand" "=d")
6986         (zero_extend:DI (truncate:SI
6987           (lshiftrt:DI
6988             (mult:DI (any_extend:DI
6989                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
6990                      (any_extend:DI
6991                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
6992             (const_int 32)))))
6993    (clobber (match_scratch:SI 3 "=1"))
6994    (clobber (reg:CC FLAGS_REG))]
6995   "TARGET_64BIT
6996    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6997   "<sgnprefix>mul{l}\t%2"
6998   [(set_attr "type" "imul")
6999    (set_attr "length_immediate" "0")
7000    (set (attr "athlon_decode")
7001      (if_then_else (eq_attr "cpu" "athlon")
7002         (const_string "vector")
7003         (const_string "double")))
7004    (set_attr "amdfam10_decode" "double")
7005    (set_attr "bdver1_decode" "direct")
7006    (set_attr "mode" "SI")])
7007
7008 ;; The patterns that match these are at the end of this file.
7009
7010 (define_expand "mulxf3"
7011   [(set (match_operand:XF 0 "register_operand" "")
7012         (mult:XF (match_operand:XF 1 "register_operand" "")
7013                  (match_operand:XF 2 "register_operand" "")))]
7014   "TARGET_80387")
7015
7016 (define_expand "mul<mode>3"
7017   [(set (match_operand:MODEF 0 "register_operand" "")
7018         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7019                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7020   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7021     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7022 \f
7023 ;; Divide instructions
7024
7025 ;; The patterns that match these are at the end of this file.
7026
7027 (define_expand "divxf3"
7028   [(set (match_operand:XF 0 "register_operand" "")
7029         (div:XF (match_operand:XF 1 "register_operand" "")
7030                 (match_operand:XF 2 "register_operand" "")))]
7031   "TARGET_80387")
7032
7033 (define_expand "divdf3"
7034   [(set (match_operand:DF 0 "register_operand" "")
7035         (div:DF (match_operand:DF 1 "register_operand" "")
7036                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7037    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7038     || (TARGET_SSE2 && TARGET_SSE_MATH)")
7039
7040 (define_expand "divsf3"
7041   [(set (match_operand:SF 0 "register_operand" "")
7042         (div:SF (match_operand:SF 1 "register_operand" "")
7043                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7044   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7045     || TARGET_SSE_MATH"
7046 {
7047   if (TARGET_SSE_MATH
7048       && TARGET_RECIP_DIV
7049       && optimize_insn_for_speed_p ()
7050       && flag_finite_math_only && !flag_trapping_math
7051       && flag_unsafe_math_optimizations)
7052     {
7053       ix86_emit_swdivsf (operands[0], operands[1],
7054                          operands[2], SFmode);
7055       DONE;
7056     }
7057 })
7058 \f
7059 ;; Divmod instructions.
7060
7061 (define_expand "divmod<mode>4"
7062   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7063                    (div:SWIM248
7064                      (match_operand:SWIM248 1 "register_operand" "")
7065                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7066               (set (match_operand:SWIM248 3 "register_operand" "")
7067                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7068               (clobber (reg:CC FLAGS_REG))])])
7069
7070 ;; Split with 8bit unsigned divide:
7071 ;;      if (dividend an divisor are in [0-255])
7072 ;;         use 8bit unsigned integer divide
7073 ;;       else
7074 ;;         use original integer divide
7075 (define_split
7076   [(set (match_operand:SWI48 0 "register_operand" "")
7077         (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7078                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7079    (set (match_operand:SWI48 1 "register_operand" "")
7080         (mod:SWI48 (match_dup 2) (match_dup 3)))
7081    (clobber (reg:CC FLAGS_REG))]
7082   "TARGET_USE_8BIT_IDIV
7083    && TARGET_QIMODE_MATH
7084    && can_create_pseudo_p ()
7085    && !optimize_insn_for_size_p ()"
7086   [(const_int 0)]
7087   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7088
7089 (define_insn_and_split "divmod<mode>4_1"
7090   [(set (match_operand:SWI48 0 "register_operand" "=a")
7091         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7092                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7093    (set (match_operand:SWI48 1 "register_operand" "=&d")
7094         (mod:SWI48 (match_dup 2) (match_dup 3)))
7095    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7096    (clobber (reg:CC FLAGS_REG))]
7097   ""
7098   "#"
7099   "reload_completed"
7100   [(parallel [(set (match_dup 1)
7101                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7102               (clobber (reg:CC FLAGS_REG))])
7103    (parallel [(set (match_dup 0)
7104                    (div:SWI48 (match_dup 2) (match_dup 3)))
7105               (set (match_dup 1)
7106                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7107               (use (match_dup 1))
7108               (clobber (reg:CC FLAGS_REG))])]
7109 {
7110   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7111
7112   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7113     operands[4] = operands[2];
7114   else
7115     {
7116       /* Avoid use of cltd in favor of a mov+shift.  */
7117       emit_move_insn (operands[1], operands[2]);
7118       operands[4] = operands[1];
7119     }
7120 }
7121   [(set_attr "type" "multi")
7122    (set_attr "mode" "<MODE>")])
7123
7124 (define_insn_and_split "*divmod<mode>4"
7125   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7126         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7127                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7128    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7129         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7130    (clobber (reg:CC FLAGS_REG))]
7131   ""
7132   "#"
7133   "reload_completed"
7134   [(parallel [(set (match_dup 1)
7135                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7136               (clobber (reg:CC FLAGS_REG))])
7137    (parallel [(set (match_dup 0)
7138                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7139               (set (match_dup 1)
7140                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7141               (use (match_dup 1))
7142               (clobber (reg:CC FLAGS_REG))])]
7143 {
7144   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7145
7146   if (<MODE>mode != HImode
7147       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7148     operands[4] = operands[2];
7149   else
7150     {
7151       /* Avoid use of cltd in favor of a mov+shift.  */
7152       emit_move_insn (operands[1], operands[2]);
7153       operands[4] = operands[1];
7154     }
7155 }
7156   [(set_attr "type" "multi")
7157    (set_attr "mode" "<MODE>")])
7158
7159 (define_insn "*divmod<mode>4_noext"
7160   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7161         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7162                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7163    (set (match_operand:SWIM248 1 "register_operand" "=d")
7164         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7165    (use (match_operand:SWIM248 4 "register_operand" "1"))
7166    (clobber (reg:CC FLAGS_REG))]
7167   ""
7168   "idiv{<imodesuffix>}\t%3"
7169   [(set_attr "type" "idiv")
7170    (set_attr "mode" "<MODE>")])
7171
7172 (define_expand "divmodqi4"
7173   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7174                    (div:QI
7175                      (match_operand:QI 1 "register_operand" "")
7176                      (match_operand:QI 2 "nonimmediate_operand" "")))
7177               (set (match_operand:QI 3 "register_operand" "")
7178                    (mod:QI (match_dup 1) (match_dup 2)))
7179               (clobber (reg:CC FLAGS_REG))])]
7180   "TARGET_QIMODE_MATH"
7181 {
7182   rtx div, mod, insn;
7183   rtx tmp0, tmp1;
7184   
7185   tmp0 = gen_reg_rtx (HImode);
7186   tmp1 = gen_reg_rtx (HImode);
7187
7188   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7189      in AX.  */
7190   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7191   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7192
7193   /* Extract remainder from AH.  */
7194   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7195   insn = emit_move_insn (operands[3], tmp1);
7196
7197   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7198   set_unique_reg_note (insn, REG_EQUAL, mod);
7199
7200   /* Extract quotient from AL.  */
7201   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7202
7203   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7204   set_unique_reg_note (insn, REG_EQUAL, div);
7205
7206   DONE;
7207 })
7208
7209 ;; Divide AX by r/m8, with result stored in
7210 ;; AL <- Quotient
7211 ;; AH <- Remainder
7212 ;; Change div/mod to HImode and extend the second argument to HImode
7213 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7214 ;; combine may fail.
7215 (define_insn "divmodhiqi3"
7216   [(set (match_operand:HI 0 "register_operand" "=a")
7217         (ior:HI
7218           (ashift:HI
7219             (zero_extend:HI
7220               (truncate:QI
7221                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7222                         (sign_extend:HI
7223                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7224             (const_int 8))
7225           (zero_extend:HI
7226             (truncate:QI
7227               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7228    (clobber (reg:CC FLAGS_REG))]
7229   "TARGET_QIMODE_MATH"
7230   "idiv{b}\t%2"
7231   [(set_attr "type" "idiv")
7232    (set_attr "mode" "QI")])
7233
7234 (define_expand "udivmod<mode>4"
7235   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7236                    (udiv:SWIM248
7237                      (match_operand:SWIM248 1 "register_operand" "")
7238                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7239               (set (match_operand:SWIM248 3 "register_operand" "")
7240                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7241               (clobber (reg:CC FLAGS_REG))])])
7242
7243 ;; Split with 8bit unsigned divide:
7244 ;;      if (dividend an divisor are in [0-255])
7245 ;;         use 8bit unsigned integer divide
7246 ;;       else
7247 ;;         use original integer divide
7248 (define_split
7249   [(set (match_operand:SWI48 0 "register_operand" "")
7250         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7251                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7252    (set (match_operand:SWI48 1 "register_operand" "")
7253         (umod:SWI48 (match_dup 2) (match_dup 3)))
7254    (clobber (reg:CC FLAGS_REG))]
7255   "TARGET_USE_8BIT_IDIV
7256    && TARGET_QIMODE_MATH
7257    && can_create_pseudo_p ()
7258    && !optimize_insn_for_size_p ()"
7259   [(const_int 0)]
7260   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7261
7262 (define_insn_and_split "udivmod<mode>4_1"
7263   [(set (match_operand:SWI48 0 "register_operand" "=a")
7264         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7265                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7266    (set (match_operand:SWI48 1 "register_operand" "=&d")
7267         (umod:SWI48 (match_dup 2) (match_dup 3)))
7268    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7269    (clobber (reg:CC FLAGS_REG))]
7270   ""
7271   "#"
7272   "reload_completed"
7273   [(set (match_dup 1) (const_int 0))
7274    (parallel [(set (match_dup 0)
7275                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7276               (set (match_dup 1)
7277                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7278               (use (match_dup 1))
7279               (clobber (reg:CC FLAGS_REG))])]
7280   ""
7281   [(set_attr "type" "multi")
7282    (set_attr "mode" "<MODE>")])
7283
7284 (define_insn_and_split "*udivmod<mode>4"
7285   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7286         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7287                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7288    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7289         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7290    (clobber (reg:CC FLAGS_REG))]
7291   ""
7292   "#"
7293   "reload_completed"
7294   [(set (match_dup 1) (const_int 0))
7295    (parallel [(set (match_dup 0)
7296                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7297               (set (match_dup 1)
7298                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7299               (use (match_dup 1))
7300               (clobber (reg:CC FLAGS_REG))])]
7301   ""
7302   [(set_attr "type" "multi")
7303    (set_attr "mode" "<MODE>")])
7304
7305 (define_insn "*udivmod<mode>4_noext"
7306   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7307         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7308                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7309    (set (match_operand:SWIM248 1 "register_operand" "=d")
7310         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7311    (use (match_operand:SWIM248 4 "register_operand" "1"))
7312    (clobber (reg:CC FLAGS_REG))]
7313   ""
7314   "div{<imodesuffix>}\t%3"
7315   [(set_attr "type" "idiv")
7316    (set_attr "mode" "<MODE>")])
7317
7318 (define_expand "udivmodqi4"
7319   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7320                    (udiv:QI
7321                      (match_operand:QI 1 "register_operand" "")
7322                      (match_operand:QI 2 "nonimmediate_operand" "")))
7323               (set (match_operand:QI 3 "register_operand" "")
7324                    (umod:QI (match_dup 1) (match_dup 2)))
7325               (clobber (reg:CC FLAGS_REG))])]
7326   "TARGET_QIMODE_MATH"
7327 {
7328   rtx div, mod, insn;
7329   rtx tmp0, tmp1;
7330   
7331   tmp0 = gen_reg_rtx (HImode);
7332   tmp1 = gen_reg_rtx (HImode);
7333
7334   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7335      in AX.  */
7336   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7337   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7338
7339   /* Extract remainder from AH.  */
7340   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7341   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7342   insn = emit_move_insn (operands[3], tmp1);
7343
7344   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7345   set_unique_reg_note (insn, REG_EQUAL, mod);
7346
7347   /* Extract quotient from AL.  */
7348   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7349
7350   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7351   set_unique_reg_note (insn, REG_EQUAL, div);
7352
7353   DONE;
7354 })
7355
7356 (define_insn "udivmodhiqi3"
7357   [(set (match_operand:HI 0 "register_operand" "=a")
7358         (ior:HI
7359           (ashift:HI
7360             (zero_extend:HI
7361               (truncate:QI
7362                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7363                         (zero_extend:HI
7364                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7365             (const_int 8))
7366           (zero_extend:HI
7367             (truncate:QI
7368               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7369    (clobber (reg:CC FLAGS_REG))]
7370   "TARGET_QIMODE_MATH"
7371   "div{b}\t%2"
7372   [(set_attr "type" "idiv")
7373    (set_attr "mode" "QI")])
7374
7375 ;; We cannot use div/idiv for double division, because it causes
7376 ;; "division by zero" on the overflow and that's not what we expect
7377 ;; from truncate.  Because true (non truncating) double division is
7378 ;; never generated, we can't create this insn anyway.
7379 ;
7380 ;(define_insn ""
7381 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7382 ;       (truncate:SI
7383 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7384 ;                  (zero_extend:DI
7385 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7386 ;   (set (match_operand:SI 3 "register_operand" "=d")
7387 ;       (truncate:SI
7388 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7389 ;   (clobber (reg:CC FLAGS_REG))]
7390 ;  ""
7391 ;  "div{l}\t{%2, %0|%0, %2}"
7392 ;  [(set_attr "type" "idiv")])
7393 \f
7394 ;;- Logical AND instructions
7395
7396 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7397 ;; Note that this excludes ah.
7398
7399 (define_expand "testsi_ccno_1"
7400   [(set (reg:CCNO FLAGS_REG)
7401         (compare:CCNO
7402           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7403                   (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7404           (const_int 0)))])
7405
7406 (define_expand "testqi_ccz_1"
7407   [(set (reg:CCZ FLAGS_REG)
7408         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7409                              (match_operand:QI 1 "nonmemory_operand" ""))
7410                  (const_int 0)))])
7411
7412 (define_expand "testdi_ccno_1"
7413   [(set (reg:CCNO FLAGS_REG)
7414         (compare:CCNO
7415           (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7416                   (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7417           (const_int 0)))]
7418   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7419
7420 (define_insn "*testdi_1"
7421   [(set (reg FLAGS_REG)
7422         (compare
7423          (and:DI
7424           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7425           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7426          (const_int 0)))]
7427   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7428    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7429   "@
7430    test{l}\t{%k1, %k0|%k0, %k1}
7431    test{l}\t{%k1, %k0|%k0, %k1}
7432    test{q}\t{%1, %0|%0, %1}
7433    test{q}\t{%1, %0|%0, %1}
7434    test{q}\t{%1, %0|%0, %1}"
7435   [(set_attr "type" "test")
7436    (set_attr "modrm" "0,1,0,1,1")
7437    (set_attr "mode" "SI,SI,DI,DI,DI")])
7438
7439 (define_insn "*testqi_1_maybe_si"
7440   [(set (reg FLAGS_REG)
7441         (compare
7442           (and:QI
7443             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7444             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7445           (const_int 0)))]
7446    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7447     && ix86_match_ccmode (insn,
7448                          CONST_INT_P (operands[1])
7449                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7450 {
7451   if (which_alternative == 3)
7452     {
7453       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7454         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7455       return "test{l}\t{%1, %k0|%k0, %1}";
7456     }
7457   return "test{b}\t{%1, %0|%0, %1}";
7458 }
7459   [(set_attr "type" "test")
7460    (set_attr "modrm" "0,1,1,1")
7461    (set_attr "mode" "QI,QI,QI,SI")
7462    (set_attr "pent_pair" "uv,np,uv,np")])
7463
7464 (define_insn "*test<mode>_1"
7465   [(set (reg FLAGS_REG)
7466         (compare
7467          (and:SWI124
7468           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7469           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7470          (const_int 0)))]
7471   "ix86_match_ccmode (insn, CCNOmode)
7472    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7473   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7474   [(set_attr "type" "test")
7475    (set_attr "modrm" "0,1,1")
7476    (set_attr "mode" "<MODE>")
7477    (set_attr "pent_pair" "uv,np,uv")])
7478
7479 (define_expand "testqi_ext_ccno_0"
7480   [(set (reg:CCNO FLAGS_REG)
7481         (compare:CCNO
7482           (and:SI
7483             (zero_extract:SI
7484               (match_operand 0 "ext_register_operand" "")
7485               (const_int 8)
7486               (const_int 8))
7487             (match_operand 1 "const_int_operand" ""))
7488           (const_int 0)))])
7489
7490 (define_insn "*testqi_ext_0"
7491   [(set (reg FLAGS_REG)
7492         (compare
7493           (and:SI
7494             (zero_extract:SI
7495               (match_operand 0 "ext_register_operand" "Q")
7496               (const_int 8)
7497               (const_int 8))
7498             (match_operand 1 "const_int_operand" "n"))
7499           (const_int 0)))]
7500   "ix86_match_ccmode (insn, CCNOmode)"
7501   "test{b}\t{%1, %h0|%h0, %1}"
7502   [(set_attr "type" "test")
7503    (set_attr "mode" "QI")
7504    (set_attr "length_immediate" "1")
7505    (set_attr "modrm" "1")
7506    (set_attr "pent_pair" "np")])
7507
7508 (define_insn "*testqi_ext_1_rex64"
7509   [(set (reg FLAGS_REG)
7510         (compare
7511           (and:SI
7512             (zero_extract:SI
7513               (match_operand 0 "ext_register_operand" "Q")
7514               (const_int 8)
7515               (const_int 8))
7516             (zero_extend:SI
7517               (match_operand:QI 1 "register_operand" "Q")))
7518           (const_int 0)))]
7519   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7520   "test{b}\t{%1, %h0|%h0, %1}"
7521   [(set_attr "type" "test")
7522    (set_attr "mode" "QI")])
7523
7524 (define_insn "*testqi_ext_1"
7525   [(set (reg FLAGS_REG)
7526         (compare
7527           (and:SI
7528             (zero_extract:SI
7529               (match_operand 0 "ext_register_operand" "Q")
7530               (const_int 8)
7531               (const_int 8))
7532             (zero_extend:SI
7533               (match_operand:QI 1 "general_operand" "Qm")))
7534           (const_int 0)))]
7535   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7536   "test{b}\t{%1, %h0|%h0, %1}"
7537   [(set_attr "type" "test")
7538    (set_attr "mode" "QI")])
7539
7540 (define_insn "*testqi_ext_2"
7541   [(set (reg FLAGS_REG)
7542         (compare
7543           (and:SI
7544             (zero_extract:SI
7545               (match_operand 0 "ext_register_operand" "Q")
7546               (const_int 8)
7547               (const_int 8))
7548             (zero_extract:SI
7549               (match_operand 1 "ext_register_operand" "Q")
7550               (const_int 8)
7551               (const_int 8)))
7552           (const_int 0)))]
7553   "ix86_match_ccmode (insn, CCNOmode)"
7554   "test{b}\t{%h1, %h0|%h0, %h1}"
7555   [(set_attr "type" "test")
7556    (set_attr "mode" "QI")])
7557
7558 (define_insn "*testqi_ext_3_rex64"
7559   [(set (reg FLAGS_REG)
7560         (compare (zero_extract:DI
7561                    (match_operand 0 "nonimmediate_operand" "rm")
7562                    (match_operand:DI 1 "const_int_operand" "")
7563                    (match_operand:DI 2 "const_int_operand" ""))
7564                  (const_int 0)))]
7565   "TARGET_64BIT
7566    && ix86_match_ccmode (insn, CCNOmode)
7567    && INTVAL (operands[1]) > 0
7568    && INTVAL (operands[2]) >= 0
7569    /* Ensure that resulting mask is zero or sign extended operand.  */
7570    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7571        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7572            && INTVAL (operands[1]) > 32))
7573    && (GET_MODE (operands[0]) == SImode
7574        || GET_MODE (operands[0]) == DImode
7575        || GET_MODE (operands[0]) == HImode
7576        || GET_MODE (operands[0]) == QImode)"
7577   "#")
7578
7579 ;; Combine likes to form bit extractions for some tests.  Humor it.
7580 (define_insn "*testqi_ext_3"
7581   [(set (reg FLAGS_REG)
7582         (compare (zero_extract:SI
7583                    (match_operand 0 "nonimmediate_operand" "rm")
7584                    (match_operand:SI 1 "const_int_operand" "")
7585                    (match_operand:SI 2 "const_int_operand" ""))
7586                  (const_int 0)))]
7587   "ix86_match_ccmode (insn, CCNOmode)
7588    && INTVAL (operands[1]) > 0
7589    && INTVAL (operands[2]) >= 0
7590    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7591    && (GET_MODE (operands[0]) == SImode
7592        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7593        || GET_MODE (operands[0]) == HImode
7594        || GET_MODE (operands[0]) == QImode)"
7595   "#")
7596
7597 (define_split
7598   [(set (match_operand 0 "flags_reg_operand" "")
7599         (match_operator 1 "compare_operator"
7600           [(zero_extract
7601              (match_operand 2 "nonimmediate_operand" "")
7602              (match_operand 3 "const_int_operand" "")
7603              (match_operand 4 "const_int_operand" ""))
7604            (const_int 0)]))]
7605   "ix86_match_ccmode (insn, CCNOmode)"
7606   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7607 {
7608   rtx val = operands[2];
7609   HOST_WIDE_INT len = INTVAL (operands[3]);
7610   HOST_WIDE_INT pos = INTVAL (operands[4]);
7611   HOST_WIDE_INT mask;
7612   enum machine_mode mode, submode;
7613
7614   mode = GET_MODE (val);
7615   if (MEM_P (val))
7616     {
7617       /* ??? Combine likes to put non-volatile mem extractions in QImode
7618          no matter the size of the test.  So find a mode that works.  */
7619       if (! MEM_VOLATILE_P (val))
7620         {
7621           mode = smallest_mode_for_size (pos + len, MODE_INT);
7622           val = adjust_address (val, mode, 0);
7623         }
7624     }
7625   else if (GET_CODE (val) == SUBREG
7626            && (submode = GET_MODE (SUBREG_REG (val)),
7627                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7628            && pos + len <= GET_MODE_BITSIZE (submode)
7629            && GET_MODE_CLASS (submode) == MODE_INT)
7630     {
7631       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7632       mode = submode;
7633       val = SUBREG_REG (val);
7634     }
7635   else if (mode == HImode && pos + len <= 8)
7636     {
7637       /* Small HImode tests can be converted to QImode.  */
7638       mode = QImode;
7639       val = gen_lowpart (QImode, val);
7640     }
7641
7642   if (len == HOST_BITS_PER_WIDE_INT)
7643     mask = -1;
7644   else
7645     mask = ((HOST_WIDE_INT)1 << len) - 1;
7646   mask <<= pos;
7647
7648   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7649 })
7650
7651 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7652 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7653 ;; this is relatively important trick.
7654 ;; Do the conversion only post-reload to avoid limiting of the register class
7655 ;; to QI regs.
7656 (define_split
7657   [(set (match_operand 0 "flags_reg_operand" "")
7658         (match_operator 1 "compare_operator"
7659           [(and (match_operand 2 "register_operand" "")
7660                 (match_operand 3 "const_int_operand" ""))
7661            (const_int 0)]))]
7662    "reload_completed
7663     && QI_REG_P (operands[2])
7664     && GET_MODE (operands[2]) != QImode
7665     && ((ix86_match_ccmode (insn, CCZmode)
7666          && !(INTVAL (operands[3]) & ~(255 << 8)))
7667         || (ix86_match_ccmode (insn, CCNOmode)
7668             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7669   [(set (match_dup 0)
7670         (match_op_dup 1
7671           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7672                    (match_dup 3))
7673            (const_int 0)]))]
7674 {
7675   operands[2] = gen_lowpart (SImode, operands[2]);
7676   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7677 })
7678
7679 (define_split
7680   [(set (match_operand 0 "flags_reg_operand" "")
7681         (match_operator 1 "compare_operator"
7682           [(and (match_operand 2 "nonimmediate_operand" "")
7683                 (match_operand 3 "const_int_operand" ""))
7684            (const_int 0)]))]
7685    "reload_completed
7686     && GET_MODE (operands[2]) != QImode
7687     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7688     && ((ix86_match_ccmode (insn, CCZmode)
7689          && !(INTVAL (operands[3]) & ~255))
7690         || (ix86_match_ccmode (insn, CCNOmode)
7691             && !(INTVAL (operands[3]) & ~127)))"
7692   [(set (match_dup 0)
7693         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7694                          (const_int 0)]))]
7695 {
7696   operands[2] = gen_lowpart (QImode, operands[2]);
7697   operands[3] = gen_lowpart (QImode, operands[3]);
7698 })
7699
7700 ;; %%% This used to optimize known byte-wide and operations to memory,
7701 ;; and sometimes to QImode registers.  If this is considered useful,
7702 ;; it should be done with splitters.
7703
7704 (define_expand "and<mode>3"
7705   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7706         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7707                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7708   ""
7709 {
7710   if (<MODE>mode == DImode
7711       && GET_CODE (operands[2]) == CONST_INT
7712       && INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff
7713       && REG_P (operands[1]))
7714     emit_insn (gen_zero_extendsidi2 (operands[0],
7715                                      gen_lowpart (SImode, operands[1])));
7716   else
7717     ix86_expand_binary_operator (AND, <MODE>mode, operands);
7718   DONE;
7719 })
7720
7721 (define_insn "*anddi_1"
7722   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7723         (and:DI
7724          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7725          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7726    (clobber (reg:CC FLAGS_REG))]
7727   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7728 {
7729   switch (get_attr_type (insn))
7730     {
7731     case TYPE_IMOVX:
7732       {
7733         enum machine_mode mode;
7734
7735         gcc_assert (CONST_INT_P (operands[2]));
7736         if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff)
7737           mode = SImode;
7738         else if (INTVAL (operands[2]) == 0xffff)
7739           mode = HImode;
7740         else
7741           {
7742             gcc_assert (INTVAL (operands[2]) == 0xff);
7743             mode = QImode;
7744           }
7745
7746         operands[1] = gen_lowpart (mode, operands[1]);
7747         if (mode == SImode)
7748           return "mov{l}\t{%1, %k0|%k0, %1}";
7749         else if (mode == HImode)
7750           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7751         else
7752           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7753       }
7754
7755     default:
7756       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7757       if (get_attr_mode (insn) == MODE_SI)
7758         return "and{l}\t{%k2, %k0|%k0, %k2}";
7759       else
7760         return "and{q}\t{%2, %0|%0, %2}";
7761     }
7762 }
7763   [(set_attr "type" "alu,alu,alu,imovx")
7764    (set_attr "length_immediate" "*,*,*,0")
7765    (set (attr "prefix_rex")
7766      (if_then_else
7767        (and (eq_attr "type" "imovx")
7768             (and (match_test "INTVAL (operands[2]) == 0xff")
7769                  (match_operand 1 "ext_QIreg_operand" "")))
7770        (const_string "1")
7771        (const_string "*")))
7772    (set_attr "mode" "SI,DI,DI,SI")])
7773
7774 (define_insn "*andsi_1"
7775   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7776         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7777                 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7778    (clobber (reg:CC FLAGS_REG))]
7779   "ix86_binary_operator_ok (AND, SImode, operands)"
7780 {
7781   switch (get_attr_type (insn))
7782     {
7783     case TYPE_IMOVX:
7784       {
7785         enum machine_mode mode;
7786
7787         gcc_assert (CONST_INT_P (operands[2]));
7788         if (INTVAL (operands[2]) == 0xffff)
7789           mode = HImode;
7790         else
7791           {
7792             gcc_assert (INTVAL (operands[2]) == 0xff);
7793             mode = QImode;
7794           }
7795
7796         operands[1] = gen_lowpart (mode, operands[1]);
7797         if (mode == HImode)
7798           return "movz{wl|x}\t{%1, %0|%0, %1}";
7799         else
7800           return "movz{bl|x}\t{%1, %0|%0, %1}";
7801       }
7802
7803     default:
7804       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7805       return "and{l}\t{%2, %0|%0, %2}";
7806     }
7807 }
7808   [(set_attr "type" "alu,alu,imovx")
7809    (set (attr "prefix_rex")
7810      (if_then_else
7811        (and (eq_attr "type" "imovx")
7812             (and (match_test "INTVAL (operands[2]) == 0xff")
7813                  (match_operand 1 "ext_QIreg_operand" "")))
7814        (const_string "1")
7815        (const_string "*")))
7816    (set_attr "length_immediate" "*,*,0")
7817    (set_attr "mode" "SI")])
7818
7819 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7820 (define_insn "*andsi_1_zext"
7821   [(set (match_operand:DI 0 "register_operand" "=r")
7822         (zero_extend:DI
7823           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7824                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7825    (clobber (reg:CC FLAGS_REG))]
7826   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7827   "and{l}\t{%2, %k0|%k0, %2}"
7828   [(set_attr "type" "alu")
7829    (set_attr "mode" "SI")])
7830
7831 (define_insn "*andhi_1"
7832   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7833         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7834                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7835    (clobber (reg:CC FLAGS_REG))]
7836   "ix86_binary_operator_ok (AND, HImode, operands)"
7837 {
7838   switch (get_attr_type (insn))
7839     {
7840     case TYPE_IMOVX:
7841       gcc_assert (CONST_INT_P (operands[2]));
7842       gcc_assert (INTVAL (operands[2]) == 0xff);
7843       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7844
7845     default:
7846       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7847
7848       return "and{w}\t{%2, %0|%0, %2}";
7849     }
7850 }
7851   [(set_attr "type" "alu,alu,imovx")
7852    (set_attr "length_immediate" "*,*,0")
7853    (set (attr "prefix_rex")
7854      (if_then_else
7855        (and (eq_attr "type" "imovx")
7856             (match_operand 1 "ext_QIreg_operand" ""))
7857        (const_string "1")
7858        (const_string "*")))
7859    (set_attr "mode" "HI,HI,SI")])
7860
7861 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7862 (define_insn "*andqi_1"
7863   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7864         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7865                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7866    (clobber (reg:CC FLAGS_REG))]
7867   "ix86_binary_operator_ok (AND, QImode, operands)"
7868   "@
7869    and{b}\t{%2, %0|%0, %2}
7870    and{b}\t{%2, %0|%0, %2}
7871    and{l}\t{%k2, %k0|%k0, %k2}"
7872   [(set_attr "type" "alu")
7873    (set_attr "mode" "QI,QI,SI")])
7874
7875 (define_insn "*andqi_1_slp"
7876   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7877         (and:QI (match_dup 0)
7878                 (match_operand:QI 1 "general_operand" "qn,qmn")))
7879    (clobber (reg:CC FLAGS_REG))]
7880   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7881    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7882   "and{b}\t{%1, %0|%0, %1}"
7883   [(set_attr "type" "alu1")
7884    (set_attr "mode" "QI")])
7885
7886 (define_split
7887   [(set (match_operand 0 "register_operand" "")
7888         (and (match_dup 0)
7889              (const_int -65536)))
7890    (clobber (reg:CC FLAGS_REG))]
7891   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7892     || optimize_function_for_size_p (cfun)"
7893   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7894   "operands[1] = gen_lowpart (HImode, operands[0]);")
7895
7896 (define_split
7897   [(set (match_operand 0 "ext_register_operand" "")
7898         (and (match_dup 0)
7899              (const_int -256)))
7900    (clobber (reg:CC FLAGS_REG))]
7901   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7902    && reload_completed"
7903   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7904   "operands[1] = gen_lowpart (QImode, operands[0]);")
7905
7906 (define_split
7907   [(set (match_operand 0 "ext_register_operand" "")
7908         (and (match_dup 0)
7909              (const_int -65281)))
7910    (clobber (reg:CC FLAGS_REG))]
7911   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7912    && reload_completed"
7913   [(parallel [(set (zero_extract:SI (match_dup 0)
7914                                     (const_int 8)
7915                                     (const_int 8))
7916                    (xor:SI
7917                      (zero_extract:SI (match_dup 0)
7918                                       (const_int 8)
7919                                       (const_int 8))
7920                      (zero_extract:SI (match_dup 0)
7921                                       (const_int 8)
7922                                       (const_int 8))))
7923               (clobber (reg:CC FLAGS_REG))])]
7924   "operands[0] = gen_lowpart (SImode, operands[0]);")
7925
7926 (define_insn "*anddi_2"
7927   [(set (reg FLAGS_REG)
7928         (compare
7929          (and:DI
7930           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7931           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7932          (const_int 0)))
7933    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7934         (and:DI (match_dup 1) (match_dup 2)))]
7935   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7936    && ix86_binary_operator_ok (AND, DImode, operands)"
7937   "@
7938    and{l}\t{%k2, %k0|%k0, %k2}
7939    and{q}\t{%2, %0|%0, %2}
7940    and{q}\t{%2, %0|%0, %2}"
7941   [(set_attr "type" "alu")
7942    (set_attr "mode" "SI,DI,DI")])
7943
7944 (define_insn "*andqi_2_maybe_si"
7945   [(set (reg FLAGS_REG)
7946         (compare (and:QI
7947                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7948                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7949                  (const_int 0)))
7950    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7951         (and:QI (match_dup 1) (match_dup 2)))]
7952   "ix86_binary_operator_ok (AND, QImode, operands)
7953    && ix86_match_ccmode (insn,
7954                          CONST_INT_P (operands[2])
7955                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7956 {
7957   if (which_alternative == 2)
7958     {
7959       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7960         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7961       return "and{l}\t{%2, %k0|%k0, %2}";
7962     }
7963   return "and{b}\t{%2, %0|%0, %2}";
7964 }
7965   [(set_attr "type" "alu")
7966    (set_attr "mode" "QI,QI,SI")])
7967
7968 (define_insn "*and<mode>_2"
7969   [(set (reg FLAGS_REG)
7970         (compare (and:SWI124
7971                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7972                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7973                  (const_int 0)))
7974    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7975         (and:SWI124 (match_dup 1) (match_dup 2)))]
7976   "ix86_match_ccmode (insn, CCNOmode)
7977    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7978   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7979   [(set_attr "type" "alu")
7980    (set_attr "mode" "<MODE>")])
7981
7982 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7983 (define_insn "*andsi_2_zext"
7984   [(set (reg FLAGS_REG)
7985         (compare (and:SI
7986                   (match_operand:SI 1 "nonimmediate_operand" "%0")
7987                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
7988                  (const_int 0)))
7989    (set (match_operand:DI 0 "register_operand" "=r")
7990         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7991   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7992    && ix86_binary_operator_ok (AND, SImode, operands)"
7993   "and{l}\t{%2, %k0|%k0, %2}"
7994   [(set_attr "type" "alu")
7995    (set_attr "mode" "SI")])
7996
7997 (define_insn "*andqi_2_slp"
7998   [(set (reg FLAGS_REG)
7999         (compare (and:QI
8000                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8001                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8002                  (const_int 0)))
8003    (set (strict_low_part (match_dup 0))
8004         (and:QI (match_dup 0) (match_dup 1)))]
8005   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8006    && ix86_match_ccmode (insn, CCNOmode)
8007    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8008   "and{b}\t{%1, %0|%0, %1}"
8009   [(set_attr "type" "alu1")
8010    (set_attr "mode" "QI")])
8011
8012 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8013 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8014 ;; for a QImode operand, which of course failed.
8015 (define_insn "andqi_ext_0"
8016   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8017                          (const_int 8)
8018                          (const_int 8))
8019         (and:SI
8020           (zero_extract:SI
8021             (match_operand 1 "ext_register_operand" "0")
8022             (const_int 8)
8023             (const_int 8))
8024           (match_operand 2 "const_int_operand" "n")))
8025    (clobber (reg:CC FLAGS_REG))]
8026   ""
8027   "and{b}\t{%2, %h0|%h0, %2}"
8028   [(set_attr "type" "alu")
8029    (set_attr "length_immediate" "1")
8030    (set_attr "modrm" "1")
8031    (set_attr "mode" "QI")])
8032
8033 ;; Generated by peephole translating test to and.  This shows up
8034 ;; often in fp comparisons.
8035 (define_insn "*andqi_ext_0_cc"
8036   [(set (reg FLAGS_REG)
8037         (compare
8038           (and:SI
8039             (zero_extract:SI
8040               (match_operand 1 "ext_register_operand" "0")
8041               (const_int 8)
8042               (const_int 8))
8043             (match_operand 2 "const_int_operand" "n"))
8044           (const_int 0)))
8045    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8046                          (const_int 8)
8047                          (const_int 8))
8048         (and:SI
8049           (zero_extract:SI
8050             (match_dup 1)
8051             (const_int 8)
8052             (const_int 8))
8053           (match_dup 2)))]
8054   "ix86_match_ccmode (insn, CCNOmode)"
8055   "and{b}\t{%2, %h0|%h0, %2}"
8056   [(set_attr "type" "alu")
8057    (set_attr "length_immediate" "1")
8058    (set_attr "modrm" "1")
8059    (set_attr "mode" "QI")])
8060
8061 (define_insn "*andqi_ext_1_rex64"
8062   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8063                          (const_int 8)
8064                          (const_int 8))
8065         (and:SI
8066           (zero_extract:SI
8067             (match_operand 1 "ext_register_operand" "0")
8068             (const_int 8)
8069             (const_int 8))
8070           (zero_extend:SI
8071             (match_operand 2 "ext_register_operand" "Q"))))
8072    (clobber (reg:CC FLAGS_REG))]
8073   "TARGET_64BIT"
8074   "and{b}\t{%2, %h0|%h0, %2}"
8075   [(set_attr "type" "alu")
8076    (set_attr "length_immediate" "0")
8077    (set_attr "mode" "QI")])
8078
8079 (define_insn "*andqi_ext_1"
8080   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8081                          (const_int 8)
8082                          (const_int 8))
8083         (and:SI
8084           (zero_extract:SI
8085             (match_operand 1 "ext_register_operand" "0")
8086             (const_int 8)
8087             (const_int 8))
8088           (zero_extend:SI
8089             (match_operand:QI 2 "general_operand" "Qm"))))
8090    (clobber (reg:CC FLAGS_REG))]
8091   "!TARGET_64BIT"
8092   "and{b}\t{%2, %h0|%h0, %2}"
8093   [(set_attr "type" "alu")
8094    (set_attr "length_immediate" "0")
8095    (set_attr "mode" "QI")])
8096
8097 (define_insn "*andqi_ext_2"
8098   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8099                          (const_int 8)
8100                          (const_int 8))
8101         (and:SI
8102           (zero_extract:SI
8103             (match_operand 1 "ext_register_operand" "%0")
8104             (const_int 8)
8105             (const_int 8))
8106           (zero_extract:SI
8107             (match_operand 2 "ext_register_operand" "Q")
8108             (const_int 8)
8109             (const_int 8))))
8110    (clobber (reg:CC FLAGS_REG))]
8111   ""
8112   "and{b}\t{%h2, %h0|%h0, %h2}"
8113   [(set_attr "type" "alu")
8114    (set_attr "length_immediate" "0")
8115    (set_attr "mode" "QI")])
8116
8117 ;; Convert wide AND instructions with immediate operand to shorter QImode
8118 ;; equivalents when possible.
8119 ;; Don't do the splitting with memory operands, since it introduces risk
8120 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8121 ;; for size, but that can (should?) be handled by generic code instead.
8122 (define_split
8123   [(set (match_operand 0 "register_operand" "")
8124         (and (match_operand 1 "register_operand" "")
8125              (match_operand 2 "const_int_operand" "")))
8126    (clobber (reg:CC FLAGS_REG))]
8127    "reload_completed
8128     && QI_REG_P (operands[0])
8129     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8130     && !(~INTVAL (operands[2]) & ~(255 << 8))
8131     && GET_MODE (operands[0]) != QImode"
8132   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8133                    (and:SI (zero_extract:SI (match_dup 1)
8134                                             (const_int 8) (const_int 8))
8135                            (match_dup 2)))
8136               (clobber (reg:CC FLAGS_REG))])]
8137 {
8138   operands[0] = gen_lowpart (SImode, operands[0]);
8139   operands[1] = gen_lowpart (SImode, operands[1]);
8140   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8141 })
8142
8143 ;; Since AND can be encoded with sign extended immediate, this is only
8144 ;; profitable when 7th bit is not set.
8145 (define_split
8146   [(set (match_operand 0 "register_operand" "")
8147         (and (match_operand 1 "general_operand" "")
8148              (match_operand 2 "const_int_operand" "")))
8149    (clobber (reg:CC FLAGS_REG))]
8150    "reload_completed
8151     && ANY_QI_REG_P (operands[0])
8152     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8153     && !(~INTVAL (operands[2]) & ~255)
8154     && !(INTVAL (operands[2]) & 128)
8155     && GET_MODE (operands[0]) != QImode"
8156   [(parallel [(set (strict_low_part (match_dup 0))
8157                    (and:QI (match_dup 1)
8158                            (match_dup 2)))
8159               (clobber (reg:CC FLAGS_REG))])]
8160 {
8161   operands[0] = gen_lowpart (QImode, operands[0]);
8162   operands[1] = gen_lowpart (QImode, operands[1]);
8163   operands[2] = gen_lowpart (QImode, operands[2]);
8164 })
8165 \f
8166 ;; Logical inclusive and exclusive OR instructions
8167
8168 ;; %%% This used to optimize known byte-wide and operations to memory.
8169 ;; If this is considered useful, it should be done with splitters.
8170
8171 (define_expand "<code><mode>3"
8172   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8173         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8174                      (match_operand:SWIM 2 "<general_operand>" "")))]
8175   ""
8176   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8177
8178 (define_insn "*<code><mode>_1"
8179   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8180         (any_or:SWI248
8181          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8182          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8183    (clobber (reg:CC FLAGS_REG))]
8184   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8185   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8186   [(set_attr "type" "alu")
8187    (set_attr "mode" "<MODE>")])
8188
8189 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8190 (define_insn "*<code>qi_1"
8191   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8192         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8193                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8194    (clobber (reg:CC FLAGS_REG))]
8195   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8196   "@
8197    <logic>{b}\t{%2, %0|%0, %2}
8198    <logic>{b}\t{%2, %0|%0, %2}
8199    <logic>{l}\t{%k2, %k0|%k0, %k2}"
8200   [(set_attr "type" "alu")
8201    (set_attr "mode" "QI,QI,SI")])
8202
8203 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8204 (define_insn "*<code>si_1_zext"
8205   [(set (match_operand:DI 0 "register_operand" "=r")
8206         (zero_extend:DI
8207          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8208                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8209    (clobber (reg:CC FLAGS_REG))]
8210   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8211   "<logic>{l}\t{%2, %k0|%k0, %2}"
8212   [(set_attr "type" "alu")
8213    (set_attr "mode" "SI")])
8214
8215 (define_insn "*<code>si_1_zext_imm"
8216   [(set (match_operand:DI 0 "register_operand" "=r")
8217         (any_or:DI
8218          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8219          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8220    (clobber (reg:CC FLAGS_REG))]
8221   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8222   "<logic>{l}\t{%2, %k0|%k0, %2}"
8223   [(set_attr "type" "alu")
8224    (set_attr "mode" "SI")])
8225
8226 (define_insn "*<code>qi_1_slp"
8227   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8228         (any_or:QI (match_dup 0)
8229                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8230    (clobber (reg:CC FLAGS_REG))]
8231   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8232    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8233   "<logic>{b}\t{%1, %0|%0, %1}"
8234   [(set_attr "type" "alu1")
8235    (set_attr "mode" "QI")])
8236
8237 (define_insn "*<code><mode>_2"
8238   [(set (reg FLAGS_REG)
8239         (compare (any_or:SWI
8240                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8241                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8242                  (const_int 0)))
8243    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8244         (any_or:SWI (match_dup 1) (match_dup 2)))]
8245   "ix86_match_ccmode (insn, CCNOmode)
8246    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8247   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8248   [(set_attr "type" "alu")
8249    (set_attr "mode" "<MODE>")])
8250
8251 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8252 ;; ??? Special case for immediate operand is missing - it is tricky.
8253 (define_insn "*<code>si_2_zext"
8254   [(set (reg FLAGS_REG)
8255         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8256                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
8257                  (const_int 0)))
8258    (set (match_operand:DI 0 "register_operand" "=r")
8259         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8260   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8261    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8262   "<logic>{l}\t{%2, %k0|%k0, %2}"
8263   [(set_attr "type" "alu")
8264    (set_attr "mode" "SI")])
8265
8266 (define_insn "*<code>si_2_zext_imm"
8267   [(set (reg FLAGS_REG)
8268         (compare (any_or:SI
8269                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8270                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8271                  (const_int 0)))
8272    (set (match_operand:DI 0 "register_operand" "=r")
8273         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8274   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8275    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8276   "<logic>{l}\t{%2, %k0|%k0, %2}"
8277   [(set_attr "type" "alu")
8278    (set_attr "mode" "SI")])
8279
8280 (define_insn "*<code>qi_2_slp"
8281   [(set (reg FLAGS_REG)
8282         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8283                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8284                  (const_int 0)))
8285    (set (strict_low_part (match_dup 0))
8286         (any_or:QI (match_dup 0) (match_dup 1)))]
8287   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8288    && ix86_match_ccmode (insn, CCNOmode)
8289    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8290   "<logic>{b}\t{%1, %0|%0, %1}"
8291   [(set_attr "type" "alu1")
8292    (set_attr "mode" "QI")])
8293
8294 (define_insn "*<code><mode>_3"
8295   [(set (reg FLAGS_REG)
8296         (compare (any_or:SWI
8297                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8298                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8299                  (const_int 0)))
8300    (clobber (match_scratch:SWI 0 "=<r>"))]
8301   "ix86_match_ccmode (insn, CCNOmode)
8302    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8303   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8304   [(set_attr "type" "alu")
8305    (set_attr "mode" "<MODE>")])
8306
8307 (define_insn "*<code>qi_ext_0"
8308   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8309                          (const_int 8)
8310                          (const_int 8))
8311         (any_or:SI
8312           (zero_extract:SI
8313             (match_operand 1 "ext_register_operand" "0")
8314             (const_int 8)
8315             (const_int 8))
8316           (match_operand 2 "const_int_operand" "n")))
8317    (clobber (reg:CC FLAGS_REG))]
8318   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8319   "<logic>{b}\t{%2, %h0|%h0, %2}"
8320   [(set_attr "type" "alu")
8321    (set_attr "length_immediate" "1")
8322    (set_attr "modrm" "1")
8323    (set_attr "mode" "QI")])
8324
8325 (define_insn "*<code>qi_ext_1_rex64"
8326   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8327                          (const_int 8)
8328                          (const_int 8))
8329         (any_or:SI
8330           (zero_extract:SI
8331             (match_operand 1 "ext_register_operand" "0")
8332             (const_int 8)
8333             (const_int 8))
8334           (zero_extend:SI
8335             (match_operand 2 "ext_register_operand" "Q"))))
8336    (clobber (reg:CC FLAGS_REG))]
8337   "TARGET_64BIT
8338    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8339   "<logic>{b}\t{%2, %h0|%h0, %2}"
8340   [(set_attr "type" "alu")
8341    (set_attr "length_immediate" "0")
8342    (set_attr "mode" "QI")])
8343
8344 (define_insn "*<code>qi_ext_1"
8345   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8346                          (const_int 8)
8347                          (const_int 8))
8348         (any_or:SI
8349           (zero_extract:SI
8350             (match_operand 1 "ext_register_operand" "0")
8351             (const_int 8)
8352             (const_int 8))
8353           (zero_extend:SI
8354             (match_operand:QI 2 "general_operand" "Qm"))))
8355    (clobber (reg:CC FLAGS_REG))]
8356   "!TARGET_64BIT
8357    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8358   "<logic>{b}\t{%2, %h0|%h0, %2}"
8359   [(set_attr "type" "alu")
8360    (set_attr "length_immediate" "0")
8361    (set_attr "mode" "QI")])
8362
8363 (define_insn "*<code>qi_ext_2"
8364   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8365                          (const_int 8)
8366                          (const_int 8))
8367         (any_or:SI
8368           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8369                            (const_int 8)
8370                            (const_int 8))
8371           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8372                            (const_int 8)
8373                            (const_int 8))))
8374    (clobber (reg:CC FLAGS_REG))]
8375   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8376   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8377   [(set_attr "type" "alu")
8378    (set_attr "length_immediate" "0")
8379    (set_attr "mode" "QI")])
8380
8381 (define_split
8382   [(set (match_operand 0 "register_operand" "")
8383         (any_or (match_operand 1 "register_operand" "")
8384                 (match_operand 2 "const_int_operand" "")))
8385    (clobber (reg:CC FLAGS_REG))]
8386    "reload_completed
8387     && QI_REG_P (operands[0])
8388     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8389     && !(INTVAL (operands[2]) & ~(255 << 8))
8390     && GET_MODE (operands[0]) != QImode"
8391   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8392                    (any_or:SI (zero_extract:SI (match_dup 1)
8393                                                (const_int 8) (const_int 8))
8394                               (match_dup 2)))
8395               (clobber (reg:CC FLAGS_REG))])]
8396 {
8397   operands[0] = gen_lowpart (SImode, operands[0]);
8398   operands[1] = gen_lowpart (SImode, operands[1]);
8399   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8400 })
8401
8402 ;; Since OR can be encoded with sign extended immediate, this is only
8403 ;; profitable when 7th bit is set.
8404 (define_split
8405   [(set (match_operand 0 "register_operand" "")
8406         (any_or (match_operand 1 "general_operand" "")
8407                 (match_operand 2 "const_int_operand" "")))
8408    (clobber (reg:CC FLAGS_REG))]
8409    "reload_completed
8410     && ANY_QI_REG_P (operands[0])
8411     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8412     && !(INTVAL (operands[2]) & ~255)
8413     && (INTVAL (operands[2]) & 128)
8414     && GET_MODE (operands[0]) != QImode"
8415   [(parallel [(set (strict_low_part (match_dup 0))
8416                    (any_or:QI (match_dup 1)
8417                               (match_dup 2)))
8418               (clobber (reg:CC FLAGS_REG))])]
8419 {
8420   operands[0] = gen_lowpart (QImode, operands[0]);
8421   operands[1] = gen_lowpart (QImode, operands[1]);
8422   operands[2] = gen_lowpart (QImode, operands[2]);
8423 })
8424
8425 (define_expand "xorqi_cc_ext_1"
8426   [(parallel [
8427      (set (reg:CCNO FLAGS_REG)
8428           (compare:CCNO
8429             (xor:SI
8430               (zero_extract:SI
8431                 (match_operand 1 "ext_register_operand" "")
8432                 (const_int 8)
8433                 (const_int 8))
8434               (match_operand:QI 2 "general_operand" ""))
8435             (const_int 0)))
8436      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8437                            (const_int 8)
8438                            (const_int 8))
8439           (xor:SI
8440             (zero_extract:SI
8441              (match_dup 1)
8442              (const_int 8)
8443              (const_int 8))
8444             (match_dup 2)))])])
8445
8446 (define_insn "*xorqi_cc_ext_1_rex64"
8447   [(set (reg FLAGS_REG)
8448         (compare
8449           (xor:SI
8450             (zero_extract:SI
8451               (match_operand 1 "ext_register_operand" "0")
8452               (const_int 8)
8453               (const_int 8))
8454             (match_operand:QI 2 "nonmemory_operand" "Qn"))
8455           (const_int 0)))
8456    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8457                          (const_int 8)
8458                          (const_int 8))
8459         (xor:SI
8460           (zero_extract:SI
8461            (match_dup 1)
8462            (const_int 8)
8463            (const_int 8))
8464           (match_dup 2)))]
8465   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8466   "xor{b}\t{%2, %h0|%h0, %2}"
8467   [(set_attr "type" "alu")
8468    (set_attr "modrm" "1")
8469    (set_attr "mode" "QI")])
8470
8471 (define_insn "*xorqi_cc_ext_1"
8472   [(set (reg FLAGS_REG)
8473         (compare
8474           (xor:SI
8475             (zero_extract:SI
8476               (match_operand 1 "ext_register_operand" "0")
8477               (const_int 8)
8478               (const_int 8))
8479             (match_operand:QI 2 "general_operand" "qmn"))
8480           (const_int 0)))
8481    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8482                          (const_int 8)
8483                          (const_int 8))
8484         (xor:SI
8485           (zero_extract:SI
8486            (match_dup 1)
8487            (const_int 8)
8488            (const_int 8))
8489           (match_dup 2)))]
8490   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8491   "xor{b}\t{%2, %h0|%h0, %2}"
8492   [(set_attr "type" "alu")
8493    (set_attr "modrm" "1")
8494    (set_attr "mode" "QI")])
8495 \f
8496 ;; Negation instructions
8497
8498 (define_expand "neg<mode>2"
8499   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8500         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8501   ""
8502   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8503
8504 (define_insn_and_split "*neg<dwi>2_doubleword"
8505   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8506         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8507    (clobber (reg:CC FLAGS_REG))]
8508   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8509   "#"
8510   "reload_completed"
8511   [(parallel
8512     [(set (reg:CCZ FLAGS_REG)
8513           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8514      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8515    (parallel
8516     [(set (match_dup 2)
8517           (plus:DWIH (match_dup 3)
8518                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8519                                 (const_int 0))))
8520      (clobber (reg:CC FLAGS_REG))])
8521    (parallel
8522     [(set (match_dup 2)
8523           (neg:DWIH (match_dup 2)))
8524      (clobber (reg:CC FLAGS_REG))])]
8525   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8526
8527 (define_insn "*neg<mode>2_1"
8528   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8529         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8530    (clobber (reg:CC FLAGS_REG))]
8531   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8532   "neg{<imodesuffix>}\t%0"
8533   [(set_attr "type" "negnot")
8534    (set_attr "mode" "<MODE>")])
8535
8536 ;; Combine is quite creative about this pattern.
8537 (define_insn "*negsi2_1_zext"
8538   [(set (match_operand:DI 0 "register_operand" "=r")
8539         (lshiftrt:DI
8540           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8541                              (const_int 32)))
8542         (const_int 32)))
8543    (clobber (reg:CC FLAGS_REG))]
8544   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8545   "neg{l}\t%k0"
8546   [(set_attr "type" "negnot")
8547    (set_attr "mode" "SI")])
8548
8549 ;; The problem with neg is that it does not perform (compare x 0),
8550 ;; it really performs (compare 0 x), which leaves us with the zero
8551 ;; flag being the only useful item.
8552
8553 (define_insn "*neg<mode>2_cmpz"
8554   [(set (reg:CCZ FLAGS_REG)
8555         (compare:CCZ
8556           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8557                    (const_int 0)))
8558    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8559         (neg:SWI (match_dup 1)))]
8560   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8561   "neg{<imodesuffix>}\t%0"
8562   [(set_attr "type" "negnot")
8563    (set_attr "mode" "<MODE>")])
8564
8565 (define_insn "*negsi2_cmpz_zext"
8566   [(set (reg:CCZ FLAGS_REG)
8567         (compare:CCZ
8568           (lshiftrt:DI
8569             (neg:DI (ashift:DI
8570                       (match_operand:DI 1 "register_operand" "0")
8571                       (const_int 32)))
8572             (const_int 32))
8573           (const_int 0)))
8574    (set (match_operand:DI 0 "register_operand" "=r")
8575         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8576                                         (const_int 32)))
8577                      (const_int 32)))]
8578   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8579   "neg{l}\t%k0"
8580   [(set_attr "type" "negnot")
8581    (set_attr "mode" "SI")])
8582
8583 ;; Changing of sign for FP values is doable using integer unit too.
8584
8585 (define_expand "<code><mode>2"
8586   [(set (match_operand:X87MODEF 0 "register_operand" "")
8587         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8588   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8589   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8590
8591 (define_insn "*absneg<mode>2_mixed"
8592   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8593         (match_operator:MODEF 3 "absneg_operator"
8594           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8595    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8596    (clobber (reg:CC FLAGS_REG))]
8597   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8598   "#")
8599
8600 (define_insn "*absneg<mode>2_sse"
8601   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8602         (match_operator:MODEF 3 "absneg_operator"
8603           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8604    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8605    (clobber (reg:CC FLAGS_REG))]
8606   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8607   "#")
8608
8609 (define_insn "*absneg<mode>2_i387"
8610   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8611         (match_operator:X87MODEF 3 "absneg_operator"
8612           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8613    (use (match_operand 2 "" ""))
8614    (clobber (reg:CC FLAGS_REG))]
8615   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8616   "#")
8617
8618 (define_expand "<code>tf2"
8619   [(set (match_operand:TF 0 "register_operand" "")
8620         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8621   "TARGET_SSE2"
8622   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8623
8624 (define_insn "*absnegtf2_sse"
8625   [(set (match_operand:TF 0 "register_operand" "=x,x")
8626         (match_operator:TF 3 "absneg_operator"
8627           [(match_operand:TF 1 "register_operand" "0,x")]))
8628    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8629    (clobber (reg:CC FLAGS_REG))]
8630   "TARGET_SSE2"
8631   "#")
8632
8633 ;; Splitters for fp abs and neg.
8634
8635 (define_split
8636   [(set (match_operand 0 "fp_register_operand" "")
8637         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8638    (use (match_operand 2 "" ""))
8639    (clobber (reg:CC FLAGS_REG))]
8640   "reload_completed"
8641   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8642
8643 (define_split
8644   [(set (match_operand 0 "register_operand" "")
8645         (match_operator 3 "absneg_operator"
8646           [(match_operand 1 "register_operand" "")]))
8647    (use (match_operand 2 "nonimmediate_operand" ""))
8648    (clobber (reg:CC FLAGS_REG))]
8649   "reload_completed && SSE_REG_P (operands[0])"
8650   [(set (match_dup 0) (match_dup 3))]
8651 {
8652   enum machine_mode mode = GET_MODE (operands[0]);
8653   enum machine_mode vmode = GET_MODE (operands[2]);
8654   rtx tmp;
8655
8656   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8657   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8658   if (operands_match_p (operands[0], operands[2]))
8659     {
8660       tmp = operands[1];
8661       operands[1] = operands[2];
8662       operands[2] = tmp;
8663     }
8664   if (GET_CODE (operands[3]) == ABS)
8665     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8666   else
8667     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8668   operands[3] = tmp;
8669 })
8670
8671 (define_split
8672   [(set (match_operand:SF 0 "register_operand" "")
8673         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8674    (use (match_operand:V4SF 2 "" ""))
8675    (clobber (reg:CC FLAGS_REG))]
8676   "reload_completed"
8677   [(parallel [(set (match_dup 0) (match_dup 1))
8678               (clobber (reg:CC FLAGS_REG))])]
8679 {
8680   rtx tmp;
8681   operands[0] = gen_lowpart (SImode, operands[0]);
8682   if (GET_CODE (operands[1]) == ABS)
8683     {
8684       tmp = gen_int_mode (0x7fffffff, SImode);
8685       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8686     }
8687   else
8688     {
8689       tmp = gen_int_mode (0x80000000, SImode);
8690       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8691     }
8692   operands[1] = tmp;
8693 })
8694
8695 (define_split
8696   [(set (match_operand:DF 0 "register_operand" "")
8697         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8698    (use (match_operand 2 "" ""))
8699    (clobber (reg:CC FLAGS_REG))]
8700   "reload_completed"
8701   [(parallel [(set (match_dup 0) (match_dup 1))
8702               (clobber (reg:CC FLAGS_REG))])]
8703 {
8704   rtx tmp;
8705   if (TARGET_64BIT)
8706     {
8707       tmp = gen_lowpart (DImode, operands[0]);
8708       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8709       operands[0] = tmp;
8710
8711       if (GET_CODE (operands[1]) == ABS)
8712         tmp = const0_rtx;
8713       else
8714         tmp = gen_rtx_NOT (DImode, tmp);
8715     }
8716   else
8717     {
8718       operands[0] = gen_highpart (SImode, operands[0]);
8719       if (GET_CODE (operands[1]) == ABS)
8720         {
8721           tmp = gen_int_mode (0x7fffffff, SImode);
8722           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8723         }
8724       else
8725         {
8726           tmp = gen_int_mode (0x80000000, SImode);
8727           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8728         }
8729     }
8730   operands[1] = tmp;
8731 })
8732
8733 (define_split
8734   [(set (match_operand:XF 0 "register_operand" "")
8735         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8736    (use (match_operand 2 "" ""))
8737    (clobber (reg:CC FLAGS_REG))]
8738   "reload_completed"
8739   [(parallel [(set (match_dup 0) (match_dup 1))
8740               (clobber (reg:CC FLAGS_REG))])]
8741 {
8742   rtx tmp;
8743   operands[0] = gen_rtx_REG (SImode,
8744                              true_regnum (operands[0])
8745                              + (TARGET_64BIT ? 1 : 2));
8746   if (GET_CODE (operands[1]) == ABS)
8747     {
8748       tmp = GEN_INT (0x7fff);
8749       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8750     }
8751   else
8752     {
8753       tmp = GEN_INT (0x8000);
8754       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8755     }
8756   operands[1] = tmp;
8757 })
8758
8759 ;; Conditionalize these after reload. If they match before reload, we
8760 ;; lose the clobber and ability to use integer instructions.
8761
8762 (define_insn "*<code><mode>2_1"
8763   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8764         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8765   "TARGET_80387
8766    && (reload_completed
8767        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8768   "f<absneg_mnemonic>"
8769   [(set_attr "type" "fsgn")
8770    (set_attr "mode" "<MODE>")])
8771
8772 (define_insn "*<code>extendsfdf2"
8773   [(set (match_operand:DF 0 "register_operand" "=f")
8774         (absneg:DF (float_extend:DF
8775                      (match_operand:SF 1 "register_operand" "0"))))]
8776   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8777   "f<absneg_mnemonic>"
8778   [(set_attr "type" "fsgn")
8779    (set_attr "mode" "DF")])
8780
8781 (define_insn "*<code>extendsfxf2"
8782   [(set (match_operand:XF 0 "register_operand" "=f")
8783         (absneg:XF (float_extend:XF
8784                      (match_operand:SF 1 "register_operand" "0"))))]
8785   "TARGET_80387"
8786   "f<absneg_mnemonic>"
8787   [(set_attr "type" "fsgn")
8788    (set_attr "mode" "XF")])
8789
8790 (define_insn "*<code>extenddfxf2"
8791   [(set (match_operand:XF 0 "register_operand" "=f")
8792         (absneg:XF (float_extend:XF
8793                      (match_operand:DF 1 "register_operand" "0"))))]
8794   "TARGET_80387"
8795   "f<absneg_mnemonic>"
8796   [(set_attr "type" "fsgn")
8797    (set_attr "mode" "XF")])
8798
8799 ;; Copysign instructions
8800
8801 (define_mode_iterator CSGNMODE [SF DF TF])
8802 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8803
8804 (define_expand "copysign<mode>3"
8805   [(match_operand:CSGNMODE 0 "register_operand" "")
8806    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8807    (match_operand:CSGNMODE 2 "register_operand" "")]
8808   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8809    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8810   "ix86_expand_copysign (operands); DONE;")
8811
8812 (define_insn_and_split "copysign<mode>3_const"
8813   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8814         (unspec:CSGNMODE
8815           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8816            (match_operand:CSGNMODE 2 "register_operand" "0")
8817            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8818           UNSPEC_COPYSIGN))]
8819   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8820    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8821   "#"
8822   "&& reload_completed"
8823   [(const_int 0)]
8824   "ix86_split_copysign_const (operands); DONE;")
8825
8826 (define_insn "copysign<mode>3_var"
8827   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8828         (unspec:CSGNMODE
8829           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8830            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8831            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8832            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8833           UNSPEC_COPYSIGN))
8834    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8835   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8836    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8837   "#")
8838
8839 (define_split
8840   [(set (match_operand:CSGNMODE 0 "register_operand" "")
8841         (unspec:CSGNMODE
8842           [(match_operand:CSGNMODE 2 "register_operand" "")
8843            (match_operand:CSGNMODE 3 "register_operand" "")
8844            (match_operand:<CSGNVMODE> 4 "" "")
8845            (match_operand:<CSGNVMODE> 5 "" "")]
8846           UNSPEC_COPYSIGN))
8847    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8848   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8849     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8850    && reload_completed"
8851   [(const_int 0)]
8852   "ix86_split_copysign_var (operands); DONE;")
8853 \f
8854 ;; One complement instructions
8855
8856 (define_expand "one_cmpl<mode>2"
8857   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8858         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8859   ""
8860   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8861
8862 (define_insn "*one_cmpl<mode>2_1"
8863   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8864         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8865   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8866   "not{<imodesuffix>}\t%0"
8867   [(set_attr "type" "negnot")
8868    (set_attr "mode" "<MODE>")])
8869
8870 ;; %%% Potential partial reg stall on alternative 1.  What to do?
8871 (define_insn "*one_cmplqi2_1"
8872   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8873         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8874   "ix86_unary_operator_ok (NOT, QImode, operands)"
8875   "@
8876    not{b}\t%0
8877    not{l}\t%k0"
8878   [(set_attr "type" "negnot")
8879    (set_attr "mode" "QI,SI")])
8880
8881 ;; ??? Currently never generated - xor is used instead.
8882 (define_insn "*one_cmplsi2_1_zext"
8883   [(set (match_operand:DI 0 "register_operand" "=r")
8884         (zero_extend:DI
8885           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8886   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8887   "not{l}\t%k0"
8888   [(set_attr "type" "negnot")
8889    (set_attr "mode" "SI")])
8890
8891 (define_insn "*one_cmpl<mode>2_2"
8892   [(set (reg FLAGS_REG)
8893         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8894                  (const_int 0)))
8895    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8896         (not:SWI (match_dup 1)))]
8897   "ix86_match_ccmode (insn, CCNOmode)
8898    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8899   "#"
8900   [(set_attr "type" "alu1")
8901    (set_attr "mode" "<MODE>")])
8902
8903 (define_split
8904   [(set (match_operand 0 "flags_reg_operand" "")
8905         (match_operator 2 "compare_operator"
8906           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8907            (const_int 0)]))
8908    (set (match_operand:SWI 1 "nonimmediate_operand" "")
8909         (not:SWI (match_dup 3)))]
8910   "ix86_match_ccmode (insn, CCNOmode)"
8911   [(parallel [(set (match_dup 0)
8912                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8913                                     (const_int 0)]))
8914               (set (match_dup 1)
8915                    (xor:SWI (match_dup 3) (const_int -1)))])])
8916
8917 ;; ??? Currently never generated - xor is used instead.
8918 (define_insn "*one_cmplsi2_2_zext"
8919   [(set (reg FLAGS_REG)
8920         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8921                  (const_int 0)))
8922    (set (match_operand:DI 0 "register_operand" "=r")
8923         (zero_extend:DI (not:SI (match_dup 1))))]
8924   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8925    && ix86_unary_operator_ok (NOT, SImode, operands)"
8926   "#"
8927   [(set_attr "type" "alu1")
8928    (set_attr "mode" "SI")])
8929
8930 (define_split
8931   [(set (match_operand 0 "flags_reg_operand" "")
8932         (match_operator 2 "compare_operator"
8933           [(not:SI (match_operand:SI 3 "register_operand" ""))
8934            (const_int 0)]))
8935    (set (match_operand:DI 1 "register_operand" "")
8936         (zero_extend:DI (not:SI (match_dup 3))))]
8937   "ix86_match_ccmode (insn, CCNOmode)"
8938   [(parallel [(set (match_dup 0)
8939                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8940                                     (const_int 0)]))
8941               (set (match_dup 1)
8942                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8943 \f
8944 ;; Shift instructions
8945
8946 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8947 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
8948 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8949 ;; from the assembler input.
8950 ;;
8951 ;; This instruction shifts the target reg/mem as usual, but instead of
8952 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
8953 ;; is a left shift double, bits are taken from the high order bits of
8954 ;; reg, else if the insn is a shift right double, bits are taken from the
8955 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
8956 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8957 ;;
8958 ;; Since sh[lr]d does not change the `reg' operand, that is done
8959 ;; separately, making all shifts emit pairs of shift double and normal
8960 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
8961 ;; support a 63 bit shift, each shift where the count is in a reg expands
8962 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8963 ;;
8964 ;; If the shift count is a constant, we need never emit more than one
8965 ;; shift pair, instead using moves and sign extension for counts greater
8966 ;; than 31.
8967
8968 (define_expand "ashl<mode>3"
8969   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8970         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8971                       (match_operand:QI 2 "nonmemory_operand" "")))]
8972   ""
8973   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8974
8975 (define_insn "*ashl<mode>3_doubleword"
8976   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8977         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8978                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8979    (clobber (reg:CC FLAGS_REG))]
8980   ""
8981   "#"
8982   [(set_attr "type" "multi")])
8983
8984 (define_split
8985   [(set (match_operand:DWI 0 "register_operand" "")
8986         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8987                     (match_operand:QI 2 "nonmemory_operand" "")))
8988    (clobber (reg:CC FLAGS_REG))]
8989   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8990   [(const_int 0)]
8991   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8992
8993 ;; By default we don't ask for a scratch register, because when DWImode
8994 ;; values are manipulated, registers are already at a premium.  But if
8995 ;; we have one handy, we won't turn it away.
8996
8997 (define_peephole2
8998   [(match_scratch:DWIH 3 "r")
8999    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9000                    (ashift:<DWI>
9001                      (match_operand:<DWI> 1 "nonmemory_operand" "")
9002                      (match_operand:QI 2 "nonmemory_operand" "")))
9003               (clobber (reg:CC FLAGS_REG))])
9004    (match_dup 3)]
9005   "TARGET_CMOVE"
9006   [(const_int 0)]
9007   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9008
9009 (define_insn "x86_64_shld"
9010   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9011         (ior:DI (ashift:DI (match_dup 0)
9012                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9013                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9014                   (minus:QI (const_int 64) (match_dup 2)))))
9015    (clobber (reg:CC FLAGS_REG))]
9016   "TARGET_64BIT"
9017   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9018   [(set_attr "type" "ishift")
9019    (set_attr "prefix_0f" "1")
9020    (set_attr "mode" "DI")
9021    (set_attr "athlon_decode" "vector")
9022    (set_attr "amdfam10_decode" "vector")
9023    (set_attr "bdver1_decode" "vector")])
9024
9025 (define_insn "x86_shld"
9026   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9027         (ior:SI (ashift:SI (match_dup 0)
9028                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9029                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9030                   (minus:QI (const_int 32) (match_dup 2)))))
9031    (clobber (reg:CC FLAGS_REG))]
9032   ""
9033   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9034   [(set_attr "type" "ishift")
9035    (set_attr "prefix_0f" "1")
9036    (set_attr "mode" "SI")
9037    (set_attr "pent_pair" "np")
9038    (set_attr "athlon_decode" "vector")
9039    (set_attr "amdfam10_decode" "vector")
9040    (set_attr "bdver1_decode" "vector")])
9041
9042 (define_expand "x86_shift<mode>_adj_1"
9043   [(set (reg:CCZ FLAGS_REG)
9044         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9045                              (match_dup 4))
9046                      (const_int 0)))
9047    (set (match_operand:SWI48 0 "register_operand" "")
9048         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9049                             (match_operand:SWI48 1 "register_operand" "")
9050                             (match_dup 0)))
9051    (set (match_dup 1)
9052         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9053                             (match_operand:SWI48 3 "register_operand" "")
9054                             (match_dup 1)))]
9055   "TARGET_CMOVE"
9056   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9057
9058 (define_expand "x86_shift<mode>_adj_2"
9059   [(use (match_operand:SWI48 0 "register_operand" ""))
9060    (use (match_operand:SWI48 1 "register_operand" ""))
9061    (use (match_operand:QI 2 "register_operand" ""))]
9062   ""
9063 {
9064   rtx label = gen_label_rtx ();
9065   rtx tmp;
9066
9067   emit_insn (gen_testqi_ccz_1 (operands[2],
9068                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9069
9070   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9071   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9072   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9073                               gen_rtx_LABEL_REF (VOIDmode, label),
9074                               pc_rtx);
9075   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9076   JUMP_LABEL (tmp) = label;
9077
9078   emit_move_insn (operands[0], operands[1]);
9079   ix86_expand_clear (operands[1]);
9080
9081   emit_label (label);
9082   LABEL_NUSES (label) = 1;
9083
9084   DONE;
9085 })
9086
9087 ;; Avoid useless masking of count operand.
9088 (define_insn "*ashl<mode>3_mask"
9089   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9090         (ashift:SWI48
9091           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9092           (subreg:QI
9093             (and:SI
9094               (match_operand:SI 2 "register_operand" "c")
9095               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9096    (clobber (reg:CC FLAGS_REG))]
9097   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9098    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9099       == GET_MODE_BITSIZE (<MODE>mode)-1"
9100 {
9101   return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9102 }
9103   [(set_attr "type" "ishift")
9104    (set_attr "mode" "<MODE>")])
9105
9106 (define_insn "*bmi2_ashl<mode>3_1"
9107   [(set (match_operand:SWI48 0 "register_operand" "=r")
9108         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9109                       (match_operand:SWI48 2 "register_operand" "r")))]
9110   "TARGET_BMI2"
9111   "shlx\t{%2, %1, %0|%0, %1, %2}"
9112   [(set_attr "type" "ishiftx")
9113    (set_attr "mode" "<MODE>")])
9114
9115 (define_insn "*ashl<mode>3_1"
9116   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9117         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9118                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9119    (clobber (reg:CC FLAGS_REG))]
9120   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9121 {
9122   switch (get_attr_type (insn))
9123     {
9124     case TYPE_LEA:
9125     case TYPE_ISHIFTX:
9126       return "#";
9127
9128     case TYPE_ALU:
9129       gcc_assert (operands[2] == const1_rtx);
9130       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9131       return "add{<imodesuffix>}\t%0, %0";
9132
9133     default:
9134       if (operands[2] == const1_rtx
9135           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9136         return "sal{<imodesuffix>}\t%0";
9137       else
9138         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9139     }
9140 }
9141   [(set_attr "isa" "*,*,bmi2")
9142    (set (attr "type")
9143      (cond [(eq_attr "alternative" "1")
9144               (const_string "lea")
9145             (eq_attr "alternative" "2")
9146               (const_string "ishiftx")
9147             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9148                       (match_operand 0 "register_operand" ""))
9149                  (match_operand 2 "const1_operand" ""))
9150               (const_string "alu")
9151            ]
9152            (const_string "ishift")))
9153    (set (attr "length_immediate")
9154      (if_then_else
9155        (ior (eq_attr "type" "alu")
9156             (and (eq_attr "type" "ishift")
9157                  (and (match_operand 2 "const1_operand" "")
9158                       (ior (match_test "TARGET_SHIFT1")
9159                            (match_test "optimize_function_for_size_p (cfun)")))))
9160        (const_string "0")
9161        (const_string "*")))
9162    (set_attr "mode" "<MODE>")])
9163
9164 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9165 (define_split
9166   [(set (match_operand:SWI48 0 "register_operand" "")
9167         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9168                       (match_operand:QI 2 "register_operand" "")))
9169    (clobber (reg:CC FLAGS_REG))]
9170   "TARGET_BMI2 && reload_completed"
9171   [(set (match_dup 0)
9172         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9173   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9174
9175 (define_insn "*bmi2_ashlsi3_1_zext"
9176   [(set (match_operand:DI 0 "register_operand" "=r")
9177         (zero_extend:DI
9178           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9179                      (match_operand:SI 2 "register_operand" "r"))))]
9180   "TARGET_64BIT && TARGET_BMI2"
9181   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9182   [(set_attr "type" "ishiftx")
9183    (set_attr "mode" "SI")])
9184
9185 (define_insn "*ashlsi3_1_zext"
9186   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9187         (zero_extend:DI
9188           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9189                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9190    (clobber (reg:CC FLAGS_REG))]
9191   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9192 {
9193   switch (get_attr_type (insn))
9194     {
9195     case TYPE_LEA:
9196     case TYPE_ISHIFTX:
9197       return "#";
9198
9199     case TYPE_ALU:
9200       gcc_assert (operands[2] == const1_rtx);
9201       return "add{l}\t%k0, %k0";
9202
9203     default:
9204       if (operands[2] == const1_rtx
9205           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9206         return "sal{l}\t%k0";
9207       else
9208         return "sal{l}\t{%2, %k0|%k0, %2}";
9209     }
9210 }
9211   [(set_attr "isa" "*,*,bmi2")
9212    (set (attr "type")
9213      (cond [(eq_attr "alternative" "1")
9214               (const_string "lea")
9215             (eq_attr "alternative" "2")
9216               (const_string "ishiftx")
9217             (and (match_test "TARGET_DOUBLE_WITH_ADD")
9218                  (match_operand 2 "const1_operand" ""))
9219               (const_string "alu")
9220            ]
9221            (const_string "ishift")))
9222    (set (attr "length_immediate")
9223      (if_then_else
9224        (ior (eq_attr "type" "alu")
9225             (and (eq_attr "type" "ishift")
9226                  (and (match_operand 2 "const1_operand" "")
9227                       (ior (match_test "TARGET_SHIFT1")
9228                            (match_test "optimize_function_for_size_p (cfun)")))))
9229        (const_string "0")
9230        (const_string "*")))
9231    (set_attr "mode" "SI")])
9232
9233 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9234 (define_split
9235   [(set (match_operand:DI 0 "register_operand" "")
9236         (zero_extend:DI
9237           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9238                      (match_operand:QI 2 "register_operand" ""))))
9239    (clobber (reg:CC FLAGS_REG))]
9240   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9241   [(set (match_dup 0)
9242         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9243   "operands[2] = gen_lowpart (SImode, operands[2]);")
9244
9245 (define_insn "*ashlhi3_1"
9246   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9247         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9248                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9249    (clobber (reg:CC FLAGS_REG))]
9250   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9251 {
9252   switch (get_attr_type (insn))
9253     {
9254     case TYPE_LEA:
9255       return "#";
9256
9257     case TYPE_ALU:
9258       gcc_assert (operands[2] == const1_rtx);
9259       return "add{w}\t%0, %0";
9260
9261     default:
9262       if (operands[2] == const1_rtx
9263           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9264         return "sal{w}\t%0";
9265       else
9266         return "sal{w}\t{%2, %0|%0, %2}";
9267     }
9268 }
9269   [(set (attr "type")
9270      (cond [(eq_attr "alternative" "1")
9271               (const_string "lea")
9272             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9273                       (match_operand 0 "register_operand" ""))
9274                  (match_operand 2 "const1_operand" ""))
9275               (const_string "alu")
9276            ]
9277            (const_string "ishift")))
9278    (set (attr "length_immediate")
9279      (if_then_else
9280        (ior (eq_attr "type" "alu")
9281             (and (eq_attr "type" "ishift")
9282                  (and (match_operand 2 "const1_operand" "")
9283                       (ior (match_test "TARGET_SHIFT1")
9284                            (match_test "optimize_function_for_size_p (cfun)")))))
9285        (const_string "0")
9286        (const_string "*")))
9287    (set_attr "mode" "HI,SI")])
9288
9289 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9290 (define_insn "*ashlqi3_1"
9291   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9292         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9293                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9294    (clobber (reg:CC FLAGS_REG))]
9295   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9296 {
9297   switch (get_attr_type (insn))
9298     {
9299     case TYPE_LEA:
9300       return "#";
9301
9302     case TYPE_ALU:
9303       gcc_assert (operands[2] == const1_rtx);
9304       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9305         return "add{l}\t%k0, %k0";
9306       else
9307         return "add{b}\t%0, %0";
9308
9309     default:
9310       if (operands[2] == const1_rtx
9311           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9312         {
9313           if (get_attr_mode (insn) == MODE_SI)
9314             return "sal{l}\t%k0";
9315           else
9316             return "sal{b}\t%0";
9317         }
9318       else
9319         {
9320           if (get_attr_mode (insn) == MODE_SI)
9321             return "sal{l}\t{%2, %k0|%k0, %2}";
9322           else
9323             return "sal{b}\t{%2, %0|%0, %2}";
9324         }
9325     }
9326 }
9327   [(set (attr "type")
9328      (cond [(eq_attr "alternative" "2")
9329               (const_string "lea")
9330             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9331                       (match_operand 0 "register_operand" ""))
9332                  (match_operand 2 "const1_operand" ""))
9333               (const_string "alu")
9334            ]
9335            (const_string "ishift")))
9336    (set (attr "length_immediate")
9337      (if_then_else
9338        (ior (eq_attr "type" "alu")
9339             (and (eq_attr "type" "ishift")
9340                  (and (match_operand 2 "const1_operand" "")
9341                       (ior (match_test "TARGET_SHIFT1")
9342                            (match_test "optimize_function_for_size_p (cfun)")))))
9343        (const_string "0")
9344        (const_string "*")))
9345    (set_attr "mode" "QI,SI,SI")])
9346
9347 (define_insn "*ashlqi3_1_slp"
9348   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9349         (ashift:QI (match_dup 0)
9350                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9351    (clobber (reg:CC FLAGS_REG))]
9352   "(optimize_function_for_size_p (cfun)
9353     || !TARGET_PARTIAL_FLAG_REG_STALL
9354     || (operands[1] == const1_rtx
9355         && (TARGET_SHIFT1
9356             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9357 {
9358   switch (get_attr_type (insn))
9359     {
9360     case TYPE_ALU:
9361       gcc_assert (operands[1] == const1_rtx);
9362       return "add{b}\t%0, %0";
9363
9364     default:
9365       if (operands[1] == const1_rtx
9366           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9367         return "sal{b}\t%0";
9368       else
9369         return "sal{b}\t{%1, %0|%0, %1}";
9370     }
9371 }
9372   [(set (attr "type")
9373      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9374                       (match_operand 0 "register_operand" ""))
9375                  (match_operand 1 "const1_operand" ""))
9376               (const_string "alu")
9377            ]
9378            (const_string "ishift1")))
9379    (set (attr "length_immediate")
9380      (if_then_else
9381        (ior (eq_attr "type" "alu")
9382             (and (eq_attr "type" "ishift1")
9383                  (and (match_operand 1 "const1_operand" "")
9384                       (ior (match_test "TARGET_SHIFT1")
9385                            (match_test "optimize_function_for_size_p (cfun)")))))
9386        (const_string "0")
9387        (const_string "*")))
9388    (set_attr "mode" "QI")])
9389
9390 ;; Convert ashift to the lea pattern to avoid flags dependency.
9391 (define_split
9392   [(set (match_operand 0 "register_operand" "")
9393         (ashift (match_operand 1 "index_register_operand" "")
9394                 (match_operand:QI 2 "const_int_operand" "")))
9395    (clobber (reg:CC FLAGS_REG))]
9396   "GET_MODE (operands[0]) == GET_MODE (operands[1])
9397    && reload_completed
9398    && true_regnum (operands[0]) != true_regnum (operands[1])"
9399   [(const_int 0)]
9400 {
9401   enum machine_mode mode = GET_MODE (operands[0]);
9402   rtx pat;
9403
9404   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9405     { 
9406       mode = SImode; 
9407       operands[0] = gen_lowpart (mode, operands[0]);
9408       operands[1] = gen_lowpart (mode, operands[1]);
9409     }
9410
9411   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9412
9413   pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9414
9415   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9416   DONE;
9417 })
9418
9419 ;; Convert ashift to the lea pattern to avoid flags dependency.
9420 (define_split
9421   [(set (match_operand:DI 0 "register_operand" "")
9422         (zero_extend:DI
9423           (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9424                      (match_operand:QI 2 "const_int_operand" ""))))
9425    (clobber (reg:CC FLAGS_REG))]
9426   "TARGET_64BIT && reload_completed
9427    && true_regnum (operands[0]) != true_regnum (operands[1])"
9428   [(set (match_dup 0)
9429         (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9430 {
9431   operands[1] = gen_lowpart (DImode, operands[1]);
9432   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9433 })
9434
9435 ;; This pattern can't accept a variable shift count, since shifts by
9436 ;; zero don't affect the flags.  We assume that shifts by constant
9437 ;; zero are optimized away.
9438 (define_insn "*ashl<mode>3_cmp"
9439   [(set (reg FLAGS_REG)
9440         (compare
9441           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9442                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9443           (const_int 0)))
9444    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9445         (ashift:SWI (match_dup 1) (match_dup 2)))]
9446   "(optimize_function_for_size_p (cfun)
9447     || !TARGET_PARTIAL_FLAG_REG_STALL
9448     || (operands[2] == const1_rtx
9449         && (TARGET_SHIFT1
9450             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9451    && ix86_match_ccmode (insn, CCGOCmode)
9452    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9453 {
9454   switch (get_attr_type (insn))
9455     {
9456     case TYPE_ALU:
9457       gcc_assert (operands[2] == const1_rtx);
9458       return "add{<imodesuffix>}\t%0, %0";
9459
9460     default:
9461       if (operands[2] == const1_rtx
9462           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9463         return "sal{<imodesuffix>}\t%0";
9464       else
9465         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9466     }
9467 }
9468   [(set (attr "type")
9469      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9470                       (match_operand 0 "register_operand" ""))
9471                  (match_operand 2 "const1_operand" ""))
9472               (const_string "alu")
9473            ]
9474            (const_string "ishift")))
9475    (set (attr "length_immediate")
9476      (if_then_else
9477        (ior (eq_attr "type" "alu")
9478             (and (eq_attr "type" "ishift")
9479                  (and (match_operand 2 "const1_operand" "")
9480                       (ior (match_test "TARGET_SHIFT1")
9481                            (match_test "optimize_function_for_size_p (cfun)")))))
9482        (const_string "0")
9483        (const_string "*")))
9484    (set_attr "mode" "<MODE>")])
9485
9486 (define_insn "*ashlsi3_cmp_zext"
9487   [(set (reg FLAGS_REG)
9488         (compare
9489           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9490                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9491           (const_int 0)))
9492    (set (match_operand:DI 0 "register_operand" "=r")
9493         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9494   "TARGET_64BIT
9495    && (optimize_function_for_size_p (cfun)
9496        || !TARGET_PARTIAL_FLAG_REG_STALL
9497        || (operands[2] == const1_rtx
9498            && (TARGET_SHIFT1
9499                || TARGET_DOUBLE_WITH_ADD)))
9500    && ix86_match_ccmode (insn, CCGOCmode)
9501    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9502 {
9503   switch (get_attr_type (insn))
9504     {
9505     case TYPE_ALU:
9506       gcc_assert (operands[2] == const1_rtx);
9507       return "add{l}\t%k0, %k0";
9508
9509     default:
9510       if (operands[2] == const1_rtx
9511           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9512         return "sal{l}\t%k0";
9513       else
9514         return "sal{l}\t{%2, %k0|%k0, %2}";
9515     }
9516 }
9517   [(set (attr "type")
9518      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9519                  (match_operand 2 "const1_operand" ""))
9520               (const_string "alu")
9521            ]
9522            (const_string "ishift")))
9523    (set (attr "length_immediate")
9524      (if_then_else
9525        (ior (eq_attr "type" "alu")
9526             (and (eq_attr "type" "ishift")
9527                  (and (match_operand 2 "const1_operand" "")
9528                       (ior (match_test "TARGET_SHIFT1")
9529                            (match_test "optimize_function_for_size_p (cfun)")))))
9530        (const_string "0")
9531        (const_string "*")))
9532    (set_attr "mode" "SI")])
9533
9534 (define_insn "*ashl<mode>3_cconly"
9535   [(set (reg FLAGS_REG)
9536         (compare
9537           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9538                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9539           (const_int 0)))
9540    (clobber (match_scratch:SWI 0 "=<r>"))]
9541   "(optimize_function_for_size_p (cfun)
9542     || !TARGET_PARTIAL_FLAG_REG_STALL
9543     || (operands[2] == const1_rtx
9544         && (TARGET_SHIFT1
9545             || TARGET_DOUBLE_WITH_ADD)))
9546    && ix86_match_ccmode (insn, CCGOCmode)"
9547 {
9548   switch (get_attr_type (insn))
9549     {
9550     case TYPE_ALU:
9551       gcc_assert (operands[2] == const1_rtx);
9552       return "add{<imodesuffix>}\t%0, %0";
9553
9554     default:
9555       if (operands[2] == const1_rtx
9556           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9557         return "sal{<imodesuffix>}\t%0";
9558       else
9559         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9560     }
9561 }
9562   [(set (attr "type")
9563      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9564                       (match_operand 0 "register_operand" ""))
9565                  (match_operand 2 "const1_operand" ""))
9566               (const_string "alu")
9567            ]
9568            (const_string "ishift")))
9569    (set (attr "length_immediate")
9570      (if_then_else
9571        (ior (eq_attr "type" "alu")
9572             (and (eq_attr "type" "ishift")
9573                  (and (match_operand 2 "const1_operand" "")
9574                       (ior (match_test "TARGET_SHIFT1")
9575                            (match_test "optimize_function_for_size_p (cfun)")))))
9576        (const_string "0")
9577        (const_string "*")))
9578    (set_attr "mode" "<MODE>")])
9579
9580 ;; See comment above `ashl<mode>3' about how this works.
9581
9582 (define_expand "<shift_insn><mode>3"
9583   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9584         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9585                            (match_operand:QI 2 "nonmemory_operand" "")))]
9586   ""
9587   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9588
9589 ;; Avoid useless masking of count operand.
9590 (define_insn "*<shift_insn><mode>3_mask"
9591   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9592         (any_shiftrt:SWI48
9593           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9594           (subreg:QI
9595             (and:SI
9596               (match_operand:SI 2 "register_operand" "c")
9597               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9598    (clobber (reg:CC FLAGS_REG))]
9599   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9600    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9601       == GET_MODE_BITSIZE (<MODE>mode)-1"
9602 {
9603   return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9604 }
9605   [(set_attr "type" "ishift")
9606    (set_attr "mode" "<MODE>")])
9607
9608 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9609   [(set (match_operand:DWI 0 "register_operand" "=r")
9610         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9611                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9612    (clobber (reg:CC FLAGS_REG))]
9613   ""
9614   "#"
9615   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9616   [(const_int 0)]
9617   "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9618   [(set_attr "type" "multi")])
9619
9620 ;; By default we don't ask for a scratch register, because when DWImode
9621 ;; values are manipulated, registers are already at a premium.  But if
9622 ;; we have one handy, we won't turn it away.
9623
9624 (define_peephole2
9625   [(match_scratch:DWIH 3 "r")
9626    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9627                    (any_shiftrt:<DWI>
9628                      (match_operand:<DWI> 1 "register_operand" "")
9629                      (match_operand:QI 2 "nonmemory_operand" "")))
9630               (clobber (reg:CC FLAGS_REG))])
9631    (match_dup 3)]
9632   "TARGET_CMOVE"
9633   [(const_int 0)]
9634   "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9635
9636 (define_insn "x86_64_shrd"
9637   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9638         (ior:DI (ashiftrt:DI (match_dup 0)
9639                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9640                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9641                   (minus:QI (const_int 64) (match_dup 2)))))
9642    (clobber (reg:CC FLAGS_REG))]
9643   "TARGET_64BIT"
9644   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9645   [(set_attr "type" "ishift")
9646    (set_attr "prefix_0f" "1")
9647    (set_attr "mode" "DI")
9648    (set_attr "athlon_decode" "vector")
9649    (set_attr "amdfam10_decode" "vector")
9650    (set_attr "bdver1_decode" "vector")])
9651
9652 (define_insn "x86_shrd"
9653   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9654         (ior:SI (ashiftrt:SI (match_dup 0)
9655                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9656                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9657                   (minus:QI (const_int 32) (match_dup 2)))))
9658    (clobber (reg:CC FLAGS_REG))]
9659   ""
9660   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9661   [(set_attr "type" "ishift")
9662    (set_attr "prefix_0f" "1")
9663    (set_attr "mode" "SI")
9664    (set_attr "pent_pair" "np")
9665    (set_attr "athlon_decode" "vector")
9666    (set_attr "amdfam10_decode" "vector")
9667    (set_attr "bdver1_decode" "vector")])
9668
9669 (define_insn "ashrdi3_cvt"
9670   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9671         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9672                      (match_operand:QI 2 "const_int_operand" "")))
9673    (clobber (reg:CC FLAGS_REG))]
9674   "TARGET_64BIT && INTVAL (operands[2]) == 63
9675    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9676    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9677   "@
9678    {cqto|cqo}
9679    sar{q}\t{%2, %0|%0, %2}"
9680   [(set_attr "type" "imovx,ishift")
9681    (set_attr "prefix_0f" "0,*")
9682    (set_attr "length_immediate" "0,*")
9683    (set_attr "modrm" "0,1")
9684    (set_attr "mode" "DI")])
9685
9686 (define_insn "ashrsi3_cvt"
9687   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9688         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9689                      (match_operand:QI 2 "const_int_operand" "")))
9690    (clobber (reg:CC FLAGS_REG))]
9691   "INTVAL (operands[2]) == 31
9692    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9693    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9694   "@
9695    {cltd|cdq}
9696    sar{l}\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" "SI")])
9702
9703 (define_insn "*ashrsi3_cvt_zext"
9704   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9705         (zero_extend:DI
9706           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9707                        (match_operand:QI 2 "const_int_operand" ""))))
9708    (clobber (reg:CC FLAGS_REG))]
9709   "TARGET_64BIT && INTVAL (operands[2]) == 31
9710    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9711    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9712   "@
9713    {cltd|cdq}
9714    sar{l}\t{%2, %k0|%k0, %2}"
9715   [(set_attr "type" "imovx,ishift")
9716    (set_attr "prefix_0f" "0,*")
9717    (set_attr "length_immediate" "0,*")
9718    (set_attr "modrm" "0,1")
9719    (set_attr "mode" "SI")])
9720
9721 (define_expand "x86_shift<mode>_adj_3"
9722   [(use (match_operand:SWI48 0 "register_operand" ""))
9723    (use (match_operand:SWI48 1 "register_operand" ""))
9724    (use (match_operand:QI 2 "register_operand" ""))]
9725   ""
9726 {
9727   rtx label = gen_label_rtx ();
9728   rtx tmp;
9729
9730   emit_insn (gen_testqi_ccz_1 (operands[2],
9731                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9732
9733   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9734   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9735   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9736                               gen_rtx_LABEL_REF (VOIDmode, label),
9737                               pc_rtx);
9738   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9739   JUMP_LABEL (tmp) = label;
9740
9741   emit_move_insn (operands[0], operands[1]);
9742   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9743                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9744   emit_label (label);
9745   LABEL_NUSES (label) = 1;
9746
9747   DONE;
9748 })
9749
9750 (define_insn "*bmi2_<shift_insn><mode>3_1"
9751   [(set (match_operand:SWI48 0 "register_operand" "=r")
9752         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9753                            (match_operand:SWI48 2 "register_operand" "r")))]
9754   "TARGET_BMI2"
9755   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9756   [(set_attr "type" "ishiftx")
9757    (set_attr "mode" "<MODE>")])
9758
9759 (define_insn "*<shift_insn><mode>3_1"
9760   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9761         (any_shiftrt:SWI48
9762           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9763           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9764    (clobber (reg:CC FLAGS_REG))]
9765   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9766 {
9767   switch (get_attr_type (insn))
9768     {
9769     case TYPE_ISHIFTX:
9770       return "#";
9771
9772     default:
9773       if (operands[2] == const1_rtx
9774           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9775         return "<shift>{<imodesuffix>}\t%0";
9776       else
9777         return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9778     }
9779 }
9780   [(set_attr "isa" "*,bmi2")
9781    (set_attr "type" "ishift,ishiftx")
9782    (set (attr "length_immediate")
9783      (if_then_else
9784        (and (match_operand 2 "const1_operand" "")
9785             (ior (match_test "TARGET_SHIFT1")
9786                  (match_test "optimize_function_for_size_p (cfun)")))
9787        (const_string "0")
9788        (const_string "*")))
9789    (set_attr "mode" "<MODE>")])
9790
9791 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9792 (define_split
9793   [(set (match_operand:SWI48 0 "register_operand" "")
9794         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9795                            (match_operand:QI 2 "register_operand" "")))
9796    (clobber (reg:CC FLAGS_REG))]
9797   "TARGET_BMI2 && reload_completed"
9798   [(set (match_dup 0)
9799         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9800   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9801
9802 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9803   [(set (match_operand:DI 0 "register_operand" "=r")
9804         (zero_extend:DI
9805           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9806                           (match_operand:SI 2 "register_operand" "r"))))]
9807   "TARGET_64BIT && TARGET_BMI2"
9808   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9809   [(set_attr "type" "ishiftx")
9810    (set_attr "mode" "SI")])
9811
9812 (define_insn "*<shift_insn>si3_1_zext"
9813   [(set (match_operand:DI 0 "register_operand" "=r,r")
9814         (zero_extend:DI
9815           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9816                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9817    (clobber (reg:CC FLAGS_REG))]
9818   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9819 {
9820   switch (get_attr_type (insn))
9821     {
9822     case TYPE_ISHIFTX:
9823       return "#";
9824
9825     default:
9826       if (operands[2] == const1_rtx
9827           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9828         return "<shift>{l}\t%k0";
9829       else
9830         return "<shift>{l}\t{%2, %k0|%k0, %2}";
9831     }
9832 }
9833   [(set_attr "isa" "*,bmi2")
9834    (set_attr "type" "ishift,ishiftx")
9835    (set (attr "length_immediate")
9836      (if_then_else
9837        (and (match_operand 2 "const1_operand" "")
9838             (ior (match_test "TARGET_SHIFT1")
9839                  (match_test "optimize_function_for_size_p (cfun)")))
9840        (const_string "0")
9841        (const_string "*")))
9842    (set_attr "mode" "SI")])
9843
9844 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9845 (define_split
9846   [(set (match_operand:DI 0 "register_operand" "")
9847         (zero_extend:DI
9848           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9849                           (match_operand:QI 2 "register_operand" ""))))
9850    (clobber (reg:CC FLAGS_REG))]
9851   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9852   [(set (match_dup 0)
9853         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9854   "operands[2] = gen_lowpart (SImode, operands[2]);")
9855
9856 (define_insn "*<shift_insn><mode>3_1"
9857   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9858         (any_shiftrt:SWI12
9859           (match_operand:SWI12 1 "nonimmediate_operand" "0")
9860           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9861    (clobber (reg:CC FLAGS_REG))]
9862   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9863 {
9864   if (operands[2] == const1_rtx
9865       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9866     return "<shift>{<imodesuffix>}\t%0";
9867   else
9868     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9869 }
9870   [(set_attr "type" "ishift")
9871    (set (attr "length_immediate")
9872      (if_then_else
9873        (and (match_operand 2 "const1_operand" "")
9874             (ior (match_test "TARGET_SHIFT1")
9875                  (match_test "optimize_function_for_size_p (cfun)")))
9876        (const_string "0")
9877        (const_string "*")))
9878    (set_attr "mode" "<MODE>")])
9879
9880 (define_insn "*<shift_insn>qi3_1_slp"
9881   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9882         (any_shiftrt:QI (match_dup 0)
9883                         (match_operand:QI 1 "nonmemory_operand" "cI")))
9884    (clobber (reg:CC FLAGS_REG))]
9885   "(optimize_function_for_size_p (cfun)
9886     || !TARGET_PARTIAL_REG_STALL
9887     || (operands[1] == const1_rtx
9888         && TARGET_SHIFT1))"
9889 {
9890   if (operands[1] == const1_rtx
9891       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9892     return "<shift>{b}\t%0";
9893   else
9894     return "<shift>{b}\t{%1, %0|%0, %1}";
9895 }
9896   [(set_attr "type" "ishift1")
9897    (set (attr "length_immediate")
9898      (if_then_else
9899        (and (match_operand 1 "const1_operand" "")
9900             (ior (match_test "TARGET_SHIFT1")
9901                  (match_test "optimize_function_for_size_p (cfun)")))
9902        (const_string "0")
9903        (const_string "*")))
9904    (set_attr "mode" "QI")])
9905
9906 ;; This pattern can't accept a variable shift count, since shifts by
9907 ;; zero don't affect the flags.  We assume that shifts by constant
9908 ;; zero are optimized away.
9909 (define_insn "*<shift_insn><mode>3_cmp"
9910   [(set (reg FLAGS_REG)
9911         (compare
9912           (any_shiftrt:SWI
9913             (match_operand:SWI 1 "nonimmediate_operand" "0")
9914             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9915           (const_int 0)))
9916    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9917         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9918   "(optimize_function_for_size_p (cfun)
9919     || !TARGET_PARTIAL_FLAG_REG_STALL
9920     || (operands[2] == const1_rtx
9921         && TARGET_SHIFT1))
9922    && ix86_match_ccmode (insn, CCGOCmode)
9923    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9924 {
9925   if (operands[2] == const1_rtx
9926       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9927     return "<shift>{<imodesuffix>}\t%0";
9928   else
9929     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9930 }
9931   [(set_attr "type" "ishift")
9932    (set (attr "length_immediate")
9933      (if_then_else
9934        (and (match_operand 2 "const1_operand" "")
9935             (ior (match_test "TARGET_SHIFT1")
9936                  (match_test "optimize_function_for_size_p (cfun)")))
9937        (const_string "0")
9938        (const_string "*")))
9939    (set_attr "mode" "<MODE>")])
9940
9941 (define_insn "*<shift_insn>si3_cmp_zext"
9942   [(set (reg FLAGS_REG)
9943         (compare
9944           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9945                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
9946           (const_int 0)))
9947    (set (match_operand:DI 0 "register_operand" "=r")
9948         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9949   "TARGET_64BIT
9950    && (optimize_function_for_size_p (cfun)
9951        || !TARGET_PARTIAL_FLAG_REG_STALL
9952        || (operands[2] == const1_rtx
9953            && TARGET_SHIFT1))
9954    && ix86_match_ccmode (insn, CCGOCmode)
9955    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9956 {
9957   if (operands[2] == const1_rtx
9958       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9959     return "<shift>{l}\t%k0";
9960   else
9961     return "<shift>{l}\t{%2, %k0|%k0, %2}";
9962 }
9963   [(set_attr "type" "ishift")
9964    (set (attr "length_immediate")
9965      (if_then_else
9966        (and (match_operand 2 "const1_operand" "")
9967             (ior (match_test "TARGET_SHIFT1")
9968                  (match_test "optimize_function_for_size_p (cfun)")))
9969        (const_string "0")
9970        (const_string "*")))
9971    (set_attr "mode" "SI")])
9972
9973 (define_insn "*<shift_insn><mode>3_cconly"
9974   [(set (reg FLAGS_REG)
9975         (compare
9976           (any_shiftrt:SWI
9977             (match_operand:SWI 1 "register_operand" "0")
9978             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9979           (const_int 0)))
9980    (clobber (match_scratch:SWI 0 "=<r>"))]
9981   "(optimize_function_for_size_p (cfun)
9982     || !TARGET_PARTIAL_FLAG_REG_STALL
9983     || (operands[2] == const1_rtx
9984         && TARGET_SHIFT1))
9985    && ix86_match_ccmode (insn, CCGOCmode)"
9986 {
9987   if (operands[2] == const1_rtx
9988       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9989     return "<shift>{<imodesuffix>}\t%0";
9990   else
9991     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9992 }
9993   [(set_attr "type" "ishift")
9994    (set (attr "length_immediate")
9995      (if_then_else
9996        (and (match_operand 2 "const1_operand" "")
9997             (ior (match_test "TARGET_SHIFT1")
9998                  (match_test "optimize_function_for_size_p (cfun)")))
9999        (const_string "0")
10000        (const_string "*")))
10001    (set_attr "mode" "<MODE>")])
10002 \f
10003 ;; Rotate instructions
10004
10005 (define_expand "<rotate_insn>ti3"
10006   [(set (match_operand:TI 0 "register_operand" "")
10007         (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10008                        (match_operand:QI 2 "nonmemory_operand" "")))]
10009   "TARGET_64BIT"
10010 {
10011   if (const_1_to_63_operand (operands[2], VOIDmode))
10012     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10013                 (operands[0], operands[1], operands[2]));
10014   else
10015     FAIL;
10016
10017   DONE;
10018 })
10019
10020 (define_expand "<rotate_insn>di3"
10021   [(set (match_operand:DI 0 "shiftdi_operand" "")
10022         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10023                        (match_operand:QI 2 "nonmemory_operand" "")))]
10024  ""
10025 {
10026   if (TARGET_64BIT)
10027     ix86_expand_binary_operator (<CODE>, DImode, operands);
10028   else if (const_1_to_31_operand (operands[2], VOIDmode))
10029     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10030                 (operands[0], operands[1], operands[2]));
10031   else
10032     FAIL;
10033
10034   DONE;
10035 })
10036
10037 (define_expand "<rotate_insn><mode>3"
10038   [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10039         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10040                             (match_operand:QI 2 "nonmemory_operand" "")))]
10041   ""
10042   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10043
10044 ;; Avoid useless masking of count operand.
10045 (define_insn "*<rotate_insn><mode>3_mask"
10046   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10047         (any_rotate:SWI48
10048           (match_operand:SWI48 1 "nonimmediate_operand" "0")
10049           (subreg:QI
10050             (and:SI
10051               (match_operand:SI 2 "register_operand" "c")
10052               (match_operand:SI 3 "const_int_operand" "n")) 0)))
10053    (clobber (reg:CC FLAGS_REG))]
10054   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10055    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10056       == GET_MODE_BITSIZE (<MODE>mode)-1"
10057 {
10058   return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10059 }
10060   [(set_attr "type" "rotate")
10061    (set_attr "mode" "<MODE>")])
10062
10063 ;; Implement rotation using two double-precision
10064 ;; shift instructions and a scratch register.
10065
10066 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10067  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10068        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10069                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10070   (clobber (reg:CC FLAGS_REG))
10071   (clobber (match_scratch:DWIH 3 "=&r"))]
10072  ""
10073  "#"
10074  "reload_completed"
10075  [(set (match_dup 3) (match_dup 4))
10076   (parallel
10077    [(set (match_dup 4)
10078          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10079                    (lshiftrt:DWIH (match_dup 5)
10080                                   (minus:QI (match_dup 6) (match_dup 2)))))
10081     (clobber (reg:CC FLAGS_REG))])
10082   (parallel
10083    [(set (match_dup 5)
10084          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10085                    (lshiftrt:DWIH (match_dup 3)
10086                                   (minus:QI (match_dup 6) (match_dup 2)))))
10087     (clobber (reg:CC FLAGS_REG))])]
10088 {
10089   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10090
10091   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10092 })
10093
10094 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10095  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10096        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10097                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10098   (clobber (reg:CC FLAGS_REG))
10099   (clobber (match_scratch:DWIH 3 "=&r"))]
10100  ""
10101  "#"
10102  "reload_completed"
10103  [(set (match_dup 3) (match_dup 4))
10104   (parallel
10105    [(set (match_dup 4)
10106          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10107                    (ashift:DWIH (match_dup 5)
10108                                 (minus:QI (match_dup 6) (match_dup 2)))))
10109     (clobber (reg:CC FLAGS_REG))])
10110   (parallel
10111    [(set (match_dup 5)
10112          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10113                    (ashift:DWIH (match_dup 3)
10114                                 (minus:QI (match_dup 6) (match_dup 2)))))
10115     (clobber (reg:CC FLAGS_REG))])]
10116 {
10117   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10118
10119   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10120 })
10121
10122 (define_insn "*bmi2_rorx<mode>3_1"
10123   [(set (match_operand:SWI48 0 "register_operand" "=r")
10124         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10125                         (match_operand:QI 2 "immediate_operand" "<S>")))]
10126   "TARGET_BMI2"
10127   "rorx\t{%2, %1, %0|%0, %1, %2}"
10128   [(set_attr "type" "rotatex")
10129    (set_attr "mode" "<MODE>")])
10130
10131 (define_insn "*<rotate_insn><mode>3_1"
10132   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10133         (any_rotate:SWI48
10134           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10135           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10136    (clobber (reg:CC FLAGS_REG))]
10137   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10138 {
10139   switch (get_attr_type (insn))
10140     {
10141     case TYPE_ROTATEX:
10142       return "#";
10143
10144     default:
10145       if (operands[2] == const1_rtx
10146           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10147         return "<rotate>{<imodesuffix>}\t%0";
10148       else
10149         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10150     }
10151 }
10152   [(set_attr "isa" "*,bmi2")
10153    (set_attr "type" "rotate,rotatex")
10154    (set (attr "length_immediate")
10155      (if_then_else
10156        (and (eq_attr "type" "rotate")
10157             (and (match_operand 2 "const1_operand" "")
10158                  (ior (match_test "TARGET_SHIFT1")
10159                       (match_test "optimize_function_for_size_p (cfun)"))))
10160        (const_string "0")
10161        (const_string "*")))
10162    (set_attr "mode" "<MODE>")])
10163
10164 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10165 (define_split
10166   [(set (match_operand:SWI48 0 "register_operand" "")
10167         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10168                       (match_operand:QI 2 "immediate_operand" "")))
10169    (clobber (reg:CC FLAGS_REG))]
10170   "TARGET_BMI2 && reload_completed"
10171   [(set (match_dup 0)
10172         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10173 {
10174   operands[2]
10175     = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10176 })
10177
10178 (define_split
10179   [(set (match_operand:SWI48 0 "register_operand" "")
10180         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10181                         (match_operand:QI 2 "immediate_operand" "")))
10182    (clobber (reg:CC FLAGS_REG))]
10183   "TARGET_BMI2 && reload_completed"
10184   [(set (match_dup 0)
10185         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10186
10187 (define_insn "*bmi2_rorxsi3_1_zext"
10188   [(set (match_operand:DI 0 "register_operand" "=r")
10189         (zero_extend:DI
10190           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10191                        (match_operand:QI 2 "immediate_operand" "I"))))]
10192   "TARGET_64BIT && TARGET_BMI2"
10193   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10194   [(set_attr "type" "rotatex")
10195    (set_attr "mode" "SI")])
10196
10197 (define_insn "*<rotate_insn>si3_1_zext"
10198   [(set (match_operand:DI 0 "register_operand" "=r,r")
10199         (zero_extend:DI
10200           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10201                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10202    (clobber (reg:CC FLAGS_REG))]
10203   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10204 {
10205   switch (get_attr_type (insn))
10206     {
10207     case TYPE_ROTATEX:
10208       return "#";
10209
10210     default:
10211       if (operands[2] == const1_rtx
10212           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10213         return "<rotate>{l}\t%k0";
10214       else
10215         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10216     }
10217 }
10218   [(set_attr "isa" "*,bmi2")
10219    (set_attr "type" "rotate,rotatex")
10220    (set (attr "length_immediate")
10221      (if_then_else
10222        (and (eq_attr "type" "rotate")
10223             (and (match_operand 2 "const1_operand" "")
10224                  (ior (match_test "TARGET_SHIFT1")
10225                       (match_test "optimize_function_for_size_p (cfun)"))))
10226        (const_string "0")
10227        (const_string "*")))
10228    (set_attr "mode" "SI")])
10229
10230 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10231 (define_split
10232   [(set (match_operand:DI 0 "register_operand" "")
10233         (zero_extend:DI
10234           (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10235                      (match_operand:QI 2 "immediate_operand" ""))))
10236    (clobber (reg:CC FLAGS_REG))]
10237   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10238   [(set (match_dup 0)
10239         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10240 {
10241   operands[2]
10242     = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10243 })
10244
10245 (define_split
10246   [(set (match_operand:DI 0 "register_operand" "")
10247         (zero_extend:DI
10248           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10249                        (match_operand:QI 2 "immediate_operand" ""))))
10250    (clobber (reg:CC FLAGS_REG))]
10251   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10252   [(set (match_dup 0)
10253         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10254
10255 (define_insn "*<rotate_insn><mode>3_1"
10256   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10257         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10258                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10259    (clobber (reg:CC FLAGS_REG))]
10260   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10261 {
10262   if (operands[2] == const1_rtx
10263       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10264     return "<rotate>{<imodesuffix>}\t%0";
10265   else
10266     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10267 }
10268   [(set_attr "type" "rotate")
10269    (set (attr "length_immediate")
10270      (if_then_else
10271        (and (match_operand 2 "const1_operand" "")
10272             (ior (match_test "TARGET_SHIFT1")
10273                  (match_test "optimize_function_for_size_p (cfun)")))
10274        (const_string "0")
10275        (const_string "*")))
10276    (set_attr "mode" "<MODE>")])
10277
10278 (define_insn "*<rotate_insn>qi3_1_slp"
10279   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10280         (any_rotate:QI (match_dup 0)
10281                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10282    (clobber (reg:CC FLAGS_REG))]
10283   "(optimize_function_for_size_p (cfun)
10284     || !TARGET_PARTIAL_REG_STALL
10285     || (operands[1] == const1_rtx
10286         && TARGET_SHIFT1))"
10287 {
10288   if (operands[1] == const1_rtx
10289       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10290     return "<rotate>{b}\t%0";
10291   else
10292     return "<rotate>{b}\t{%1, %0|%0, %1}";
10293 }
10294   [(set_attr "type" "rotate1")
10295    (set (attr "length_immediate")
10296      (if_then_else
10297        (and (match_operand 1 "const1_operand" "")
10298             (ior (match_test "TARGET_SHIFT1")
10299                  (match_test "optimize_function_for_size_p (cfun)")))
10300        (const_string "0")
10301        (const_string "*")))
10302    (set_attr "mode" "QI")])
10303
10304 (define_split
10305  [(set (match_operand:HI 0 "register_operand" "")
10306        (any_rotate:HI (match_dup 0) (const_int 8)))
10307   (clobber (reg:CC FLAGS_REG))]
10308  "reload_completed
10309   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10310  [(parallel [(set (strict_low_part (match_dup 0))
10311                   (bswap:HI (match_dup 0)))
10312              (clobber (reg:CC FLAGS_REG))])])
10313 \f
10314 ;; Bit set / bit test instructions
10315
10316 (define_expand "extv"
10317   [(set (match_operand:SI 0 "register_operand" "")
10318         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10319                          (match_operand:SI 2 "const8_operand" "")
10320                          (match_operand:SI 3 "const8_operand" "")))]
10321   ""
10322 {
10323   /* Handle extractions from %ah et al.  */
10324   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10325     FAIL;
10326
10327   /* From mips.md: extract_bit_field doesn't verify that our source
10328      matches the predicate, so check it again here.  */
10329   if (! ext_register_operand (operands[1], VOIDmode))
10330     FAIL;
10331 })
10332
10333 (define_expand "extzv"
10334   [(set (match_operand:SI 0 "register_operand" "")
10335         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10336                          (match_operand:SI 2 "const8_operand" "")
10337                          (match_operand:SI 3 "const8_operand" "")))]
10338   ""
10339 {
10340   /* Handle extractions from %ah et al.  */
10341   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10342     FAIL;
10343
10344   /* From mips.md: extract_bit_field doesn't verify that our source
10345      matches the predicate, so check it again here.  */
10346   if (! ext_register_operand (operands[1], VOIDmode))
10347     FAIL;
10348 })
10349
10350 (define_expand "insv"
10351   [(set (zero_extract (match_operand 0 "register_operand" "")
10352                       (match_operand 1 "const_int_operand" "")
10353                       (match_operand 2 "const_int_operand" ""))
10354         (match_operand 3 "register_operand" ""))]
10355   ""
10356 {
10357   rtx (*gen_mov_insv_1) (rtx, rtx);
10358
10359   if (ix86_expand_pinsr (operands))
10360     DONE;
10361
10362   /* Handle insertions to %ah et al.  */
10363   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10364     FAIL;
10365
10366   /* From mips.md: insert_bit_field doesn't verify that our source
10367      matches the predicate, so check it again here.  */
10368   if (! ext_register_operand (operands[0], VOIDmode))
10369     FAIL;
10370
10371   gen_mov_insv_1 = (TARGET_64BIT
10372                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10373
10374   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10375   DONE;
10376 })
10377
10378 ;; %%% bts, btr, btc, bt.
10379 ;; In general these instructions are *slow* when applied to memory,
10380 ;; since they enforce atomic operation.  When applied to registers,
10381 ;; it depends on the cpu implementation.  They're never faster than
10382 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10383 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10384 ;; within the instruction itself, so operating on bits in the high
10385 ;; 32-bits of a register becomes easier.
10386 ;;
10387 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10388 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10389 ;; negdf respectively, so they can never be disabled entirely.
10390
10391 (define_insn "*btsq"
10392   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10393                          (const_int 1)
10394                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10395         (const_int 1))
10396    (clobber (reg:CC FLAGS_REG))]
10397   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10398   "bts{q}\t{%1, %0|%0, %1}"
10399   [(set_attr "type" "alu1")
10400    (set_attr "prefix_0f" "1")
10401    (set_attr "mode" "DI")])
10402
10403 (define_insn "*btrq"
10404   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10405                          (const_int 1)
10406                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10407         (const_int 0))
10408    (clobber (reg:CC FLAGS_REG))]
10409   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10410   "btr{q}\t{%1, %0|%0, %1}"
10411   [(set_attr "type" "alu1")
10412    (set_attr "prefix_0f" "1")
10413    (set_attr "mode" "DI")])
10414
10415 (define_insn "*btcq"
10416   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10417                          (const_int 1)
10418                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10419         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10420    (clobber (reg:CC FLAGS_REG))]
10421   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10422   "btc{q}\t{%1, %0|%0, %1}"
10423   [(set_attr "type" "alu1")
10424    (set_attr "prefix_0f" "1")
10425    (set_attr "mode" "DI")])
10426
10427 ;; Allow Nocona to avoid these instructions if a register is available.
10428
10429 (define_peephole2
10430   [(match_scratch:DI 2 "r")
10431    (parallel [(set (zero_extract:DI
10432                      (match_operand:DI 0 "register_operand" "")
10433                      (const_int 1)
10434                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10435                    (const_int 1))
10436               (clobber (reg:CC FLAGS_REG))])]
10437   "TARGET_64BIT && !TARGET_USE_BT"
10438   [(const_int 0)]
10439 {
10440   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10441   rtx op1;
10442
10443   if (HOST_BITS_PER_WIDE_INT >= 64)
10444     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10445   else if (i < HOST_BITS_PER_WIDE_INT)
10446     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10447   else
10448     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10449
10450   op1 = immed_double_const (lo, hi, DImode);
10451   if (i >= 31)
10452     {
10453       emit_move_insn (operands[2], op1);
10454       op1 = operands[2];
10455     }
10456
10457   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10458   DONE;
10459 })
10460
10461 (define_peephole2
10462   [(match_scratch:DI 2 "r")
10463    (parallel [(set (zero_extract:DI
10464                      (match_operand:DI 0 "register_operand" "")
10465                      (const_int 1)
10466                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10467                    (const_int 0))
10468               (clobber (reg:CC FLAGS_REG))])]
10469   "TARGET_64BIT && !TARGET_USE_BT"
10470   [(const_int 0)]
10471 {
10472   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10473   rtx op1;
10474
10475   if (HOST_BITS_PER_WIDE_INT >= 64)
10476     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10477   else if (i < HOST_BITS_PER_WIDE_INT)
10478     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10479   else
10480     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10481
10482   op1 = immed_double_const (~lo, ~hi, DImode);
10483   if (i >= 32)
10484     {
10485       emit_move_insn (operands[2], op1);
10486       op1 = operands[2];
10487     }
10488
10489   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10490   DONE;
10491 })
10492
10493 (define_peephole2
10494   [(match_scratch:DI 2 "r")
10495    (parallel [(set (zero_extract:DI
10496                      (match_operand:DI 0 "register_operand" "")
10497                      (const_int 1)
10498                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10499               (not:DI (zero_extract:DI
10500                         (match_dup 0) (const_int 1) (match_dup 1))))
10501               (clobber (reg:CC FLAGS_REG))])]
10502   "TARGET_64BIT && !TARGET_USE_BT"
10503   [(const_int 0)]
10504 {
10505   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10506   rtx op1;
10507
10508   if (HOST_BITS_PER_WIDE_INT >= 64)
10509     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10510   else if (i < HOST_BITS_PER_WIDE_INT)
10511     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10512   else
10513     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10514
10515   op1 = immed_double_const (lo, hi, DImode);
10516   if (i >= 31)
10517     {
10518       emit_move_insn (operands[2], op1);
10519       op1 = operands[2];
10520     }
10521
10522   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10523   DONE;
10524 })
10525
10526 (define_insn "*bt<mode>"
10527   [(set (reg:CCC FLAGS_REG)
10528         (compare:CCC
10529           (zero_extract:SWI48
10530             (match_operand:SWI48 0 "register_operand" "r")
10531             (const_int 1)
10532             (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10533           (const_int 0)))]
10534   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10535   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10536   [(set_attr "type" "alu1")
10537    (set_attr "prefix_0f" "1")
10538    (set_attr "mode" "<MODE>")])
10539 \f
10540 ;; Store-flag instructions.
10541
10542 ;; For all sCOND expanders, also expand the compare or test insn that
10543 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10544
10545 (define_insn_and_split "*setcc_di_1"
10546   [(set (match_operand:DI 0 "register_operand" "=q")
10547         (match_operator:DI 1 "ix86_comparison_operator"
10548           [(reg FLAGS_REG) (const_int 0)]))]
10549   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10550   "#"
10551   "&& reload_completed"
10552   [(set (match_dup 2) (match_dup 1))
10553    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10554 {
10555   PUT_MODE (operands[1], QImode);
10556   operands[2] = gen_lowpart (QImode, operands[0]);
10557 })
10558
10559 (define_insn_and_split "*setcc_si_1_and"
10560   [(set (match_operand:SI 0 "register_operand" "=q")
10561         (match_operator:SI 1 "ix86_comparison_operator"
10562           [(reg FLAGS_REG) (const_int 0)]))
10563    (clobber (reg:CC FLAGS_REG))]
10564   "!TARGET_PARTIAL_REG_STALL
10565    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10566   "#"
10567   "&& reload_completed"
10568   [(set (match_dup 2) (match_dup 1))
10569    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10570               (clobber (reg:CC FLAGS_REG))])]
10571 {
10572   PUT_MODE (operands[1], QImode);
10573   operands[2] = gen_lowpart (QImode, operands[0]);
10574 })
10575
10576 (define_insn_and_split "*setcc_si_1_movzbl"
10577   [(set (match_operand:SI 0 "register_operand" "=q")
10578         (match_operator:SI 1 "ix86_comparison_operator"
10579           [(reg FLAGS_REG) (const_int 0)]))]
10580   "!TARGET_PARTIAL_REG_STALL
10581    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10582   "#"
10583   "&& reload_completed"
10584   [(set (match_dup 2) (match_dup 1))
10585    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10586 {
10587   PUT_MODE (operands[1], QImode);
10588   operands[2] = gen_lowpart (QImode, operands[0]);
10589 })
10590
10591 (define_insn "*setcc_qi"
10592   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10593         (match_operator:QI 1 "ix86_comparison_operator"
10594           [(reg FLAGS_REG) (const_int 0)]))]
10595   ""
10596   "set%C1\t%0"
10597   [(set_attr "type" "setcc")
10598    (set_attr "mode" "QI")])
10599
10600 (define_insn "*setcc_qi_slp"
10601   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10602         (match_operator:QI 1 "ix86_comparison_operator"
10603           [(reg FLAGS_REG) (const_int 0)]))]
10604   ""
10605   "set%C1\t%0"
10606   [(set_attr "type" "setcc")
10607    (set_attr "mode" "QI")])
10608
10609 ;; In general it is not safe to assume too much about CCmode registers,
10610 ;; so simplify-rtx stops when it sees a second one.  Under certain
10611 ;; conditions this is safe on x86, so help combine not create
10612 ;;
10613 ;;      seta    %al
10614 ;;      testb   %al, %al
10615 ;;      sete    %al
10616
10617 (define_split
10618   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10619         (ne:QI (match_operator 1 "ix86_comparison_operator"
10620                  [(reg FLAGS_REG) (const_int 0)])
10621             (const_int 0)))]
10622   ""
10623   [(set (match_dup 0) (match_dup 1))]
10624   "PUT_MODE (operands[1], QImode);")
10625
10626 (define_split
10627   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10628         (ne:QI (match_operator 1 "ix86_comparison_operator"
10629                  [(reg FLAGS_REG) (const_int 0)])
10630             (const_int 0)))]
10631   ""
10632   [(set (match_dup 0) (match_dup 1))]
10633   "PUT_MODE (operands[1], QImode);")
10634
10635 (define_split
10636   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10637         (eq:QI (match_operator 1 "ix86_comparison_operator"
10638                  [(reg FLAGS_REG) (const_int 0)])
10639             (const_int 0)))]
10640   ""
10641   [(set (match_dup 0) (match_dup 1))]
10642 {
10643   rtx new_op1 = copy_rtx (operands[1]);
10644   operands[1] = new_op1;
10645   PUT_MODE (new_op1, QImode);
10646   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10647                                              GET_MODE (XEXP (new_op1, 0))));
10648
10649   /* Make sure that (a) the CCmode we have for the flags is strong
10650      enough for the reversed compare or (b) we have a valid FP compare.  */
10651   if (! ix86_comparison_operator (new_op1, VOIDmode))
10652     FAIL;
10653 })
10654
10655 (define_split
10656   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10657         (eq:QI (match_operator 1 "ix86_comparison_operator"
10658                  [(reg FLAGS_REG) (const_int 0)])
10659             (const_int 0)))]
10660   ""
10661   [(set (match_dup 0) (match_dup 1))]
10662 {
10663   rtx new_op1 = copy_rtx (operands[1]);
10664   operands[1] = new_op1;
10665   PUT_MODE (new_op1, QImode);
10666   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10667                                              GET_MODE (XEXP (new_op1, 0))));
10668
10669   /* Make sure that (a) the CCmode we have for the flags is strong
10670      enough for the reversed compare or (b) we have a valid FP compare.  */
10671   if (! ix86_comparison_operator (new_op1, VOIDmode))
10672     FAIL;
10673 })
10674
10675 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10676 ;; subsequent logical operations are used to imitate conditional moves.
10677 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10678 ;; it directly.
10679
10680 (define_insn "setcc_<mode>_sse"
10681   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10682         (match_operator:MODEF 3 "sse_comparison_operator"
10683           [(match_operand:MODEF 1 "register_operand" "0,x")
10684            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10685   "SSE_FLOAT_MODE_P (<MODE>mode)"
10686   "@
10687    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10688    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10689   [(set_attr "isa" "noavx,avx")
10690    (set_attr "type" "ssecmp")
10691    (set_attr "length_immediate" "1")
10692    (set_attr "prefix" "orig,vex")
10693    (set_attr "mode" "<MODE>")])
10694 \f
10695 ;; Basic conditional jump instructions.
10696 ;; We ignore the overflow flag for signed branch instructions.
10697
10698 (define_insn "*jcc_1"
10699   [(set (pc)
10700         (if_then_else (match_operator 1 "ix86_comparison_operator"
10701                                       [(reg FLAGS_REG) (const_int 0)])
10702                       (label_ref (match_operand 0 "" ""))
10703                       (pc)))]
10704   ""
10705   "%+j%C1\t%l0"
10706   [(set_attr "type" "ibr")
10707    (set_attr "modrm" "0")
10708    (set (attr "length")
10709            (if_then_else (and (ge (minus (match_dup 0) (pc))
10710                                   (const_int -126))
10711                               (lt (minus (match_dup 0) (pc))
10712                                   (const_int 128)))
10713              (const_int 2)
10714              (const_int 6)))])
10715
10716 (define_insn "*jcc_2"
10717   [(set (pc)
10718         (if_then_else (match_operator 1 "ix86_comparison_operator"
10719                                       [(reg FLAGS_REG) (const_int 0)])
10720                       (pc)
10721                       (label_ref (match_operand 0 "" ""))))]
10722   ""
10723   "%+j%c1\t%l0"
10724   [(set_attr "type" "ibr")
10725    (set_attr "modrm" "0")
10726    (set (attr "length")
10727            (if_then_else (and (ge (minus (match_dup 0) (pc))
10728                                   (const_int -126))
10729                               (lt (minus (match_dup 0) (pc))
10730                                   (const_int 128)))
10731              (const_int 2)
10732              (const_int 6)))])
10733
10734 ;; In general it is not safe to assume too much about CCmode registers,
10735 ;; so simplify-rtx stops when it sees a second one.  Under certain
10736 ;; conditions this is safe on x86, so help combine not create
10737 ;;
10738 ;;      seta    %al
10739 ;;      testb   %al, %al
10740 ;;      je      Lfoo
10741
10742 (define_split
10743   [(set (pc)
10744         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10745                                       [(reg FLAGS_REG) (const_int 0)])
10746                           (const_int 0))
10747                       (label_ref (match_operand 1 "" ""))
10748                       (pc)))]
10749   ""
10750   [(set (pc)
10751         (if_then_else (match_dup 0)
10752                       (label_ref (match_dup 1))
10753                       (pc)))]
10754   "PUT_MODE (operands[0], VOIDmode);")
10755
10756 (define_split
10757   [(set (pc)
10758         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10759                                       [(reg FLAGS_REG) (const_int 0)])
10760                           (const_int 0))
10761                       (label_ref (match_operand 1 "" ""))
10762                       (pc)))]
10763   ""
10764   [(set (pc)
10765         (if_then_else (match_dup 0)
10766                       (label_ref (match_dup 1))
10767                       (pc)))]
10768 {
10769   rtx new_op0 = copy_rtx (operands[0]);
10770   operands[0] = new_op0;
10771   PUT_MODE (new_op0, VOIDmode);
10772   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10773                                              GET_MODE (XEXP (new_op0, 0))));
10774
10775   /* Make sure that (a) the CCmode we have for the flags is strong
10776      enough for the reversed compare or (b) we have a valid FP compare.  */
10777   if (! ix86_comparison_operator (new_op0, VOIDmode))
10778     FAIL;
10779 })
10780
10781 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10782 ;; pass generates from shift insn with QImode operand.  Actually, the mode
10783 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10784 ;; appropriate modulo of the bit offset value.
10785
10786 (define_insn_and_split "*jcc_bt<mode>"
10787   [(set (pc)
10788         (if_then_else (match_operator 0 "bt_comparison_operator"
10789                         [(zero_extract:SWI48
10790                            (match_operand:SWI48 1 "register_operand" "r")
10791                            (const_int 1)
10792                            (zero_extend:SI
10793                              (match_operand:QI 2 "register_operand" "r")))
10794                          (const_int 0)])
10795                       (label_ref (match_operand 3 "" ""))
10796                       (pc)))
10797    (clobber (reg:CC FLAGS_REG))]
10798   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10799   "#"
10800   "&& 1"
10801   [(set (reg:CCC FLAGS_REG)
10802         (compare:CCC
10803           (zero_extract:SWI48
10804             (match_dup 1)
10805             (const_int 1)
10806             (match_dup 2))
10807           (const_int 0)))
10808    (set (pc)
10809         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10810                       (label_ref (match_dup 3))
10811                       (pc)))]
10812 {
10813   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10814
10815   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10816 })
10817
10818 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10819 ;; also for DImode, this is what combine produces.
10820 (define_insn_and_split "*jcc_bt<mode>_mask"
10821   [(set (pc)
10822         (if_then_else (match_operator 0 "bt_comparison_operator"
10823                         [(zero_extract:SWI48
10824                            (match_operand:SWI48 1 "register_operand" "r")
10825                            (const_int 1)
10826                            (and:SI
10827                              (match_operand:SI 2 "register_operand" "r")
10828                              (match_operand:SI 3 "const_int_operand" "n")))])
10829                       (label_ref (match_operand 4 "" ""))
10830                       (pc)))
10831    (clobber (reg:CC FLAGS_REG))]
10832   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10833    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10834       == GET_MODE_BITSIZE (<MODE>mode)-1"
10835   "#"
10836   "&& 1"
10837   [(set (reg:CCC FLAGS_REG)
10838         (compare:CCC
10839           (zero_extract:SWI48
10840             (match_dup 1)
10841             (const_int 1)
10842             (match_dup 2))
10843           (const_int 0)))
10844    (set (pc)
10845         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10846                       (label_ref (match_dup 4))
10847                       (pc)))]
10848 {
10849   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10850
10851   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10852 })
10853
10854 (define_insn_and_split "*jcc_btsi_1"
10855   [(set (pc)
10856         (if_then_else (match_operator 0 "bt_comparison_operator"
10857                         [(and:SI
10858                            (lshiftrt:SI
10859                              (match_operand:SI 1 "register_operand" "r")
10860                              (match_operand:QI 2 "register_operand" "r"))
10861                            (const_int 1))
10862                          (const_int 0)])
10863                       (label_ref (match_operand 3 "" ""))
10864                       (pc)))
10865    (clobber (reg:CC FLAGS_REG))]
10866   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10867   "#"
10868   "&& 1"
10869   [(set (reg:CCC FLAGS_REG)
10870         (compare:CCC
10871           (zero_extract:SI
10872             (match_dup 1)
10873             (const_int 1)
10874             (match_dup 2))
10875           (const_int 0)))
10876    (set (pc)
10877         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10878                       (label_ref (match_dup 3))
10879                       (pc)))]
10880 {
10881   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10882
10883   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10884 })
10885
10886 ;; avoid useless masking of bit offset operand
10887 (define_insn_and_split "*jcc_btsi_mask_1"
10888   [(set (pc)
10889         (if_then_else
10890           (match_operator 0 "bt_comparison_operator"
10891             [(and:SI
10892                (lshiftrt:SI
10893                  (match_operand:SI 1 "register_operand" "r")
10894                  (subreg:QI
10895                    (and:SI
10896                      (match_operand:SI 2 "register_operand" "r")
10897                      (match_operand:SI 3 "const_int_operand" "n")) 0))
10898                (const_int 1))
10899              (const_int 0)])
10900           (label_ref (match_operand 4 "" ""))
10901           (pc)))
10902    (clobber (reg:CC FLAGS_REG))]
10903   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10904    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10905   "#"
10906   "&& 1"
10907   [(set (reg:CCC FLAGS_REG)
10908         (compare:CCC
10909           (zero_extract:SI
10910             (match_dup 1)
10911             (const_int 1)
10912             (match_dup 2))
10913           (const_int 0)))
10914    (set (pc)
10915         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10916                       (label_ref (match_dup 4))
10917                       (pc)))]
10918   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10919
10920 ;; Define combination compare-and-branch fp compare instructions to help
10921 ;; combine.
10922
10923 (define_insn "*fp_jcc_1_387"
10924   [(set (pc)
10925         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10926                         [(match_operand 1 "register_operand" "f")
10927                          (match_operand 2 "nonimmediate_operand" "fm")])
10928           (label_ref (match_operand 3 "" ""))
10929           (pc)))
10930    (clobber (reg:CCFP FPSR_REG))
10931    (clobber (reg:CCFP FLAGS_REG))
10932    (clobber (match_scratch:HI 4 "=a"))]
10933   "TARGET_80387
10934    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10935    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10936    && SELECT_CC_MODE (GET_CODE (operands[0]),
10937                       operands[1], operands[2]) == CCFPmode
10938    && !TARGET_CMOVE"
10939   "#")
10940
10941 (define_insn "*fp_jcc_1r_387"
10942   [(set (pc)
10943         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10944                         [(match_operand 1 "register_operand" "f")
10945                          (match_operand 2 "nonimmediate_operand" "fm")])
10946           (pc)
10947           (label_ref (match_operand 3 "" ""))))
10948    (clobber (reg:CCFP FPSR_REG))
10949    (clobber (reg:CCFP FLAGS_REG))
10950    (clobber (match_scratch:HI 4 "=a"))]
10951   "TARGET_80387
10952    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10953    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10954    && SELECT_CC_MODE (GET_CODE (operands[0]),
10955                       operands[1], operands[2]) == CCFPmode
10956    && !TARGET_CMOVE"
10957   "#")
10958
10959 (define_insn "*fp_jcc_2_387"
10960   [(set (pc)
10961         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10962                         [(match_operand 1 "register_operand" "f")
10963                          (match_operand 2 "register_operand" "f")])
10964           (label_ref (match_operand 3 "" ""))
10965           (pc)))
10966    (clobber (reg:CCFP FPSR_REG))
10967    (clobber (reg:CCFP FLAGS_REG))
10968    (clobber (match_scratch:HI 4 "=a"))]
10969   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10970    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10971    && !TARGET_CMOVE"
10972   "#")
10973
10974 (define_insn "*fp_jcc_2r_387"
10975   [(set (pc)
10976         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10977                         [(match_operand 1 "register_operand" "f")
10978                          (match_operand 2 "register_operand" "f")])
10979           (pc)
10980           (label_ref (match_operand 3 "" ""))))
10981    (clobber (reg:CCFP FPSR_REG))
10982    (clobber (reg:CCFP FLAGS_REG))
10983    (clobber (match_scratch:HI 4 "=a"))]
10984   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10985    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10986    && !TARGET_CMOVE"
10987   "#")
10988
10989 (define_insn "*fp_jcc_3_387"
10990   [(set (pc)
10991         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10992                         [(match_operand 1 "register_operand" "f")
10993                          (match_operand 2 "const0_operand" "")])
10994           (label_ref (match_operand 3 "" ""))
10995           (pc)))
10996    (clobber (reg:CCFP FPSR_REG))
10997    (clobber (reg:CCFP FLAGS_REG))
10998    (clobber (match_scratch:HI 4 "=a"))]
10999   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11000    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11001    && SELECT_CC_MODE (GET_CODE (operands[0]),
11002                       operands[1], operands[2]) == CCFPmode
11003    && !TARGET_CMOVE"
11004   "#")
11005
11006 (define_split
11007   [(set (pc)
11008         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11009                         [(match_operand 1 "register_operand" "")
11010                          (match_operand 2 "nonimmediate_operand" "")])
11011           (match_operand 3 "" "")
11012           (match_operand 4 "" "")))
11013    (clobber (reg:CCFP FPSR_REG))
11014    (clobber (reg:CCFP FLAGS_REG))]
11015   "reload_completed"
11016   [(const_int 0)]
11017 {
11018   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11019                         operands[3], operands[4], NULL_RTX, NULL_RTX);
11020   DONE;
11021 })
11022
11023 (define_split
11024   [(set (pc)
11025         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11026                         [(match_operand 1 "register_operand" "")
11027                          (match_operand 2 "general_operand" "")])
11028           (match_operand 3 "" "")
11029           (match_operand 4 "" "")))
11030    (clobber (reg:CCFP FPSR_REG))
11031    (clobber (reg:CCFP FLAGS_REG))
11032    (clobber (match_scratch:HI 5 "=a"))]
11033   "reload_completed"
11034   [(const_int 0)]
11035 {
11036   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11037                         operands[3], operands[4], operands[5], NULL_RTX);
11038   DONE;
11039 })
11040
11041 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11042 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11043 ;; with a precedence over other operators and is always put in the first
11044 ;; place. Swap condition and operands to match ficom instruction.
11045
11046 (define_insn "*fp_jcc_4_<mode>_387"
11047   [(set (pc)
11048         (if_then_else
11049           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11050             [(match_operator 1 "float_operator"
11051               [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11052              (match_operand 3 "register_operand" "f,f")])
11053           (label_ref (match_operand 4 "" ""))
11054           (pc)))
11055    (clobber (reg:CCFP FPSR_REG))
11056    (clobber (reg:CCFP FLAGS_REG))
11057    (clobber (match_scratch:HI 5 "=a,a"))]
11058   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11059    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11060    && GET_MODE (operands[1]) == GET_MODE (operands[3])
11061    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11062    && !TARGET_CMOVE"
11063   "#")
11064
11065 (define_split
11066   [(set (pc)
11067         (if_then_else
11068           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11069             [(match_operator 1 "float_operator"
11070               [(match_operand:SWI24 2 "memory_operand" "")])
11071              (match_operand 3 "register_operand" "")])
11072           (match_operand 4 "" "")
11073           (match_operand 5 "" "")))
11074    (clobber (reg:CCFP FPSR_REG))
11075    (clobber (reg:CCFP FLAGS_REG))
11076    (clobber (match_scratch:HI 6 "=a"))]
11077   "reload_completed"
11078   [(const_int 0)]
11079 {
11080   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11081
11082   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11083                         operands[3], operands[7],
11084                         operands[4], operands[5], operands[6], NULL_RTX);
11085   DONE;
11086 })
11087
11088 ;; %%% Kill this when reload knows how to do it.
11089 (define_split
11090   [(set (pc)
11091         (if_then_else
11092           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11093             [(match_operator 1 "float_operator"
11094               [(match_operand:SWI24 2 "register_operand" "")])
11095              (match_operand 3 "register_operand" "")])
11096           (match_operand 4 "" "")
11097           (match_operand 5 "" "")))
11098    (clobber (reg:CCFP FPSR_REG))
11099    (clobber (reg:CCFP FLAGS_REG))
11100    (clobber (match_scratch:HI 6 "=a"))]
11101   "reload_completed"
11102   [(const_int 0)]
11103 {
11104   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11105   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11106
11107   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11108                         operands[3], operands[7],
11109                         operands[4], operands[5], operands[6], operands[2]);
11110   DONE;
11111 })
11112 \f
11113 ;; Unconditional and other jump instructions
11114
11115 (define_insn "jump"
11116   [(set (pc)
11117         (label_ref (match_operand 0 "" "")))]
11118   ""
11119   "jmp\t%l0"
11120   [(set_attr "type" "ibr")
11121    (set (attr "length")
11122            (if_then_else (and (ge (minus (match_dup 0) (pc))
11123                                   (const_int -126))
11124                               (lt (minus (match_dup 0) (pc))
11125                                   (const_int 128)))
11126              (const_int 2)
11127              (const_int 5)))
11128    (set_attr "modrm" "0")])
11129
11130 (define_expand "indirect_jump"
11131   [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11132
11133 (define_insn "*indirect_jump"
11134   [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11135   ""
11136   "jmp\t%A0"
11137   [(set_attr "type" "ibr")
11138    (set_attr "length_immediate" "0")])
11139
11140 (define_expand "tablejump"
11141   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11142               (use (label_ref (match_operand 1 "" "")))])]
11143   ""
11144 {
11145   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11146      relative.  Convert the relative address to an absolute address.  */
11147   if (flag_pic)
11148     {
11149       rtx op0, op1;
11150       enum rtx_code code;
11151
11152       /* We can't use @GOTOFF for text labels on VxWorks;
11153          see gotoff_operand.  */
11154       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11155         {
11156           code = PLUS;
11157           op0 = operands[0];
11158           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11159         }
11160       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11161         {
11162           code = PLUS;
11163           op0 = operands[0];
11164           op1 = pic_offset_table_rtx;
11165         }
11166       else
11167         {
11168           code = MINUS;
11169           op0 = pic_offset_table_rtx;
11170           op1 = operands[0];
11171         }
11172
11173       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11174                                          OPTAB_DIRECT);
11175     }
11176   else if (TARGET_X32)
11177     operands[0] = convert_memory_address (Pmode, operands[0]);
11178 })
11179
11180 (define_insn "*tablejump_1"
11181   [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11182    (use (label_ref (match_operand 1 "" "")))]
11183   ""
11184   "jmp\t%A0"
11185   [(set_attr "type" "ibr")
11186    (set_attr "length_immediate" "0")])
11187 \f
11188 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11189
11190 (define_peephole2
11191   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11192    (set (match_operand:QI 1 "register_operand" "")
11193         (match_operator:QI 2 "ix86_comparison_operator"
11194           [(reg FLAGS_REG) (const_int 0)]))
11195    (set (match_operand 3 "q_regs_operand" "")
11196         (zero_extend (match_dup 1)))]
11197   "(peep2_reg_dead_p (3, operands[1])
11198     || operands_match_p (operands[1], operands[3]))
11199    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11200   [(set (match_dup 4) (match_dup 0))
11201    (set (strict_low_part (match_dup 5))
11202         (match_dup 2))]
11203 {
11204   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11205   operands[5] = gen_lowpart (QImode, operands[3]);
11206   ix86_expand_clear (operands[3]);
11207 })
11208
11209 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11210
11211 (define_peephole2
11212   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11213    (set (match_operand:QI 1 "register_operand" "")
11214         (match_operator:QI 2 "ix86_comparison_operator"
11215           [(reg FLAGS_REG) (const_int 0)]))
11216    (parallel [(set (match_operand 3 "q_regs_operand" "")
11217                    (zero_extend (match_dup 1)))
11218               (clobber (reg:CC FLAGS_REG))])]
11219   "(peep2_reg_dead_p (3, operands[1])
11220     || operands_match_p (operands[1], operands[3]))
11221    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11222   [(set (match_dup 4) (match_dup 0))
11223    (set (strict_low_part (match_dup 5))
11224         (match_dup 2))]
11225 {
11226   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11227   operands[5] = gen_lowpart (QImode, operands[3]);
11228   ix86_expand_clear (operands[3]);
11229 })
11230 \f
11231 ;; Call instructions.
11232
11233 ;; The predicates normally associated with named expanders are not properly
11234 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11235 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11236
11237 ;; P6 processors will jump to the address after the decrement when %esp
11238 ;; is used as a call operand, so they will execute return address as a code.
11239 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11240
11241 ;; Register constraint for call instruction.
11242 (define_mode_attr c [(SI "l") (DI "r")])
11243
11244 ;; Call subroutine returning no value.
11245
11246 (define_expand "call"
11247   [(call (match_operand:QI 0 "" "")
11248          (match_operand 1 "" ""))
11249    (use (match_operand 2 "" ""))]
11250   ""
11251 {
11252   ix86_expand_call (NULL, operands[0], operands[1],
11253                     operands[2], NULL, false);
11254   DONE;
11255 })
11256
11257 (define_expand "sibcall"
11258   [(call (match_operand:QI 0 "" "")
11259          (match_operand 1 "" ""))
11260    (use (match_operand 2 "" ""))]
11261   ""
11262 {
11263   ix86_expand_call (NULL, operands[0], operands[1],
11264                     operands[2], NULL, true);
11265   DONE;
11266 })
11267
11268 (define_insn_and_split "*call_vzeroupper"
11269   [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11270          (match_operand 1 "" ""))
11271    (unspec [(match_operand 2 "const_int_operand" "")]
11272            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11273   "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11274   "#"
11275   "&& reload_completed"
11276   [(const_int 0)]
11277   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11278   [(set_attr "type" "call")])
11279
11280 (define_insn "*call"
11281   [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11282          (match_operand 1 "" ""))]
11283   "!SIBLING_CALL_P (insn)"
11284   "* return ix86_output_call_insn (insn, operands[0]);"
11285   [(set_attr "type" "call")])
11286
11287 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11288   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11289          (match_operand 1 "" ""))
11290    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11291    (clobber (reg:TI XMM6_REG))
11292    (clobber (reg:TI XMM7_REG))
11293    (clobber (reg:TI XMM8_REG))
11294    (clobber (reg:TI XMM9_REG))
11295    (clobber (reg:TI XMM10_REG))
11296    (clobber (reg:TI XMM11_REG))
11297    (clobber (reg:TI XMM12_REG))
11298    (clobber (reg:TI XMM13_REG))
11299    (clobber (reg:TI XMM14_REG))
11300    (clobber (reg:TI XMM15_REG))
11301    (clobber (reg:DI SI_REG))
11302    (clobber (reg:DI DI_REG))
11303    (unspec [(match_operand 2 "const_int_operand" "")]
11304            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11305   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11306   "#"
11307   "&& reload_completed"
11308   [(const_int 0)]
11309   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11310   [(set_attr "type" "call")])
11311
11312 (define_insn "*call_rex64_ms_sysv"
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   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11329   "* return ix86_output_call_insn (insn, operands[0]);"
11330   [(set_attr "type" "call")])
11331
11332 (define_insn_and_split "*sibcall_vzeroupper"
11333   [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11334          (match_operand 1 "" ""))
11335    (unspec [(match_operand 2 "const_int_operand" "")]
11336            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11337   "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11338   "#"
11339   "&& reload_completed"
11340   [(const_int 0)]
11341   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11342   [(set_attr "type" "call")])
11343
11344 (define_insn "*sibcall"
11345   [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11346          (match_operand 1 "" ""))]
11347   "SIBLING_CALL_P (insn)"
11348   "* return ix86_output_call_insn (insn, operands[0]);"
11349   [(set_attr "type" "call")])
11350
11351 (define_expand "call_pop"
11352   [(parallel [(call (match_operand:QI 0 "" "")
11353                     (match_operand:SI 1 "" ""))
11354               (set (reg:SI SP_REG)
11355                    (plus:SI (reg:SI SP_REG)
11356                             (match_operand:SI 3 "" "")))])]
11357   "!TARGET_64BIT"
11358 {
11359   ix86_expand_call (NULL, operands[0], operands[1],
11360                     operands[2], operands[3], false);
11361   DONE;
11362 })
11363
11364 (define_insn_and_split "*call_pop_vzeroupper"
11365   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11366          (match_operand:SI 1 "" ""))
11367    (set (reg:SI SP_REG)
11368         (plus:SI (reg:SI SP_REG)
11369                  (match_operand:SI 2 "immediate_operand" "i")))
11370    (unspec [(match_operand 3 "const_int_operand" "")]
11371            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11372   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11373   "#"
11374   "&& reload_completed"
11375   [(const_int 0)]
11376   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11377   [(set_attr "type" "call")])
11378
11379 (define_insn "*call_pop"
11380   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11381          (match_operand 1 "" ""))
11382    (set (reg:SI SP_REG)
11383         (plus:SI (reg:SI SP_REG)
11384                  (match_operand:SI 2 "immediate_operand" "i")))]
11385   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11386   "* return ix86_output_call_insn (insn, operands[0]);"
11387   [(set_attr "type" "call")])
11388
11389 (define_insn_and_split "*sibcall_pop_vzeroupper"
11390   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11391          (match_operand 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 "*sibcall_pop"
11405   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
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 ;; Call subroutine, returning value in operand 0
11415
11416 (define_expand "call_value"
11417   [(set (match_operand 0 "" "")
11418         (call (match_operand:QI 1 "" "")
11419               (match_operand 2 "" "")))
11420    (use (match_operand 3 "" ""))]
11421   ""
11422 {
11423   ix86_expand_call (operands[0], operands[1], operands[2],
11424                     operands[3], NULL, false);
11425   DONE;
11426 })
11427
11428 (define_expand "sibcall_value"
11429   [(set (match_operand 0 "" "")
11430         (call (match_operand:QI 1 "" "")
11431               (match_operand 2 "" "")))
11432    (use (match_operand 3 "" ""))]
11433   ""
11434 {
11435   ix86_expand_call (operands[0], operands[1], operands[2],
11436                     operands[3], NULL, true);
11437   DONE;
11438 })
11439
11440 (define_insn_and_split "*call_value_vzeroupper"
11441   [(set (match_operand 0 "" "")
11442         (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11443               (match_operand 2 "" "")))
11444    (unspec [(match_operand 3 "const_int_operand" "")]
11445            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11446   "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11447   "#"
11448   "&& reload_completed"
11449   [(const_int 0)]
11450   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11451   [(set_attr "type" "callv")])
11452
11453 (define_insn "*call_value"
11454   [(set (match_operand 0 "" "")
11455         (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11456               (match_operand 2 "" "")))]
11457   "!SIBLING_CALL_P (insn)"
11458   "* return ix86_output_call_insn (insn, operands[1]);"
11459   [(set_attr "type" "callv")])
11460
11461 (define_insn_and_split "*sibcall_value_vzeroupper"
11462   [(set (match_operand 0 "" "")
11463         (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11464               (match_operand 2 "" "")))
11465    (unspec [(match_operand 3 "const_int_operand" "")]
11466            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11467   "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11468   "#"
11469   "&& reload_completed"
11470   [(const_int 0)]
11471   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11472   [(set_attr "type" "callv")])
11473
11474 (define_insn "*sibcall_value"
11475   [(set (match_operand 0 "" "")
11476         (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11477               (match_operand 2 "" "")))]
11478   "SIBLING_CALL_P (insn)"
11479   "* return ix86_output_call_insn (insn, operands[1]);"
11480   [(set_attr "type" "callv")])
11481
11482 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11483   [(set (match_operand 0 "" "")
11484         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11485               (match_operand 2 "" "")))
11486    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11487    (clobber (reg:TI XMM6_REG))
11488    (clobber (reg:TI XMM7_REG))
11489    (clobber (reg:TI XMM8_REG))
11490    (clobber (reg:TI XMM9_REG))
11491    (clobber (reg:TI XMM10_REG))
11492    (clobber (reg:TI XMM11_REG))
11493    (clobber (reg:TI XMM12_REG))
11494    (clobber (reg:TI XMM13_REG))
11495    (clobber (reg:TI XMM14_REG))
11496    (clobber (reg:TI XMM15_REG))
11497    (clobber (reg:DI SI_REG))
11498    (clobber (reg:DI DI_REG))
11499    (unspec [(match_operand 3 "const_int_operand" "")]
11500            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11501   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11502   "#"
11503   "&& reload_completed"
11504   [(const_int 0)]
11505   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11506   [(set_attr "type" "callv")])
11507
11508 (define_insn "*call_value_rex64_ms_sysv"
11509   [(set (match_operand 0 "" "")
11510         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11511               (match_operand 2 "" "")))
11512    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11513    (clobber (reg:TI XMM6_REG))
11514    (clobber (reg:TI XMM7_REG))
11515    (clobber (reg:TI XMM8_REG))
11516    (clobber (reg:TI XMM9_REG))
11517    (clobber (reg:TI XMM10_REG))
11518    (clobber (reg:TI XMM11_REG))
11519    (clobber (reg:TI XMM12_REG))
11520    (clobber (reg:TI XMM13_REG))
11521    (clobber (reg:TI XMM14_REG))
11522    (clobber (reg:TI XMM15_REG))
11523    (clobber (reg:DI SI_REG))
11524    (clobber (reg:DI DI_REG))]
11525   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11526   "* return ix86_output_call_insn (insn, operands[1]);"
11527   [(set_attr "type" "callv")])
11528
11529 (define_expand "call_value_pop"
11530   [(parallel [(set (match_operand 0 "" "")
11531                    (call (match_operand:QI 1 "" "")
11532                          (match_operand:SI 2 "" "")))
11533               (set (reg:SI SP_REG)
11534                    (plus:SI (reg:SI SP_REG)
11535                             (match_operand:SI 4 "" "")))])]
11536   "!TARGET_64BIT"
11537 {
11538   ix86_expand_call (operands[0], operands[1], operands[2],
11539                     operands[3], operands[4], false);
11540   DONE;
11541 })
11542
11543 (define_insn_and_split "*call_value_pop_vzeroupper"
11544   [(set (match_operand 0 "" "")
11545         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11546               (match_operand 2 "" "")))
11547    (set (reg:SI SP_REG)
11548         (plus:SI (reg:SI SP_REG)
11549                  (match_operand:SI 3 "immediate_operand" "i")))
11550    (unspec [(match_operand 4 "const_int_operand" "")]
11551            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11552   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11553   "#"
11554   "&& reload_completed"
11555   [(const_int 0)]
11556   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11557   [(set_attr "type" "callv")])
11558
11559 (define_insn "*call_value_pop"
11560   [(set (match_operand 0 "" "")
11561         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11562               (match_operand 2 "" "")))
11563    (set (reg:SI SP_REG)
11564         (plus:SI (reg:SI SP_REG)
11565                  (match_operand:SI 3 "immediate_operand" "i")))]
11566   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11567   "* return ix86_output_call_insn (insn, operands[1]);"
11568   [(set_attr "type" "callv")])
11569
11570 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11571   [(set (match_operand 0 "" "")
11572         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11573               (match_operand 2 "" "")))
11574    (set (reg:SI SP_REG)
11575         (plus:SI (reg:SI SP_REG)
11576                  (match_operand:SI 3 "immediate_operand" "i")))
11577    (unspec [(match_operand 4 "const_int_operand" "")]
11578            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11579   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11580   "#"
11581   "&& reload_completed"
11582   [(const_int 0)]
11583   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11584   [(set_attr "type" "callv")])
11585
11586 (define_insn "*sibcall_value_pop"
11587   [(set (match_operand 0 "" "")
11588         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11589               (match_operand 2 "" "")))
11590    (set (reg:SI SP_REG)
11591         (plus:SI (reg:SI SP_REG)
11592                  (match_operand:SI 3 "immediate_operand" "i")))]
11593   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11594   "* return ix86_output_call_insn (insn, operands[1]);"
11595   [(set_attr "type" "callv")])
11596
11597 ;; Call subroutine returning any type.
11598
11599 (define_expand "untyped_call"
11600   [(parallel [(call (match_operand 0 "" "")
11601                     (const_int 0))
11602               (match_operand 1 "" "")
11603               (match_operand 2 "" "")])]
11604   ""
11605 {
11606   int i;
11607
11608   /* In order to give reg-stack an easier job in validating two
11609      coprocessor registers as containing a possible return value,
11610      simply pretend the untyped call returns a complex long double
11611      value. 
11612
11613      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11614      and should have the default ABI.  */
11615
11616   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11617                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11618                     operands[0], const0_rtx,
11619                     GEN_INT ((TARGET_64BIT
11620                               ? (ix86_abi == SYSV_ABI
11621                                  ? X86_64_SSE_REGPARM_MAX
11622                                  : X86_64_MS_SSE_REGPARM_MAX)
11623                               : X86_32_SSE_REGPARM_MAX)
11624                              - 1),
11625                     NULL, false);
11626
11627   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11628     {
11629       rtx set = XVECEXP (operands[2], 0, i);
11630       emit_move_insn (SET_DEST (set), SET_SRC (set));
11631     }
11632
11633   /* The optimizer does not know that the call sets the function value
11634      registers we stored in the result block.  We avoid problems by
11635      claiming that all hard registers are used and clobbered at this
11636      point.  */
11637   emit_insn (gen_blockage ());
11638
11639   DONE;
11640 })
11641 \f
11642 ;; Prologue and epilogue instructions
11643
11644 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11645 ;; all of memory.  This blocks insns from being moved across this point.
11646
11647 (define_insn "blockage"
11648   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11649   ""
11650   ""
11651   [(set_attr "length" "0")])
11652
11653 ;; Do not schedule instructions accessing memory across this point.
11654
11655 (define_expand "memory_blockage"
11656   [(set (match_dup 0)
11657         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11658   ""
11659 {
11660   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11661   MEM_VOLATILE_P (operands[0]) = 1;
11662 })
11663
11664 (define_insn "*memory_blockage"
11665   [(set (match_operand:BLK 0 "" "")
11666         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11667   ""
11668   ""
11669   [(set_attr "length" "0")])
11670
11671 ;; As USE insns aren't meaningful after reload, this is used instead
11672 ;; to prevent deleting instructions setting registers for PIC code
11673 (define_insn "prologue_use"
11674   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11675   ""
11676   ""
11677   [(set_attr "length" "0")])
11678
11679 ;; Insn emitted into the body of a function to return from a function.
11680 ;; This is only done if the function's epilogue is known to be simple.
11681 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11682
11683 (define_expand "return"
11684   [(simple_return)]
11685   "ix86_can_use_return_insn_p ()"
11686 {
11687   ix86_maybe_emit_epilogue_vzeroupper ();
11688   if (crtl->args.pops_args)
11689     {
11690       rtx popc = GEN_INT (crtl->args.pops_args);
11691       emit_jump_insn (gen_simple_return_pop_internal (popc));
11692       DONE;
11693     }
11694 })
11695
11696 ;; We need to disable this for TARGET_SEH, as otherwise
11697 ;; shrink-wrapped prologue gets enabled too.  This might exceed
11698 ;; the maximum size of prologue in unwind information.
11699
11700 (define_expand "simple_return"
11701   [(simple_return)]
11702   "!TARGET_SEH"
11703 {
11704   ix86_maybe_emit_epilogue_vzeroupper ();
11705   if (crtl->args.pops_args)
11706     {
11707       rtx popc = GEN_INT (crtl->args.pops_args);
11708       emit_jump_insn (gen_simple_return_pop_internal (popc));
11709       DONE;
11710     }
11711 })
11712
11713 (define_insn "simple_return_internal"
11714   [(simple_return)]
11715   "reload_completed"
11716   "ret"
11717   [(set_attr "length" "1")
11718    (set_attr "atom_unit" "jeu")
11719    (set_attr "length_immediate" "0")
11720    (set_attr "modrm" "0")])
11721
11722 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11723 ;; instruction Athlon and K8 have.
11724
11725 (define_insn "simple_return_internal_long"
11726   [(simple_return)
11727    (unspec [(const_int 0)] UNSPEC_REP)]
11728   "reload_completed"
11729   "rep\;ret"
11730   [(set_attr "length" "2")
11731    (set_attr "atom_unit" "jeu")
11732    (set_attr "length_immediate" "0")
11733    (set_attr "prefix_rep" "1")
11734    (set_attr "modrm" "0")])
11735
11736 (define_insn "simple_return_pop_internal"
11737   [(simple_return)
11738    (use (match_operand:SI 0 "const_int_operand" ""))]
11739   "reload_completed"
11740   "ret\t%0"
11741   [(set_attr "length" "3")
11742    (set_attr "atom_unit" "jeu")
11743    (set_attr "length_immediate" "2")
11744    (set_attr "modrm" "0")])
11745
11746 (define_insn "simple_return_indirect_internal"
11747   [(simple_return)
11748    (use (match_operand:SI 0 "register_operand" "r"))]
11749   "reload_completed"
11750   "jmp\t%A0"
11751   [(set_attr "type" "ibr")
11752    (set_attr "length_immediate" "0")])
11753
11754 (define_insn "nop"
11755   [(const_int 0)]
11756   ""
11757   "nop"
11758   [(set_attr "length" "1")
11759    (set_attr "length_immediate" "0")
11760    (set_attr "modrm" "0")])
11761
11762 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
11763 (define_insn "nops"
11764   [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11765                     UNSPECV_NOPS)]
11766   "reload_completed"
11767 {
11768   int num = INTVAL (operands[0]);
11769
11770   gcc_assert (num >= 1 && num <= 8);
11771
11772   while (num--)
11773     fputs ("\tnop\n", asm_out_file);
11774
11775   return "";
11776 }
11777   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11778    (set_attr "length_immediate" "0")
11779    (set_attr "modrm" "0")])
11780
11781 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11782 ;; branch prediction penalty for the third jump in a 16-byte
11783 ;; block on K8.
11784
11785 (define_insn "pad"
11786   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11787   ""
11788 {
11789 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11790   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11791 #else
11792   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11793      The align insn is used to avoid 3 jump instructions in the row to improve
11794      branch prediction and the benefits hardly outweigh the cost of extra 8
11795      nops on the average inserted by full alignment pseudo operation.  */
11796 #endif
11797   return "";
11798 }
11799   [(set_attr "length" "16")])
11800
11801 (define_expand "prologue"
11802   [(const_int 0)]
11803   ""
11804   "ix86_expand_prologue (); DONE;")
11805
11806 (define_insn "set_got"
11807   [(set (match_operand:SI 0 "register_operand" "=r")
11808         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11809    (clobber (reg:CC FLAGS_REG))]
11810   "!TARGET_64BIT"
11811   "* return output_set_got (operands[0], NULL_RTX);"
11812   [(set_attr "type" "multi")
11813    (set_attr "length" "12")])
11814
11815 (define_insn "set_got_labelled"
11816   [(set (match_operand:SI 0 "register_operand" "=r")
11817         (unspec:SI [(label_ref (match_operand 1 "" ""))]
11818          UNSPEC_SET_GOT))
11819    (clobber (reg:CC FLAGS_REG))]
11820   "!TARGET_64BIT"
11821   "* return output_set_got (operands[0], operands[1]);"
11822   [(set_attr "type" "multi")
11823    (set_attr "length" "12")])
11824
11825 (define_insn "set_got_rex64"
11826   [(set (match_operand:DI 0 "register_operand" "=r")
11827         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11828   "TARGET_64BIT"
11829   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11830   [(set_attr "type" "lea")
11831    (set_attr "length_address" "4")
11832    (set_attr "mode" "DI")])
11833
11834 (define_insn "set_rip_rex64"
11835   [(set (match_operand:DI 0 "register_operand" "=r")
11836         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11837   "TARGET_64BIT"
11838   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11839   [(set_attr "type" "lea")
11840    (set_attr "length_address" "4")
11841    (set_attr "mode" "DI")])
11842
11843 (define_insn "set_got_offset_rex64"
11844   [(set (match_operand:DI 0 "register_operand" "=r")
11845         (unspec:DI
11846           [(label_ref (match_operand 1 "" ""))]
11847           UNSPEC_SET_GOT_OFFSET))]
11848   "TARGET_LP64"
11849   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11850   [(set_attr "type" "imov")
11851    (set_attr "length_immediate" "0")
11852    (set_attr "length_address" "8")
11853    (set_attr "mode" "DI")])
11854
11855 (define_expand "epilogue"
11856   [(const_int 0)]
11857   ""
11858   "ix86_expand_epilogue (1); DONE;")
11859
11860 (define_expand "sibcall_epilogue"
11861   [(const_int 0)]
11862   ""
11863   "ix86_expand_epilogue (0); DONE;")
11864
11865 (define_expand "eh_return"
11866   [(use (match_operand 0 "register_operand" ""))]
11867   ""
11868 {
11869   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11870
11871   /* Tricky bit: we write the address of the handler to which we will
11872      be returning into someone else's stack frame, one word below the
11873      stack address we wish to restore.  */
11874   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11875   tmp = plus_constant (tmp, -UNITS_PER_WORD);
11876   tmp = gen_rtx_MEM (Pmode, tmp);
11877   emit_move_insn (tmp, ra);
11878
11879   emit_jump_insn (gen_eh_return_internal ());
11880   emit_barrier ();
11881   DONE;
11882 })
11883
11884 (define_insn_and_split "eh_return_internal"
11885   [(eh_return)]
11886   ""
11887   "#"
11888   "epilogue_completed"
11889   [(const_int 0)]
11890   "ix86_expand_epilogue (2); DONE;")
11891
11892 (define_insn "leave"
11893   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11894    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11895    (clobber (mem:BLK (scratch)))]
11896   "!TARGET_64BIT"
11897   "leave"
11898   [(set_attr "type" "leave")])
11899
11900 (define_insn "leave_rex64"
11901   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11902    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11903    (clobber (mem:BLK (scratch)))]
11904   "TARGET_64BIT"
11905   "leave"
11906   [(set_attr "type" "leave")])
11907 \f
11908 ;; Handle -fsplit-stack.
11909
11910 (define_expand "split_stack_prologue"
11911   [(const_int 0)]
11912   ""
11913 {
11914   ix86_expand_split_stack_prologue ();
11915   DONE;
11916 })
11917
11918 ;; In order to support the call/return predictor, we use a return
11919 ;; instruction which the middle-end doesn't see.
11920 (define_insn "split_stack_return"
11921   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11922                      UNSPECV_SPLIT_STACK_RETURN)]
11923   ""
11924 {
11925   if (operands[0] == const0_rtx)
11926     return "ret";
11927   else
11928     return "ret\t%0";
11929 }
11930   [(set_attr "atom_unit" "jeu")
11931    (set_attr "modrm" "0")
11932    (set (attr "length")
11933         (if_then_else (match_operand:SI 0 "const0_operand" "")
11934                       (const_int 1)
11935                       (const_int 3)))
11936    (set (attr "length_immediate")
11937         (if_then_else (match_operand:SI 0 "const0_operand" "")
11938                       (const_int 0)
11939                       (const_int 2)))])
11940
11941 ;; If there are operand 0 bytes available on the stack, jump to
11942 ;; operand 1.
11943
11944 (define_expand "split_stack_space_check"
11945   [(set (pc) (if_then_else
11946               (ltu (minus (reg SP_REG)
11947                           (match_operand 0 "register_operand" ""))
11948                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11949               (label_ref (match_operand 1 "" ""))
11950               (pc)))]
11951   ""
11952 {
11953   rtx reg, size, limit;
11954
11955   reg = gen_reg_rtx (Pmode);
11956   size = force_reg (Pmode, operands[0]);
11957   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11958   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11959                           UNSPEC_STACK_CHECK);
11960   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11961   ix86_expand_branch (GEU, reg, limit, operands[1]);
11962
11963   DONE;
11964 })
11965 \f
11966 ;; Bit manipulation instructions.
11967
11968 (define_expand "ffs<mode>2"
11969   [(set (match_dup 2) (const_int -1))
11970    (parallel [(set (reg:CCZ FLAGS_REG)
11971                    (compare:CCZ
11972                      (match_operand:SWI48 1 "nonimmediate_operand" "")
11973                      (const_int 0)))
11974               (set (match_operand:SWI48 0 "register_operand" "")
11975                    (ctz:SWI48 (match_dup 1)))])
11976    (set (match_dup 0) (if_then_else:SWI48
11977                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
11978                         (match_dup 2)
11979                         (match_dup 0)))
11980    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11981               (clobber (reg:CC FLAGS_REG))])]
11982   ""
11983 {
11984   if (<MODE>mode == SImode && !TARGET_CMOVE)
11985     {
11986       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11987       DONE;
11988     }
11989   operands[2] = gen_reg_rtx (<MODE>mode);
11990 })
11991
11992 (define_insn_and_split "ffssi2_no_cmove"
11993   [(set (match_operand:SI 0 "register_operand" "=r")
11994         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11995    (clobber (match_scratch:SI 2 "=&q"))
11996    (clobber (reg:CC FLAGS_REG))]
11997   "!TARGET_CMOVE"
11998   "#"
11999   "&& reload_completed"
12000   [(parallel [(set (reg:CCZ FLAGS_REG)
12001                    (compare:CCZ (match_dup 1) (const_int 0)))
12002               (set (match_dup 0) (ctz:SI (match_dup 1)))])
12003    (set (strict_low_part (match_dup 3))
12004         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12005    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12006               (clobber (reg:CC FLAGS_REG))])
12007    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12008               (clobber (reg:CC FLAGS_REG))])
12009    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12010               (clobber (reg:CC FLAGS_REG))])]
12011 {
12012   operands[3] = gen_lowpart (QImode, operands[2]);
12013   ix86_expand_clear (operands[2]);
12014 })
12015
12016 (define_insn "*ffs<mode>_1"
12017   [(set (reg:CCZ FLAGS_REG)
12018         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12019                      (const_int 0)))
12020    (set (match_operand:SWI48 0 "register_operand" "=r")
12021         (ctz:SWI48 (match_dup 1)))]
12022   ""
12023   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12024   [(set_attr "type" "alu1")
12025    (set_attr "prefix_0f" "1")
12026    (set_attr "mode" "<MODE>")])
12027
12028 (define_insn "ctz<mode>2"
12029   [(set (match_operand:SWI248 0 "register_operand" "=r")
12030         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12031    (clobber (reg:CC FLAGS_REG))]
12032   ""
12033 {
12034   if (TARGET_BMI)
12035     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12036   else
12037     return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12038 }
12039   [(set_attr "type" "alu1")
12040    (set_attr "prefix_0f" "1")
12041    (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12042    (set_attr "mode" "<MODE>")])
12043
12044 (define_expand "clz<mode>2"
12045   [(parallel
12046      [(set (match_operand:SWI248 0 "register_operand" "")
12047            (minus:SWI248
12048              (match_dup 2)
12049              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12050       (clobber (reg:CC FLAGS_REG))])
12051    (parallel
12052      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12053       (clobber (reg:CC FLAGS_REG))])]
12054   ""
12055 {
12056   if (TARGET_LZCNT)
12057     {
12058       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12059       DONE;
12060     }
12061   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12062 })
12063
12064 (define_insn "clz<mode>2_lzcnt"
12065   [(set (match_operand:SWI248 0 "register_operand" "=r")
12066         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12067    (clobber (reg:CC FLAGS_REG))]
12068   "TARGET_LZCNT"
12069   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12070   [(set_attr "prefix_rep" "1")
12071    (set_attr "type" "bitmanip")
12072    (set_attr "mode" "<MODE>")])
12073
12074 ;; BMI instructions.
12075 (define_insn "*bmi_andn_<mode>"
12076   [(set (match_operand:SWI48 0 "register_operand" "=r")
12077         (and:SWI48
12078           (not:SWI48
12079             (match_operand:SWI48 1 "register_operand" "r"))
12080             (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12081    (clobber (reg:CC FLAGS_REG))]
12082   "TARGET_BMI"
12083   "andn\t{%2, %1, %0|%0, %1, %2}"
12084   [(set_attr "type" "bitmanip")
12085    (set_attr "mode" "<MODE>")])
12086
12087 (define_insn "bmi_bextr_<mode>"
12088   [(set (match_operand:SWI48 0 "register_operand" "=r")
12089         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12090                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12091                        UNSPEC_BEXTR))
12092    (clobber (reg:CC FLAGS_REG))]
12093   "TARGET_BMI"
12094   "bextr\t{%2, %1, %0|%0, %1, %2}"
12095   [(set_attr "type" "bitmanip")
12096    (set_attr "mode" "<MODE>")])
12097
12098 (define_insn "*bmi_blsi_<mode>"
12099   [(set (match_operand:SWI48 0 "register_operand" "=r")
12100         (and:SWI48
12101           (neg:SWI48
12102             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12103           (match_dup 1)))
12104    (clobber (reg:CC FLAGS_REG))]
12105   "TARGET_BMI"
12106   "blsi\t{%1, %0|%0, %1}"
12107   [(set_attr "type" "bitmanip")
12108    (set_attr "mode" "<MODE>")])
12109
12110 (define_insn "*bmi_blsmsk_<mode>"
12111   [(set (match_operand:SWI48 0 "register_operand" "=r")
12112         (xor:SWI48
12113           (plus:SWI48
12114             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12115             (const_int -1))
12116           (match_dup 1)))
12117    (clobber (reg:CC FLAGS_REG))]
12118   "TARGET_BMI"
12119   "blsmsk\t{%1, %0|%0, %1}"
12120   [(set_attr "type" "bitmanip")
12121    (set_attr "mode" "<MODE>")])
12122
12123 (define_insn "*bmi_blsr_<mode>"
12124   [(set (match_operand:SWI48 0 "register_operand" "=r")
12125         (and:SWI48
12126           (plus:SWI48
12127             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12128             (const_int -1))
12129           (match_dup 1)))
12130    (clobber (reg:CC FLAGS_REG))]
12131    "TARGET_BMI"
12132    "blsr\t{%1, %0|%0, %1}"
12133   [(set_attr "type" "bitmanip")
12134    (set_attr "mode" "<MODE>")])
12135
12136 ;; BMI2 instructions.
12137 (define_insn "bmi2_bzhi_<mode>3"
12138   [(set (match_operand:SWI48 0 "register_operand" "=r")
12139         (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12140                    (lshiftrt:SWI48 (const_int -1)
12141                                    (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12142    (clobber (reg:CC FLAGS_REG))]
12143   "TARGET_BMI2"
12144   "bzhi\t{%2, %1, %0|%0, %1, %2}"
12145   [(set_attr "type" "bitmanip")
12146    (set_attr "prefix" "vex")
12147    (set_attr "mode" "<MODE>")])
12148
12149 (define_insn "bmi2_pdep_<mode>3"
12150   [(set (match_operand:SWI48 0 "register_operand" "=r")
12151         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12152                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12153                        UNSPEC_PDEP))]
12154   "TARGET_BMI2"
12155   "pdep\t{%2, %1, %0|%0, %1, %2}"
12156   [(set_attr "type" "bitmanip")
12157    (set_attr "prefix" "vex")
12158    (set_attr "mode" "<MODE>")])
12159
12160 (define_insn "bmi2_pext_<mode>3"
12161   [(set (match_operand:SWI48 0 "register_operand" "=r")
12162         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12163                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12164                        UNSPEC_PEXT))]
12165   "TARGET_BMI2"
12166   "pext\t{%2, %1, %0|%0, %1, %2}"
12167   [(set_attr "type" "bitmanip")
12168    (set_attr "prefix" "vex")
12169    (set_attr "mode" "<MODE>")])
12170
12171 ;; TBM instructions.
12172 (define_insn "tbm_bextri_<mode>"
12173   [(set (match_operand:SWI48 0 "register_operand" "=r")
12174         (zero_extract:SWI48
12175           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12176           (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12177           (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12178    (clobber (reg:CC FLAGS_REG))]
12179    "TARGET_TBM"
12180 {
12181   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12182   return "bextr\t{%2, %1, %0|%0, %1, %2}";
12183 }
12184   [(set_attr "type" "bitmanip")
12185    (set_attr "mode" "<MODE>")])
12186
12187 (define_insn "*tbm_blcfill_<mode>"
12188   [(set (match_operand:SWI48 0 "register_operand" "=r")
12189         (and:SWI48
12190           (plus:SWI48
12191             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12192             (const_int 1))
12193           (match_dup 1)))
12194    (clobber (reg:CC FLAGS_REG))]
12195    "TARGET_TBM"
12196    "blcfill\t{%1, %0|%0, %1}"
12197   [(set_attr "type" "bitmanip")
12198    (set_attr "mode" "<MODE>")])
12199
12200 (define_insn "*tbm_blci_<mode>"
12201   [(set (match_operand:SWI48 0 "register_operand" "=r")
12202         (ior:SWI48
12203           (not:SWI48
12204             (plus:SWI48
12205               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12206               (const_int 1)))
12207           (match_dup 1)))
12208    (clobber (reg:CC FLAGS_REG))]
12209    "TARGET_TBM"
12210    "blci\t{%1, %0|%0, %1}"
12211   [(set_attr "type" "bitmanip")
12212    (set_attr "mode" "<MODE>")])
12213
12214 (define_insn "*tbm_blcic_<mode>"
12215   [(set (match_operand:SWI48 0 "register_operand" "=r")
12216         (and:SWI48
12217           (plus:SWI48
12218             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12219             (const_int 1))
12220           (not:SWI48
12221             (match_dup 1))))
12222    (clobber (reg:CC FLAGS_REG))]
12223    "TARGET_TBM"
12224    "blcic\t{%1, %0|%0, %1}"
12225   [(set_attr "type" "bitmanip")
12226    (set_attr "mode" "<MODE>")])
12227
12228 (define_insn "*tbm_blcmsk_<mode>"
12229   [(set (match_operand:SWI48 0 "register_operand" "=r")
12230         (xor:SWI48
12231           (plus:SWI48
12232             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12233             (const_int 1))
12234           (match_dup 1)))
12235    (clobber (reg:CC FLAGS_REG))]
12236    "TARGET_TBM"
12237    "blcmsk\t{%1, %0|%0, %1}"
12238   [(set_attr "type" "bitmanip")
12239    (set_attr "mode" "<MODE>")])
12240
12241 (define_insn "*tbm_blcs_<mode>"
12242   [(set (match_operand:SWI48 0 "register_operand" "=r")
12243         (ior:SWI48
12244           (plus:SWI48
12245             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12246             (const_int 1))
12247           (match_dup 1)))
12248    (clobber (reg:CC FLAGS_REG))]
12249    "TARGET_TBM"
12250    "blcs\t{%1, %0|%0, %1}"
12251   [(set_attr "type" "bitmanip")
12252    (set_attr "mode" "<MODE>")])
12253
12254 (define_insn "*tbm_blsfill_<mode>"
12255   [(set (match_operand:SWI48 0 "register_operand" "=r")
12256         (ior:SWI48
12257           (plus:SWI48
12258             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12259             (const_int -1))
12260           (match_dup 1)))
12261    (clobber (reg:CC FLAGS_REG))]
12262    "TARGET_TBM"
12263    "blsfill\t{%1, %0|%0, %1}"
12264   [(set_attr "type" "bitmanip")
12265    (set_attr "mode" "<MODE>")])
12266
12267 (define_insn "*tbm_blsic_<mode>"
12268   [(set (match_operand:SWI48 0 "register_operand" "=r")
12269         (ior:SWI48
12270           (plus:SWI48
12271             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12272             (const_int -1))
12273           (not:SWI48
12274             (match_dup 1))))
12275    (clobber (reg:CC FLAGS_REG))]
12276    "TARGET_TBM"
12277    "blsic\t{%1, %0|%0, %1}"
12278   [(set_attr "type" "bitmanip")
12279    (set_attr "mode" "<MODE>")])
12280
12281 (define_insn "*tbm_t1mskc_<mode>"
12282   [(set (match_operand:SWI48 0 "register_operand" "=r")
12283         (ior:SWI48
12284           (plus:SWI48
12285             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12286             (const_int 1))
12287           (not:SWI48
12288             (match_dup 1))))
12289    (clobber (reg:CC FLAGS_REG))]
12290    "TARGET_TBM"
12291    "t1mskc\t{%1, %0|%0, %1}"
12292   [(set_attr "type" "bitmanip")
12293    (set_attr "mode" "<MODE>")])
12294
12295 (define_insn "*tbm_tzmsk_<mode>"
12296   [(set (match_operand:SWI48 0 "register_operand" "=r")
12297         (and:SWI48
12298           (plus:SWI48
12299             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12300             (const_int -1))
12301           (not:SWI48
12302             (match_dup 1))))
12303    (clobber (reg:CC FLAGS_REG))]
12304    "TARGET_TBM"
12305    "tzmsk\t{%1, %0|%0, %1}"
12306   [(set_attr "type" "bitmanip")
12307    (set_attr "mode" "<MODE>")])
12308
12309 (define_insn "bsr_rex64"
12310   [(set (match_operand:DI 0 "register_operand" "=r")
12311         (minus:DI (const_int 63)
12312                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12313    (clobber (reg:CC FLAGS_REG))]
12314   "TARGET_64BIT"
12315   "bsr{q}\t{%1, %0|%0, %1}"
12316   [(set_attr "type" "alu1")
12317    (set_attr "prefix_0f" "1")
12318    (set_attr "mode" "DI")])
12319
12320 (define_insn "bsr"
12321   [(set (match_operand:SI 0 "register_operand" "=r")
12322         (minus:SI (const_int 31)
12323                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12324    (clobber (reg:CC FLAGS_REG))]
12325   ""
12326   "bsr{l}\t{%1, %0|%0, %1}"
12327   [(set_attr "type" "alu1")
12328    (set_attr "prefix_0f" "1")
12329    (set_attr "mode" "SI")])
12330
12331 (define_insn "*bsrhi"
12332   [(set (match_operand:HI 0 "register_operand" "=r")
12333         (minus:HI (const_int 15)
12334                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12335    (clobber (reg:CC FLAGS_REG))]
12336   ""
12337   "bsr{w}\t{%1, %0|%0, %1}"
12338   [(set_attr "type" "alu1")
12339    (set_attr "prefix_0f" "1")
12340    (set_attr "mode" "HI")])
12341
12342 (define_insn "popcount<mode>2"
12343   [(set (match_operand:SWI248 0 "register_operand" "=r")
12344         (popcount:SWI248
12345           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12346    (clobber (reg:CC FLAGS_REG))]
12347   "TARGET_POPCNT"
12348 {
12349 #if TARGET_MACHO
12350   return "popcnt\t{%1, %0|%0, %1}";
12351 #else
12352   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12353 #endif
12354 }
12355   [(set_attr "prefix_rep" "1")
12356    (set_attr "type" "bitmanip")
12357    (set_attr "mode" "<MODE>")])
12358
12359 (define_insn "*popcount<mode>2_cmp"
12360   [(set (reg FLAGS_REG)
12361         (compare
12362           (popcount:SWI248
12363             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12364           (const_int 0)))
12365    (set (match_operand:SWI248 0 "register_operand" "=r")
12366         (popcount:SWI248 (match_dup 1)))]
12367   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12368 {
12369 #if TARGET_MACHO
12370   return "popcnt\t{%1, %0|%0, %1}";
12371 #else
12372   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12373 #endif
12374 }
12375   [(set_attr "prefix_rep" "1")
12376    (set_attr "type" "bitmanip")
12377    (set_attr "mode" "<MODE>")])
12378
12379 (define_insn "*popcountsi2_cmp_zext"
12380   [(set (reg FLAGS_REG)
12381         (compare
12382           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12383           (const_int 0)))
12384    (set (match_operand:DI 0 "register_operand" "=r")
12385         (zero_extend:DI(popcount:SI (match_dup 1))))]
12386   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12387 {
12388 #if TARGET_MACHO
12389   return "popcnt\t{%1, %0|%0, %1}";
12390 #else
12391   return "popcnt{l}\t{%1, %0|%0, %1}";
12392 #endif
12393 }
12394   [(set_attr "prefix_rep" "1")
12395    (set_attr "type" "bitmanip")
12396    (set_attr "mode" "SI")])
12397
12398 (define_expand "bswap<mode>2"
12399   [(set (match_operand:SWI48 0 "register_operand" "")
12400         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12401   ""
12402 {
12403   if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12404     {
12405       rtx x = operands[0];
12406
12407       emit_move_insn (x, operands[1]);
12408       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12409       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12410       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12411       DONE;
12412     }
12413 })
12414
12415 (define_insn "*bswap<mode>2_movbe"
12416   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12417         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12418   "TARGET_MOVBE
12419    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12420   "@
12421     bswap\t%0
12422     movbe\t{%1, %0|%0, %1}
12423     movbe\t{%1, %0|%0, %1}"
12424   [(set_attr "type" "bitmanip,imov,imov")
12425    (set_attr "modrm" "0,1,1")
12426    (set_attr "prefix_0f" "*,1,1")
12427    (set_attr "prefix_extra" "*,1,1")
12428    (set_attr "mode" "<MODE>")])
12429
12430 (define_insn "*bswap<mode>2_1"
12431   [(set (match_operand:SWI48 0 "register_operand" "=r")
12432         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12433   "TARGET_BSWAP"
12434   "bswap\t%0"
12435   [(set_attr "type" "bitmanip")
12436    (set_attr "modrm" "0")
12437    (set_attr "mode" "<MODE>")])
12438
12439 (define_insn "*bswaphi_lowpart_1"
12440   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12441         (bswap:HI (match_dup 0)))
12442    (clobber (reg:CC FLAGS_REG))]
12443   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12444   "@
12445     xchg{b}\t{%h0, %b0|%b0, %h0}
12446     rol{w}\t{$8, %0|%0, 8}"
12447   [(set_attr "length" "2,4")
12448    (set_attr "mode" "QI,HI")])
12449
12450 (define_insn "bswaphi_lowpart"
12451   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12452         (bswap:HI (match_dup 0)))
12453    (clobber (reg:CC FLAGS_REG))]
12454   ""
12455   "rol{w}\t{$8, %0|%0, 8}"
12456   [(set_attr "length" "4")
12457    (set_attr "mode" "HI")])
12458
12459 (define_expand "paritydi2"
12460   [(set (match_operand:DI 0 "register_operand" "")
12461         (parity:DI (match_operand:DI 1 "register_operand" "")))]
12462   "! TARGET_POPCNT"
12463 {
12464   rtx scratch = gen_reg_rtx (QImode);
12465   rtx cond;
12466
12467   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12468                                 NULL_RTX, operands[1]));
12469
12470   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12471                          gen_rtx_REG (CCmode, FLAGS_REG),
12472                          const0_rtx);
12473   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12474
12475   if (TARGET_64BIT)
12476     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12477   else
12478     {
12479       rtx tmp = gen_reg_rtx (SImode);
12480
12481       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12482       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12483     }
12484   DONE;
12485 })
12486
12487 (define_expand "paritysi2"
12488   [(set (match_operand:SI 0 "register_operand" "")
12489         (parity:SI (match_operand:SI 1 "register_operand" "")))]
12490   "! TARGET_POPCNT"
12491 {
12492   rtx scratch = gen_reg_rtx (QImode);
12493   rtx cond;
12494
12495   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12496
12497   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12498                          gen_rtx_REG (CCmode, FLAGS_REG),
12499                          const0_rtx);
12500   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12501
12502   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12503   DONE;
12504 })
12505
12506 (define_insn_and_split "paritydi2_cmp"
12507   [(set (reg:CC FLAGS_REG)
12508         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12509                    UNSPEC_PARITY))
12510    (clobber (match_scratch:DI 0 "=r"))
12511    (clobber (match_scratch:SI 1 "=&r"))
12512    (clobber (match_scratch:HI 2 "=Q"))]
12513   "! TARGET_POPCNT"
12514   "#"
12515   "&& reload_completed"
12516   [(parallel
12517      [(set (match_dup 1)
12518            (xor:SI (match_dup 1) (match_dup 4)))
12519       (clobber (reg:CC FLAGS_REG))])
12520    (parallel
12521      [(set (reg:CC FLAGS_REG)
12522            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12523       (clobber (match_dup 1))
12524       (clobber (match_dup 2))])]
12525 {
12526   operands[4] = gen_lowpart (SImode, operands[3]);
12527
12528   if (TARGET_64BIT)
12529     {
12530       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12531       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12532     }
12533   else
12534     operands[1] = gen_highpart (SImode, operands[3]);
12535 })
12536
12537 (define_insn_and_split "paritysi2_cmp"
12538   [(set (reg:CC FLAGS_REG)
12539         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12540                    UNSPEC_PARITY))
12541    (clobber (match_scratch:SI 0 "=r"))
12542    (clobber (match_scratch:HI 1 "=&Q"))]
12543   "! TARGET_POPCNT"
12544   "#"
12545   "&& reload_completed"
12546   [(parallel
12547      [(set (match_dup 1)
12548            (xor:HI (match_dup 1) (match_dup 3)))
12549       (clobber (reg:CC FLAGS_REG))])
12550    (parallel
12551      [(set (reg:CC FLAGS_REG)
12552            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12553       (clobber (match_dup 1))])]
12554 {
12555   operands[3] = gen_lowpart (HImode, operands[2]);
12556
12557   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12558   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12559 })
12560
12561 (define_insn "*parityhi2_cmp"
12562   [(set (reg:CC FLAGS_REG)
12563         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12564                    UNSPEC_PARITY))
12565    (clobber (match_scratch:HI 0 "=Q"))]
12566   "! TARGET_POPCNT"
12567   "xor{b}\t{%h0, %b0|%b0, %h0}"
12568   [(set_attr "length" "2")
12569    (set_attr "mode" "HI")])
12570
12571 \f
12572 ;; Thread-local storage patterns for ELF.
12573 ;;
12574 ;; Note that these code sequences must appear exactly as shown
12575 ;; in order to allow linker relaxation.
12576
12577 (define_insn "*tls_global_dynamic_32_gnu"
12578   [(set (match_operand:SI 0 "register_operand" "=a")
12579         (unspec:SI
12580          [(match_operand:SI 1 "register_operand" "b")
12581           (match_operand:SI 2 "tls_symbolic_operand" "")
12582           (match_operand:SI 3 "constant_call_address_operand" "z")]
12583          UNSPEC_TLS_GD))
12584    (clobber (match_scratch:SI 4 "=d"))
12585    (clobber (match_scratch:SI 5 "=c"))
12586    (clobber (reg:CC FLAGS_REG))]
12587   "!TARGET_64BIT && TARGET_GNU_TLS"
12588 {
12589   output_asm_insn
12590     ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12591   if (TARGET_SUN_TLS)
12592 #ifdef HAVE_AS_IX86_TLSGDPLT
12593     return "call\t%a2@tlsgdplt";
12594 #else
12595     return "call\t%p3@plt";
12596 #endif
12597   return "call\t%P3";
12598 }
12599   [(set_attr "type" "multi")
12600    (set_attr "length" "12")])
12601
12602 (define_expand "tls_global_dynamic_32"
12603   [(parallel
12604     [(set (match_operand:SI 0 "register_operand" "")
12605           (unspec:SI [(match_operand:SI 2 "register_operand" "")
12606                       (match_operand:SI 1 "tls_symbolic_operand" "")
12607                       (match_operand:SI 3 "constant_call_address_operand" "")]
12608                      UNSPEC_TLS_GD))
12609      (clobber (match_scratch:SI 4 ""))
12610      (clobber (match_scratch:SI 5 ""))
12611      (clobber (reg:CC FLAGS_REG))])])
12612
12613 (define_insn "*tls_global_dynamic_64"
12614   [(set (match_operand:DI 0 "register_operand" "=a")
12615         (call:DI
12616          (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12617          (match_operand:DI 3 "" "")))
12618    (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12619               UNSPEC_TLS_GD)]
12620   "TARGET_64BIT"
12621 {
12622   if (!TARGET_X32)
12623     fputs (ASM_BYTE "0x66\n", asm_out_file);
12624   output_asm_insn
12625     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12626   fputs (ASM_SHORT "0x6666\n", asm_out_file);
12627   fputs ("\trex64\n", asm_out_file);
12628   if (TARGET_SUN_TLS)
12629     return "call\t%p2@plt";
12630   return "call\t%P2";
12631 }
12632   [(set_attr "type" "multi")
12633    (set (attr "length")
12634         (symbol_ref "TARGET_X32 ? 15 : 16"))])
12635
12636 (define_expand "tls_global_dynamic_64"
12637   [(parallel
12638     [(set (match_operand:DI 0 "register_operand" "")
12639           (call:DI
12640            (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12641            (const_int 0)))
12642      (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12643                 UNSPEC_TLS_GD)])])
12644
12645 (define_insn "*tls_local_dynamic_base_32_gnu"
12646   [(set (match_operand:SI 0 "register_operand" "=a")
12647         (unspec:SI
12648          [(match_operand:SI 1 "register_operand" "b")
12649           (match_operand:SI 2 "constant_call_address_operand" "z")]
12650          UNSPEC_TLS_LD_BASE))
12651    (clobber (match_scratch:SI 3 "=d"))
12652    (clobber (match_scratch:SI 4 "=c"))
12653    (clobber (reg:CC FLAGS_REG))]
12654   "!TARGET_64BIT && TARGET_GNU_TLS"
12655 {
12656   output_asm_insn
12657     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12658   if (TARGET_SUN_TLS)
12659 #ifdef HAVE_AS_IX86_TLSLDMPLT
12660     return "call\t%&@tlsldmplt";
12661 #else
12662     return "call\t%p2@plt";
12663 #endif
12664   return "call\t%P2";
12665 }
12666   [(set_attr "type" "multi")
12667    (set_attr "length" "11")])
12668
12669 (define_expand "tls_local_dynamic_base_32"
12670   [(parallel
12671      [(set (match_operand:SI 0 "register_operand" "")
12672            (unspec:SI
12673             [(match_operand:SI 1 "register_operand" "")
12674              (match_operand:SI 2 "constant_call_address_operand" "")]
12675             UNSPEC_TLS_LD_BASE))
12676       (clobber (match_scratch:SI 3 ""))
12677       (clobber (match_scratch:SI 4 ""))
12678       (clobber (reg:CC FLAGS_REG))])])
12679
12680 (define_insn "*tls_local_dynamic_base_64"
12681   [(set (match_operand:DI 0 "register_operand" "=a")
12682         (call:DI
12683          (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12684          (match_operand:DI 2 "" "")))
12685    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12686   "TARGET_64BIT"
12687 {
12688   output_asm_insn
12689     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12690   if (TARGET_SUN_TLS)
12691     return "call\t%p1@plt";
12692   return "call\t%P1";
12693 }
12694   [(set_attr "type" "multi")
12695    (set_attr "length" "12")])
12696
12697 (define_expand "tls_local_dynamic_base_64"
12698   [(parallel
12699      [(set (match_operand:DI 0 "register_operand" "")
12700            (call:DI
12701             (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12702             (const_int 0)))
12703       (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12704
12705 ;; Local dynamic of a single variable is a lose.  Show combine how
12706 ;; to convert that back to global dynamic.
12707
12708 (define_insn_and_split "*tls_local_dynamic_32_once"
12709   [(set (match_operand:SI 0 "register_operand" "=a")
12710         (plus:SI
12711          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12712                      (match_operand:SI 2 "constant_call_address_operand" "z")]
12713                     UNSPEC_TLS_LD_BASE)
12714          (const:SI (unspec:SI
12715                     [(match_operand:SI 3 "tls_symbolic_operand" "")]
12716                     UNSPEC_DTPOFF))))
12717    (clobber (match_scratch:SI 4 "=d"))
12718    (clobber (match_scratch:SI 5 "=c"))
12719    (clobber (reg:CC FLAGS_REG))]
12720   ""
12721   "#"
12722   ""
12723   [(parallel
12724      [(set (match_dup 0)
12725            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12726                       UNSPEC_TLS_GD))
12727       (clobber (match_dup 4))
12728       (clobber (match_dup 5))
12729       (clobber (reg:CC FLAGS_REG))])])
12730
12731 ;; Segment register for the thread base ptr load
12732 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12733
12734 ;; Load and add the thread base pointer from %<tp_seg>:0.
12735 (define_insn "*load_tp_x32"
12736   [(set (match_operand:SI 0 "register_operand" "=r")
12737         (unspec:SI [(const_int 0)] UNSPEC_TP))]
12738   "TARGET_X32"
12739   "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12740   [(set_attr "type" "imov")
12741    (set_attr "modrm" "0")
12742    (set_attr "length" "7")
12743    (set_attr "memory" "load")
12744    (set_attr "imm_disp" "false")])
12745
12746 (define_insn "*load_tp_x32_zext"
12747   [(set (match_operand:DI 0 "register_operand" "=r")
12748         (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12749   "TARGET_X32"
12750   "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12751   [(set_attr "type" "imov")
12752    (set_attr "modrm" "0")
12753    (set_attr "length" "7")
12754    (set_attr "memory" "load")
12755    (set_attr "imm_disp" "false")])
12756
12757 (define_insn "*load_tp_<mode>"
12758   [(set (match_operand:P 0 "register_operand" "=r")
12759         (unspec:P [(const_int 0)] UNSPEC_TP))]
12760   "!TARGET_X32"
12761   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12762   [(set_attr "type" "imov")
12763    (set_attr "modrm" "0")
12764    (set_attr "length" "7")
12765    (set_attr "memory" "load")
12766    (set_attr "imm_disp" "false")])
12767
12768 (define_insn "*add_tp_x32"
12769   [(set (match_operand:SI 0 "register_operand" "=r")
12770         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12771                  (match_operand:SI 1 "register_operand" "0")))
12772    (clobber (reg:CC FLAGS_REG))]
12773   "TARGET_X32"
12774   "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12775   [(set_attr "type" "alu")
12776    (set_attr "modrm" "0")
12777    (set_attr "length" "7")
12778    (set_attr "memory" "load")
12779    (set_attr "imm_disp" "false")])
12780
12781 (define_insn "*add_tp_x32_zext"
12782   [(set (match_operand:DI 0 "register_operand" "=r")
12783         (zero_extend:DI
12784           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12785                    (match_operand:SI 1 "register_operand" "0"))))
12786    (clobber (reg:CC FLAGS_REG))]
12787   "TARGET_X32"
12788   "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12789   [(set_attr "type" "alu")
12790    (set_attr "modrm" "0")
12791    (set_attr "length" "7")
12792    (set_attr "memory" "load")
12793    (set_attr "imm_disp" "false")])
12794
12795 (define_insn "*add_tp_<mode>"
12796   [(set (match_operand:P 0 "register_operand" "=r")
12797         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12798                 (match_operand:P 1 "register_operand" "0")))
12799    (clobber (reg:CC FLAGS_REG))]
12800   "!TARGET_X32"
12801   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12802   [(set_attr "type" "alu")
12803    (set_attr "modrm" "0")
12804    (set_attr "length" "7")
12805    (set_attr "memory" "load")
12806    (set_attr "imm_disp" "false")])
12807
12808 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12809 ;; %rax as destination of the initial executable code sequence.
12810 (define_insn "tls_initial_exec_64_sun"
12811   [(set (match_operand:DI 0 "register_operand" "=a")
12812         (unspec:DI
12813          [(match_operand:DI 1 "tls_symbolic_operand" "")]
12814          UNSPEC_TLS_IE_SUN))
12815    (clobber (reg:CC FLAGS_REG))]
12816   "TARGET_64BIT && TARGET_SUN_TLS"
12817 {
12818   output_asm_insn
12819     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12820   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12821 }
12822   [(set_attr "type" "multi")])
12823
12824 ;; GNU2 TLS patterns can be split.
12825
12826 (define_expand "tls_dynamic_gnu2_32"
12827   [(set (match_dup 3)
12828         (plus:SI (match_operand:SI 2 "register_operand" "")
12829                  (const:SI
12830                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12831                              UNSPEC_TLSDESC))))
12832    (parallel
12833     [(set (match_operand:SI 0 "register_operand" "")
12834           (unspec:SI [(match_dup 1) (match_dup 3)
12835                       (match_dup 2) (reg:SI SP_REG)]
12836                       UNSPEC_TLSDESC))
12837      (clobber (reg:CC FLAGS_REG))])]
12838   "!TARGET_64BIT && TARGET_GNU2_TLS"
12839 {
12840   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12841   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12842 })
12843
12844 (define_insn "*tls_dynamic_gnu2_lea_32"
12845   [(set (match_operand:SI 0 "register_operand" "=r")
12846         (plus:SI (match_operand:SI 1 "register_operand" "b")
12847                  (const:SI
12848                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12849                               UNSPEC_TLSDESC))))]
12850   "!TARGET_64BIT && TARGET_GNU2_TLS"
12851   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
12852   [(set_attr "type" "lea")
12853    (set_attr "mode" "SI")
12854    (set_attr "length" "6")
12855    (set_attr "length_address" "4")])
12856
12857 (define_insn "*tls_dynamic_gnu2_call_32"
12858   [(set (match_operand:SI 0 "register_operand" "=a")
12859         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12860                     (match_operand:SI 2 "register_operand" "0")
12861                     ;; we have to make sure %ebx still points to the GOT
12862                     (match_operand:SI 3 "register_operand" "b")
12863                     (reg:SI SP_REG)]
12864                    UNSPEC_TLSDESC))
12865    (clobber (reg:CC FLAGS_REG))]
12866   "!TARGET_64BIT && TARGET_GNU2_TLS"
12867   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12868   [(set_attr "type" "call")
12869    (set_attr "length" "2")
12870    (set_attr "length_address" "0")])
12871
12872 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12873   [(set (match_operand:SI 0 "register_operand" "=&a")
12874         (plus:SI
12875          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12876                      (match_operand:SI 4 "" "")
12877                      (match_operand:SI 2 "register_operand" "b")
12878                      (reg:SI SP_REG)]
12879                     UNSPEC_TLSDESC)
12880          (const:SI (unspec:SI
12881                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
12882                     UNSPEC_DTPOFF))))
12883    (clobber (reg:CC FLAGS_REG))]
12884   "!TARGET_64BIT && TARGET_GNU2_TLS"
12885   "#"
12886   ""
12887   [(set (match_dup 0) (match_dup 5))]
12888 {
12889   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12890   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12891 })
12892
12893 (define_expand "tls_dynamic_gnu2_64"
12894   [(set (match_dup 2)
12895         (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12896                    UNSPEC_TLSDESC))
12897    (parallel
12898     [(set (match_operand:DI 0 "register_operand" "")
12899           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12900                      UNSPEC_TLSDESC))
12901      (clobber (reg:CC FLAGS_REG))])]
12902   "TARGET_64BIT && TARGET_GNU2_TLS"
12903 {
12904   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12905   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12906 })
12907
12908 (define_insn "*tls_dynamic_gnu2_lea_64"
12909   [(set (match_operand:DI 0 "register_operand" "=r")
12910         (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12911                    UNSPEC_TLSDESC))]
12912   "TARGET_64BIT && TARGET_GNU2_TLS"
12913   "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
12914   [(set_attr "type" "lea")
12915    (set_attr "mode" "DI")
12916    (set_attr "length" "7")
12917    (set_attr "length_address" "4")])
12918
12919 (define_insn "*tls_dynamic_gnu2_call_64"
12920   [(set (match_operand:DI 0 "register_operand" "=a")
12921         (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12922                     (match_operand:DI 2 "register_operand" "0")
12923                     (reg:DI SP_REG)]
12924                    UNSPEC_TLSDESC))
12925    (clobber (reg:CC FLAGS_REG))]
12926   "TARGET_64BIT && TARGET_GNU2_TLS"
12927   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12928   [(set_attr "type" "call")
12929    (set_attr "length" "2")
12930    (set_attr "length_address" "0")])
12931
12932 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12933   [(set (match_operand:DI 0 "register_operand" "=&a")
12934         (plus:DI
12935          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12936                      (match_operand:DI 3 "" "")
12937                      (reg:DI SP_REG)]
12938                     UNSPEC_TLSDESC)
12939          (const:DI (unspec:DI
12940                     [(match_operand 1 "tls_symbolic_operand" "")]
12941                     UNSPEC_DTPOFF))))
12942    (clobber (reg:CC FLAGS_REG))]
12943   "TARGET_64BIT && TARGET_GNU2_TLS"
12944   "#"
12945   ""
12946   [(set (match_dup 0) (match_dup 4))]
12947 {
12948   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12949   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12950 })
12951 \f
12952 ;; These patterns match the binary 387 instructions for addM3, subM3,
12953 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
12954 ;; SFmode.  The first is the normal insn, the second the same insn but
12955 ;; with one operand a conversion, and the third the same insn but with
12956 ;; the other operand a conversion.  The conversion may be SFmode or
12957 ;; SImode if the target mode DFmode, but only SImode if the target mode
12958 ;; is SFmode.
12959
12960 ;; Gcc is slightly more smart about handling normal two address instructions
12961 ;; so use special patterns for add and mull.
12962
12963 (define_insn "*fop_<mode>_comm_mixed"
12964   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12965         (match_operator:MODEF 3 "binary_fp_operator"
12966           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12967            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12968   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12969    && COMMUTATIVE_ARITH_P (operands[3])
12970    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12971   "* return output_387_binary_op (insn, operands);"
12972   [(set (attr "type")
12973         (if_then_else (eq_attr "alternative" "1,2")
12974            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12975               (const_string "ssemul")
12976               (const_string "sseadd"))
12977            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12978               (const_string "fmul")
12979               (const_string "fop"))))
12980    (set_attr "isa" "*,noavx,avx")
12981    (set_attr "prefix" "orig,orig,vex")
12982    (set_attr "mode" "<MODE>")])
12983
12984 (define_insn "*fop_<mode>_comm_sse"
12985   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12986         (match_operator:MODEF 3 "binary_fp_operator"
12987           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12988            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12989   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12990    && COMMUTATIVE_ARITH_P (operands[3])
12991    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12992   "* return output_387_binary_op (insn, operands);"
12993   [(set (attr "type")
12994         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12995            (const_string "ssemul")
12996            (const_string "sseadd")))
12997    (set_attr "isa" "noavx,avx")
12998    (set_attr "prefix" "orig,vex")
12999    (set_attr "mode" "<MODE>")])
13000
13001 (define_insn "*fop_<mode>_comm_i387"
13002   [(set (match_operand:MODEF 0 "register_operand" "=f")
13003         (match_operator:MODEF 3 "binary_fp_operator"
13004           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13005            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13006   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13007    && COMMUTATIVE_ARITH_P (operands[3])
13008    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13009   "* return output_387_binary_op (insn, operands);"
13010   [(set (attr "type")
13011         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13012            (const_string "fmul")
13013            (const_string "fop")))
13014    (set_attr "mode" "<MODE>")])
13015
13016 (define_insn "*fop_<mode>_1_mixed"
13017   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13018         (match_operator:MODEF 3 "binary_fp_operator"
13019           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13020            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13021   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13022    && !COMMUTATIVE_ARITH_P (operands[3])
13023    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13024   "* return output_387_binary_op (insn, operands);"
13025   [(set (attr "type")
13026         (cond [(and (eq_attr "alternative" "2,3")
13027                     (match_operand:MODEF 3 "mult_operator" ""))
13028                  (const_string "ssemul")
13029                (and (eq_attr "alternative" "2,3")
13030                     (match_operand:MODEF 3 "div_operator" ""))
13031                  (const_string "ssediv")
13032                (eq_attr "alternative" "2,3")
13033                  (const_string "sseadd")
13034                (match_operand:MODEF 3 "mult_operator" "")
13035                  (const_string "fmul")
13036                (match_operand:MODEF 3 "div_operator" "")
13037                  (const_string "fdiv")
13038               ]
13039               (const_string "fop")))
13040    (set_attr "isa" "*,*,noavx,avx")
13041    (set_attr "prefix" "orig,orig,orig,vex")
13042    (set_attr "mode" "<MODE>")])
13043
13044 (define_insn "*rcpsf2_sse"
13045   [(set (match_operand:SF 0 "register_operand" "=x")
13046         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13047                    UNSPEC_RCP))]
13048   "TARGET_SSE_MATH"
13049   "%vrcpss\t{%1, %d0|%d0, %1}"
13050   [(set_attr "type" "sse")
13051    (set_attr "atom_sse_attr" "rcp")
13052    (set_attr "prefix" "maybe_vex")
13053    (set_attr "mode" "SF")])
13054
13055 (define_insn "*fop_<mode>_1_sse"
13056   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13057         (match_operator:MODEF 3 "binary_fp_operator"
13058           [(match_operand:MODEF 1 "register_operand" "0,x")
13059            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13060   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13061    && !COMMUTATIVE_ARITH_P (operands[3])"
13062   "* return output_387_binary_op (insn, operands);"
13063   [(set (attr "type")
13064         (cond [(match_operand:MODEF 3 "mult_operator" "")
13065                  (const_string "ssemul")
13066                (match_operand:MODEF 3 "div_operator" "")
13067                  (const_string "ssediv")
13068               ]
13069               (const_string "sseadd")))
13070    (set_attr "isa" "noavx,avx")
13071    (set_attr "prefix" "orig,vex")
13072    (set_attr "mode" "<MODE>")])
13073
13074 ;; This pattern is not fully shadowed by the pattern above.
13075 (define_insn "*fop_<mode>_1_i387"
13076   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13077         (match_operator:MODEF 3 "binary_fp_operator"
13078           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13079            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13080   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13081    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13082    && !COMMUTATIVE_ARITH_P (operands[3])
13083    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13084   "* return output_387_binary_op (insn, operands);"
13085   [(set (attr "type")
13086         (cond [(match_operand:MODEF 3 "mult_operator" "")
13087                  (const_string "fmul")
13088                (match_operand:MODEF 3 "div_operator" "")
13089                  (const_string "fdiv")
13090               ]
13091               (const_string "fop")))
13092    (set_attr "mode" "<MODE>")])
13093
13094 ;; ??? Add SSE splitters for these!
13095 (define_insn "*fop_<MODEF:mode>_2_i387"
13096   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13097         (match_operator:MODEF 3 "binary_fp_operator"
13098           [(float:MODEF
13099              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13100            (match_operand:MODEF 2 "register_operand" "0,0")]))]
13101   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13102    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13103    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13104   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13105   [(set (attr "type")
13106         (cond [(match_operand:MODEF 3 "mult_operator" "")
13107                  (const_string "fmul")
13108                (match_operand:MODEF 3 "div_operator" "")
13109                  (const_string "fdiv")
13110               ]
13111               (const_string "fop")))
13112    (set_attr "fp_int_src" "true")
13113    (set_attr "mode" "<SWI24:MODE>")])
13114
13115 (define_insn "*fop_<MODEF:mode>_3_i387"
13116   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13117         (match_operator:MODEF 3 "binary_fp_operator"
13118           [(match_operand:MODEF 1 "register_operand" "0,0")
13119            (float:MODEF
13120              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13121   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13122    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13123    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13124   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13125   [(set (attr "type")
13126         (cond [(match_operand:MODEF 3 "mult_operator" "")
13127                  (const_string "fmul")
13128                (match_operand:MODEF 3 "div_operator" "")
13129                  (const_string "fdiv")
13130               ]
13131               (const_string "fop")))
13132    (set_attr "fp_int_src" "true")
13133    (set_attr "mode" "<MODE>")])
13134
13135 (define_insn "*fop_df_4_i387"
13136   [(set (match_operand:DF 0 "register_operand" "=f,f")
13137         (match_operator:DF 3 "binary_fp_operator"
13138            [(float_extend:DF
13139              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13140             (match_operand:DF 2 "register_operand" "0,f")]))]
13141   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13142    && !(TARGET_SSE2 && TARGET_SSE_MATH)
13143    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13144   "* return output_387_binary_op (insn, operands);"
13145   [(set (attr "type")
13146         (cond [(match_operand:DF 3 "mult_operator" "")
13147                  (const_string "fmul")
13148                (match_operand:DF 3 "div_operator" "")
13149                  (const_string "fdiv")
13150               ]
13151               (const_string "fop")))
13152    (set_attr "mode" "SF")])
13153
13154 (define_insn "*fop_df_5_i387"
13155   [(set (match_operand:DF 0 "register_operand" "=f,f")
13156         (match_operator:DF 3 "binary_fp_operator"
13157           [(match_operand:DF 1 "register_operand" "0,f")
13158            (float_extend:DF
13159             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13160   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13161    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13162   "* return output_387_binary_op (insn, operands);"
13163   [(set (attr "type")
13164         (cond [(match_operand:DF 3 "mult_operator" "")
13165                  (const_string "fmul")
13166                (match_operand:DF 3 "div_operator" "")
13167                  (const_string "fdiv")
13168               ]
13169               (const_string "fop")))
13170    (set_attr "mode" "SF")])
13171
13172 (define_insn "*fop_df_6_i387"
13173   [(set (match_operand:DF 0 "register_operand" "=f,f")
13174         (match_operator:DF 3 "binary_fp_operator"
13175           [(float_extend:DF
13176             (match_operand:SF 1 "register_operand" "0,f"))
13177            (float_extend:DF
13178             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13179   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13180    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13181   "* return output_387_binary_op (insn, operands);"
13182   [(set (attr "type")
13183         (cond [(match_operand:DF 3 "mult_operator" "")
13184                  (const_string "fmul")
13185                (match_operand:DF 3 "div_operator" "")
13186                  (const_string "fdiv")
13187               ]
13188               (const_string "fop")))
13189    (set_attr "mode" "SF")])
13190
13191 (define_insn "*fop_xf_comm_i387"
13192   [(set (match_operand:XF 0 "register_operand" "=f")
13193         (match_operator:XF 3 "binary_fp_operator"
13194                         [(match_operand:XF 1 "register_operand" "%0")
13195                          (match_operand:XF 2 "register_operand" "f")]))]
13196   "TARGET_80387
13197    && COMMUTATIVE_ARITH_P (operands[3])"
13198   "* return output_387_binary_op (insn, operands);"
13199   [(set (attr "type")
13200         (if_then_else (match_operand:XF 3 "mult_operator" "")
13201            (const_string "fmul")
13202            (const_string "fop")))
13203    (set_attr "mode" "XF")])
13204
13205 (define_insn "*fop_xf_1_i387"
13206   [(set (match_operand:XF 0 "register_operand" "=f,f")
13207         (match_operator:XF 3 "binary_fp_operator"
13208                         [(match_operand:XF 1 "register_operand" "0,f")
13209                          (match_operand:XF 2 "register_operand" "f,0")]))]
13210   "TARGET_80387
13211    && !COMMUTATIVE_ARITH_P (operands[3])"
13212   "* return output_387_binary_op (insn, operands);"
13213   [(set (attr "type")
13214         (cond [(match_operand:XF 3 "mult_operator" "")
13215                  (const_string "fmul")
13216                (match_operand:XF 3 "div_operator" "")
13217                  (const_string "fdiv")
13218               ]
13219               (const_string "fop")))
13220    (set_attr "mode" "XF")])
13221
13222 (define_insn "*fop_xf_2_i387"
13223   [(set (match_operand:XF 0 "register_operand" "=f,f")
13224         (match_operator:XF 3 "binary_fp_operator"
13225           [(float:XF
13226              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13227            (match_operand:XF 2 "register_operand" "0,0")]))]
13228   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13229   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13230   [(set (attr "type")
13231         (cond [(match_operand:XF 3 "mult_operator" "")
13232                  (const_string "fmul")
13233                (match_operand:XF 3 "div_operator" "")
13234                  (const_string "fdiv")
13235               ]
13236               (const_string "fop")))
13237    (set_attr "fp_int_src" "true")
13238    (set_attr "mode" "<MODE>")])
13239
13240 (define_insn "*fop_xf_3_i387"
13241   [(set (match_operand:XF 0 "register_operand" "=f,f")
13242         (match_operator:XF 3 "binary_fp_operator"
13243           [(match_operand:XF 1 "register_operand" "0,0")
13244            (float:XF
13245              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13246   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13247   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13248   [(set (attr "type")
13249         (cond [(match_operand:XF 3 "mult_operator" "")
13250                  (const_string "fmul")
13251                (match_operand:XF 3 "div_operator" "")
13252                  (const_string "fdiv")
13253               ]
13254               (const_string "fop")))
13255    (set_attr "fp_int_src" "true")
13256    (set_attr "mode" "<MODE>")])
13257
13258 (define_insn "*fop_xf_4_i387"
13259   [(set (match_operand:XF 0 "register_operand" "=f,f")
13260         (match_operator:XF 3 "binary_fp_operator"
13261            [(float_extend:XF
13262               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13263             (match_operand:XF 2 "register_operand" "0,f")]))]
13264   "TARGET_80387"
13265   "* return output_387_binary_op (insn, operands);"
13266   [(set (attr "type")
13267         (cond [(match_operand:XF 3 "mult_operator" "")
13268                  (const_string "fmul")
13269                (match_operand:XF 3 "div_operator" "")
13270                  (const_string "fdiv")
13271               ]
13272               (const_string "fop")))
13273    (set_attr "mode" "<MODE>")])
13274
13275 (define_insn "*fop_xf_5_i387"
13276   [(set (match_operand:XF 0 "register_operand" "=f,f")
13277         (match_operator:XF 3 "binary_fp_operator"
13278           [(match_operand:XF 1 "register_operand" "0,f")
13279            (float_extend:XF
13280              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13281   "TARGET_80387"
13282   "* return output_387_binary_op (insn, operands);"
13283   [(set (attr "type")
13284         (cond [(match_operand:XF 3 "mult_operator" "")
13285                  (const_string "fmul")
13286                (match_operand:XF 3 "div_operator" "")
13287                  (const_string "fdiv")
13288               ]
13289               (const_string "fop")))
13290    (set_attr "mode" "<MODE>")])
13291
13292 (define_insn "*fop_xf_6_i387"
13293   [(set (match_operand:XF 0 "register_operand" "=f,f")
13294         (match_operator:XF 3 "binary_fp_operator"
13295           [(float_extend:XF
13296              (match_operand:MODEF 1 "register_operand" "0,f"))
13297            (float_extend:XF
13298              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13299   "TARGET_80387"
13300   "* return output_387_binary_op (insn, operands);"
13301   [(set (attr "type")
13302         (cond [(match_operand:XF 3 "mult_operator" "")
13303                  (const_string "fmul")
13304                (match_operand:XF 3 "div_operator" "")
13305                  (const_string "fdiv")
13306               ]
13307               (const_string "fop")))
13308    (set_attr "mode" "<MODE>")])
13309
13310 (define_split
13311   [(set (match_operand 0 "register_operand" "")
13312         (match_operator 3 "binary_fp_operator"
13313            [(float (match_operand:SWI24 1 "register_operand" ""))
13314             (match_operand 2 "register_operand" "")]))]
13315   "reload_completed
13316    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13317    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13318   [(const_int 0)]
13319 {
13320   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13321   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13322   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13323                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13324                                           GET_MODE (operands[3]),
13325                                           operands[4],
13326                                           operands[2])));
13327   ix86_free_from_memory (GET_MODE (operands[1]));
13328   DONE;
13329 })
13330
13331 (define_split
13332   [(set (match_operand 0 "register_operand" "")
13333         (match_operator 3 "binary_fp_operator"
13334            [(match_operand 1 "register_operand" "")
13335             (float (match_operand:SWI24 2 "register_operand" ""))]))]
13336   "reload_completed
13337    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13338    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13339   [(const_int 0)]
13340 {
13341   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13342   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13343   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13344                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13345                                           GET_MODE (operands[3]),
13346                                           operands[1],
13347                                           operands[4])));
13348   ix86_free_from_memory (GET_MODE (operands[2]));
13349   DONE;
13350 })
13351 \f
13352 ;; FPU special functions.
13353
13354 ;; This pattern implements a no-op XFmode truncation for
13355 ;; all fancy i386 XFmode math functions.
13356
13357 (define_insn "truncxf<mode>2_i387_noop_unspec"
13358   [(set (match_operand:MODEF 0 "register_operand" "=f")
13359         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13360         UNSPEC_TRUNC_NOOP))]
13361   "TARGET_USE_FANCY_MATH_387"
13362   "* return output_387_reg_move (insn, operands);"
13363   [(set_attr "type" "fmov")
13364    (set_attr "mode" "<MODE>")])
13365
13366 (define_insn "sqrtxf2"
13367   [(set (match_operand:XF 0 "register_operand" "=f")
13368         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13369   "TARGET_USE_FANCY_MATH_387"
13370   "fsqrt"
13371   [(set_attr "type" "fpspc")
13372    (set_attr "mode" "XF")
13373    (set_attr "athlon_decode" "direct")
13374    (set_attr "amdfam10_decode" "direct")
13375    (set_attr "bdver1_decode" "direct")])
13376
13377 (define_insn "sqrt_extend<mode>xf2_i387"
13378   [(set (match_operand:XF 0 "register_operand" "=f")
13379         (sqrt:XF
13380           (float_extend:XF
13381             (match_operand:MODEF 1 "register_operand" "0"))))]
13382   "TARGET_USE_FANCY_MATH_387"
13383   "fsqrt"
13384   [(set_attr "type" "fpspc")
13385    (set_attr "mode" "XF")
13386    (set_attr "athlon_decode" "direct")
13387    (set_attr "amdfam10_decode" "direct")
13388    (set_attr "bdver1_decode" "direct")])
13389
13390 (define_insn "*rsqrtsf2_sse"
13391   [(set (match_operand:SF 0 "register_operand" "=x")
13392         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13393                    UNSPEC_RSQRT))]
13394   "TARGET_SSE_MATH"
13395   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13396   [(set_attr "type" "sse")
13397    (set_attr "atom_sse_attr" "rcp")
13398    (set_attr "prefix" "maybe_vex")
13399    (set_attr "mode" "SF")])
13400
13401 (define_expand "rsqrtsf2"
13402   [(set (match_operand:SF 0 "register_operand" "")
13403         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13404                    UNSPEC_RSQRT))]
13405   "TARGET_SSE_MATH"
13406 {
13407   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13408   DONE;
13409 })
13410
13411 (define_insn "*sqrt<mode>2_sse"
13412   [(set (match_operand:MODEF 0 "register_operand" "=x")
13413         (sqrt:MODEF
13414           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13415   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13416   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13417   [(set_attr "type" "sse")
13418    (set_attr "atom_sse_attr" "sqrt")
13419    (set_attr "prefix" "maybe_vex")
13420    (set_attr "mode" "<MODE>")
13421    (set_attr "athlon_decode" "*")
13422    (set_attr "amdfam10_decode" "*")
13423    (set_attr "bdver1_decode" "*")])
13424
13425 (define_expand "sqrt<mode>2"
13426   [(set (match_operand:MODEF 0 "register_operand" "")
13427         (sqrt:MODEF
13428           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13429   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13430    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13431 {
13432   if (<MODE>mode == SFmode
13433       && TARGET_SSE_MATH
13434       && TARGET_RECIP_SQRT
13435       && !optimize_function_for_size_p (cfun)
13436       && flag_finite_math_only && !flag_trapping_math
13437       && flag_unsafe_math_optimizations)
13438     {
13439       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13440       DONE;
13441     }
13442
13443   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13444     {
13445       rtx op0 = gen_reg_rtx (XFmode);
13446       rtx op1 = force_reg (<MODE>mode, operands[1]);
13447
13448       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13449       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13450       DONE;
13451    }
13452 })
13453
13454 (define_insn "fpremxf4_i387"
13455   [(set (match_operand:XF 0 "register_operand" "=f")
13456         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13457                     (match_operand:XF 3 "register_operand" "1")]
13458                    UNSPEC_FPREM_F))
13459    (set (match_operand:XF 1 "register_operand" "=u")
13460         (unspec:XF [(match_dup 2) (match_dup 3)]
13461                    UNSPEC_FPREM_U))
13462    (set (reg:CCFP FPSR_REG)
13463         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13464                      UNSPEC_C2_FLAG))]
13465   "TARGET_USE_FANCY_MATH_387"
13466   "fprem"
13467   [(set_attr "type" "fpspc")
13468    (set_attr "mode" "XF")])
13469
13470 (define_expand "fmodxf3"
13471   [(use (match_operand:XF 0 "register_operand" ""))
13472    (use (match_operand:XF 1 "general_operand" ""))
13473    (use (match_operand:XF 2 "general_operand" ""))]
13474   "TARGET_USE_FANCY_MATH_387"
13475 {
13476   rtx label = gen_label_rtx ();
13477
13478   rtx op1 = gen_reg_rtx (XFmode);
13479   rtx op2 = gen_reg_rtx (XFmode);
13480
13481   emit_move_insn (op2, operands[2]);
13482   emit_move_insn (op1, operands[1]);
13483
13484   emit_label (label);
13485   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13486   ix86_emit_fp_unordered_jump (label);
13487   LABEL_NUSES (label) = 1;
13488
13489   emit_move_insn (operands[0], op1);
13490   DONE;
13491 })
13492
13493 (define_expand "fmod<mode>3"
13494   [(use (match_operand:MODEF 0 "register_operand" ""))
13495    (use (match_operand:MODEF 1 "general_operand" ""))
13496    (use (match_operand:MODEF 2 "general_operand" ""))]
13497   "TARGET_USE_FANCY_MATH_387"
13498 {
13499   rtx (*gen_truncxf) (rtx, rtx);
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_insn (gen_extend<mode>xf2 (op2, operands[2]));
13507   emit_insn (gen_extend<mode>xf2 (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   /* Truncate the result properly for strict SSE math.  */
13515   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13516       && !TARGET_MIX_SSE_I387)
13517     gen_truncxf = gen_truncxf<mode>2;
13518   else
13519     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13520
13521   emit_insn (gen_truncxf (operands[0], op1));
13522   DONE;
13523 })
13524
13525 (define_insn "fprem1xf4_i387"
13526   [(set (match_operand:XF 0 "register_operand" "=f")
13527         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13528                     (match_operand:XF 3 "register_operand" "1")]
13529                    UNSPEC_FPREM1_F))
13530    (set (match_operand:XF 1 "register_operand" "=u")
13531         (unspec:XF [(match_dup 2) (match_dup 3)]
13532                    UNSPEC_FPREM1_U))
13533    (set (reg:CCFP FPSR_REG)
13534         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13535                      UNSPEC_C2_FLAG))]
13536   "TARGET_USE_FANCY_MATH_387"
13537   "fprem1"
13538   [(set_attr "type" "fpspc")
13539    (set_attr "mode" "XF")])
13540
13541 (define_expand "remainderxf3"
13542   [(use (match_operand:XF 0 "register_operand" ""))
13543    (use (match_operand:XF 1 "general_operand" ""))
13544    (use (match_operand:XF 2 "general_operand" ""))]
13545   "TARGET_USE_FANCY_MATH_387"
13546 {
13547   rtx label = gen_label_rtx ();
13548
13549   rtx op1 = gen_reg_rtx (XFmode);
13550   rtx op2 = gen_reg_rtx (XFmode);
13551
13552   emit_move_insn (op2, operands[2]);
13553   emit_move_insn (op1, operands[1]);
13554
13555   emit_label (label);
13556   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13557   ix86_emit_fp_unordered_jump (label);
13558   LABEL_NUSES (label) = 1;
13559
13560   emit_move_insn (operands[0], op1);
13561   DONE;
13562 })
13563
13564 (define_expand "remainder<mode>3"
13565   [(use (match_operand:MODEF 0 "register_operand" ""))
13566    (use (match_operand:MODEF 1 "general_operand" ""))
13567    (use (match_operand:MODEF 2 "general_operand" ""))]
13568   "TARGET_USE_FANCY_MATH_387"
13569 {
13570   rtx (*gen_truncxf) (rtx, rtx);
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_insn (gen_extend<mode>xf2 (op2, operands[2]));
13578   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13579
13580   emit_label (label);
13581
13582   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13583   ix86_emit_fp_unordered_jump (label);
13584   LABEL_NUSES (label) = 1;
13585
13586   /* Truncate the result properly for strict SSE math.  */
13587   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13588       && !TARGET_MIX_SSE_I387)
13589     gen_truncxf = gen_truncxf<mode>2;
13590   else
13591     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13592
13593   emit_insn (gen_truncxf (operands[0], op1));
13594   DONE;
13595 })
13596
13597 (define_insn "*sinxf2_i387"
13598   [(set (match_operand:XF 0 "register_operand" "=f")
13599         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13600   "TARGET_USE_FANCY_MATH_387
13601    && flag_unsafe_math_optimizations"
13602   "fsin"
13603   [(set_attr "type" "fpspc")
13604    (set_attr "mode" "XF")])
13605
13606 (define_insn "*sin_extend<mode>xf2_i387"
13607   [(set (match_operand:XF 0 "register_operand" "=f")
13608         (unspec:XF [(float_extend:XF
13609                       (match_operand:MODEF 1 "register_operand" "0"))]
13610                    UNSPEC_SIN))]
13611   "TARGET_USE_FANCY_MATH_387
13612    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13613        || TARGET_MIX_SSE_I387)
13614    && flag_unsafe_math_optimizations"
13615   "fsin"
13616   [(set_attr "type" "fpspc")
13617    (set_attr "mode" "XF")])
13618
13619 (define_insn "*cosxf2_i387"
13620   [(set (match_operand:XF 0 "register_operand" "=f")
13621         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13622   "TARGET_USE_FANCY_MATH_387
13623    && flag_unsafe_math_optimizations"
13624   "fcos"
13625   [(set_attr "type" "fpspc")
13626    (set_attr "mode" "XF")])
13627
13628 (define_insn "*cos_extend<mode>xf2_i387"
13629   [(set (match_operand:XF 0 "register_operand" "=f")
13630         (unspec:XF [(float_extend:XF
13631                       (match_operand:MODEF 1 "register_operand" "0"))]
13632                    UNSPEC_COS))]
13633   "TARGET_USE_FANCY_MATH_387
13634    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13635        || TARGET_MIX_SSE_I387)
13636    && flag_unsafe_math_optimizations"
13637   "fcos"
13638   [(set_attr "type" "fpspc")
13639    (set_attr "mode" "XF")])
13640
13641 ;; When sincos pattern is defined, sin and cos builtin functions will be
13642 ;; expanded to sincos pattern with one of its outputs left unused.
13643 ;; CSE pass will figure out if two sincos patterns can be combined,
13644 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13645 ;; depending on the unused output.
13646
13647 (define_insn "sincosxf3"
13648   [(set (match_operand:XF 0 "register_operand" "=f")
13649         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13650                    UNSPEC_SINCOS_COS))
13651    (set (match_operand:XF 1 "register_operand" "=u")
13652         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13653   "TARGET_USE_FANCY_MATH_387
13654    && flag_unsafe_math_optimizations"
13655   "fsincos"
13656   [(set_attr "type" "fpspc")
13657    (set_attr "mode" "XF")])
13658
13659 (define_split
13660   [(set (match_operand:XF 0 "register_operand" "")
13661         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13662                    UNSPEC_SINCOS_COS))
13663    (set (match_operand:XF 1 "register_operand" "")
13664         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13665   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13666    && can_create_pseudo_p ()"
13667   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13668
13669 (define_split
13670   [(set (match_operand:XF 0 "register_operand" "")
13671         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13672                    UNSPEC_SINCOS_COS))
13673    (set (match_operand:XF 1 "register_operand" "")
13674         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13675   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13676    && can_create_pseudo_p ()"
13677   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13678
13679 (define_insn "sincos_extend<mode>xf3_i387"
13680   [(set (match_operand:XF 0 "register_operand" "=f")
13681         (unspec:XF [(float_extend:XF
13682                       (match_operand:MODEF 2 "register_operand" "0"))]
13683                    UNSPEC_SINCOS_COS))
13684    (set (match_operand:XF 1 "register_operand" "=u")
13685         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13686   "TARGET_USE_FANCY_MATH_387
13687    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13688        || TARGET_MIX_SSE_I387)
13689    && flag_unsafe_math_optimizations"
13690   "fsincos"
13691   [(set_attr "type" "fpspc")
13692    (set_attr "mode" "XF")])
13693
13694 (define_split
13695   [(set (match_operand:XF 0 "register_operand" "")
13696         (unspec:XF [(float_extend:XF
13697                       (match_operand:MODEF 2 "register_operand" ""))]
13698                    UNSPEC_SINCOS_COS))
13699    (set (match_operand:XF 1 "register_operand" "")
13700         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13701   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13702    && can_create_pseudo_p ()"
13703   [(set (match_dup 1)
13704         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13705
13706 (define_split
13707   [(set (match_operand:XF 0 "register_operand" "")
13708         (unspec:XF [(float_extend:XF
13709                       (match_operand:MODEF 2 "register_operand" ""))]
13710                    UNSPEC_SINCOS_COS))
13711    (set (match_operand:XF 1 "register_operand" "")
13712         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13713   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13714    && can_create_pseudo_p ()"
13715   [(set (match_dup 0)
13716         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13717
13718 (define_expand "sincos<mode>3"
13719   [(use (match_operand:MODEF 0 "register_operand" ""))
13720    (use (match_operand:MODEF 1 "register_operand" ""))
13721    (use (match_operand:MODEF 2 "register_operand" ""))]
13722   "TARGET_USE_FANCY_MATH_387
13723    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13724        || TARGET_MIX_SSE_I387)
13725    && flag_unsafe_math_optimizations"
13726 {
13727   rtx op0 = gen_reg_rtx (XFmode);
13728   rtx op1 = gen_reg_rtx (XFmode);
13729
13730   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13731   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13732   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13733   DONE;
13734 })
13735
13736 (define_insn "fptanxf4_i387"
13737   [(set (match_operand:XF 0 "register_operand" "=f")
13738         (match_operand:XF 3 "const_double_operand" "F"))
13739    (set (match_operand:XF 1 "register_operand" "=u")
13740         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13741                    UNSPEC_TAN))]
13742   "TARGET_USE_FANCY_MATH_387
13743    && flag_unsafe_math_optimizations
13744    && standard_80387_constant_p (operands[3]) == 2"
13745   "fptan"
13746   [(set_attr "type" "fpspc")
13747    (set_attr "mode" "XF")])
13748
13749 (define_insn "fptan_extend<mode>xf4_i387"
13750   [(set (match_operand:MODEF 0 "register_operand" "=f")
13751         (match_operand:MODEF 3 "const_double_operand" "F"))
13752    (set (match_operand:XF 1 "register_operand" "=u")
13753         (unspec:XF [(float_extend:XF
13754                       (match_operand:MODEF 2 "register_operand" "0"))]
13755                    UNSPEC_TAN))]
13756   "TARGET_USE_FANCY_MATH_387
13757    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13758        || TARGET_MIX_SSE_I387)
13759    && flag_unsafe_math_optimizations
13760    && standard_80387_constant_p (operands[3]) == 2"
13761   "fptan"
13762   [(set_attr "type" "fpspc")
13763    (set_attr "mode" "XF")])
13764
13765 (define_expand "tanxf2"
13766   [(use (match_operand:XF 0 "register_operand" ""))
13767    (use (match_operand:XF 1 "register_operand" ""))]
13768   "TARGET_USE_FANCY_MATH_387
13769    && flag_unsafe_math_optimizations"
13770 {
13771   rtx one = gen_reg_rtx (XFmode);
13772   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13773
13774   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13775   DONE;
13776 })
13777
13778 (define_expand "tan<mode>2"
13779   [(use (match_operand:MODEF 0 "register_operand" ""))
13780    (use (match_operand:MODEF 1 "register_operand" ""))]
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 {
13786   rtx op0 = gen_reg_rtx (XFmode);
13787
13788   rtx one = gen_reg_rtx (<MODE>mode);
13789   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13790
13791   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13792                                              operands[1], op2));
13793   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13794   DONE;
13795 })
13796
13797 (define_insn "*fpatanxf3_i387"
13798   [(set (match_operand:XF 0 "register_operand" "=f")
13799         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13800                     (match_operand:XF 2 "register_operand" "u")]
13801                    UNSPEC_FPATAN))
13802    (clobber (match_scratch:XF 3 "=2"))]
13803   "TARGET_USE_FANCY_MATH_387
13804    && flag_unsafe_math_optimizations"
13805   "fpatan"
13806   [(set_attr "type" "fpspc")
13807    (set_attr "mode" "XF")])
13808
13809 (define_insn "fpatan_extend<mode>xf3_i387"
13810   [(set (match_operand:XF 0 "register_operand" "=f")
13811         (unspec:XF [(float_extend:XF
13812                       (match_operand:MODEF 1 "register_operand" "0"))
13813                     (float_extend:XF
13814                       (match_operand:MODEF 2 "register_operand" "u"))]
13815                    UNSPEC_FPATAN))
13816    (clobber (match_scratch:XF 3 "=2"))]
13817   "TARGET_USE_FANCY_MATH_387
13818    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13819        || TARGET_MIX_SSE_I387)
13820    && flag_unsafe_math_optimizations"
13821   "fpatan"
13822   [(set_attr "type" "fpspc")
13823    (set_attr "mode" "XF")])
13824
13825 (define_expand "atan2xf3"
13826   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13827                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
13828                                (match_operand:XF 1 "register_operand" "")]
13829                               UNSPEC_FPATAN))
13830               (clobber (match_scratch:XF 3 ""))])]
13831   "TARGET_USE_FANCY_MATH_387
13832    && flag_unsafe_math_optimizations")
13833
13834 (define_expand "atan2<mode>3"
13835   [(use (match_operand:MODEF 0 "register_operand" ""))
13836    (use (match_operand:MODEF 1 "register_operand" ""))
13837    (use (match_operand:MODEF 2 "register_operand" ""))]
13838   "TARGET_USE_FANCY_MATH_387
13839    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13840        || TARGET_MIX_SSE_I387)
13841    && flag_unsafe_math_optimizations"
13842 {
13843   rtx op0 = gen_reg_rtx (XFmode);
13844
13845   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13846   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13847   DONE;
13848 })
13849
13850 (define_expand "atanxf2"
13851   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13852                    (unspec:XF [(match_dup 2)
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   operands[2] = gen_reg_rtx (XFmode);
13860   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13861 })
13862
13863 (define_expand "atan<mode>2"
13864   [(use (match_operand:MODEF 0 "register_operand" ""))
13865    (use (match_operand:MODEF 1 "register_operand" ""))]
13866   "TARGET_USE_FANCY_MATH_387
13867    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13868        || TARGET_MIX_SSE_I387)
13869    && flag_unsafe_math_optimizations"
13870 {
13871   rtx op0 = gen_reg_rtx (XFmode);
13872
13873   rtx op2 = gen_reg_rtx (<MODE>mode);
13874   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13875
13876   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13877   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13878   DONE;
13879 })
13880
13881 (define_expand "asinxf2"
13882   [(set (match_dup 2)
13883         (mult:XF (match_operand:XF 1 "register_operand" "")
13884                  (match_dup 1)))
13885    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13886    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13887    (parallel [(set (match_operand:XF 0 "register_operand" "")
13888                    (unspec:XF [(match_dup 5) (match_dup 1)]
13889                               UNSPEC_FPATAN))
13890               (clobber (match_scratch:XF 6 ""))])]
13891   "TARGET_USE_FANCY_MATH_387
13892    && flag_unsafe_math_optimizations"
13893 {
13894   int i;
13895
13896   if (optimize_insn_for_size_p ())
13897     FAIL;
13898
13899   for (i = 2; i < 6; i++)
13900     operands[i] = gen_reg_rtx (XFmode);
13901
13902   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13903 })
13904
13905 (define_expand "asin<mode>2"
13906   [(use (match_operand:MODEF 0 "register_operand" ""))
13907    (use (match_operand:MODEF 1 "general_operand" ""))]
13908  "TARGET_USE_FANCY_MATH_387
13909    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13910        || TARGET_MIX_SSE_I387)
13911    && flag_unsafe_math_optimizations"
13912 {
13913   rtx op0 = gen_reg_rtx (XFmode);
13914   rtx op1 = gen_reg_rtx (XFmode);
13915
13916   if (optimize_insn_for_size_p ())
13917     FAIL;
13918
13919   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13920   emit_insn (gen_asinxf2 (op0, op1));
13921   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13922   DONE;
13923 })
13924
13925 (define_expand "acosxf2"
13926   [(set (match_dup 2)
13927         (mult:XF (match_operand:XF 1 "register_operand" "")
13928                  (match_dup 1)))
13929    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13930    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13931    (parallel [(set (match_operand:XF 0 "register_operand" "")
13932                    (unspec:XF [(match_dup 1) (match_dup 5)]
13933                               UNSPEC_FPATAN))
13934               (clobber (match_scratch:XF 6 ""))])]
13935   "TARGET_USE_FANCY_MATH_387
13936    && flag_unsafe_math_optimizations"
13937 {
13938   int i;
13939
13940   if (optimize_insn_for_size_p ())
13941     FAIL;
13942
13943   for (i = 2; i < 6; i++)
13944     operands[i] = gen_reg_rtx (XFmode);
13945
13946   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13947 })
13948
13949 (define_expand "acos<mode>2"
13950   [(use (match_operand:MODEF 0 "register_operand" ""))
13951    (use (match_operand:MODEF 1 "general_operand" ""))]
13952  "TARGET_USE_FANCY_MATH_387
13953    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13954        || TARGET_MIX_SSE_I387)
13955    && flag_unsafe_math_optimizations"
13956 {
13957   rtx op0 = gen_reg_rtx (XFmode);
13958   rtx op1 = gen_reg_rtx (XFmode);
13959
13960   if (optimize_insn_for_size_p ())
13961     FAIL;
13962
13963   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13964   emit_insn (gen_acosxf2 (op0, op1));
13965   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13966   DONE;
13967 })
13968
13969 (define_insn "fyl2xxf3_i387"
13970   [(set (match_operand:XF 0 "register_operand" "=f")
13971         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13972                     (match_operand:XF 2 "register_operand" "u")]
13973                    UNSPEC_FYL2X))
13974    (clobber (match_scratch:XF 3 "=2"))]
13975   "TARGET_USE_FANCY_MATH_387
13976    && flag_unsafe_math_optimizations"
13977   "fyl2x"
13978   [(set_attr "type" "fpspc")
13979    (set_attr "mode" "XF")])
13980
13981 (define_insn "fyl2x_extend<mode>xf3_i387"
13982   [(set (match_operand:XF 0 "register_operand" "=f")
13983         (unspec:XF [(float_extend:XF
13984                       (match_operand:MODEF 1 "register_operand" "0"))
13985                     (match_operand:XF 2 "register_operand" "u")]
13986                    UNSPEC_FYL2X))
13987    (clobber (match_scratch:XF 3 "=2"))]
13988   "TARGET_USE_FANCY_MATH_387
13989    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13990        || TARGET_MIX_SSE_I387)
13991    && flag_unsafe_math_optimizations"
13992   "fyl2x"
13993   [(set_attr "type" "fpspc")
13994    (set_attr "mode" "XF")])
13995
13996 (define_expand "logxf2"
13997   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13998                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13999                                (match_dup 2)] UNSPEC_FYL2X))
14000               (clobber (match_scratch:XF 3 ""))])]
14001   "TARGET_USE_FANCY_MATH_387
14002    && flag_unsafe_math_optimizations"
14003 {
14004   operands[2] = gen_reg_rtx (XFmode);
14005   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14006 })
14007
14008 (define_expand "log<mode>2"
14009   [(use (match_operand:MODEF 0 "register_operand" ""))
14010    (use (match_operand:MODEF 1 "register_operand" ""))]
14011   "TARGET_USE_FANCY_MATH_387
14012    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14013        || TARGET_MIX_SSE_I387)
14014    && flag_unsafe_math_optimizations"
14015 {
14016   rtx op0 = gen_reg_rtx (XFmode);
14017
14018   rtx op2 = gen_reg_rtx (XFmode);
14019   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14020
14021   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14022   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14023   DONE;
14024 })
14025
14026 (define_expand "log10xf2"
14027   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14028                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14029                                (match_dup 2)] UNSPEC_FYL2X))
14030               (clobber (match_scratch:XF 3 ""))])]
14031   "TARGET_USE_FANCY_MATH_387
14032    && flag_unsafe_math_optimizations"
14033 {
14034   operands[2] = gen_reg_rtx (XFmode);
14035   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14036 })
14037
14038 (define_expand "log10<mode>2"
14039   [(use (match_operand:MODEF 0 "register_operand" ""))
14040    (use (match_operand:MODEF 1 "register_operand" ""))]
14041   "TARGET_USE_FANCY_MATH_387
14042    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14043        || TARGET_MIX_SSE_I387)
14044    && flag_unsafe_math_optimizations"
14045 {
14046   rtx op0 = gen_reg_rtx (XFmode);
14047
14048   rtx op2 = gen_reg_rtx (XFmode);
14049   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14050
14051   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14052   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14053   DONE;
14054 })
14055
14056 (define_expand "log2xf2"
14057   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14058                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14059                                (match_dup 2)] UNSPEC_FYL2X))
14060               (clobber (match_scratch:XF 3 ""))])]
14061   "TARGET_USE_FANCY_MATH_387
14062    && flag_unsafe_math_optimizations"
14063 {
14064   operands[2] = gen_reg_rtx (XFmode);
14065   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14066 })
14067
14068 (define_expand "log2<mode>2"
14069   [(use (match_operand:MODEF 0 "register_operand" ""))
14070    (use (match_operand:MODEF 1 "register_operand" ""))]
14071   "TARGET_USE_FANCY_MATH_387
14072    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14073        || TARGET_MIX_SSE_I387)
14074    && flag_unsafe_math_optimizations"
14075 {
14076   rtx op0 = gen_reg_rtx (XFmode);
14077
14078   rtx op2 = gen_reg_rtx (XFmode);
14079   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14080
14081   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14082   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14083   DONE;
14084 })
14085
14086 (define_insn "fyl2xp1xf3_i387"
14087   [(set (match_operand:XF 0 "register_operand" "=f")
14088         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14089                     (match_operand:XF 2 "register_operand" "u")]
14090                    UNSPEC_FYL2XP1))
14091    (clobber (match_scratch:XF 3 "=2"))]
14092   "TARGET_USE_FANCY_MATH_387
14093    && flag_unsafe_math_optimizations"
14094   "fyl2xp1"
14095   [(set_attr "type" "fpspc")
14096    (set_attr "mode" "XF")])
14097
14098 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14099   [(set (match_operand:XF 0 "register_operand" "=f")
14100         (unspec:XF [(float_extend:XF
14101                       (match_operand:MODEF 1 "register_operand" "0"))
14102                     (match_operand:XF 2 "register_operand" "u")]
14103                    UNSPEC_FYL2XP1))
14104    (clobber (match_scratch:XF 3 "=2"))]
14105   "TARGET_USE_FANCY_MATH_387
14106    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14107        || TARGET_MIX_SSE_I387)
14108    && flag_unsafe_math_optimizations"
14109   "fyl2xp1"
14110   [(set_attr "type" "fpspc")
14111    (set_attr "mode" "XF")])
14112
14113 (define_expand "log1pxf2"
14114   [(use (match_operand:XF 0 "register_operand" ""))
14115    (use (match_operand:XF 1 "register_operand" ""))]
14116   "TARGET_USE_FANCY_MATH_387
14117    && flag_unsafe_math_optimizations"
14118 {
14119   if (optimize_insn_for_size_p ())
14120     FAIL;
14121
14122   ix86_emit_i387_log1p (operands[0], operands[1]);
14123   DONE;
14124 })
14125
14126 (define_expand "log1p<mode>2"
14127   [(use (match_operand:MODEF 0 "register_operand" ""))
14128    (use (match_operand:MODEF 1 "register_operand" ""))]
14129   "TARGET_USE_FANCY_MATH_387
14130    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14131        || TARGET_MIX_SSE_I387)
14132    && flag_unsafe_math_optimizations"
14133 {
14134   rtx op0;
14135
14136   if (optimize_insn_for_size_p ())
14137     FAIL;
14138
14139   op0 = gen_reg_rtx (XFmode);
14140
14141   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14142
14143   ix86_emit_i387_log1p (op0, operands[1]);
14144   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14145   DONE;
14146 })
14147
14148 (define_insn "fxtractxf3_i387"
14149   [(set (match_operand:XF 0 "register_operand" "=f")
14150         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14151                    UNSPEC_XTRACT_FRACT))
14152    (set (match_operand:XF 1 "register_operand" "=u")
14153         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14154   "TARGET_USE_FANCY_MATH_387
14155    && flag_unsafe_math_optimizations"
14156   "fxtract"
14157   [(set_attr "type" "fpspc")
14158    (set_attr "mode" "XF")])
14159
14160 (define_insn "fxtract_extend<mode>xf3_i387"
14161   [(set (match_operand:XF 0 "register_operand" "=f")
14162         (unspec:XF [(float_extend:XF
14163                       (match_operand:MODEF 2 "register_operand" "0"))]
14164                    UNSPEC_XTRACT_FRACT))
14165    (set (match_operand:XF 1 "register_operand" "=u")
14166         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14167   "TARGET_USE_FANCY_MATH_387
14168    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14169        || TARGET_MIX_SSE_I387)
14170    && flag_unsafe_math_optimizations"
14171   "fxtract"
14172   [(set_attr "type" "fpspc")
14173    (set_attr "mode" "XF")])
14174
14175 (define_expand "logbxf2"
14176   [(parallel [(set (match_dup 2)
14177                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14178                               UNSPEC_XTRACT_FRACT))
14179               (set (match_operand:XF 0 "register_operand" "")
14180                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14181   "TARGET_USE_FANCY_MATH_387
14182    && flag_unsafe_math_optimizations"
14183   "operands[2] = gen_reg_rtx (XFmode);")
14184
14185 (define_expand "logb<mode>2"
14186   [(use (match_operand:MODEF 0 "register_operand" ""))
14187    (use (match_operand:MODEF 1 "register_operand" ""))]
14188   "TARGET_USE_FANCY_MATH_387
14189    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14190        || TARGET_MIX_SSE_I387)
14191    && flag_unsafe_math_optimizations"
14192 {
14193   rtx op0 = gen_reg_rtx (XFmode);
14194   rtx op1 = gen_reg_rtx (XFmode);
14195
14196   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14197   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14198   DONE;
14199 })
14200
14201 (define_expand "ilogbxf2"
14202   [(use (match_operand:SI 0 "register_operand" ""))
14203    (use (match_operand:XF 1 "register_operand" ""))]
14204   "TARGET_USE_FANCY_MATH_387
14205    && flag_unsafe_math_optimizations"
14206 {
14207   rtx op0, op1;
14208
14209   if (optimize_insn_for_size_p ())
14210     FAIL;
14211
14212   op0 = gen_reg_rtx (XFmode);
14213   op1 = gen_reg_rtx (XFmode);
14214
14215   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14216   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14217   DONE;
14218 })
14219
14220 (define_expand "ilogb<mode>2"
14221   [(use (match_operand:SI 0 "register_operand" ""))
14222    (use (match_operand:MODEF 1 "register_operand" ""))]
14223   "TARGET_USE_FANCY_MATH_387
14224    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14225        || TARGET_MIX_SSE_I387)
14226    && flag_unsafe_math_optimizations"
14227 {
14228   rtx op0, op1;
14229
14230   if (optimize_insn_for_size_p ())
14231     FAIL;
14232
14233   op0 = gen_reg_rtx (XFmode);
14234   op1 = gen_reg_rtx (XFmode);
14235
14236   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14237   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14238   DONE;
14239 })
14240
14241 (define_insn "*f2xm1xf2_i387"
14242   [(set (match_operand:XF 0 "register_operand" "=f")
14243         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14244                    UNSPEC_F2XM1))]
14245   "TARGET_USE_FANCY_MATH_387
14246    && flag_unsafe_math_optimizations"
14247   "f2xm1"
14248   [(set_attr "type" "fpspc")
14249    (set_attr "mode" "XF")])
14250
14251 (define_insn "*fscalexf4_i387"
14252   [(set (match_operand:XF 0 "register_operand" "=f")
14253         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14254                     (match_operand:XF 3 "register_operand" "1")]
14255                    UNSPEC_FSCALE_FRACT))
14256    (set (match_operand:XF 1 "register_operand" "=u")
14257         (unspec:XF [(match_dup 2) (match_dup 3)]
14258                    UNSPEC_FSCALE_EXP))]
14259   "TARGET_USE_FANCY_MATH_387
14260    && flag_unsafe_math_optimizations"
14261   "fscale"
14262   [(set_attr "type" "fpspc")
14263    (set_attr "mode" "XF")])
14264
14265 (define_expand "expNcorexf3"
14266   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14267                                (match_operand:XF 2 "register_operand" "")))
14268    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14269    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14270    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14271    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14272    (parallel [(set (match_operand:XF 0 "register_operand" "")
14273                    (unspec:XF [(match_dup 8) (match_dup 4)]
14274                               UNSPEC_FSCALE_FRACT))
14275               (set (match_dup 9)
14276                    (unspec:XF [(match_dup 8) (match_dup 4)]
14277                               UNSPEC_FSCALE_EXP))])]
14278   "TARGET_USE_FANCY_MATH_387
14279    && flag_unsafe_math_optimizations"
14280 {
14281   int i;
14282
14283   if (optimize_insn_for_size_p ())
14284     FAIL;
14285
14286   for (i = 3; i < 10; i++)
14287     operands[i] = gen_reg_rtx (XFmode);
14288
14289   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14290 })
14291
14292 (define_expand "expxf2"
14293   [(use (match_operand:XF 0 "register_operand" ""))
14294    (use (match_operand:XF 1 "register_operand" ""))]
14295   "TARGET_USE_FANCY_MATH_387
14296    && flag_unsafe_math_optimizations"
14297 {
14298   rtx op2;
14299
14300   if (optimize_insn_for_size_p ())
14301     FAIL;
14302
14303   op2 = gen_reg_rtx (XFmode);
14304   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14305
14306   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14307   DONE;
14308 })
14309
14310 (define_expand "exp<mode>2"
14311   [(use (match_operand:MODEF 0 "register_operand" ""))
14312    (use (match_operand:MODEF 1 "general_operand" ""))]
14313  "TARGET_USE_FANCY_MATH_387
14314    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14315        || TARGET_MIX_SSE_I387)
14316    && flag_unsafe_math_optimizations"
14317 {
14318   rtx op0, op1;
14319
14320   if (optimize_insn_for_size_p ())
14321     FAIL;
14322
14323   op0 = gen_reg_rtx (XFmode);
14324   op1 = gen_reg_rtx (XFmode);
14325
14326   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14327   emit_insn (gen_expxf2 (op0, op1));
14328   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14329   DONE;
14330 })
14331
14332 (define_expand "exp10xf2"
14333   [(use (match_operand:XF 0 "register_operand" ""))
14334    (use (match_operand:XF 1 "register_operand" ""))]
14335   "TARGET_USE_FANCY_MATH_387
14336    && flag_unsafe_math_optimizations"
14337 {
14338   rtx op2;
14339
14340   if (optimize_insn_for_size_p ())
14341     FAIL;
14342
14343   op2 = gen_reg_rtx (XFmode);
14344   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14345
14346   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14347   DONE;
14348 })
14349
14350 (define_expand "exp10<mode>2"
14351   [(use (match_operand:MODEF 0 "register_operand" ""))
14352    (use (match_operand:MODEF 1 "general_operand" ""))]
14353  "TARGET_USE_FANCY_MATH_387
14354    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14355        || TARGET_MIX_SSE_I387)
14356    && flag_unsafe_math_optimizations"
14357 {
14358   rtx op0, op1;
14359
14360   if (optimize_insn_for_size_p ())
14361     FAIL;
14362
14363   op0 = gen_reg_rtx (XFmode);
14364   op1 = gen_reg_rtx (XFmode);
14365
14366   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14367   emit_insn (gen_exp10xf2 (op0, op1));
14368   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14369   DONE;
14370 })
14371
14372 (define_expand "exp2xf2"
14373   [(use (match_operand:XF 0 "register_operand" ""))
14374    (use (match_operand:XF 1 "register_operand" ""))]
14375   "TARGET_USE_FANCY_MATH_387
14376    && flag_unsafe_math_optimizations"
14377 {
14378   rtx op2;
14379
14380   if (optimize_insn_for_size_p ())
14381     FAIL;
14382
14383   op2 = gen_reg_rtx (XFmode);
14384   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14385
14386   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14387   DONE;
14388 })
14389
14390 (define_expand "exp2<mode>2"
14391   [(use (match_operand:MODEF 0 "register_operand" ""))
14392    (use (match_operand:MODEF 1 "general_operand" ""))]
14393  "TARGET_USE_FANCY_MATH_387
14394    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14395        || TARGET_MIX_SSE_I387)
14396    && flag_unsafe_math_optimizations"
14397 {
14398   rtx op0, op1;
14399
14400   if (optimize_insn_for_size_p ())
14401     FAIL;
14402
14403   op0 = gen_reg_rtx (XFmode);
14404   op1 = gen_reg_rtx (XFmode);
14405
14406   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14407   emit_insn (gen_exp2xf2 (op0, op1));
14408   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14409   DONE;
14410 })
14411
14412 (define_expand "expm1xf2"
14413   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14414                                (match_dup 2)))
14415    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14416    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14417    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14418    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14419    (parallel [(set (match_dup 7)
14420                    (unspec:XF [(match_dup 6) (match_dup 4)]
14421                               UNSPEC_FSCALE_FRACT))
14422               (set (match_dup 8)
14423                    (unspec:XF [(match_dup 6) (match_dup 4)]
14424                               UNSPEC_FSCALE_EXP))])
14425    (parallel [(set (match_dup 10)
14426                    (unspec:XF [(match_dup 9) (match_dup 8)]
14427                               UNSPEC_FSCALE_FRACT))
14428               (set (match_dup 11)
14429                    (unspec:XF [(match_dup 9) (match_dup 8)]
14430                               UNSPEC_FSCALE_EXP))])
14431    (set (match_dup 12) (minus:XF (match_dup 10)
14432                                  (float_extend:XF (match_dup 13))))
14433    (set (match_operand:XF 0 "register_operand" "")
14434         (plus:XF (match_dup 12) (match_dup 7)))]
14435   "TARGET_USE_FANCY_MATH_387
14436    && flag_unsafe_math_optimizations"
14437 {
14438   int i;
14439
14440   if (optimize_insn_for_size_p ())
14441     FAIL;
14442
14443   for (i = 2; i < 13; i++)
14444     operands[i] = gen_reg_rtx (XFmode);
14445
14446   operands[13]
14447     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14448
14449   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14450 })
14451
14452 (define_expand "expm1<mode>2"
14453   [(use (match_operand:MODEF 0 "register_operand" ""))
14454    (use (match_operand:MODEF 1 "general_operand" ""))]
14455  "TARGET_USE_FANCY_MATH_387
14456    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14457        || TARGET_MIX_SSE_I387)
14458    && flag_unsafe_math_optimizations"
14459 {
14460   rtx op0, op1;
14461
14462   if (optimize_insn_for_size_p ())
14463     FAIL;
14464
14465   op0 = gen_reg_rtx (XFmode);
14466   op1 = gen_reg_rtx (XFmode);
14467
14468   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14469   emit_insn (gen_expm1xf2 (op0, op1));
14470   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14471   DONE;
14472 })
14473
14474 (define_expand "ldexpxf3"
14475   [(set (match_dup 3)
14476         (float:XF (match_operand:SI 2 "register_operand" "")))
14477    (parallel [(set (match_operand:XF 0 " register_operand" "")
14478                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14479                                (match_dup 3)]
14480                               UNSPEC_FSCALE_FRACT))
14481               (set (match_dup 4)
14482                    (unspec:XF [(match_dup 1) (match_dup 3)]
14483                               UNSPEC_FSCALE_EXP))])]
14484   "TARGET_USE_FANCY_MATH_387
14485    && flag_unsafe_math_optimizations"
14486 {
14487   if (optimize_insn_for_size_p ())
14488     FAIL;
14489
14490   operands[3] = gen_reg_rtx (XFmode);
14491   operands[4] = gen_reg_rtx (XFmode);
14492 })
14493
14494 (define_expand "ldexp<mode>3"
14495   [(use (match_operand:MODEF 0 "register_operand" ""))
14496    (use (match_operand:MODEF 1 "general_operand" ""))
14497    (use (match_operand:SI 2 "register_operand" ""))]
14498  "TARGET_USE_FANCY_MATH_387
14499    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14500        || TARGET_MIX_SSE_I387)
14501    && flag_unsafe_math_optimizations"
14502 {
14503   rtx op0, op1;
14504
14505   if (optimize_insn_for_size_p ())
14506     FAIL;
14507
14508   op0 = gen_reg_rtx (XFmode);
14509   op1 = gen_reg_rtx (XFmode);
14510
14511   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14512   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14513   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14514   DONE;
14515 })
14516
14517 (define_expand "scalbxf3"
14518   [(parallel [(set (match_operand:XF 0 " register_operand" "")
14519                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14520                                (match_operand:XF 2 "register_operand" "")]
14521                               UNSPEC_FSCALE_FRACT))
14522               (set (match_dup 3)
14523                    (unspec:XF [(match_dup 1) (match_dup 2)]
14524                               UNSPEC_FSCALE_EXP))])]
14525   "TARGET_USE_FANCY_MATH_387
14526    && flag_unsafe_math_optimizations"
14527 {
14528   if (optimize_insn_for_size_p ())
14529     FAIL;
14530
14531   operands[3] = gen_reg_rtx (XFmode);
14532 })
14533
14534 (define_expand "scalb<mode>3"
14535   [(use (match_operand:MODEF 0 "register_operand" ""))
14536    (use (match_operand:MODEF 1 "general_operand" ""))
14537    (use (match_operand:MODEF 2 "general_operand" ""))]
14538  "TARGET_USE_FANCY_MATH_387
14539    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14540        || TARGET_MIX_SSE_I387)
14541    && flag_unsafe_math_optimizations"
14542 {
14543   rtx op0, op1, op2;
14544
14545   if (optimize_insn_for_size_p ())
14546     FAIL;
14547
14548   op0 = gen_reg_rtx (XFmode);
14549   op1 = gen_reg_rtx (XFmode);
14550   op2 = gen_reg_rtx (XFmode);
14551
14552   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14553   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14554   emit_insn (gen_scalbxf3 (op0, op1, op2));
14555   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14556   DONE;
14557 })
14558
14559 (define_expand "significandxf2"
14560   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14561                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14562                               UNSPEC_XTRACT_FRACT))
14563               (set (match_dup 2)
14564                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14565   "TARGET_USE_FANCY_MATH_387
14566    && flag_unsafe_math_optimizations"
14567   "operands[2] = gen_reg_rtx (XFmode);")
14568
14569 (define_expand "significand<mode>2"
14570   [(use (match_operand:MODEF 0 "register_operand" ""))
14571    (use (match_operand:MODEF 1 "register_operand" ""))]
14572   "TARGET_USE_FANCY_MATH_387
14573    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14574        || TARGET_MIX_SSE_I387)
14575    && flag_unsafe_math_optimizations"
14576 {
14577   rtx op0 = gen_reg_rtx (XFmode);
14578   rtx op1 = gen_reg_rtx (XFmode);
14579
14580   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14581   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14582   DONE;
14583 })
14584 \f
14585
14586 (define_insn "sse4_1_round<mode>2"
14587   [(set (match_operand:MODEF 0 "register_operand" "=x")
14588         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14589                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14590                       UNSPEC_ROUND))]
14591   "TARGET_ROUND"
14592   "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14593   [(set_attr "type" "ssecvt")
14594    (set_attr "prefix_extra" "1")
14595    (set_attr "prefix" "maybe_vex")
14596    (set_attr "mode" "<MODE>")])
14597
14598 (define_insn "rintxf2"
14599   [(set (match_operand:XF 0 "register_operand" "=f")
14600         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14601                    UNSPEC_FRNDINT))]
14602   "TARGET_USE_FANCY_MATH_387
14603    && flag_unsafe_math_optimizations"
14604   "frndint"
14605   [(set_attr "type" "fpspc")
14606    (set_attr "mode" "XF")])
14607
14608 (define_expand "rint<mode>2"
14609   [(use (match_operand:MODEF 0 "register_operand" ""))
14610    (use (match_operand:MODEF 1 "register_operand" ""))]
14611   "(TARGET_USE_FANCY_MATH_387
14612     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14613         || TARGET_MIX_SSE_I387)
14614     && flag_unsafe_math_optimizations)
14615    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14616        && !flag_trapping_math)"
14617 {
14618   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14619       && !flag_trapping_math)
14620     {
14621       if (TARGET_ROUND)
14622         emit_insn (gen_sse4_1_round<mode>2
14623                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14624       else if (optimize_insn_for_size_p ())
14625         FAIL;
14626       else
14627         ix86_expand_rint (operands[0], operands[1]);
14628     }
14629   else
14630     {
14631       rtx op0 = gen_reg_rtx (XFmode);
14632       rtx op1 = gen_reg_rtx (XFmode);
14633
14634       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14635       emit_insn (gen_rintxf2 (op0, op1));
14636
14637       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14638     }
14639   DONE;
14640 })
14641
14642 (define_expand "round<mode>2"
14643   [(match_operand:X87MODEF 0 "register_operand" "")
14644    (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14645   "(TARGET_USE_FANCY_MATH_387
14646     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14647         || TARGET_MIX_SSE_I387)
14648     && flag_unsafe_math_optimizations)
14649    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14650        && !flag_trapping_math && !flag_rounding_math)"
14651 {
14652   if (optimize_insn_for_size_p ())
14653     FAIL;
14654
14655   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14656       && !flag_trapping_math && !flag_rounding_math)
14657     {
14658       if (TARGET_ROUND)
14659         {
14660           operands[1] = force_reg (<MODE>mode, operands[1]);
14661           ix86_expand_round_sse4 (operands[0], operands[1]);
14662         }
14663       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14664         ix86_expand_round (operands[0], operands[1]);
14665       else
14666         ix86_expand_rounddf_32 (operands[0], operands[1]);
14667     }
14668   else
14669     {
14670       operands[1] = force_reg (<MODE>mode, operands[1]);
14671       ix86_emit_i387_round (operands[0], operands[1]);
14672     }
14673   DONE;
14674 })
14675
14676 (define_insn_and_split "*fistdi2_1"
14677   [(set (match_operand:DI 0 "nonimmediate_operand" "")
14678         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14679                    UNSPEC_FIST))]
14680   "TARGET_USE_FANCY_MATH_387
14681    && can_create_pseudo_p ()"
14682   "#"
14683   "&& 1"
14684   [(const_int 0)]
14685 {
14686   if (memory_operand (operands[0], VOIDmode))
14687     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14688   else
14689     {
14690       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14691       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14692                                          operands[2]));
14693     }
14694   DONE;
14695 }
14696   [(set_attr "type" "fpspc")
14697    (set_attr "mode" "DI")])
14698
14699 (define_insn "fistdi2"
14700   [(set (match_operand:DI 0 "memory_operand" "=m")
14701         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14702                    UNSPEC_FIST))
14703    (clobber (match_scratch:XF 2 "=&1f"))]
14704   "TARGET_USE_FANCY_MATH_387"
14705   "* return output_fix_trunc (insn, operands, false);"
14706   [(set_attr "type" "fpspc")
14707    (set_attr "mode" "DI")])
14708
14709 (define_insn "fistdi2_with_temp"
14710   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14711         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14712                    UNSPEC_FIST))
14713    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14714    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14715   "TARGET_USE_FANCY_MATH_387"
14716   "#"
14717   [(set_attr "type" "fpspc")
14718    (set_attr "mode" "DI")])
14719
14720 (define_split
14721   [(set (match_operand:DI 0 "register_operand" "")
14722         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14723                    UNSPEC_FIST))
14724    (clobber (match_operand:DI 2 "memory_operand" ""))
14725    (clobber (match_scratch 3 ""))]
14726   "reload_completed"
14727   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14728               (clobber (match_dup 3))])
14729    (set (match_dup 0) (match_dup 2))])
14730
14731 (define_split
14732   [(set (match_operand:DI 0 "memory_operand" "")
14733         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14734                    UNSPEC_FIST))
14735    (clobber (match_operand:DI 2 "memory_operand" ""))
14736    (clobber (match_scratch 3 ""))]
14737   "reload_completed"
14738   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14739               (clobber (match_dup 3))])])
14740
14741 (define_insn_and_split "*fist<mode>2_1"
14742   [(set (match_operand:SWI24 0 "register_operand" "")
14743         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14744                       UNSPEC_FIST))]
14745   "TARGET_USE_FANCY_MATH_387
14746    && can_create_pseudo_p ()"
14747   "#"
14748   "&& 1"
14749   [(const_int 0)]
14750 {
14751   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14752   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14753                                         operands[2]));
14754   DONE;
14755 }
14756   [(set_attr "type" "fpspc")
14757    (set_attr "mode" "<MODE>")])
14758
14759 (define_insn "fist<mode>2"
14760   [(set (match_operand:SWI24 0 "memory_operand" "=m")
14761         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14762                       UNSPEC_FIST))]
14763   "TARGET_USE_FANCY_MATH_387"
14764   "* return output_fix_trunc (insn, operands, false);"
14765   [(set_attr "type" "fpspc")
14766    (set_attr "mode" "<MODE>")])
14767
14768 (define_insn "fist<mode>2_with_temp"
14769   [(set (match_operand:SWI24 0 "register_operand" "=r")
14770         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14771                       UNSPEC_FIST))
14772    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14773   "TARGET_USE_FANCY_MATH_387"
14774   "#"
14775   [(set_attr "type" "fpspc")
14776    (set_attr "mode" "<MODE>")])
14777
14778 (define_split
14779   [(set (match_operand:SWI24 0 "register_operand" "")
14780         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14781                       UNSPEC_FIST))
14782    (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14783   "reload_completed"
14784   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14785    (set (match_dup 0) (match_dup 2))])
14786
14787 (define_split
14788   [(set (match_operand:SWI24 0 "memory_operand" "")
14789         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14790                       UNSPEC_FIST))
14791    (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14792   "reload_completed"
14793   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14794
14795 (define_expand "lrintxf<mode>2"
14796   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14797      (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14798                      UNSPEC_FIST))]
14799   "TARGET_USE_FANCY_MATH_387")
14800
14801 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14802   [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14803      (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14804                         UNSPEC_FIX_NOTRUNC))]
14805   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14806    && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14807
14808 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14809   [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14810    (match_operand:X87MODEF 1 "register_operand" "")]
14811   "(TARGET_USE_FANCY_MATH_387
14812     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14813         || TARGET_MIX_SSE_I387)
14814     && flag_unsafe_math_optimizations)
14815    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14816        && <SWI248x:MODE>mode != HImode 
14817        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14818        && !flag_trapping_math && !flag_rounding_math)"
14819 {
14820   if (optimize_insn_for_size_p ())
14821     FAIL;
14822
14823   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14824       && <SWI248x:MODE>mode != HImode
14825       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14826       && !flag_trapping_math && !flag_rounding_math)
14827     ix86_expand_lround (operands[0], operands[1]);
14828   else
14829     ix86_emit_i387_round (operands[0], operands[1]);
14830   DONE;
14831 })
14832
14833 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14834 (define_insn_and_split "frndintxf2_floor"
14835   [(set (match_operand:XF 0 "register_operand" "")
14836         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14837          UNSPEC_FRNDINT_FLOOR))
14838    (clobber (reg:CC FLAGS_REG))]
14839   "TARGET_USE_FANCY_MATH_387
14840    && flag_unsafe_math_optimizations
14841    && can_create_pseudo_p ()"
14842   "#"
14843   "&& 1"
14844   [(const_int 0)]
14845 {
14846   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14847
14848   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14849   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14850
14851   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14852                                         operands[2], operands[3]));
14853   DONE;
14854 }
14855   [(set_attr "type" "frndint")
14856    (set_attr "i387_cw" "floor")
14857    (set_attr "mode" "XF")])
14858
14859 (define_insn "frndintxf2_floor_i387"
14860   [(set (match_operand:XF 0 "register_operand" "=f")
14861         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14862          UNSPEC_FRNDINT_FLOOR))
14863    (use (match_operand:HI 2 "memory_operand" "m"))
14864    (use (match_operand:HI 3 "memory_operand" "m"))]
14865   "TARGET_USE_FANCY_MATH_387
14866    && flag_unsafe_math_optimizations"
14867   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14868   [(set_attr "type" "frndint")
14869    (set_attr "i387_cw" "floor")
14870    (set_attr "mode" "XF")])
14871
14872 (define_expand "floorxf2"
14873   [(use (match_operand:XF 0 "register_operand" ""))
14874    (use (match_operand:XF 1 "register_operand" ""))]
14875   "TARGET_USE_FANCY_MATH_387
14876    && flag_unsafe_math_optimizations"
14877 {
14878   if (optimize_insn_for_size_p ())
14879     FAIL;
14880   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14881   DONE;
14882 })
14883
14884 (define_expand "floor<mode>2"
14885   [(use (match_operand:MODEF 0 "register_operand" ""))
14886    (use (match_operand:MODEF 1 "register_operand" ""))]
14887   "(TARGET_USE_FANCY_MATH_387
14888     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14889         || TARGET_MIX_SSE_I387)
14890     && flag_unsafe_math_optimizations)
14891    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14892        && !flag_trapping_math)"
14893 {
14894   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14895       && !flag_trapping_math)
14896     {
14897       if (TARGET_ROUND)
14898         emit_insn (gen_sse4_1_round<mode>2
14899                    (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14900       else if (optimize_insn_for_size_p ())
14901         FAIL;
14902       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14903         ix86_expand_floorceil (operands[0], operands[1], true);
14904       else
14905         ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14906     }
14907   else
14908     {
14909       rtx op0, op1;
14910
14911       if (optimize_insn_for_size_p ())
14912         FAIL;
14913
14914       op0 = gen_reg_rtx (XFmode);
14915       op1 = gen_reg_rtx (XFmode);
14916       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14917       emit_insn (gen_frndintxf2_floor (op0, op1));
14918
14919       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14920     }
14921   DONE;
14922 })
14923
14924 (define_insn_and_split "*fist<mode>2_floor_1"
14925   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14926         (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14927                         UNSPEC_FIST_FLOOR))
14928    (clobber (reg:CC FLAGS_REG))]
14929   "TARGET_USE_FANCY_MATH_387
14930    && flag_unsafe_math_optimizations
14931    && can_create_pseudo_p ()"
14932   "#"
14933   "&& 1"
14934   [(const_int 0)]
14935 {
14936   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14937
14938   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14939   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14940   if (memory_operand (operands[0], VOIDmode))
14941     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14942                                       operands[2], operands[3]));
14943   else
14944     {
14945       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14946       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14947                                                   operands[2], operands[3],
14948                                                   operands[4]));
14949     }
14950   DONE;
14951 }
14952   [(set_attr "type" "fistp")
14953    (set_attr "i387_cw" "floor")
14954    (set_attr "mode" "<MODE>")])
14955
14956 (define_insn "fistdi2_floor"
14957   [(set (match_operand:DI 0 "memory_operand" "=m")
14958         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14959                    UNSPEC_FIST_FLOOR))
14960    (use (match_operand:HI 2 "memory_operand" "m"))
14961    (use (match_operand:HI 3 "memory_operand" "m"))
14962    (clobber (match_scratch:XF 4 "=&1f"))]
14963   "TARGET_USE_FANCY_MATH_387
14964    && flag_unsafe_math_optimizations"
14965   "* return output_fix_trunc (insn, operands, false);"
14966   [(set_attr "type" "fistp")
14967    (set_attr "i387_cw" "floor")
14968    (set_attr "mode" "DI")])
14969
14970 (define_insn "fistdi2_floor_with_temp"
14971   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14972         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14973                    UNSPEC_FIST_FLOOR))
14974    (use (match_operand:HI 2 "memory_operand" "m,m"))
14975    (use (match_operand:HI 3 "memory_operand" "m,m"))
14976    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14977    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14978   "TARGET_USE_FANCY_MATH_387
14979    && flag_unsafe_math_optimizations"
14980   "#"
14981   [(set_attr "type" "fistp")
14982    (set_attr "i387_cw" "floor")
14983    (set_attr "mode" "DI")])
14984
14985 (define_split
14986   [(set (match_operand:DI 0 "register_operand" "")
14987         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14988                    UNSPEC_FIST_FLOOR))
14989    (use (match_operand:HI 2 "memory_operand" ""))
14990    (use (match_operand:HI 3 "memory_operand" ""))
14991    (clobber (match_operand:DI 4 "memory_operand" ""))
14992    (clobber (match_scratch 5 ""))]
14993   "reload_completed"
14994   [(parallel [(set (match_dup 4)
14995                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14996               (use (match_dup 2))
14997               (use (match_dup 3))
14998               (clobber (match_dup 5))])
14999    (set (match_dup 0) (match_dup 4))])
15000
15001 (define_split
15002   [(set (match_operand:DI 0 "memory_operand" "")
15003         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15004                    UNSPEC_FIST_FLOOR))
15005    (use (match_operand:HI 2 "memory_operand" ""))
15006    (use (match_operand:HI 3 "memory_operand" ""))
15007    (clobber (match_operand:DI 4 "memory_operand" ""))
15008    (clobber (match_scratch 5 ""))]
15009   "reload_completed"
15010   [(parallel [(set (match_dup 0)
15011                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15012               (use (match_dup 2))
15013               (use (match_dup 3))
15014               (clobber (match_dup 5))])])
15015
15016 (define_insn "fist<mode>2_floor"
15017   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15018         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15019                       UNSPEC_FIST_FLOOR))
15020    (use (match_operand:HI 2 "memory_operand" "m"))
15021    (use (match_operand:HI 3 "memory_operand" "m"))]
15022   "TARGET_USE_FANCY_MATH_387
15023    && flag_unsafe_math_optimizations"
15024   "* return output_fix_trunc (insn, operands, false);"
15025   [(set_attr "type" "fistp")
15026    (set_attr "i387_cw" "floor")
15027    (set_attr "mode" "<MODE>")])
15028
15029 (define_insn "fist<mode>2_floor_with_temp"
15030   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15031         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15032                       UNSPEC_FIST_FLOOR))
15033    (use (match_operand:HI 2 "memory_operand" "m,m"))
15034    (use (match_operand:HI 3 "memory_operand" "m,m"))
15035    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15036   "TARGET_USE_FANCY_MATH_387
15037    && flag_unsafe_math_optimizations"
15038   "#"
15039   [(set_attr "type" "fistp")
15040    (set_attr "i387_cw" "floor")
15041    (set_attr "mode" "<MODE>")])
15042
15043 (define_split
15044   [(set (match_operand:SWI24 0 "register_operand" "")
15045         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15046                       UNSPEC_FIST_FLOOR))
15047    (use (match_operand:HI 2 "memory_operand" ""))
15048    (use (match_operand:HI 3 "memory_operand" ""))
15049    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15050   "reload_completed"
15051   [(parallel [(set (match_dup 4)
15052                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15053               (use (match_dup 2))
15054               (use (match_dup 3))])
15055    (set (match_dup 0) (match_dup 4))])
15056
15057 (define_split
15058   [(set (match_operand:SWI24 0 "memory_operand" "")
15059         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15060                       UNSPEC_FIST_FLOOR))
15061    (use (match_operand:HI 2 "memory_operand" ""))
15062    (use (match_operand:HI 3 "memory_operand" ""))
15063    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15064   "reload_completed"
15065   [(parallel [(set (match_dup 0)
15066                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15067               (use (match_dup 2))
15068               (use (match_dup 3))])])
15069
15070 (define_expand "lfloorxf<mode>2"
15071   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15072                    (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15073                                    UNSPEC_FIST_FLOOR))
15074               (clobber (reg:CC FLAGS_REG))])]
15075   "TARGET_USE_FANCY_MATH_387
15076    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15077    && flag_unsafe_math_optimizations")
15078
15079 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15080   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15081    (match_operand:MODEF 1 "register_operand" "")]
15082   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15083    && !flag_trapping_math"
15084 {
15085   if (TARGET_64BIT && optimize_insn_for_size_p ())
15086     FAIL;
15087   ix86_expand_lfloorceil (operands[0], operands[1], true);
15088   DONE;
15089 })
15090
15091 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15092 (define_insn_and_split "frndintxf2_ceil"
15093   [(set (match_operand:XF 0 "register_operand" "")
15094         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15095          UNSPEC_FRNDINT_CEIL))
15096    (clobber (reg:CC FLAGS_REG))]
15097   "TARGET_USE_FANCY_MATH_387
15098    && flag_unsafe_math_optimizations
15099    && can_create_pseudo_p ()"
15100   "#"
15101   "&& 1"
15102   [(const_int 0)]
15103 {
15104   ix86_optimize_mode_switching[I387_CEIL] = 1;
15105
15106   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15107   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15108
15109   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15110                                        operands[2], operands[3]));
15111   DONE;
15112 }
15113   [(set_attr "type" "frndint")
15114    (set_attr "i387_cw" "ceil")
15115    (set_attr "mode" "XF")])
15116
15117 (define_insn "frndintxf2_ceil_i387"
15118   [(set (match_operand:XF 0 "register_operand" "=f")
15119         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15120          UNSPEC_FRNDINT_CEIL))
15121    (use (match_operand:HI 2 "memory_operand" "m"))
15122    (use (match_operand:HI 3 "memory_operand" "m"))]
15123   "TARGET_USE_FANCY_MATH_387
15124    && flag_unsafe_math_optimizations"
15125   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15126   [(set_attr "type" "frndint")
15127    (set_attr "i387_cw" "ceil")
15128    (set_attr "mode" "XF")])
15129
15130 (define_expand "ceilxf2"
15131   [(use (match_operand:XF 0 "register_operand" ""))
15132    (use (match_operand:XF 1 "register_operand" ""))]
15133   "TARGET_USE_FANCY_MATH_387
15134    && flag_unsafe_math_optimizations"
15135 {
15136   if (optimize_insn_for_size_p ())
15137     FAIL;
15138   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15139   DONE;
15140 })
15141
15142 (define_expand "ceil<mode>2"
15143   [(use (match_operand:MODEF 0 "register_operand" ""))
15144    (use (match_operand:MODEF 1 "register_operand" ""))]
15145   "(TARGET_USE_FANCY_MATH_387
15146     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15147         || TARGET_MIX_SSE_I387)
15148     && flag_unsafe_math_optimizations)
15149    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15150        && !flag_trapping_math)"
15151 {
15152   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15153       && !flag_trapping_math)
15154     {
15155       if (TARGET_ROUND)
15156         emit_insn (gen_sse4_1_round<mode>2
15157                    (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15158       else if (optimize_insn_for_size_p ())
15159         FAIL;
15160       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15161         ix86_expand_floorceil (operands[0], operands[1], false);
15162       else
15163         ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15164     }
15165   else
15166     {
15167       rtx op0, op1;
15168
15169       if (optimize_insn_for_size_p ())
15170         FAIL;
15171
15172       op0 = gen_reg_rtx (XFmode);
15173       op1 = gen_reg_rtx (XFmode);
15174       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15175       emit_insn (gen_frndintxf2_ceil (op0, op1));
15176
15177       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15178     }
15179   DONE;
15180 })
15181
15182 (define_insn_and_split "*fist<mode>2_ceil_1"
15183   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15184         (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15185                         UNSPEC_FIST_CEIL))
15186    (clobber (reg:CC FLAGS_REG))]
15187   "TARGET_USE_FANCY_MATH_387
15188    && flag_unsafe_math_optimizations
15189    && can_create_pseudo_p ()"
15190   "#"
15191   "&& 1"
15192   [(const_int 0)]
15193 {
15194   ix86_optimize_mode_switching[I387_CEIL] = 1;
15195
15196   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15197   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15198   if (memory_operand (operands[0], VOIDmode))
15199     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15200                                      operands[2], operands[3]));
15201   else
15202     {
15203       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15204       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15205                                                  operands[2], operands[3],
15206                                                  operands[4]));
15207     }
15208   DONE;
15209 }
15210   [(set_attr "type" "fistp")
15211    (set_attr "i387_cw" "ceil")
15212    (set_attr "mode" "<MODE>")])
15213
15214 (define_insn "fistdi2_ceil"
15215   [(set (match_operand:DI 0 "memory_operand" "=m")
15216         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15217                    UNSPEC_FIST_CEIL))
15218    (use (match_operand:HI 2 "memory_operand" "m"))
15219    (use (match_operand:HI 3 "memory_operand" "m"))
15220    (clobber (match_scratch:XF 4 "=&1f"))]
15221   "TARGET_USE_FANCY_MATH_387
15222    && flag_unsafe_math_optimizations"
15223   "* return output_fix_trunc (insn, operands, false);"
15224   [(set_attr "type" "fistp")
15225    (set_attr "i387_cw" "ceil")
15226    (set_attr "mode" "DI")])
15227
15228 (define_insn "fistdi2_ceil_with_temp"
15229   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15230         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15231                    UNSPEC_FIST_CEIL))
15232    (use (match_operand:HI 2 "memory_operand" "m,m"))
15233    (use (match_operand:HI 3 "memory_operand" "m,m"))
15234    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15235    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15236   "TARGET_USE_FANCY_MATH_387
15237    && flag_unsafe_math_optimizations"
15238   "#"
15239   [(set_attr "type" "fistp")
15240    (set_attr "i387_cw" "ceil")
15241    (set_attr "mode" "DI")])
15242
15243 (define_split
15244   [(set (match_operand:DI 0 "register_operand" "")
15245         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15246                    UNSPEC_FIST_CEIL))
15247    (use (match_operand:HI 2 "memory_operand" ""))
15248    (use (match_operand:HI 3 "memory_operand" ""))
15249    (clobber (match_operand:DI 4 "memory_operand" ""))
15250    (clobber (match_scratch 5 ""))]
15251   "reload_completed"
15252   [(parallel [(set (match_dup 4)
15253                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15254               (use (match_dup 2))
15255               (use (match_dup 3))
15256               (clobber (match_dup 5))])
15257    (set (match_dup 0) (match_dup 4))])
15258
15259 (define_split
15260   [(set (match_operand:DI 0 "memory_operand" "")
15261         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15262                    UNSPEC_FIST_CEIL))
15263    (use (match_operand:HI 2 "memory_operand" ""))
15264    (use (match_operand:HI 3 "memory_operand" ""))
15265    (clobber (match_operand:DI 4 "memory_operand" ""))
15266    (clobber (match_scratch 5 ""))]
15267   "reload_completed"
15268   [(parallel [(set (match_dup 0)
15269                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15270               (use (match_dup 2))
15271               (use (match_dup 3))
15272               (clobber (match_dup 5))])])
15273
15274 (define_insn "fist<mode>2_ceil"
15275   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15276         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15277                       UNSPEC_FIST_CEIL))
15278    (use (match_operand:HI 2 "memory_operand" "m"))
15279    (use (match_operand:HI 3 "memory_operand" "m"))]
15280   "TARGET_USE_FANCY_MATH_387
15281    && flag_unsafe_math_optimizations"
15282   "* return output_fix_trunc (insn, operands, false);"
15283   [(set_attr "type" "fistp")
15284    (set_attr "i387_cw" "ceil")
15285    (set_attr "mode" "<MODE>")])
15286
15287 (define_insn "fist<mode>2_ceil_with_temp"
15288   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15289         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15290                       UNSPEC_FIST_CEIL))
15291    (use (match_operand:HI 2 "memory_operand" "m,m"))
15292    (use (match_operand:HI 3 "memory_operand" "m,m"))
15293    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15294   "TARGET_USE_FANCY_MATH_387
15295    && flag_unsafe_math_optimizations"
15296   "#"
15297   [(set_attr "type" "fistp")
15298    (set_attr "i387_cw" "ceil")
15299    (set_attr "mode" "<MODE>")])
15300
15301 (define_split
15302   [(set (match_operand:SWI24 0 "register_operand" "")
15303         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15304                       UNSPEC_FIST_CEIL))
15305    (use (match_operand:HI 2 "memory_operand" ""))
15306    (use (match_operand:HI 3 "memory_operand" ""))
15307    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15308   "reload_completed"
15309   [(parallel [(set (match_dup 4)
15310                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15311               (use (match_dup 2))
15312               (use (match_dup 3))])
15313    (set (match_dup 0) (match_dup 4))])
15314
15315 (define_split
15316   [(set (match_operand:SWI24 0 "memory_operand" "")
15317         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15318                       UNSPEC_FIST_CEIL))
15319    (use (match_operand:HI 2 "memory_operand" ""))
15320    (use (match_operand:HI 3 "memory_operand" ""))
15321    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15322   "reload_completed"
15323   [(parallel [(set (match_dup 0)
15324                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15325               (use (match_dup 2))
15326               (use (match_dup 3))])])
15327
15328 (define_expand "lceilxf<mode>2"
15329   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15330                    (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15331                                    UNSPEC_FIST_CEIL))
15332               (clobber (reg:CC FLAGS_REG))])]
15333   "TARGET_USE_FANCY_MATH_387
15334    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15335    && flag_unsafe_math_optimizations")
15336
15337 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15338   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15339    (match_operand:MODEF 1 "register_operand" "")]
15340   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15341    && !flag_trapping_math"
15342 {
15343   ix86_expand_lfloorceil (operands[0], operands[1], false);
15344   DONE;
15345 })
15346
15347 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15348 (define_insn_and_split "frndintxf2_trunc"
15349   [(set (match_operand:XF 0 "register_operand" "")
15350         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15351          UNSPEC_FRNDINT_TRUNC))
15352    (clobber (reg:CC FLAGS_REG))]
15353   "TARGET_USE_FANCY_MATH_387
15354    && flag_unsafe_math_optimizations
15355    && can_create_pseudo_p ()"
15356   "#"
15357   "&& 1"
15358   [(const_int 0)]
15359 {
15360   ix86_optimize_mode_switching[I387_TRUNC] = 1;
15361
15362   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15363   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15364
15365   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15366                                         operands[2], operands[3]));
15367   DONE;
15368 }
15369   [(set_attr "type" "frndint")
15370    (set_attr "i387_cw" "trunc")
15371    (set_attr "mode" "XF")])
15372
15373 (define_insn "frndintxf2_trunc_i387"
15374   [(set (match_operand:XF 0 "register_operand" "=f")
15375         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15376          UNSPEC_FRNDINT_TRUNC))
15377    (use (match_operand:HI 2 "memory_operand" "m"))
15378    (use (match_operand:HI 3 "memory_operand" "m"))]
15379   "TARGET_USE_FANCY_MATH_387
15380    && flag_unsafe_math_optimizations"
15381   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15382   [(set_attr "type" "frndint")
15383    (set_attr "i387_cw" "trunc")
15384    (set_attr "mode" "XF")])
15385
15386 (define_expand "btruncxf2"
15387   [(use (match_operand:XF 0 "register_operand" ""))
15388    (use (match_operand:XF 1 "register_operand" ""))]
15389   "TARGET_USE_FANCY_MATH_387
15390    && flag_unsafe_math_optimizations"
15391 {
15392   if (optimize_insn_for_size_p ())
15393     FAIL;
15394   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15395   DONE;
15396 })
15397
15398 (define_expand "btrunc<mode>2"
15399   [(use (match_operand:MODEF 0 "register_operand" ""))
15400    (use (match_operand:MODEF 1 "register_operand" ""))]
15401   "(TARGET_USE_FANCY_MATH_387
15402     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15403         || TARGET_MIX_SSE_I387)
15404     && flag_unsafe_math_optimizations)
15405    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15406        && !flag_trapping_math)"
15407 {
15408   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15409       && !flag_trapping_math)
15410     {
15411       if (TARGET_ROUND)
15412         emit_insn (gen_sse4_1_round<mode>2
15413                    (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15414       else if (optimize_insn_for_size_p ())
15415         FAIL;
15416       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15417         ix86_expand_trunc (operands[0], operands[1]);
15418       else
15419         ix86_expand_truncdf_32 (operands[0], operands[1]);
15420     }
15421   else
15422     {
15423       rtx op0, op1;
15424
15425       if (optimize_insn_for_size_p ())
15426         FAIL;
15427
15428       op0 = gen_reg_rtx (XFmode);
15429       op1 = gen_reg_rtx (XFmode);
15430       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15431       emit_insn (gen_frndintxf2_trunc (op0, op1));
15432
15433       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15434     }
15435   DONE;
15436 })
15437
15438 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15439 (define_insn_and_split "frndintxf2_mask_pm"
15440   [(set (match_operand:XF 0 "register_operand" "")
15441         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15442          UNSPEC_FRNDINT_MASK_PM))
15443    (clobber (reg:CC FLAGS_REG))]
15444   "TARGET_USE_FANCY_MATH_387
15445    && flag_unsafe_math_optimizations
15446    && can_create_pseudo_p ()"
15447   "#"
15448   "&& 1"
15449   [(const_int 0)]
15450 {
15451   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15452
15453   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15454   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15455
15456   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15457                                           operands[2], operands[3]));
15458   DONE;
15459 }
15460   [(set_attr "type" "frndint")
15461    (set_attr "i387_cw" "mask_pm")
15462    (set_attr "mode" "XF")])
15463
15464 (define_insn "frndintxf2_mask_pm_i387"
15465   [(set (match_operand:XF 0 "register_operand" "=f")
15466         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15467          UNSPEC_FRNDINT_MASK_PM))
15468    (use (match_operand:HI 2 "memory_operand" "m"))
15469    (use (match_operand:HI 3 "memory_operand" "m"))]
15470   "TARGET_USE_FANCY_MATH_387
15471    && flag_unsafe_math_optimizations"
15472   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15473   [(set_attr "type" "frndint")
15474    (set_attr "i387_cw" "mask_pm")
15475    (set_attr "mode" "XF")])
15476
15477 (define_expand "nearbyintxf2"
15478   [(use (match_operand:XF 0 "register_operand" ""))
15479    (use (match_operand:XF 1 "register_operand" ""))]
15480   "TARGET_USE_FANCY_MATH_387
15481    && flag_unsafe_math_optimizations"
15482 {
15483   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15484   DONE;
15485 })
15486
15487 (define_expand "nearbyint<mode>2"
15488   [(use (match_operand:MODEF 0 "register_operand" ""))
15489    (use (match_operand:MODEF 1 "register_operand" ""))]
15490   "TARGET_USE_FANCY_MATH_387
15491    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15492        || TARGET_MIX_SSE_I387)
15493    && flag_unsafe_math_optimizations"
15494 {
15495   rtx op0 = gen_reg_rtx (XFmode);
15496   rtx op1 = gen_reg_rtx (XFmode);
15497
15498   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15499   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15500
15501   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15502   DONE;
15503 })
15504
15505 (define_insn "fxam<mode>2_i387"
15506   [(set (match_operand:HI 0 "register_operand" "=a")
15507         (unspec:HI
15508           [(match_operand:X87MODEF 1 "register_operand" "f")]
15509           UNSPEC_FXAM))]
15510   "TARGET_USE_FANCY_MATH_387"
15511   "fxam\n\tfnstsw\t%0"
15512   [(set_attr "type" "multi")
15513    (set_attr "length" "4")
15514    (set_attr "unit" "i387")
15515    (set_attr "mode" "<MODE>")])
15516
15517 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15518   [(set (match_operand:HI 0 "register_operand" "")
15519         (unspec:HI
15520           [(match_operand:MODEF 1 "memory_operand" "")]
15521           UNSPEC_FXAM_MEM))]
15522   "TARGET_USE_FANCY_MATH_387
15523    && can_create_pseudo_p ()"
15524   "#"
15525   "&& 1"
15526   [(set (match_dup 2)(match_dup 1))
15527    (set (match_dup 0)
15528         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15529 {
15530   operands[2] = gen_reg_rtx (<MODE>mode);
15531
15532   MEM_VOLATILE_P (operands[1]) = 1;
15533 }
15534   [(set_attr "type" "multi")
15535    (set_attr "unit" "i387")
15536    (set_attr "mode" "<MODE>")])
15537
15538 (define_expand "isinfxf2"
15539   [(use (match_operand:SI 0 "register_operand" ""))
15540    (use (match_operand:XF 1 "register_operand" ""))]
15541   "TARGET_USE_FANCY_MATH_387
15542    && TARGET_C99_FUNCTIONS"
15543 {
15544   rtx mask = GEN_INT (0x45);
15545   rtx val = GEN_INT (0x05);
15546
15547   rtx cond;
15548
15549   rtx scratch = gen_reg_rtx (HImode);
15550   rtx res = gen_reg_rtx (QImode);
15551
15552   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15553
15554   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15555   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15556   cond = gen_rtx_fmt_ee (EQ, QImode,
15557                          gen_rtx_REG (CCmode, FLAGS_REG),
15558                          const0_rtx);
15559   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15560   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15561   DONE;
15562 })
15563
15564 (define_expand "isinf<mode>2"
15565   [(use (match_operand:SI 0 "register_operand" ""))
15566    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15567   "TARGET_USE_FANCY_MATH_387
15568    && TARGET_C99_FUNCTIONS
15569    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15570 {
15571   rtx mask = GEN_INT (0x45);
15572   rtx val = GEN_INT (0x05);
15573
15574   rtx cond;
15575
15576   rtx scratch = gen_reg_rtx (HImode);
15577   rtx res = gen_reg_rtx (QImode);
15578
15579   /* Remove excess precision by forcing value through memory. */
15580   if (memory_operand (operands[1], VOIDmode))
15581     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15582   else
15583     {
15584       rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15585
15586       emit_move_insn (temp, operands[1]);
15587       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15588     }
15589
15590   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15591   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15592   cond = gen_rtx_fmt_ee (EQ, QImode,
15593                          gen_rtx_REG (CCmode, FLAGS_REG),
15594                          const0_rtx);
15595   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15596   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15597   DONE;
15598 })
15599
15600 (define_expand "signbitxf2"
15601   [(use (match_operand:SI 0 "register_operand" ""))
15602    (use (match_operand:XF 1 "register_operand" ""))]
15603   "TARGET_USE_FANCY_MATH_387"
15604 {
15605   rtx scratch = gen_reg_rtx (HImode);
15606
15607   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15608   emit_insn (gen_andsi3 (operands[0],
15609              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15610   DONE;
15611 })
15612
15613 (define_insn "movmsk_df"
15614   [(set (match_operand:SI 0 "register_operand" "=r")
15615         (unspec:SI
15616           [(match_operand:DF 1 "register_operand" "x")]
15617           UNSPEC_MOVMSK))]
15618   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15619   "%vmovmskpd\t{%1, %0|%0, %1}"
15620   [(set_attr "type" "ssemov")
15621    (set_attr "prefix" "maybe_vex")
15622    (set_attr "mode" "DF")])
15623
15624 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15625 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15626 (define_expand "signbitdf2"
15627   [(use (match_operand:SI 0 "register_operand" ""))
15628    (use (match_operand:DF 1 "register_operand" ""))]
15629   "TARGET_USE_FANCY_MATH_387
15630    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15631 {
15632   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15633     {
15634       emit_insn (gen_movmsk_df (operands[0], operands[1]));
15635       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15636     }
15637   else
15638     {
15639       rtx scratch = gen_reg_rtx (HImode);
15640
15641       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15642       emit_insn (gen_andsi3 (operands[0],
15643                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15644     }
15645   DONE;
15646 })
15647
15648 (define_expand "signbitsf2"
15649   [(use (match_operand:SI 0 "register_operand" ""))
15650    (use (match_operand:SF 1 "register_operand" ""))]
15651   "TARGET_USE_FANCY_MATH_387
15652    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15653 {
15654   rtx scratch = gen_reg_rtx (HImode);
15655
15656   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15657   emit_insn (gen_andsi3 (operands[0],
15658              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15659   DONE;
15660 })
15661 \f
15662 ;; Block operation instructions
15663
15664 (define_insn "cld"
15665   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15666   ""
15667   "cld"
15668   [(set_attr "length" "1")
15669    (set_attr "length_immediate" "0")
15670    (set_attr "modrm" "0")])
15671
15672 (define_expand "movmem<mode>"
15673   [(use (match_operand:BLK 0 "memory_operand" ""))
15674    (use (match_operand:BLK 1 "memory_operand" ""))
15675    (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15676    (use (match_operand:SWI48 3 "const_int_operand" ""))
15677    (use (match_operand:SI 4 "const_int_operand" ""))
15678    (use (match_operand:SI 5 "const_int_operand" ""))]
15679   ""
15680 {
15681  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15682                          operands[4], operands[5]))
15683    DONE;
15684  else
15685    FAIL;
15686 })
15687
15688 ;; Most CPUs don't like single string operations
15689 ;; Handle this case here to simplify previous expander.
15690
15691 (define_expand "strmov"
15692   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15693    (set (match_operand 1 "memory_operand" "") (match_dup 4))
15694    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15695               (clobber (reg:CC FLAGS_REG))])
15696    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15697               (clobber (reg:CC FLAGS_REG))])]
15698   ""
15699 {
15700   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15701
15702   /* If .md ever supports :P for Pmode, these can be directly
15703      in the pattern above.  */
15704   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15705   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15706
15707   /* Can't use this if the user has appropriated esi or edi.  */
15708   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15709       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15710     {
15711       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15712                                       operands[2], operands[3],
15713                                       operands[5], operands[6]));
15714       DONE;
15715     }
15716
15717   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15718 })
15719
15720 (define_expand "strmov_singleop"
15721   [(parallel [(set (match_operand 1 "memory_operand" "")
15722                    (match_operand 3 "memory_operand" ""))
15723               (set (match_operand 0 "register_operand" "")
15724                    (match_operand 4 "" ""))
15725               (set (match_operand 2 "register_operand" "")
15726                    (match_operand 5 "" ""))])]
15727   ""
15728   "ix86_current_function_needs_cld = 1;")
15729
15730 (define_insn "*strmovdi_rex_1"
15731   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15732         (mem:DI (match_operand:DI 3 "register_operand" "1")))
15733    (set (match_operand:DI 0 "register_operand" "=D")
15734         (plus:DI (match_dup 2)
15735                  (const_int 8)))
15736    (set (match_operand:DI 1 "register_operand" "=S")
15737         (plus:DI (match_dup 3)
15738                  (const_int 8)))]
15739   "TARGET_64BIT
15740    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15741   "movsq"
15742   [(set_attr "type" "str")
15743    (set_attr "memory" "both")
15744    (set_attr "mode" "DI")])
15745
15746 (define_insn "*strmovsi_1"
15747   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15748         (mem:SI (match_operand:P 3 "register_operand" "1")))
15749    (set (match_operand:P 0 "register_operand" "=D")
15750         (plus:P (match_dup 2)
15751                 (const_int 4)))
15752    (set (match_operand:P 1 "register_operand" "=S")
15753         (plus:P (match_dup 3)
15754                 (const_int 4)))]
15755   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15756   "movs{l|d}"
15757   [(set_attr "type" "str")
15758    (set_attr "memory" "both")
15759    (set_attr "mode" "SI")])
15760
15761 (define_insn "*strmovhi_1"
15762   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15763         (mem:HI (match_operand:P 3 "register_operand" "1")))
15764    (set (match_operand:P 0 "register_operand" "=D")
15765         (plus:P (match_dup 2)
15766                 (const_int 2)))
15767    (set (match_operand:P 1 "register_operand" "=S")
15768         (plus:P (match_dup 3)
15769                 (const_int 2)))]
15770   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15771   "movsw"
15772   [(set_attr "type" "str")
15773    (set_attr "memory" "both")
15774    (set_attr "mode" "HI")])
15775
15776 (define_insn "*strmovqi_1"
15777   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15778         (mem:QI (match_operand:P 3 "register_operand" "1")))
15779    (set (match_operand:P 0 "register_operand" "=D")
15780         (plus:P (match_dup 2)
15781                 (const_int 1)))
15782    (set (match_operand:P 1 "register_operand" "=S")
15783         (plus:P (match_dup 3)
15784                 (const_int 1)))]
15785   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15786   "movsb"
15787   [(set_attr "type" "str")
15788    (set_attr "memory" "both")
15789    (set (attr "prefix_rex")
15790         (if_then_else
15791           (match_test "<P:MODE>mode == DImode")
15792           (const_string "0")
15793           (const_string "*")))
15794    (set_attr "mode" "QI")])
15795
15796 (define_expand "rep_mov"
15797   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15798               (set (match_operand 0 "register_operand" "")
15799                    (match_operand 5 "" ""))
15800               (set (match_operand 2 "register_operand" "")
15801                    (match_operand 6 "" ""))
15802               (set (match_operand 1 "memory_operand" "")
15803                    (match_operand 3 "memory_operand" ""))
15804               (use (match_dup 4))])]
15805   ""
15806   "ix86_current_function_needs_cld = 1;")
15807
15808 (define_insn "*rep_movdi_rex64"
15809   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15810    (set (match_operand:DI 0 "register_operand" "=D")
15811         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15812                             (const_int 3))
15813                  (match_operand:DI 3 "register_operand" "0")))
15814    (set (match_operand:DI 1 "register_operand" "=S")
15815         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15816                  (match_operand:DI 4 "register_operand" "1")))
15817    (set (mem:BLK (match_dup 3))
15818         (mem:BLK (match_dup 4)))
15819    (use (match_dup 5))]
15820   "TARGET_64BIT
15821    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15822   "rep{%;} movsq"
15823   [(set_attr "type" "str")
15824    (set_attr "prefix_rep" "1")
15825    (set_attr "memory" "both")
15826    (set_attr "mode" "DI")])
15827
15828 (define_insn "*rep_movsi"
15829   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15830    (set (match_operand:P 0 "register_operand" "=D")
15831         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15832                           (const_int 2))
15833                  (match_operand:P 3 "register_operand" "0")))
15834    (set (match_operand:P 1 "register_operand" "=S")
15835         (plus:P (ashift:P (match_dup 5) (const_int 2))
15836                 (match_operand:P 4 "register_operand" "1")))
15837    (set (mem:BLK (match_dup 3))
15838         (mem:BLK (match_dup 4)))
15839    (use (match_dup 5))]
15840   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15841   "rep{%;} movs{l|d}"
15842   [(set_attr "type" "str")
15843    (set_attr "prefix_rep" "1")
15844    (set_attr "memory" "both")
15845    (set_attr "mode" "SI")])
15846
15847 (define_insn "*rep_movqi"
15848   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15849    (set (match_operand:P 0 "register_operand" "=D")
15850         (plus:P (match_operand:P 3 "register_operand" "0")
15851                 (match_operand:P 5 "register_operand" "2")))
15852    (set (match_operand:P 1 "register_operand" "=S")
15853         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15854    (set (mem:BLK (match_dup 3))
15855         (mem:BLK (match_dup 4)))
15856    (use (match_dup 5))]
15857   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15858   "rep{%;} movsb"
15859   [(set_attr "type" "str")
15860    (set_attr "prefix_rep" "1")
15861    (set_attr "memory" "both")
15862    (set_attr "mode" "QI")])
15863
15864 (define_expand "setmem<mode>"
15865    [(use (match_operand:BLK 0 "memory_operand" ""))
15866     (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15867     (use (match_operand:QI 2 "nonmemory_operand" ""))
15868     (use (match_operand 3 "const_int_operand" ""))
15869     (use (match_operand:SI 4 "const_int_operand" ""))
15870     (use (match_operand:SI 5 "const_int_operand" ""))]
15871   ""
15872 {
15873  if (ix86_expand_setmem (operands[0], operands[1],
15874                          operands[2], operands[3],
15875                          operands[4], operands[5]))
15876    DONE;
15877  else
15878    FAIL;
15879 })
15880
15881 ;; Most CPUs don't like single string operations
15882 ;; Handle this case here to simplify previous expander.
15883
15884 (define_expand "strset"
15885   [(set (match_operand 1 "memory_operand" "")
15886         (match_operand 2 "register_operand" ""))
15887    (parallel [(set (match_operand 0 "register_operand" "")
15888                    (match_dup 3))
15889               (clobber (reg:CC FLAGS_REG))])]
15890   ""
15891 {
15892   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15893     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15894
15895   /* If .md ever supports :P for Pmode, this can be directly
15896      in the pattern above.  */
15897   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15898                               GEN_INT (GET_MODE_SIZE (GET_MODE
15899                                                       (operands[2]))));
15900   /* Can't use this if the user has appropriated eax or edi.  */
15901   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15902       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15903     {
15904       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15905                                       operands[3]));
15906       DONE;
15907     }
15908 })
15909
15910 (define_expand "strset_singleop"
15911   [(parallel [(set (match_operand 1 "memory_operand" "")
15912                    (match_operand 2 "register_operand" ""))
15913               (set (match_operand 0 "register_operand" "")
15914                    (match_operand 3 "" ""))
15915               (unspec [(const_int 0)] UNSPEC_STOS)])]
15916   ""
15917   "ix86_current_function_needs_cld = 1;")
15918
15919 (define_insn "*strsetdi_rex_1"
15920   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15921         (match_operand:DI 2 "register_operand" "a"))
15922    (set (match_operand:DI 0 "register_operand" "=D")
15923         (plus:DI (match_dup 1)
15924                  (const_int 8)))
15925    (unspec [(const_int 0)] UNSPEC_STOS)]
15926   "TARGET_64BIT
15927    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15928   "stosq"
15929   [(set_attr "type" "str")
15930    (set_attr "memory" "store")
15931    (set_attr "mode" "DI")])
15932
15933 (define_insn "*strsetsi_1"
15934   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15935         (match_operand:SI 2 "register_operand" "a"))
15936    (set (match_operand:P 0 "register_operand" "=D")
15937         (plus:P (match_dup 1)
15938                 (const_int 4)))
15939    (unspec [(const_int 0)] UNSPEC_STOS)]
15940   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15941   "stos{l|d}"
15942   [(set_attr "type" "str")
15943    (set_attr "memory" "store")
15944    (set_attr "mode" "SI")])
15945
15946 (define_insn "*strsethi_1"
15947   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15948         (match_operand:HI 2 "register_operand" "a"))
15949    (set (match_operand:P 0 "register_operand" "=D")
15950         (plus:P (match_dup 1)
15951                 (const_int 2)))
15952    (unspec [(const_int 0)] UNSPEC_STOS)]
15953   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15954   "stosw"
15955   [(set_attr "type" "str")
15956    (set_attr "memory" "store")
15957    (set_attr "mode" "HI")])
15958
15959 (define_insn "*strsetqi_1"
15960   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15961         (match_operand:QI 2 "register_operand" "a"))
15962    (set (match_operand:P 0 "register_operand" "=D")
15963         (plus:P (match_dup 1)
15964                 (const_int 1)))
15965    (unspec [(const_int 0)] UNSPEC_STOS)]
15966   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15967   "stosb"
15968   [(set_attr "type" "str")
15969    (set_attr "memory" "store")
15970    (set (attr "prefix_rex")
15971         (if_then_else
15972           (match_test "<P:MODE>mode == DImode")
15973           (const_string "0")
15974           (const_string "*")))
15975    (set_attr "mode" "QI")])
15976
15977 (define_expand "rep_stos"
15978   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15979               (set (match_operand 0 "register_operand" "")
15980                    (match_operand 4 "" ""))
15981               (set (match_operand 2 "memory_operand" "") (const_int 0))
15982               (use (match_operand 3 "register_operand" ""))
15983               (use (match_dup 1))])]
15984   ""
15985   "ix86_current_function_needs_cld = 1;")
15986
15987 (define_insn "*rep_stosdi_rex64"
15988   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15989    (set (match_operand:DI 0 "register_operand" "=D")
15990         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15991                             (const_int 3))
15992                  (match_operand:DI 3 "register_operand" "0")))
15993    (set (mem:BLK (match_dup 3))
15994         (const_int 0))
15995    (use (match_operand:DI 2 "register_operand" "a"))
15996    (use (match_dup 4))]
15997   "TARGET_64BIT
15998    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15999   "rep{%;} stosq"
16000   [(set_attr "type" "str")
16001    (set_attr "prefix_rep" "1")
16002    (set_attr "memory" "store")
16003    (set_attr "mode" "DI")])
16004
16005 (define_insn "*rep_stossi"
16006   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16007    (set (match_operand:P 0 "register_operand" "=D")
16008         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16009                           (const_int 2))
16010                  (match_operand:P 3 "register_operand" "0")))
16011    (set (mem:BLK (match_dup 3))
16012         (const_int 0))
16013    (use (match_operand:SI 2 "register_operand" "a"))
16014    (use (match_dup 4))]
16015   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16016   "rep{%;} stos{l|d}"
16017   [(set_attr "type" "str")
16018    (set_attr "prefix_rep" "1")
16019    (set_attr "memory" "store")
16020    (set_attr "mode" "SI")])
16021
16022 (define_insn "*rep_stosqi"
16023   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16024    (set (match_operand:P 0 "register_operand" "=D")
16025         (plus:P (match_operand:P 3 "register_operand" "0")
16026                 (match_operand:P 4 "register_operand" "1")))
16027    (set (mem:BLK (match_dup 3))
16028         (const_int 0))
16029    (use (match_operand:QI 2 "register_operand" "a"))
16030    (use (match_dup 4))]
16031   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16032   "rep{%;} stosb"
16033   [(set_attr "type" "str")
16034    (set_attr "prefix_rep" "1")
16035    (set_attr "memory" "store")
16036    (set (attr "prefix_rex")
16037         (if_then_else
16038           (match_test "<P:MODE>mode == DImode")
16039           (const_string "0")
16040           (const_string "*")))
16041    (set_attr "mode" "QI")])
16042
16043 (define_expand "cmpstrnsi"
16044   [(set (match_operand:SI 0 "register_operand" "")
16045         (compare:SI (match_operand:BLK 1 "general_operand" "")
16046                     (match_operand:BLK 2 "general_operand" "")))
16047    (use (match_operand 3 "general_operand" ""))
16048    (use (match_operand 4 "immediate_operand" ""))]
16049   ""
16050 {
16051   rtx addr1, addr2, out, outlow, count, countreg, align;
16052
16053   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16054     FAIL;
16055
16056   /* Can't use this if the user has appropriated ecx, esi or edi.  */
16057   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16058     FAIL;
16059
16060   out = operands[0];
16061   if (!REG_P (out))
16062     out = gen_reg_rtx (SImode);
16063
16064   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16065   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16066   if (addr1 != XEXP (operands[1], 0))
16067     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16068   if (addr2 != XEXP (operands[2], 0))
16069     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16070
16071   count = operands[3];
16072   countreg = ix86_zero_extend_to_Pmode (count);
16073
16074   /* %%% Iff we are testing strict equality, we can use known alignment
16075      to good advantage.  This may be possible with combine, particularly
16076      once cc0 is dead.  */
16077   align = operands[4];
16078
16079   if (CONST_INT_P (count))
16080     {
16081       if (INTVAL (count) == 0)
16082         {
16083           emit_move_insn (operands[0], const0_rtx);
16084           DONE;
16085         }
16086       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16087                                      operands[1], operands[2]));
16088     }
16089   else
16090     {
16091       rtx (*gen_cmp) (rtx, rtx);
16092
16093       gen_cmp = (TARGET_64BIT
16094                  ? gen_cmpdi_1 : gen_cmpsi_1);
16095
16096       emit_insn (gen_cmp (countreg, countreg));
16097       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16098                                   operands[1], operands[2]));
16099     }
16100
16101   outlow = gen_lowpart (QImode, out);
16102   emit_insn (gen_cmpintqi (outlow));
16103   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16104
16105   if (operands[0] != out)
16106     emit_move_insn (operands[0], out);
16107
16108   DONE;
16109 })
16110
16111 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16112
16113 (define_expand "cmpintqi"
16114   [(set (match_dup 1)
16115         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16116    (set (match_dup 2)
16117         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16118    (parallel [(set (match_operand:QI 0 "register_operand" "")
16119                    (minus:QI (match_dup 1)
16120                              (match_dup 2)))
16121               (clobber (reg:CC FLAGS_REG))])]
16122   ""
16123 {
16124   operands[1] = gen_reg_rtx (QImode);
16125   operands[2] = gen_reg_rtx (QImode);
16126 })
16127
16128 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16129 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16130
16131 (define_expand "cmpstrnqi_nz_1"
16132   [(parallel [(set (reg:CC FLAGS_REG)
16133                    (compare:CC (match_operand 4 "memory_operand" "")
16134                                (match_operand 5 "memory_operand" "")))
16135               (use (match_operand 2 "register_operand" ""))
16136               (use (match_operand:SI 3 "immediate_operand" ""))
16137               (clobber (match_operand 0 "register_operand" ""))
16138               (clobber (match_operand 1 "register_operand" ""))
16139               (clobber (match_dup 2))])]
16140   ""
16141   "ix86_current_function_needs_cld = 1;")
16142
16143 (define_insn "*cmpstrnqi_nz_1"
16144   [(set (reg:CC FLAGS_REG)
16145         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16146                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16147    (use (match_operand:P 6 "register_operand" "2"))
16148    (use (match_operand:SI 3 "immediate_operand" "i"))
16149    (clobber (match_operand:P 0 "register_operand" "=S"))
16150    (clobber (match_operand:P 1 "register_operand" "=D"))
16151    (clobber (match_operand:P 2 "register_operand" "=c"))]
16152   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16153   "repz{%;} cmpsb"
16154   [(set_attr "type" "str")
16155    (set_attr "mode" "QI")
16156    (set (attr "prefix_rex")
16157         (if_then_else
16158           (match_test "<P:MODE>mode == DImode")
16159           (const_string "0")
16160           (const_string "*")))
16161    (set_attr "prefix_rep" "1")])
16162
16163 ;; The same, but the count is not known to not be zero.
16164
16165 (define_expand "cmpstrnqi_1"
16166   [(parallel [(set (reg:CC FLAGS_REG)
16167                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16168                                      (const_int 0))
16169                   (compare:CC (match_operand 4 "memory_operand" "")
16170                               (match_operand 5 "memory_operand" ""))
16171                   (const_int 0)))
16172               (use (match_operand:SI 3 "immediate_operand" ""))
16173               (use (reg:CC FLAGS_REG))
16174               (clobber (match_operand 0 "register_operand" ""))
16175               (clobber (match_operand 1 "register_operand" ""))
16176               (clobber (match_dup 2))])]
16177   ""
16178   "ix86_current_function_needs_cld = 1;")
16179
16180 (define_insn "*cmpstrnqi_1"
16181   [(set (reg:CC FLAGS_REG)
16182         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16183                              (const_int 0))
16184           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16185                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
16186           (const_int 0)))
16187    (use (match_operand:SI 3 "immediate_operand" "i"))
16188    (use (reg:CC FLAGS_REG))
16189    (clobber (match_operand:P 0 "register_operand" "=S"))
16190    (clobber (match_operand:P 1 "register_operand" "=D"))
16191    (clobber (match_operand:P 2 "register_operand" "=c"))]
16192   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16193   "repz{%;} cmpsb"
16194   [(set_attr "type" "str")
16195    (set_attr "mode" "QI")
16196    (set (attr "prefix_rex")
16197         (if_then_else
16198           (match_test "<P:MODE>mode == DImode")
16199           (const_string "0")
16200           (const_string "*")))
16201    (set_attr "prefix_rep" "1")])
16202
16203 (define_expand "strlen<mode>"
16204   [(set (match_operand:P 0 "register_operand" "")
16205         (unspec:P [(match_operand:BLK 1 "general_operand" "")
16206                    (match_operand:QI 2 "immediate_operand" "")
16207                    (match_operand 3 "immediate_operand" "")]
16208                   UNSPEC_SCAS))]
16209   ""
16210 {
16211  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16212    DONE;
16213  else
16214    FAIL;
16215 })
16216
16217 (define_expand "strlenqi_1"
16218   [(parallel [(set (match_operand 0 "register_operand" "")
16219                    (match_operand 2 "" ""))
16220               (clobber (match_operand 1 "register_operand" ""))
16221               (clobber (reg:CC FLAGS_REG))])]
16222   ""
16223   "ix86_current_function_needs_cld = 1;")
16224
16225 (define_insn "*strlenqi_1"
16226   [(set (match_operand:P 0 "register_operand" "=&c")
16227         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16228                    (match_operand:QI 2 "register_operand" "a")
16229                    (match_operand:P 3 "immediate_operand" "i")
16230                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16231    (clobber (match_operand:P 1 "register_operand" "=D"))
16232    (clobber (reg:CC FLAGS_REG))]
16233   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16234   "repnz{%;} scasb"
16235   [(set_attr "type" "str")
16236    (set_attr "mode" "QI")
16237    (set (attr "prefix_rex")
16238         (if_then_else
16239           (match_test "<P:MODE>mode == DImode")
16240           (const_string "0")
16241           (const_string "*")))
16242    (set_attr "prefix_rep" "1")])
16243
16244 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
16245 ;; handled in combine, but it is not currently up to the task.
16246 ;; When used for their truth value, the cmpstrn* expanders generate
16247 ;; code like this:
16248 ;;
16249 ;;   repz cmpsb
16250 ;;   seta       %al
16251 ;;   setb       %dl
16252 ;;   cmpb       %al, %dl
16253 ;;   jcc        label
16254 ;;
16255 ;; The intermediate three instructions are unnecessary.
16256
16257 ;; This one handles cmpstrn*_nz_1...
16258 (define_peephole2
16259   [(parallel[
16260      (set (reg:CC FLAGS_REG)
16261           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16262                       (mem:BLK (match_operand 5 "register_operand" ""))))
16263      (use (match_operand 6 "register_operand" ""))
16264      (use (match_operand:SI 3 "immediate_operand" ""))
16265      (clobber (match_operand 0 "register_operand" ""))
16266      (clobber (match_operand 1 "register_operand" ""))
16267      (clobber (match_operand 2 "register_operand" ""))])
16268    (set (match_operand:QI 7 "register_operand" "")
16269         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16270    (set (match_operand:QI 8 "register_operand" "")
16271         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16272    (set (reg FLAGS_REG)
16273         (compare (match_dup 7) (match_dup 8)))
16274   ]
16275   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16276   [(parallel[
16277      (set (reg:CC FLAGS_REG)
16278           (compare:CC (mem:BLK (match_dup 4))
16279                       (mem:BLK (match_dup 5))))
16280      (use (match_dup 6))
16281      (use (match_dup 3))
16282      (clobber (match_dup 0))
16283      (clobber (match_dup 1))
16284      (clobber (match_dup 2))])])
16285
16286 ;; ...and this one handles cmpstrn*_1.
16287 (define_peephole2
16288   [(parallel[
16289      (set (reg:CC FLAGS_REG)
16290           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16291                                (const_int 0))
16292             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16293                         (mem:BLK (match_operand 5 "register_operand" "")))
16294             (const_int 0)))
16295      (use (match_operand:SI 3 "immediate_operand" ""))
16296      (use (reg:CC FLAGS_REG))
16297      (clobber (match_operand 0 "register_operand" ""))
16298      (clobber (match_operand 1 "register_operand" ""))
16299      (clobber (match_operand 2 "register_operand" ""))])
16300    (set (match_operand:QI 7 "register_operand" "")
16301         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16302    (set (match_operand:QI 8 "register_operand" "")
16303         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16304    (set (reg FLAGS_REG)
16305         (compare (match_dup 7) (match_dup 8)))
16306   ]
16307   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16308   [(parallel[
16309      (set (reg:CC FLAGS_REG)
16310           (if_then_else:CC (ne (match_dup 6)
16311                                (const_int 0))
16312             (compare:CC (mem:BLK (match_dup 4))
16313                         (mem:BLK (match_dup 5)))
16314             (const_int 0)))
16315      (use (match_dup 3))
16316      (use (reg:CC FLAGS_REG))
16317      (clobber (match_dup 0))
16318      (clobber (match_dup 1))
16319      (clobber (match_dup 2))])])
16320 \f
16321 ;; Conditional move instructions.
16322
16323 (define_expand "mov<mode>cc"
16324   [(set (match_operand:SWIM 0 "register_operand" "")
16325         (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16326                            (match_operand:SWIM 2 "<general_operand>" "")
16327                            (match_operand:SWIM 3 "<general_operand>" "")))]
16328   ""
16329   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16330
16331 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16332 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16333 ;; So just document what we're doing explicitly.
16334
16335 (define_expand "x86_mov<mode>cc_0_m1"
16336   [(parallel
16337     [(set (match_operand:SWI48 0 "register_operand" "")
16338           (if_then_else:SWI48
16339             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16340              [(match_operand 1 "flags_reg_operand" "")
16341               (const_int 0)])
16342             (const_int -1)
16343             (const_int 0)))
16344      (clobber (reg:CC FLAGS_REG))])])
16345
16346 (define_insn "*x86_mov<mode>cc_0_m1"
16347   [(set (match_operand:SWI48 0 "register_operand" "=r")
16348         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16349                              [(reg FLAGS_REG) (const_int 0)])
16350           (const_int -1)
16351           (const_int 0)))
16352    (clobber (reg:CC FLAGS_REG))]
16353   ""
16354   "sbb{<imodesuffix>}\t%0, %0"
16355   ; Since we don't have the proper number of operands for an alu insn,
16356   ; fill in all the blanks.
16357   [(set_attr "type" "alu")
16358    (set_attr "use_carry" "1")
16359    (set_attr "pent_pair" "pu")
16360    (set_attr "memory" "none")
16361    (set_attr "imm_disp" "false")
16362    (set_attr "mode" "<MODE>")
16363    (set_attr "length_immediate" "0")])
16364
16365 (define_insn "*x86_mov<mode>cc_0_m1_se"
16366   [(set (match_operand:SWI48 0 "register_operand" "=r")
16367         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16368                              [(reg FLAGS_REG) (const_int 0)])
16369                             (const_int 1)
16370                             (const_int 0)))
16371    (clobber (reg:CC FLAGS_REG))]
16372   ""
16373   "sbb{<imodesuffix>}\t%0, %0"
16374   [(set_attr "type" "alu")
16375    (set_attr "use_carry" "1")
16376    (set_attr "pent_pair" "pu")
16377    (set_attr "memory" "none")
16378    (set_attr "imm_disp" "false")
16379    (set_attr "mode" "<MODE>")
16380    (set_attr "length_immediate" "0")])
16381
16382 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16383   [(set (match_operand:SWI48 0 "register_operand" "=r")
16384         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16385                     [(reg FLAGS_REG) (const_int 0)])))
16386    (clobber (reg:CC FLAGS_REG))]
16387   ""
16388   "sbb{<imodesuffix>}\t%0, %0"
16389   [(set_attr "type" "alu")
16390    (set_attr "use_carry" "1")
16391    (set_attr "pent_pair" "pu")
16392    (set_attr "memory" "none")
16393    (set_attr "imm_disp" "false")
16394    (set_attr "mode" "<MODE>")
16395    (set_attr "length_immediate" "0")])
16396
16397 (define_insn "*mov<mode>cc_noc"
16398   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16399         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16400                                [(reg FLAGS_REG) (const_int 0)])
16401           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16402           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16403   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16404   "@
16405    cmov%O2%C1\t{%2, %0|%0, %2}
16406    cmov%O2%c1\t{%3, %0|%0, %3}"
16407   [(set_attr "type" "icmov")
16408    (set_attr "mode" "<MODE>")])
16409
16410 (define_insn "*movqicc_noc"
16411   [(set (match_operand:QI 0 "register_operand" "=r,r")
16412         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16413                            [(reg FLAGS_REG) (const_int 0)])
16414                       (match_operand:QI 2 "register_operand" "r,0")
16415                       (match_operand:QI 3 "register_operand" "0,r")))]
16416   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16417   "#"
16418   [(set_attr "type" "icmov")
16419    (set_attr "mode" "QI")])
16420
16421 (define_split
16422   [(set (match_operand 0 "register_operand")
16423         (if_then_else (match_operator 1 "ix86_comparison_operator"
16424                         [(reg FLAGS_REG) (const_int 0)])
16425                       (match_operand 2 "register_operand")
16426                       (match_operand 3 "register_operand")))]
16427   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16428    && (GET_MODE (operands[0]) == QImode
16429        || GET_MODE (operands[0]) == HImode)
16430    && reload_completed"
16431   [(set (match_dup 0)
16432         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16433 {
16434   operands[0] = gen_lowpart (SImode, operands[0]);
16435   operands[2] = gen_lowpart (SImode, operands[2]);
16436   operands[3] = gen_lowpart (SImode, operands[3]);
16437 })
16438
16439 (define_expand "mov<mode>cc"
16440   [(set (match_operand:X87MODEF 0 "register_operand" "")
16441         (if_then_else:X87MODEF
16442           (match_operand 1 "ix86_fp_comparison_operator" "")
16443           (match_operand:X87MODEF 2 "register_operand" "")
16444           (match_operand:X87MODEF 3 "register_operand" "")))]
16445   "(TARGET_80387 && TARGET_CMOVE)
16446    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16447   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16448
16449 (define_insn "*movxfcc_1"
16450   [(set (match_operand:XF 0 "register_operand" "=f,f")
16451         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16452                                 [(reg FLAGS_REG) (const_int 0)])
16453                       (match_operand:XF 2 "register_operand" "f,0")
16454                       (match_operand:XF 3 "register_operand" "0,f")))]
16455   "TARGET_80387 && TARGET_CMOVE"
16456   "@
16457    fcmov%F1\t{%2, %0|%0, %2}
16458    fcmov%f1\t{%3, %0|%0, %3}"
16459   [(set_attr "type" "fcmov")
16460    (set_attr "mode" "XF")])
16461
16462 (define_insn "*movdfcc_1_rex64"
16463   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16464         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16465                                 [(reg FLAGS_REG) (const_int 0)])
16466                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16467                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16468   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16469    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16470   "@
16471    fcmov%F1\t{%2, %0|%0, %2}
16472    fcmov%f1\t{%3, %0|%0, %3}
16473    cmov%O2%C1\t{%2, %0|%0, %2}
16474    cmov%O2%c1\t{%3, %0|%0, %3}"
16475   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16476    (set_attr "mode" "DF,DF,DI,DI")])
16477
16478 (define_insn "*movdfcc_1"
16479   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16480         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16481                                 [(reg FLAGS_REG) (const_int 0)])
16482                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16483                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16484   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16485    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16486   "@
16487    fcmov%F1\t{%2, %0|%0, %2}
16488    fcmov%f1\t{%3, %0|%0, %3}
16489    #
16490    #"
16491   [(set_attr "type" "fcmov,fcmov,multi,multi")
16492    (set_attr "mode" "DF,DF,DI,DI")])
16493
16494 (define_split
16495   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16496         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16497                                 [(reg FLAGS_REG) (const_int 0)])
16498                       (match_operand:DF 2 "nonimmediate_operand")
16499                       (match_operand:DF 3 "nonimmediate_operand")))]
16500   "!TARGET_64BIT && reload_completed"
16501   [(set (match_dup 2)
16502         (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16503    (set (match_dup 3)
16504         (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16505 {
16506   split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16507   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16508 })
16509
16510 (define_insn "*movsfcc_1_387"
16511   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16512         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16513                                 [(reg FLAGS_REG) (const_int 0)])
16514                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16515                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16516   "TARGET_80387 && TARGET_CMOVE
16517    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16518   "@
16519    fcmov%F1\t{%2, %0|%0, %2}
16520    fcmov%f1\t{%3, %0|%0, %3}
16521    cmov%O2%C1\t{%2, %0|%0, %2}
16522    cmov%O2%c1\t{%3, %0|%0, %3}"
16523   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16524    (set_attr "mode" "SF,SF,SI,SI")])
16525
16526 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16527 ;; the scalar versions to have only XMM registers as operands.
16528
16529 ;; XOP conditional move
16530 (define_insn "*xop_pcmov_<mode>"
16531   [(set (match_operand:MODEF 0 "register_operand" "=x")
16532         (if_then_else:MODEF
16533           (match_operand:MODEF 1 "register_operand" "x")
16534           (match_operand:MODEF 2 "register_operand" "x")
16535           (match_operand:MODEF 3 "register_operand" "x")))]
16536   "TARGET_XOP"
16537   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16538   [(set_attr "type" "sse4arg")])
16539
16540 ;; These versions of the min/max patterns are intentionally ignorant of
16541 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16542 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16543 ;; are undefined in this condition, we're certain this is correct.
16544
16545 (define_insn "<code><mode>3"
16546   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16547         (smaxmin:MODEF
16548           (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16549           (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16550   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16551   "@
16552    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16553    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16554   [(set_attr "isa" "noavx,avx")
16555    (set_attr "prefix" "orig,vex")
16556    (set_attr "type" "sseadd")
16557    (set_attr "mode" "<MODE>")])
16558
16559 ;; These versions of the min/max patterns implement exactly the operations
16560 ;;   min = (op1 < op2 ? op1 : op2)
16561 ;;   max = (!(op1 < op2) ? op1 : op2)
16562 ;; Their operands are not commutative, and thus they may be used in the
16563 ;; presence of -0.0 and NaN.
16564
16565 (define_insn "*ieee_smin<mode>3"
16566   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16567         (unspec:MODEF
16568           [(match_operand:MODEF 1 "register_operand" "0,x")
16569            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16570          UNSPEC_IEEE_MIN))]
16571   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16572   "@
16573    min<ssemodesuffix>\t{%2, %0|%0, %2}
16574    vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16575   [(set_attr "isa" "noavx,avx")
16576    (set_attr "prefix" "orig,vex")
16577    (set_attr "type" "sseadd")
16578    (set_attr "mode" "<MODE>")])
16579
16580 (define_insn "*ieee_smax<mode>3"
16581   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16582         (unspec:MODEF
16583           [(match_operand:MODEF 1 "register_operand" "0,x")
16584            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16585          UNSPEC_IEEE_MAX))]
16586   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16587   "@
16588    max<ssemodesuffix>\t{%2, %0|%0, %2}
16589    vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16590   [(set_attr "isa" "noavx,avx")
16591    (set_attr "prefix" "orig,vex")
16592    (set_attr "type" "sseadd")
16593    (set_attr "mode" "<MODE>")])
16594
16595 ;; Make two stack loads independent:
16596 ;;   fld aa              fld aa
16597 ;;   fld %st(0)     ->   fld bb
16598 ;;   fmul bb             fmul %st(1), %st
16599 ;;
16600 ;; Actually we only match the last two instructions for simplicity.
16601 (define_peephole2
16602   [(set (match_operand 0 "fp_register_operand" "")
16603         (match_operand 1 "fp_register_operand" ""))
16604    (set (match_dup 0)
16605         (match_operator 2 "binary_fp_operator"
16606            [(match_dup 0)
16607             (match_operand 3 "memory_operand" "")]))]
16608   "REGNO (operands[0]) != REGNO (operands[1])"
16609   [(set (match_dup 0) (match_dup 3))
16610    (set (match_dup 0) (match_dup 4))]
16611
16612   ;; The % modifier is not operational anymore in peephole2's, so we have to
16613   ;; swap the operands manually in the case of addition and multiplication.
16614 {
16615   rtx op0, op1;
16616
16617   if (COMMUTATIVE_ARITH_P (operands[2]))
16618     op0 = operands[0], op1 = operands[1];
16619   else
16620     op0 = operands[1], op1 = operands[0];
16621
16622   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16623                                 GET_MODE (operands[2]),
16624                                 op0, op1);
16625 })
16626
16627 ;; Conditional addition patterns
16628 (define_expand "add<mode>cc"
16629   [(match_operand:SWI 0 "register_operand" "")
16630    (match_operand 1 "ordered_comparison_operator" "")
16631    (match_operand:SWI 2 "register_operand" "")
16632    (match_operand:SWI 3 "const_int_operand" "")]
16633   ""
16634   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16635 \f
16636 ;; Misc patterns (?)
16637
16638 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16639 ;; Otherwise there will be nothing to keep
16640 ;;
16641 ;; [(set (reg ebp) (reg esp))]
16642 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16643 ;;  (clobber (eflags)]
16644 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16645 ;;
16646 ;; in proper program order.
16647
16648 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16649   [(set (match_operand:P 0 "register_operand" "=r,r")
16650         (plus:P (match_operand:P 1 "register_operand" "0,r")
16651                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16652    (clobber (reg:CC FLAGS_REG))
16653    (clobber (mem:BLK (scratch)))]
16654   ""
16655 {
16656   switch (get_attr_type (insn))
16657     {
16658     case TYPE_IMOV:
16659       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16660
16661     case TYPE_ALU:
16662       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16663       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16664         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16665
16666       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16667
16668     default:
16669       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16670       return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16671     }
16672 }
16673   [(set (attr "type")
16674         (cond [(and (eq_attr "alternative" "0")
16675                     (not (match_test "TARGET_OPT_AGU")))
16676                  (const_string "alu")
16677                (match_operand:<MODE> 2 "const0_operand" "")
16678                  (const_string "imov")
16679               ]
16680               (const_string "lea")))
16681    (set (attr "length_immediate")
16682         (cond [(eq_attr "type" "imov")
16683                  (const_string "0")
16684                (and (eq_attr "type" "alu")
16685                     (match_operand 2 "const128_operand" ""))
16686                  (const_string "1")
16687               ]
16688               (const_string "*")))
16689    (set_attr "mode" "<MODE>")])
16690
16691 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16692   [(set (match_operand:P 0 "register_operand" "=r")
16693         (minus:P (match_operand:P 1 "register_operand" "0")
16694                  (match_operand:P 2 "register_operand" "r")))
16695    (clobber (reg:CC FLAGS_REG))
16696    (clobber (mem:BLK (scratch)))]
16697   ""
16698   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16699   [(set_attr "type" "alu")
16700    (set_attr "mode" "<MODE>")])
16701
16702 (define_insn "allocate_stack_worker_probe_<mode>"
16703   [(set (match_operand:P 0 "register_operand" "=a")
16704         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16705                             UNSPECV_STACK_PROBE))
16706    (clobber (reg:CC FLAGS_REG))]
16707   "ix86_target_stack_probe ()"
16708   "call\t___chkstk_ms"
16709   [(set_attr "type" "multi")
16710    (set_attr "length" "5")])
16711
16712 (define_expand "allocate_stack"
16713   [(match_operand 0 "register_operand" "")
16714    (match_operand 1 "general_operand" "")]
16715   "ix86_target_stack_probe ()"
16716 {
16717   rtx x;
16718
16719 #ifndef CHECK_STACK_LIMIT
16720 #define CHECK_STACK_LIMIT 0
16721 #endif
16722
16723   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16724       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16725     {
16726       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16727                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16728       if (x != stack_pointer_rtx)
16729         emit_move_insn (stack_pointer_rtx, x);
16730     }
16731   else
16732     {
16733       x = copy_to_mode_reg (Pmode, operands[1]);
16734       if (TARGET_64BIT)
16735         emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16736       else
16737         emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16738       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16739                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16740       if (x != stack_pointer_rtx)
16741         emit_move_insn (stack_pointer_rtx, x);
16742     }
16743
16744   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16745   DONE;
16746 })
16747
16748 ;; Use IOR for stack probes, this is shorter.
16749 (define_expand "probe_stack"
16750   [(match_operand 0 "memory_operand" "")]
16751   ""
16752 {
16753   rtx (*gen_ior3) (rtx, rtx, rtx);
16754
16755   gen_ior3 = (GET_MODE (operands[0]) == DImode
16756               ? gen_iordi3 : gen_iorsi3);
16757
16758   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16759   DONE;
16760 })
16761
16762 (define_insn "adjust_stack_and_probe<mode>"
16763   [(set (match_operand:P 0 "register_operand" "=r")
16764         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16765                             UNSPECV_PROBE_STACK_RANGE))
16766    (set (reg:P SP_REG)
16767         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16768    (clobber (reg:CC FLAGS_REG))
16769    (clobber (mem:BLK (scratch)))]
16770   ""
16771   "* return output_adjust_stack_and_probe (operands[0]);"
16772   [(set_attr "type" "multi")])
16773
16774 (define_insn "probe_stack_range<mode>"
16775   [(set (match_operand:P 0 "register_operand" "=r")
16776         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16777                             (match_operand:P 2 "const_int_operand" "n")]
16778                             UNSPECV_PROBE_STACK_RANGE))
16779    (clobber (reg:CC FLAGS_REG))]
16780   ""
16781   "* return output_probe_stack_range (operands[0], operands[2]);"
16782   [(set_attr "type" "multi")])
16783
16784 (define_expand "builtin_setjmp_receiver"
16785   [(label_ref (match_operand 0 "" ""))]
16786   "!TARGET_64BIT && flag_pic"
16787 {
16788 #if TARGET_MACHO
16789   if (TARGET_MACHO)
16790     {
16791       rtx xops[3];
16792       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16793       rtx label_rtx = gen_label_rtx ();
16794       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16795       xops[0] = xops[1] = picreg;
16796       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16797       ix86_expand_binary_operator (MINUS, SImode, xops);
16798     }
16799   else
16800 #endif
16801     emit_insn (gen_set_got (pic_offset_table_rtx));
16802   DONE;
16803 })
16804 \f
16805 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16806
16807 (define_split
16808   [(set (match_operand 0 "register_operand" "")
16809         (match_operator 3 "promotable_binary_operator"
16810            [(match_operand 1 "register_operand" "")
16811             (match_operand 2 "aligned_operand" "")]))
16812    (clobber (reg:CC FLAGS_REG))]
16813   "! TARGET_PARTIAL_REG_STALL && reload_completed
16814    && ((GET_MODE (operands[0]) == HImode
16815         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16816             /* ??? next two lines just !satisfies_constraint_K (...) */
16817             || !CONST_INT_P (operands[2])
16818             || satisfies_constraint_K (operands[2])))
16819        || (GET_MODE (operands[0]) == QImode
16820            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16821   [(parallel [(set (match_dup 0)
16822                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16823               (clobber (reg:CC FLAGS_REG))])]
16824 {
16825   operands[0] = gen_lowpart (SImode, operands[0]);
16826   operands[1] = gen_lowpart (SImode, operands[1]);
16827   if (GET_CODE (operands[3]) != ASHIFT)
16828     operands[2] = gen_lowpart (SImode, operands[2]);
16829   PUT_MODE (operands[3], SImode);
16830 })
16831
16832 ; Promote the QImode tests, as i386 has encoding of the AND
16833 ; instruction with 32-bit sign-extended immediate and thus the
16834 ; instruction size is unchanged, except in the %eax case for
16835 ; which it is increased by one byte, hence the ! optimize_size.
16836 (define_split
16837   [(set (match_operand 0 "flags_reg_operand" "")
16838         (match_operator 2 "compare_operator"
16839           [(and (match_operand 3 "aligned_operand" "")
16840                 (match_operand 4 "const_int_operand" ""))
16841            (const_int 0)]))
16842    (set (match_operand 1 "register_operand" "")
16843         (and (match_dup 3) (match_dup 4)))]
16844   "! TARGET_PARTIAL_REG_STALL && reload_completed
16845    && optimize_insn_for_speed_p ()
16846    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16847        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16848    /* Ensure that the operand will remain sign-extended immediate.  */
16849    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16850   [(parallel [(set (match_dup 0)
16851                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16852                                     (const_int 0)]))
16853               (set (match_dup 1)
16854                    (and:SI (match_dup 3) (match_dup 4)))])]
16855 {
16856   operands[4]
16857     = gen_int_mode (INTVAL (operands[4])
16858                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16859   operands[1] = gen_lowpart (SImode, operands[1]);
16860   operands[3] = gen_lowpart (SImode, operands[3]);
16861 })
16862
16863 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16864 ; the TEST instruction with 32-bit sign-extended immediate and thus
16865 ; the instruction size would at least double, which is not what we
16866 ; want even with ! optimize_size.
16867 (define_split
16868   [(set (match_operand 0 "flags_reg_operand" "")
16869         (match_operator 1 "compare_operator"
16870           [(and (match_operand:HI 2 "aligned_operand" "")
16871                 (match_operand:HI 3 "const_int_operand" ""))
16872            (const_int 0)]))]
16873   "! TARGET_PARTIAL_REG_STALL && reload_completed
16874    && ! TARGET_FAST_PREFIX
16875    && optimize_insn_for_speed_p ()
16876    /* Ensure that the operand will remain sign-extended immediate.  */
16877    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16878   [(set (match_dup 0)
16879         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16880                          (const_int 0)]))]
16881 {
16882   operands[3]
16883     = gen_int_mode (INTVAL (operands[3])
16884                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16885   operands[2] = gen_lowpart (SImode, operands[2]);
16886 })
16887
16888 (define_split
16889   [(set (match_operand 0 "register_operand" "")
16890         (neg (match_operand 1 "register_operand" "")))
16891    (clobber (reg:CC FLAGS_REG))]
16892   "! TARGET_PARTIAL_REG_STALL && reload_completed
16893    && (GET_MODE (operands[0]) == HImode
16894        || (GET_MODE (operands[0]) == QImode
16895            && (TARGET_PROMOTE_QImode
16896                || optimize_insn_for_size_p ())))"
16897   [(parallel [(set (match_dup 0)
16898                    (neg:SI (match_dup 1)))
16899               (clobber (reg:CC FLAGS_REG))])]
16900 {
16901   operands[0] = gen_lowpart (SImode, operands[0]);
16902   operands[1] = gen_lowpart (SImode, operands[1]);
16903 })
16904
16905 (define_split
16906   [(set (match_operand 0 "register_operand" "")
16907         (not (match_operand 1 "register_operand" "")))]
16908   "! TARGET_PARTIAL_REG_STALL && reload_completed
16909    && (GET_MODE (operands[0]) == HImode
16910        || (GET_MODE (operands[0]) == QImode
16911            && (TARGET_PROMOTE_QImode
16912                || optimize_insn_for_size_p ())))"
16913   [(set (match_dup 0)
16914         (not:SI (match_dup 1)))]
16915 {
16916   operands[0] = gen_lowpart (SImode, operands[0]);
16917   operands[1] = gen_lowpart (SImode, operands[1]);
16918 })
16919 \f
16920 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
16921 ;; transform a complex memory operation into two memory to register operations.
16922
16923 ;; Don't push memory operands
16924 (define_peephole2
16925   [(set (match_operand:SWI 0 "push_operand" "")
16926         (match_operand:SWI 1 "memory_operand" ""))
16927    (match_scratch:SWI 2 "<r>")]
16928   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16929    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16930   [(set (match_dup 2) (match_dup 1))
16931    (set (match_dup 0) (match_dup 2))])
16932
16933 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16934 ;; SImode pushes.
16935 (define_peephole2
16936   [(set (match_operand:SF 0 "push_operand" "")
16937         (match_operand:SF 1 "memory_operand" ""))
16938    (match_scratch:SF 2 "r")]
16939   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16940    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16941   [(set (match_dup 2) (match_dup 1))
16942    (set (match_dup 0) (match_dup 2))])
16943
16944 ;; Don't move an immediate directly to memory when the instruction
16945 ;; gets too big.
16946 (define_peephole2
16947   [(match_scratch:SWI124 1 "<r>")
16948    (set (match_operand:SWI124 0 "memory_operand" "")
16949         (const_int 0))]
16950   "optimize_insn_for_speed_p ()
16951    && !TARGET_USE_MOV0
16952    && TARGET_SPLIT_LONG_MOVES
16953    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16954    && peep2_regno_dead_p (0, FLAGS_REG)"
16955   [(parallel [(set (match_dup 2) (const_int 0))
16956               (clobber (reg:CC FLAGS_REG))])
16957    (set (match_dup 0) (match_dup 1))]
16958   "operands[2] = gen_lowpart (SImode, operands[1]);")
16959
16960 (define_peephole2
16961   [(match_scratch:SWI124 2 "<r>")
16962    (set (match_operand:SWI124 0 "memory_operand" "")
16963         (match_operand:SWI124 1 "immediate_operand" ""))]
16964   "optimize_insn_for_speed_p ()
16965    && TARGET_SPLIT_LONG_MOVES
16966    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16967   [(set (match_dup 2) (match_dup 1))
16968    (set (match_dup 0) (match_dup 2))])
16969
16970 ;; Don't compare memory with zero, load and use a test instead.
16971 (define_peephole2
16972   [(set (match_operand 0 "flags_reg_operand" "")
16973         (match_operator 1 "compare_operator"
16974           [(match_operand:SI 2 "memory_operand" "")
16975            (const_int 0)]))
16976    (match_scratch:SI 3 "r")]
16977   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16978   [(set (match_dup 3) (match_dup 2))
16979    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16980
16981 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16982 ;; Don't split NOTs with a displacement operand, because resulting XOR
16983 ;; will not be pairable anyway.
16984 ;;
16985 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16986 ;; represented using a modRM byte.  The XOR replacement is long decoded,
16987 ;; so this split helps here as well.
16988 ;;
16989 ;; Note: Can't do this as a regular split because we can't get proper
16990 ;; lifetime information then.
16991
16992 (define_peephole2
16993   [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16994         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16995   "optimize_insn_for_speed_p ()
16996    && ((TARGET_NOT_UNPAIRABLE
16997         && (!MEM_P (operands[0])
16998             || !memory_displacement_operand (operands[0], <MODE>mode)))
16999        || (TARGET_NOT_VECTORMODE
17000            && long_memory_operand (operands[0], <MODE>mode)))
17001    && peep2_regno_dead_p (0, FLAGS_REG)"
17002   [(parallel [(set (match_dup 0)
17003                    (xor:SWI124 (match_dup 1) (const_int -1)))
17004               (clobber (reg:CC FLAGS_REG))])])
17005
17006 ;; Non pairable "test imm, reg" instructions can be translated to
17007 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17008 ;; byte opcode instead of two, have a short form for byte operands),
17009 ;; so do it for other CPUs as well.  Given that the value was dead,
17010 ;; this should not create any new dependencies.  Pass on the sub-word
17011 ;; versions if we're concerned about partial register stalls.
17012
17013 (define_peephole2
17014   [(set (match_operand 0 "flags_reg_operand" "")
17015         (match_operator 1 "compare_operator"
17016           [(and:SI (match_operand:SI 2 "register_operand" "")
17017                    (match_operand:SI 3 "immediate_operand" ""))
17018            (const_int 0)]))]
17019   "ix86_match_ccmode (insn, CCNOmode)
17020    && (true_regnum (operands[2]) != AX_REG
17021        || satisfies_constraint_K (operands[3]))
17022    && peep2_reg_dead_p (1, operands[2])"
17023   [(parallel
17024      [(set (match_dup 0)
17025            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17026                             (const_int 0)]))
17027       (set (match_dup 2)
17028            (and:SI (match_dup 2) (match_dup 3)))])])
17029
17030 ;; We don't need to handle HImode case, because it will be promoted to SImode
17031 ;; on ! TARGET_PARTIAL_REG_STALL
17032
17033 (define_peephole2
17034   [(set (match_operand 0 "flags_reg_operand" "")
17035         (match_operator 1 "compare_operator"
17036           [(and:QI (match_operand:QI 2 "register_operand" "")
17037                    (match_operand:QI 3 "immediate_operand" ""))
17038            (const_int 0)]))]
17039   "! TARGET_PARTIAL_REG_STALL
17040    && ix86_match_ccmode (insn, CCNOmode)
17041    && true_regnum (operands[2]) != AX_REG
17042    && peep2_reg_dead_p (1, operands[2])"
17043   [(parallel
17044      [(set (match_dup 0)
17045            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17046                             (const_int 0)]))
17047       (set (match_dup 2)
17048            (and:QI (match_dup 2) (match_dup 3)))])])
17049
17050 (define_peephole2
17051   [(set (match_operand 0 "flags_reg_operand" "")
17052         (match_operator 1 "compare_operator"
17053           [(and:SI
17054              (zero_extract:SI
17055                (match_operand 2 "ext_register_operand" "")
17056                (const_int 8)
17057                (const_int 8))
17058              (match_operand 3 "const_int_operand" ""))
17059            (const_int 0)]))]
17060   "! TARGET_PARTIAL_REG_STALL
17061    && ix86_match_ccmode (insn, CCNOmode)
17062    && true_regnum (operands[2]) != AX_REG
17063    && peep2_reg_dead_p (1, operands[2])"
17064   [(parallel [(set (match_dup 0)
17065                    (match_op_dup 1
17066                      [(and:SI
17067                         (zero_extract:SI
17068                           (match_dup 2)
17069                           (const_int 8)
17070                           (const_int 8))
17071                         (match_dup 3))
17072                       (const_int 0)]))
17073               (set (zero_extract:SI (match_dup 2)
17074                                     (const_int 8)
17075                                     (const_int 8))
17076                    (and:SI
17077                      (zero_extract:SI
17078                        (match_dup 2)
17079                        (const_int 8)
17080                        (const_int 8))
17081                      (match_dup 3)))])])
17082
17083 ;; Don't do logical operations with memory inputs.
17084 (define_peephole2
17085   [(match_scratch:SI 2 "r")
17086    (parallel [(set (match_operand:SI 0 "register_operand" "")
17087                    (match_operator:SI 3 "arith_or_logical_operator"
17088                      [(match_dup 0)
17089                       (match_operand:SI 1 "memory_operand" "")]))
17090               (clobber (reg:CC FLAGS_REG))])]
17091   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17092   [(set (match_dup 2) (match_dup 1))
17093    (parallel [(set (match_dup 0)
17094                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17095               (clobber (reg:CC FLAGS_REG))])])
17096
17097 (define_peephole2
17098   [(match_scratch:SI 2 "r")
17099    (parallel [(set (match_operand:SI 0 "register_operand" "")
17100                    (match_operator:SI 3 "arith_or_logical_operator"
17101                      [(match_operand:SI 1 "memory_operand" "")
17102                       (match_dup 0)]))
17103               (clobber (reg:CC FLAGS_REG))])]
17104   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17105   [(set (match_dup 2) (match_dup 1))
17106    (parallel [(set (match_dup 0)
17107                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17108               (clobber (reg:CC FLAGS_REG))])])
17109
17110 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17111 ;; refers to the destination of the load!
17112
17113 (define_peephole2
17114   [(set (match_operand:SI 0 "register_operand" "")
17115         (match_operand:SI 1 "register_operand" ""))
17116    (parallel [(set (match_dup 0)
17117                    (match_operator:SI 3 "commutative_operator"
17118                      [(match_dup 0)
17119                       (match_operand:SI 2 "memory_operand" "")]))
17120               (clobber (reg:CC FLAGS_REG))])]
17121   "REGNO (operands[0]) != REGNO (operands[1])
17122    && GENERAL_REGNO_P (REGNO (operands[0]))
17123    && GENERAL_REGNO_P (REGNO (operands[1]))"
17124   [(set (match_dup 0) (match_dup 4))
17125    (parallel [(set (match_dup 0)
17126                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17127               (clobber (reg:CC FLAGS_REG))])]
17128   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17129
17130 (define_peephole2
17131   [(set (match_operand 0 "register_operand" "")
17132         (match_operand 1 "register_operand" ""))
17133    (set (match_dup 0)
17134                    (match_operator 3 "commutative_operator"
17135                      [(match_dup 0)
17136                       (match_operand 2 "memory_operand" "")]))]
17137   "REGNO (operands[0]) != REGNO (operands[1])
17138    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
17139        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17140   [(set (match_dup 0) (match_dup 2))
17141    (set (match_dup 0)
17142         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17143
17144 ; Don't do logical operations with memory outputs
17145 ;
17146 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17147 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17148 ; the same decoder scheduling characteristics as the original.
17149
17150 (define_peephole2
17151   [(match_scratch:SI 2 "r")
17152    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17153                    (match_operator:SI 3 "arith_or_logical_operator"
17154                      [(match_dup 0)
17155                       (match_operand:SI 1 "nonmemory_operand" "")]))
17156               (clobber (reg:CC FLAGS_REG))])]
17157   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17158    /* Do not split stack checking probes.  */
17159    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17160   [(set (match_dup 2) (match_dup 0))
17161    (parallel [(set (match_dup 2)
17162                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17163               (clobber (reg:CC FLAGS_REG))])
17164    (set (match_dup 0) (match_dup 2))])
17165
17166 (define_peephole2
17167   [(match_scratch:SI 2 "r")
17168    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17169                    (match_operator:SI 3 "arith_or_logical_operator"
17170                      [(match_operand:SI 1 "nonmemory_operand" "")
17171                       (match_dup 0)]))
17172               (clobber (reg:CC FLAGS_REG))])]
17173   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17174    /* Do not split stack checking probes.  */
17175    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17176   [(set (match_dup 2) (match_dup 0))
17177    (parallel [(set (match_dup 2)
17178                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17179               (clobber (reg:CC FLAGS_REG))])
17180    (set (match_dup 0) (match_dup 2))])
17181
17182 ;; Attempt to use arith or logical operations with memory outputs with
17183 ;; setting of flags.
17184 (define_peephole2
17185   [(set (match_operand:SWI 0 "register_operand" "")
17186         (match_operand:SWI 1 "memory_operand" ""))
17187    (parallel [(set (match_dup 0)
17188                    (match_operator:SWI 3 "plusminuslogic_operator"
17189                      [(match_dup 0)
17190                       (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17191               (clobber (reg:CC FLAGS_REG))])
17192    (set (match_dup 1) (match_dup 0))
17193    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17194   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17195    && peep2_reg_dead_p (4, operands[0])
17196    && !reg_overlap_mentioned_p (operands[0], operands[1])
17197    && !reg_overlap_mentioned_p (operands[0], operands[2])
17198    && (<MODE>mode != QImode
17199        || immediate_operand (operands[2], QImode)
17200        || q_regs_operand (operands[2], QImode))
17201    && ix86_match_ccmode (peep2_next_insn (3),
17202                          (GET_CODE (operands[3]) == PLUS
17203                           || GET_CODE (operands[3]) == MINUS)
17204                          ? CCGOCmode : CCNOmode)"
17205   [(parallel [(set (match_dup 4) (match_dup 5))
17206               (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17207                                                   (match_dup 2)]))])]
17208 {
17209   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17210   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17211                                 copy_rtx (operands[1]),
17212                                 copy_rtx (operands[2]));
17213   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17214                                  operands[5], const0_rtx);
17215 })
17216
17217 (define_peephole2
17218   [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17219                    (match_operator:SWI 2 "plusminuslogic_operator"
17220                      [(match_dup 0)
17221                       (match_operand:SWI 1 "memory_operand" "")]))
17222               (clobber (reg:CC FLAGS_REG))])
17223    (set (match_dup 1) (match_dup 0))
17224    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17225   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17226    && GET_CODE (operands[2]) != MINUS
17227    && peep2_reg_dead_p (3, operands[0])
17228    && !reg_overlap_mentioned_p (operands[0], operands[1])
17229    && ix86_match_ccmode (peep2_next_insn (2),
17230                          GET_CODE (operands[2]) == PLUS
17231                          ? CCGOCmode : CCNOmode)"
17232   [(parallel [(set (match_dup 3) (match_dup 4))
17233               (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17234                                                   (match_dup 0)]))])]
17235 {
17236   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17237   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17238                                 copy_rtx (operands[1]),
17239                                 copy_rtx (operands[0]));
17240   operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17241                                  operands[4], const0_rtx);
17242 })
17243
17244 (define_peephole2
17245   [(set (match_operand:SWI12 0 "register_operand" "")
17246         (match_operand:SWI12 1 "memory_operand" ""))
17247    (parallel [(set (match_operand:SI 4 "register_operand" "")
17248                    (match_operator:SI 3 "plusminuslogic_operator"
17249                      [(match_dup 4)
17250                       (match_operand:SI 2 "nonmemory_operand" "")]))
17251               (clobber (reg:CC FLAGS_REG))])
17252    (set (match_dup 1) (match_dup 0))
17253    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17254   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17255    && REG_P (operands[0]) && REG_P (operands[4])
17256    && REGNO (operands[0]) == REGNO (operands[4])
17257    && peep2_reg_dead_p (4, operands[0])
17258    && (<MODE>mode != QImode
17259        || immediate_operand (operands[2], SImode)
17260        || q_regs_operand (operands[2], SImode))
17261    && !reg_overlap_mentioned_p (operands[0], operands[1])
17262    && !reg_overlap_mentioned_p (operands[0], operands[2])
17263    && ix86_match_ccmode (peep2_next_insn (3),
17264                          (GET_CODE (operands[3]) == PLUS
17265                           || GET_CODE (operands[3]) == MINUS)
17266                          ? CCGOCmode : CCNOmode)"
17267   [(parallel [(set (match_dup 4) (match_dup 5))
17268               (set (match_dup 1) (match_dup 6))])]
17269 {
17270   operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17271   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17272   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17273                                 copy_rtx (operands[1]), operands[2]);
17274   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17275                                  operands[5], const0_rtx);
17276   operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17277                                 copy_rtx (operands[1]),
17278                                 copy_rtx (operands[2]));
17279 })
17280
17281 ;; Attempt to always use XOR for zeroing registers.
17282 (define_peephole2
17283   [(set (match_operand 0 "register_operand" "")
17284         (match_operand 1 "const0_operand" ""))]
17285   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17286    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17287    && GENERAL_REG_P (operands[0])
17288    && peep2_regno_dead_p (0, FLAGS_REG)"
17289   [(parallel [(set (match_dup 0) (const_int 0))
17290               (clobber (reg:CC FLAGS_REG))])]
17291   "operands[0] = gen_lowpart (word_mode, operands[0]);")
17292
17293 (define_peephole2
17294   [(set (strict_low_part (match_operand 0 "register_operand" ""))
17295         (const_int 0))]
17296   "(GET_MODE (operands[0]) == QImode
17297     || GET_MODE (operands[0]) == HImode)
17298    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17299    && peep2_regno_dead_p (0, FLAGS_REG)"
17300   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17301               (clobber (reg:CC FLAGS_REG))])])
17302
17303 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17304 (define_peephole2
17305   [(set (match_operand:SWI248 0 "register_operand" "")
17306         (const_int -1))]
17307   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17308    && peep2_regno_dead_p (0, FLAGS_REG)"
17309   [(parallel [(set (match_dup 0) (const_int -1))
17310               (clobber (reg:CC FLAGS_REG))])]
17311 {
17312   if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17313     operands[0] = gen_lowpart (SImode, operands[0]);
17314 })
17315
17316 ;; Attempt to convert simple lea to add/shift.
17317 ;; These can be created by move expanders.
17318
17319 (define_peephole2
17320   [(set (match_operand:SWI48 0 "register_operand" "")
17321         (plus:SWI48 (match_dup 0)
17322                     (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17323   "peep2_regno_dead_p (0, FLAGS_REG)"
17324   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17325               (clobber (reg:CC FLAGS_REG))])])
17326
17327 (define_peephole2
17328   [(set (match_operand:SI 0 "register_operand" "")
17329         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17330                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17331   "TARGET_64BIT
17332    && peep2_regno_dead_p (0, FLAGS_REG)
17333    && REGNO (operands[0]) == REGNO (operands[1])"
17334   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17335               (clobber (reg:CC FLAGS_REG))])]
17336   "operands[2] = gen_lowpart (SImode, operands[2]);")
17337
17338 (define_peephole2
17339   [(set (match_operand:SWI48 0 "register_operand" "")
17340         (mult:SWI48 (match_dup 0)
17341                     (match_operand:SWI48 1 "const_int_operand" "")))]
17342   "exact_log2 (INTVAL (operands[1])) >= 0
17343    && peep2_regno_dead_p (0, FLAGS_REG)"
17344   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17345               (clobber (reg:CC FLAGS_REG))])]
17346   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17347
17348 (define_peephole2
17349   [(set (match_operand:SI 0 "register_operand" "")
17350         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17351                    (match_operand:DI 2 "const_int_operand" "")) 0))]
17352   "TARGET_64BIT
17353    && exact_log2 (INTVAL (operands[2])) >= 0
17354    && REGNO (operands[0]) == REGNO (operands[1])
17355    && peep2_regno_dead_p (0, FLAGS_REG)"
17356   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17357               (clobber (reg:CC FLAGS_REG))])]
17358   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17359
17360 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17361 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17362 ;; On many CPUs it is also faster, since special hardware to avoid esp
17363 ;; dependencies is present.
17364
17365 ;; While some of these conversions may be done using splitters, we use
17366 ;; peepholes in order to allow combine_stack_adjustments pass to see
17367 ;; nonobfuscated RTL.
17368
17369 ;; Convert prologue esp subtractions to push.
17370 ;; We need register to push.  In order to keep verify_flow_info happy we have
17371 ;; two choices
17372 ;; - use scratch and clobber it in order to avoid dependencies
17373 ;; - use already live register
17374 ;; We can't use the second way right now, since there is no reliable way how to
17375 ;; verify that given register is live.  First choice will also most likely in
17376 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17377 ;; call clobbered registers are dead.  We may want to use base pointer as an
17378 ;; alternative when no register is available later.
17379
17380 (define_peephole2
17381   [(match_scratch:P 1 "r")
17382    (parallel [(set (reg:P SP_REG)
17383                    (plus:P (reg:P SP_REG)
17384                            (match_operand:P 0 "const_int_operand" "")))
17385               (clobber (reg:CC FLAGS_REG))
17386               (clobber (mem:BLK (scratch)))])]
17387   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17388    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17389   [(clobber (match_dup 1))
17390    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17391               (clobber (mem:BLK (scratch)))])])
17392
17393 (define_peephole2
17394   [(match_scratch:P 1 "r")
17395    (parallel [(set (reg:P SP_REG)
17396                    (plus:P (reg:P SP_REG)
17397                            (match_operand:P 0 "const_int_operand" "")))
17398               (clobber (reg:CC FLAGS_REG))
17399               (clobber (mem:BLK (scratch)))])]
17400   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17401    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17402   [(clobber (match_dup 1))
17403    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17404    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17405               (clobber (mem:BLK (scratch)))])])
17406
17407 ;; Convert esp subtractions to push.
17408 (define_peephole2
17409   [(match_scratch:P 1 "r")
17410    (parallel [(set (reg:P SP_REG)
17411                    (plus:P (reg:P SP_REG)
17412                            (match_operand:P 0 "const_int_operand" "")))
17413               (clobber (reg:CC FLAGS_REG))])]
17414   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17415    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17416   [(clobber (match_dup 1))
17417    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17418
17419 (define_peephole2
17420   [(match_scratch:P 1 "r")
17421    (parallel [(set (reg:P SP_REG)
17422                    (plus:P (reg:P SP_REG)
17423                            (match_operand:P 0 "const_int_operand" "")))
17424               (clobber (reg:CC FLAGS_REG))])]
17425   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17426    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17427   [(clobber (match_dup 1))
17428    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17429    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17430
17431 ;; Convert epilogue deallocator to pop.
17432 (define_peephole2
17433   [(match_scratch:P 1 "r")
17434    (parallel [(set (reg:P SP_REG)
17435                    (plus:P (reg:P SP_REG)
17436                            (match_operand:P 0 "const_int_operand" "")))
17437               (clobber (reg:CC FLAGS_REG))
17438               (clobber (mem:BLK (scratch)))])]
17439   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17440    && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17441   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17442               (clobber (mem:BLK (scratch)))])])
17443
17444 ;; Two pops case is tricky, since pop causes dependency
17445 ;; on destination register.  We use two registers if available.
17446 (define_peephole2
17447   [(match_scratch:P 1 "r")
17448    (match_scratch:P 2 "r")
17449    (parallel [(set (reg:P SP_REG)
17450                    (plus:P (reg:P SP_REG)
17451                            (match_operand:P 0 "const_int_operand" "")))
17452               (clobber (reg:CC FLAGS_REG))
17453               (clobber (mem:BLK (scratch)))])]
17454   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17455    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17456   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17457               (clobber (mem:BLK (scratch)))])
17458    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17459
17460 (define_peephole2
17461   [(match_scratch:P 1 "r")
17462    (parallel [(set (reg:P SP_REG)
17463                    (plus:P (reg:P SP_REG)
17464                            (match_operand:P 0 "const_int_operand" "")))
17465               (clobber (reg:CC FLAGS_REG))
17466               (clobber (mem:BLK (scratch)))])]
17467   "optimize_insn_for_size_p ()
17468    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17469   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17470               (clobber (mem:BLK (scratch)))])
17471    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17472
17473 ;; Convert esp additions to pop.
17474 (define_peephole2
17475   [(match_scratch:P 1 "r")
17476    (parallel [(set (reg:P SP_REG)
17477                    (plus:P (reg:P SP_REG)
17478                            (match_operand:P 0 "const_int_operand" "")))
17479               (clobber (reg:CC FLAGS_REG))])]
17480   "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17481   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17482
17483 ;; Two pops case is tricky, since pop causes dependency
17484 ;; on destination register.  We use two registers if available.
17485 (define_peephole2
17486   [(match_scratch:P 1 "r")
17487    (match_scratch:P 2 "r")
17488    (parallel [(set (reg:P SP_REG)
17489                    (plus:P (reg:P SP_REG)
17490                            (match_operand:P 0 "const_int_operand" "")))
17491               (clobber (reg:CC FLAGS_REG))])]
17492   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17493   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17494    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17495
17496 (define_peephole2
17497   [(match_scratch:P 1 "r")
17498    (parallel [(set (reg:P SP_REG)
17499                    (plus:P (reg:P SP_REG)
17500                            (match_operand:P 0 "const_int_operand" "")))
17501               (clobber (reg:CC FLAGS_REG))])]
17502   "optimize_insn_for_size_p ()
17503    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17504   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17505    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17506 \f
17507 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17508 ;; required and register dies.  Similarly for 128 to -128.
17509 (define_peephole2
17510   [(set (match_operand 0 "flags_reg_operand" "")
17511         (match_operator 1 "compare_operator"
17512           [(match_operand 2 "register_operand" "")
17513            (match_operand 3 "const_int_operand" "")]))]
17514   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17515      && incdec_operand (operands[3], GET_MODE (operands[3])))
17516     || (!TARGET_FUSE_CMP_AND_BRANCH
17517         && INTVAL (operands[3]) == 128))
17518    && ix86_match_ccmode (insn, CCGCmode)
17519    && peep2_reg_dead_p (1, operands[2])"
17520   [(parallel [(set (match_dup 0)
17521                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17522               (clobber (match_dup 2))])])
17523 \f
17524 ;; Convert imul by three, five and nine into lea
17525 (define_peephole2
17526   [(parallel
17527     [(set (match_operand:SWI48 0 "register_operand" "")
17528           (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17529                       (match_operand:SWI48 2 "const359_operand" "")))
17530      (clobber (reg:CC FLAGS_REG))])]
17531   "!TARGET_PARTIAL_REG_STALL
17532    || <MODE>mode == SImode
17533    || optimize_function_for_size_p (cfun)"
17534   [(set (match_dup 0)
17535         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17536                     (match_dup 1)))]
17537   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17538
17539 (define_peephole2
17540   [(parallel
17541     [(set (match_operand:SWI48 0 "register_operand" "")
17542           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17543                       (match_operand:SWI48 2 "const359_operand" "")))
17544      (clobber (reg:CC FLAGS_REG))])]
17545   "optimize_insn_for_speed_p ()
17546    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17547   [(set (match_dup 0) (match_dup 1))
17548    (set (match_dup 0)
17549         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17550                     (match_dup 0)))]
17551   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17552
17553 ;; imul $32bit_imm, mem, reg is vector decoded, while
17554 ;; imul $32bit_imm, reg, reg is direct decoded.
17555 (define_peephole2
17556   [(match_scratch:SWI48 3 "r")
17557    (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17558                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17559                                (match_operand:SWI48 2 "immediate_operand" "")))
17560               (clobber (reg:CC FLAGS_REG))])]
17561   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17562    && !satisfies_constraint_K (operands[2])"
17563   [(set (match_dup 3) (match_dup 1))
17564    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17565               (clobber (reg:CC FLAGS_REG))])])
17566
17567 (define_peephole2
17568   [(match_scratch:SI 3 "r")
17569    (parallel [(set (match_operand:DI 0 "register_operand" "")
17570                    (zero_extend:DI
17571                      (mult:SI (match_operand:SI 1 "memory_operand" "")
17572                               (match_operand:SI 2 "immediate_operand" ""))))
17573               (clobber (reg:CC FLAGS_REG))])]
17574   "TARGET_64BIT
17575    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17576    && !satisfies_constraint_K (operands[2])"
17577   [(set (match_dup 3) (match_dup 1))
17578    (parallel [(set (match_dup 0)
17579                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17580               (clobber (reg:CC FLAGS_REG))])])
17581
17582 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17583 ;; Convert it into imul reg, reg
17584 ;; It would be better to force assembler to encode instruction using long
17585 ;; immediate, but there is apparently no way to do so.
17586 (define_peephole2
17587   [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17588                    (mult:SWI248
17589                     (match_operand:SWI248 1 "nonimmediate_operand" "")
17590                     (match_operand:SWI248 2 "const_int_operand" "")))
17591               (clobber (reg:CC FLAGS_REG))])
17592    (match_scratch:SWI248 3 "r")]
17593   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17594    && satisfies_constraint_K (operands[2])"
17595   [(set (match_dup 3) (match_dup 2))
17596    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17597               (clobber (reg:CC FLAGS_REG))])]
17598 {
17599   if (!rtx_equal_p (operands[0], operands[1]))
17600     emit_move_insn (operands[0], operands[1]);
17601 })
17602
17603 ;; After splitting up read-modify operations, array accesses with memory
17604 ;; operands might end up in form:
17605 ;;  sall    $2, %eax
17606 ;;  movl    4(%esp), %edx
17607 ;;  addl    %edx, %eax
17608 ;; instead of pre-splitting:
17609 ;;  sall    $2, %eax
17610 ;;  addl    4(%esp), %eax
17611 ;; Turn it into:
17612 ;;  movl    4(%esp), %edx
17613 ;;  leal    (%edx,%eax,4), %eax
17614
17615 (define_peephole2
17616   [(match_scratch:P 5 "r")
17617    (parallel [(set (match_operand 0 "register_operand" "")
17618                    (ashift (match_operand 1 "register_operand" "")
17619                            (match_operand 2 "const_int_operand" "")))
17620                (clobber (reg:CC FLAGS_REG))])
17621    (parallel [(set (match_operand 3 "register_operand" "")
17622                    (plus (match_dup 0)
17623                          (match_operand 4 "x86_64_general_operand" "")))
17624                    (clobber (reg:CC FLAGS_REG))])]
17625   "IN_RANGE (INTVAL (operands[2]), 1, 3)
17626    /* Validate MODE for lea.  */
17627    && ((!TARGET_PARTIAL_REG_STALL
17628         && (GET_MODE (operands[0]) == QImode
17629             || GET_MODE (operands[0]) == HImode))
17630        || GET_MODE (operands[0]) == SImode
17631        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17632    && (rtx_equal_p (operands[0], operands[3])
17633        || peep2_reg_dead_p (2, operands[0]))
17634    /* We reorder load and the shift.  */
17635    && !reg_overlap_mentioned_p (operands[0], operands[4])"
17636   [(set (match_dup 5) (match_dup 4))
17637    (set (match_dup 0) (match_dup 1))]
17638 {
17639   enum machine_mode op1mode = GET_MODE (operands[1]);
17640   enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17641   int scale = 1 << INTVAL (operands[2]);
17642   rtx index = gen_lowpart (Pmode, operands[1]);
17643   rtx base = gen_lowpart (Pmode, operands[5]);
17644   rtx dest = gen_lowpart (mode, operands[3]);
17645
17646   operands[1] = gen_rtx_PLUS (Pmode, base,
17647                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17648   operands[5] = base;
17649   if (mode != Pmode)
17650     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17651   if (op1mode != Pmode)
17652     operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17653   operands[0] = dest;
17654 })
17655 \f
17656 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17657 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17658 ;; caught for use by garbage collectors and the like.  Using an insn that
17659 ;; maps to SIGILL makes it more likely the program will rightfully die.
17660 ;; Keeping with tradition, "6" is in honor of #UD.
17661 (define_insn "trap"
17662   [(trap_if (const_int 1) (const_int 6))]
17663   ""
17664   { return ASM_SHORT "0x0b0f"; }
17665   [(set_attr "length" "2")])
17666
17667 (define_expand "prefetch"
17668   [(prefetch (match_operand 0 "address_operand" "")
17669              (match_operand:SI 1 "const_int_operand" "")
17670              (match_operand:SI 2 "const_int_operand" ""))]
17671   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17672 {
17673   int rw = INTVAL (operands[1]);
17674   int locality = INTVAL (operands[2]);
17675
17676   gcc_assert (rw == 0 || rw == 1);
17677   gcc_assert (IN_RANGE (locality, 0, 3));
17678
17679   if (TARGET_PREFETCHW && rw)
17680     operands[2] = GEN_INT (3);
17681   /* Use 3dNOW prefetch in case we are asking for write prefetch not
17682      supported by SSE counterpart or the SSE prefetch is not available
17683      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17684      of locality.  */
17685   else if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17686     operands[2] = GEN_INT (3);
17687   else
17688     operands[1] = const0_rtx;
17689 })
17690
17691 (define_insn "*prefetch_sse"
17692   [(prefetch (match_operand 0 "address_operand" "p")
17693              (const_int 0)
17694              (match_operand:SI 1 "const_int_operand" ""))]
17695   "TARGET_PREFETCH_SSE"
17696 {
17697   static const char * const patterns[4] = {
17698    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17699   };
17700
17701   int locality = INTVAL (operands[1]);
17702   gcc_assert (IN_RANGE (locality, 0, 3));
17703
17704   return patterns[locality];
17705 }
17706   [(set_attr "type" "sse")
17707    (set_attr "atom_sse_attr" "prefetch")
17708    (set (attr "length_address")
17709         (symbol_ref "memory_address_length (operands[0], false)"))
17710    (set_attr "memory" "none")])
17711
17712 (define_insn "*prefetch_3dnow"
17713   [(prefetch (match_operand 0 "address_operand" "p")
17714              (match_operand:SI 1 "const_int_operand" "n")
17715              (const_int 3))]
17716   "TARGET_3DNOW || TARGET_PREFETCHW"
17717 {
17718   if (INTVAL (operands[1]) == 0)
17719     return "prefetch\t%a0";
17720   else
17721     return "prefetchw\t%a0";
17722 }
17723   [(set_attr "type" "mmx")
17724    (set (attr "length_address")
17725         (symbol_ref "memory_address_length (operands[0], false)"))
17726    (set_attr "memory" "none")])
17727
17728 (define_expand "stack_protect_set"
17729   [(match_operand 0 "memory_operand" "")
17730    (match_operand 1 "memory_operand" "")]
17731   "!TARGET_HAS_BIONIC"
17732 {
17733   rtx (*insn)(rtx, rtx);
17734
17735 #ifdef TARGET_THREAD_SSP_OFFSET
17736   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17737   insn = (TARGET_LP64
17738           ? gen_stack_tls_protect_set_di
17739           : gen_stack_tls_protect_set_si);
17740 #else
17741   insn = (TARGET_LP64
17742           ? gen_stack_protect_set_di
17743           : gen_stack_protect_set_si);
17744 #endif
17745
17746   emit_insn (insn (operands[0], operands[1]));
17747   DONE;
17748 })
17749
17750 (define_insn "stack_protect_set_<mode>"
17751   [(set (match_operand:PTR 0 "memory_operand" "=m")
17752         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17753                     UNSPEC_SP_SET))
17754    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17755    (clobber (reg:CC FLAGS_REG))]
17756   "!TARGET_HAS_BIONIC"
17757   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17758   [(set_attr "type" "multi")])
17759
17760 (define_insn "stack_tls_protect_set_<mode>"
17761   [(set (match_operand:PTR 0 "memory_operand" "=m")
17762         (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17763                     UNSPEC_SP_TLS_SET))
17764    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17765    (clobber (reg:CC FLAGS_REG))]
17766   ""
17767   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17768   [(set_attr "type" "multi")])
17769
17770 (define_expand "stack_protect_test"
17771   [(match_operand 0 "memory_operand" "")
17772    (match_operand 1 "memory_operand" "")
17773    (match_operand 2 "" "")]
17774   "!TARGET_HAS_BIONIC"
17775 {
17776   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17777
17778   rtx (*insn)(rtx, rtx, rtx);
17779
17780 #ifdef TARGET_THREAD_SSP_OFFSET
17781   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17782   insn = (TARGET_LP64
17783           ? gen_stack_tls_protect_test_di
17784           : gen_stack_tls_protect_test_si);
17785 #else
17786   insn = (TARGET_LP64
17787           ? gen_stack_protect_test_di
17788           : gen_stack_protect_test_si);
17789 #endif
17790
17791   emit_insn (insn (flags, operands[0], operands[1]));
17792
17793   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17794                                   flags, const0_rtx, operands[2]));
17795   DONE;
17796 })
17797
17798 (define_insn "stack_protect_test_<mode>"
17799   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17800         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17801                      (match_operand:PTR 2 "memory_operand" "m")]
17802                     UNSPEC_SP_TEST))
17803    (clobber (match_scratch:PTR 3 "=&r"))]
17804   "!TARGET_HAS_BIONIC"
17805   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17806   [(set_attr "type" "multi")])
17807
17808 (define_insn "stack_tls_protect_test_<mode>"
17809   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17810         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17811                      (match_operand:PTR 2 "const_int_operand" "i")]
17812                     UNSPEC_SP_TLS_TEST))
17813    (clobber (match_scratch:PTR 3 "=r"))]
17814   ""
17815   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17816   [(set_attr "type" "multi")])
17817
17818 (define_insn "sse4_2_crc32<mode>"
17819   [(set (match_operand:SI 0 "register_operand" "=r")
17820         (unspec:SI
17821           [(match_operand:SI 1 "register_operand" "0")
17822            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17823           UNSPEC_CRC32))]
17824   "TARGET_SSE4_2 || TARGET_CRC32"
17825   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17826   [(set_attr "type" "sselog1")
17827    (set_attr "prefix_rep" "1")
17828    (set_attr "prefix_extra" "1")
17829    (set (attr "prefix_data16")
17830      (if_then_else (match_operand:HI 2 "" "")
17831        (const_string "1")
17832        (const_string "*")))
17833    (set (attr "prefix_rex")
17834      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17835        (const_string "1")
17836        (const_string "*")))
17837    (set_attr "mode" "SI")])
17838
17839 (define_insn "sse4_2_crc32di"
17840   [(set (match_operand:DI 0 "register_operand" "=r")
17841         (unspec:DI
17842           [(match_operand:DI 1 "register_operand" "0")
17843            (match_operand:DI 2 "nonimmediate_operand" "rm")]
17844           UNSPEC_CRC32))]
17845   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17846   "crc32{q}\t{%2, %0|%0, %2}"
17847   [(set_attr "type" "sselog1")
17848    (set_attr "prefix_rep" "1")
17849    (set_attr "prefix_extra" "1")
17850    (set_attr "mode" "DI")])
17851
17852 (define_expand "rdpmc"
17853   [(match_operand:DI 0 "register_operand" "")
17854    (match_operand:SI 1 "register_operand" "")]
17855   ""
17856 {
17857   rtx reg = gen_reg_rtx (DImode);
17858   rtx si;
17859
17860   /* Force operand 1 into ECX.  */
17861   rtx ecx = gen_rtx_REG (SImode, CX_REG);
17862   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17863   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17864                                 UNSPECV_RDPMC);
17865
17866   if (TARGET_64BIT)
17867     {
17868       rtvec vec = rtvec_alloc (2);
17869       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17870       rtx upper = gen_reg_rtx (DImode);
17871       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17872                                         gen_rtvec (1, const0_rtx),
17873                                         UNSPECV_RDPMC);
17874       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17875       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17876       emit_insn (load);
17877       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17878                                    NULL, 1, OPTAB_DIRECT);
17879       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17880                                  OPTAB_DIRECT);
17881     }
17882   else
17883     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17884   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17885   DONE;
17886 })
17887
17888 (define_insn "*rdpmc"
17889   [(set (match_operand:DI 0 "register_operand" "=A")
17890         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17891                             UNSPECV_RDPMC))]
17892   "!TARGET_64BIT"
17893   "rdpmc"
17894   [(set_attr "type" "other")
17895    (set_attr "length" "2")])
17896
17897 (define_insn "*rdpmc_rex64"
17898   [(set (match_operand:DI 0 "register_operand" "=a")
17899         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17900                             UNSPECV_RDPMC))
17901   (set (match_operand:DI 1 "register_operand" "=d")
17902        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17903   "TARGET_64BIT"
17904   "rdpmc"
17905   [(set_attr "type" "other")
17906    (set_attr "length" "2")])
17907
17908 (define_expand "rdtsc"
17909   [(set (match_operand:DI 0 "register_operand" "")
17910         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17911   ""
17912 {
17913   if (TARGET_64BIT)
17914     {
17915       rtvec vec = rtvec_alloc (2);
17916       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17917       rtx upper = gen_reg_rtx (DImode);
17918       rtx lower = gen_reg_rtx (DImode);
17919       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17920                                          gen_rtvec (1, const0_rtx),
17921                                          UNSPECV_RDTSC);
17922       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17923       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17924       emit_insn (load);
17925       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17926                                    NULL, 1, OPTAB_DIRECT);
17927       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17928                                    OPTAB_DIRECT);
17929       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17930       DONE;
17931     }
17932 })
17933
17934 (define_insn "*rdtsc"
17935   [(set (match_operand:DI 0 "register_operand" "=A")
17936         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17937   "!TARGET_64BIT"
17938   "rdtsc"
17939   [(set_attr "type" "other")
17940    (set_attr "length" "2")])
17941
17942 (define_insn "*rdtsc_rex64"
17943   [(set (match_operand:DI 0 "register_operand" "=a")
17944         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17945    (set (match_operand:DI 1 "register_operand" "=d")
17946         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17947   "TARGET_64BIT"
17948   "rdtsc"
17949   [(set_attr "type" "other")
17950    (set_attr "length" "2")])
17951
17952 (define_expand "rdtscp"
17953   [(match_operand:DI 0 "register_operand" "")
17954    (match_operand:SI 1 "memory_operand" "")]
17955   ""
17956 {
17957   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17958                                     gen_rtvec (1, const0_rtx),
17959                                     UNSPECV_RDTSCP);
17960   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17961                                     gen_rtvec (1, const0_rtx),
17962                                     UNSPECV_RDTSCP);
17963   rtx reg = gen_reg_rtx (DImode);
17964   rtx tmp = gen_reg_rtx (SImode);
17965
17966   if (TARGET_64BIT)
17967     {
17968       rtvec vec = rtvec_alloc (3);
17969       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17970       rtx upper = gen_reg_rtx (DImode);
17971       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17972       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17973       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17974       emit_insn (load);
17975       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17976                                    NULL, 1, OPTAB_DIRECT);
17977       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17978                                  OPTAB_DIRECT);
17979     }
17980   else
17981     {
17982       rtvec vec = rtvec_alloc (2);
17983       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17984       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17985       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17986       emit_insn (load);
17987     }
17988   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17989   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17990   DONE;
17991 })
17992
17993 (define_insn "*rdtscp"
17994   [(set (match_operand:DI 0 "register_operand" "=A")
17995         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17996    (set (match_operand:SI 1 "register_operand" "=c")
17997         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17998   "!TARGET_64BIT"
17999   "rdtscp"
18000   [(set_attr "type" "other")
18001    (set_attr "length" "3")])
18002
18003 (define_insn "*rdtscp_rex64"
18004   [(set (match_operand:DI 0 "register_operand" "=a")
18005         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18006    (set (match_operand:DI 1 "register_operand" "=d")
18007         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18008    (set (match_operand:SI 2 "register_operand" "=c")
18009         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18010   "TARGET_64BIT"
18011   "rdtscp"
18012   [(set_attr "type" "other")
18013    (set_attr "length" "3")])
18014
18015 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18016 ;;
18017 ;; LWP instructions
18018 ;;
18019 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18020
18021 (define_expand "lwp_llwpcb"
18022   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18023                     UNSPECV_LLWP_INTRINSIC)]
18024   "TARGET_LWP")
18025
18026 (define_insn "*lwp_llwpcb<mode>1"
18027   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18028                     UNSPECV_LLWP_INTRINSIC)]
18029   "TARGET_LWP"
18030   "llwpcb\t%0"
18031   [(set_attr "type" "lwp")
18032    (set_attr "mode" "<MODE>")
18033    (set_attr "length" "5")])
18034
18035 (define_expand "lwp_slwpcb"
18036   [(set (match_operand 0 "register_operand" "=r")
18037         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18038   "TARGET_LWP"
18039 {
18040   rtx (*insn)(rtx);
18041
18042   insn = (TARGET_64BIT
18043           ? gen_lwp_slwpcbdi
18044           : gen_lwp_slwpcbsi);
18045
18046   emit_insn (insn (operands[0]));
18047   DONE;
18048 })
18049
18050 (define_insn "lwp_slwpcb<mode>"
18051   [(set (match_operand:P 0 "register_operand" "=r")
18052         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18053   "TARGET_LWP"
18054   "slwpcb\t%0"
18055   [(set_attr "type" "lwp")
18056    (set_attr "mode" "<MODE>")
18057    (set_attr "length" "5")])
18058
18059 (define_expand "lwp_lwpval<mode>3"
18060   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18061                      (match_operand:SI 2 "nonimmediate_operand" "rm")
18062                      (match_operand:SI 3 "const_int_operand" "i")]
18063                     UNSPECV_LWPVAL_INTRINSIC)]
18064   "TARGET_LWP"
18065   ;; Avoid unused variable warning.
18066   "(void) operands[0];")
18067
18068 (define_insn "*lwp_lwpval<mode>3_1"
18069   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18070                      (match_operand:SI 1 "nonimmediate_operand" "rm")
18071                      (match_operand:SI 2 "const_int_operand" "i")]
18072                     UNSPECV_LWPVAL_INTRINSIC)]
18073   "TARGET_LWP"
18074   "lwpval\t{%2, %1, %0|%0, %1, %2}"
18075   [(set_attr "type" "lwp")
18076    (set_attr "mode" "<MODE>")
18077    (set (attr "length")
18078         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18079
18080 (define_expand "lwp_lwpins<mode>3"
18081   [(set (reg:CCC FLAGS_REG)
18082         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18083                               (match_operand:SI 2 "nonimmediate_operand" "rm")
18084                               (match_operand:SI 3 "const_int_operand" "i")]
18085                              UNSPECV_LWPINS_INTRINSIC))
18086    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18087         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18088   "TARGET_LWP")
18089
18090 (define_insn "*lwp_lwpins<mode>3_1"
18091   [(set (reg:CCC FLAGS_REG)
18092         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18093                               (match_operand:SI 1 "nonimmediate_operand" "rm")
18094                               (match_operand:SI 2 "const_int_operand" "i")]
18095                              UNSPECV_LWPINS_INTRINSIC))]
18096   "TARGET_LWP"
18097   "lwpins\t{%2, %1, %0|%0, %1, %2}"
18098   [(set_attr "type" "lwp")
18099    (set_attr "mode" "<MODE>")
18100    (set (attr "length")
18101         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18102
18103 (define_insn "rdfsbase<mode>"
18104   [(set (match_operand:SWI48 0 "register_operand" "=r")
18105         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18106   "TARGET_64BIT && TARGET_FSGSBASE"
18107   "rdfsbase %0"
18108   [(set_attr "type" "other")
18109    (set_attr "prefix_extra" "2")])
18110
18111 (define_insn "rdgsbase<mode>"
18112   [(set (match_operand:SWI48 0 "register_operand" "=r")
18113         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18114   "TARGET_64BIT && TARGET_FSGSBASE"
18115   "rdgsbase %0"
18116   [(set_attr "type" "other")
18117    (set_attr "prefix_extra" "2")])
18118
18119 (define_insn "wrfsbase<mode>"
18120   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18121                     UNSPECV_WRFSBASE)]
18122   "TARGET_64BIT && TARGET_FSGSBASE"
18123   "wrfsbase %0"
18124   [(set_attr "type" "other")
18125    (set_attr "prefix_extra" "2")])
18126
18127 (define_insn "wrgsbase<mode>"
18128   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18129                     UNSPECV_WRGSBASE)]
18130   "TARGET_64BIT && TARGET_FSGSBASE"
18131   "wrgsbase %0"
18132   [(set_attr "type" "other")
18133    (set_attr "prefix_extra" "2")])
18134
18135 (define_insn "rdrand<mode>_1"
18136   [(set (match_operand:SWI248 0 "register_operand" "=r")
18137         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18138    (set (reg:CCC FLAGS_REG)
18139         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18140   "TARGET_RDRND"
18141   "rdrand\t%0"
18142   [(set_attr "type" "other")
18143    (set_attr "prefix_extra" "1")])
18144
18145 (define_expand "pause"
18146   [(set (match_dup 0)
18147         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18148   ""
18149 {
18150   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18151   MEM_VOLATILE_P (operands[0]) = 1;
18152 })
18153
18154 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18155 ;; They have the same encoding.
18156 (define_insn "*pause"
18157   [(set (match_operand:BLK 0 "" "")
18158         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18159   ""
18160   "rep; nop"
18161   [(set_attr "length" "2")
18162    (set_attr "memory" "unknown")])
18163
18164 (include "mmx.md")
18165 (include "sse.md")
18166 (include "sync.md")