OSDN Git Service

gcc/:
[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
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3.  If not see
22 ;; <http://www.gnu.org/licenses/>.  */
23 ;;
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
26 ;;
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
35 ;;      otherwise nothing
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
43 ;;      delimiter.
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;;      %b0 would print %al if operands[0] is reg 0.
46 ;; w --  likewise, print the HImode name of the register.
47 ;; k --  likewise, print the SImode name of the register.
48 ;; q --  likewise, print the DImode name of the register.
49 ;; x --  likewise, print the V4SFmode name of the register.
50 ;; t --  likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; Y -- print condition for XOP pcom* instruction.
60 ;; + -- print a branch hint as 'cs' or 'ds' prefix
61 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
62 ;; @ -- print a segment register of thread base pointer load
63
64 ;; UNSPEC usage:
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
80   ;; Prologue support
81   UNSPEC_STACK_ALLOC
82   UNSPEC_SET_GOT
83   UNSPEC_REG_SAVE
84   UNSPEC_DEF_CFA
85   UNSPEC_SET_RIP
86   UNSPEC_SET_GOT_OFFSET
87   UNSPEC_MEMORY_BLOCKAGE
88   UNSPEC_STACK_CHECK
89
90   ;; TLS support
91   UNSPEC_TP
92   UNSPEC_TLS_GD
93   UNSPEC_TLS_LD_BASE
94   UNSPEC_TLSDESC
95
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
109   ;; For SSE/MMX support:
110   UNSPEC_FIX_NOTRUNC
111   UNSPEC_MASKMOV
112   UNSPEC_MOVMSK
113   UNSPEC_MOVNT
114   UNSPEC_MOVU
115   UNSPEC_RCP
116   UNSPEC_RSQRT
117   UNSPEC_SFENCE
118   UNSPEC_PFRCP
119   UNSPEC_PFRCPIT1
120   UNSPEC_PFRCPIT2
121   UNSPEC_PFRSQRT
122   UNSPEC_PFRSQIT1
123   UNSPEC_MFENCE
124   UNSPEC_LFENCE
125   UNSPEC_PSADBW
126   UNSPEC_LDDQU
127   UNSPEC_MS_TO_SYSV_CALL
128
129   ;; Generic math support
130   UNSPEC_COPYSIGN
131   UNSPEC_IEEE_MIN       ; not commutative
132   UNSPEC_IEEE_MAX       ; not commutative
133
134   ;; x87 Floating point
135   UNSPEC_SIN
136   UNSPEC_COS
137   UNSPEC_FPATAN
138   UNSPEC_FYL2X
139   UNSPEC_FYL2XP1
140   UNSPEC_FRNDINT
141   UNSPEC_FIST
142   UNSPEC_F2XM1
143   UNSPEC_TAN
144   UNSPEC_FXAM
145
146   ;; x87 Rounding
147   UNSPEC_FRNDINT_FLOOR
148   UNSPEC_FRNDINT_CEIL
149   UNSPEC_FRNDINT_TRUNC
150   UNSPEC_FRNDINT_MASK_PM
151   UNSPEC_FIST_FLOOR
152   UNSPEC_FIST_CEIL
153
154   ;; x87 Double output FP
155   UNSPEC_SINCOS_COS
156   UNSPEC_SINCOS_SIN
157   UNSPEC_XTRACT_FRACT
158   UNSPEC_XTRACT_EXP
159   UNSPEC_FSCALE_FRACT
160   UNSPEC_FSCALE_EXP
161   UNSPEC_FPREM_F
162   UNSPEC_FPREM_U
163   UNSPEC_FPREM1_F
164   UNSPEC_FPREM1_U
165
166   UNSPEC_C2_FLAG
167   UNSPEC_FXAM_MEM
168
169   ;; SSP patterns
170   UNSPEC_SP_SET
171   UNSPEC_SP_TEST
172   UNSPEC_SP_TLS_SET
173   UNSPEC_SP_TLS_TEST
174
175   ;; SSSE3
176   UNSPEC_PSHUFB
177   UNSPEC_PSIGN
178   UNSPEC_PALIGNR
179
180   ;; For SSE4A support
181   UNSPEC_EXTRQI
182   UNSPEC_EXTRQ
183   UNSPEC_INSERTQI
184   UNSPEC_INSERTQ
185
186   ;; For SSE4.1 support
187   UNSPEC_BLENDV
188   UNSPEC_INSERTPS
189   UNSPEC_DP
190   UNSPEC_MOVNTDQA
191   UNSPEC_MPSADBW
192   UNSPEC_PHMINPOSUW
193   UNSPEC_PTEST
194   UNSPEC_ROUND
195
196   ;; For SSE4.2 support
197   UNSPEC_CRC32
198   UNSPEC_PCMPESTR
199   UNSPEC_PCMPISTR
200
201   ;; For FMA4 support
202   UNSPEC_FMA4_INTRINSIC
203   UNSPEC_FMA4_FMADDSUB
204   UNSPEC_FMA4_FMSUBADD
205   UNSPEC_XOP_UNSIGNED_CMP
206   UNSPEC_XOP_TRUEFALSE
207   UNSPEC_XOP_PERMUTE
208   UNSPEC_FRCZ
209
210   ;; For AES support
211   UNSPEC_AESENC
212   UNSPEC_AESENCLAST
213   UNSPEC_AESDEC
214   UNSPEC_AESDECLAST
215   UNSPEC_AESIMC
216   UNSPEC_AESKEYGENASSIST
217
218   ;; For PCLMUL support
219   UNSPEC_PCLMUL
220
221   ;; For AVX support
222   UNSPEC_PCMP
223   UNSPEC_VPERMIL
224   UNSPEC_VPERMIL2
225   UNSPEC_VPERMIL2F128
226   UNSPEC_MASKLOAD
227   UNSPEC_MASKSTORE
228   UNSPEC_CAST
229   UNSPEC_VTESTP
230   UNSPEC_VCVTPH2PS
231   UNSPEC_VCVTPS2PH
232 ])
233
234 (define_c_enum "unspecv" [
235   UNSPECV_BLOCKAGE
236   UNSPECV_STACK_PROBE
237   UNSPECV_PROBE_STACK_RANGE
238   UNSPECV_EMMS
239   UNSPECV_LDMXCSR
240   UNSPECV_STMXCSR
241   UNSPECV_FEMMS
242   UNSPECV_CLFLUSH
243   UNSPECV_ALIGN
244   UNSPECV_MONITOR
245   UNSPECV_MWAIT
246   UNSPECV_CMPXCHG
247   UNSPECV_XCHG
248   UNSPECV_LOCK
249   UNSPECV_PROLOGUE_USE
250   UNSPECV_CLD
251   UNSPECV_NOPS
252   UNSPECV_VZEROALL
253   UNSPECV_VZEROUPPER
254   UNSPECV_RDTSC
255   UNSPECV_RDTSCP
256   UNSPECV_RDPMC
257   UNSPECV_LLWP_INTRINSIC
258   UNSPECV_SLWP_INTRINSIC
259   UNSPECV_LWPVAL_INTRINSIC
260   UNSPECV_LWPINS_INTRINSIC
261   UNSPECV_RDFSBASE
262   UNSPECV_RDGSBASE
263   UNSPECV_WRFSBASE
264   UNSPECV_WRGSBASE
265   UNSPECV_RDRAND
266 ])
267
268 ;; Constants to represent pcomtrue/pcomfalse variants
269 (define_constants
270   [(PCOM_FALSE                  0)
271    (PCOM_TRUE                   1)
272    (COM_FALSE_S                 2)
273    (COM_FALSE_P                 3)
274    (COM_TRUE_S                  4)
275    (COM_TRUE_P                  5)
276   ])
277
278 ;; Constants used in the XOP pperm instruction
279 (define_constants
280   [(PPERM_SRC                   0x00)   /* copy source */
281    (PPERM_INVERT                0x20)   /* invert source */
282    (PPERM_REVERSE               0x40)   /* bit reverse source */
283    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
284    (PPERM_ZERO                  0x80)   /* all 0's */
285    (PPERM_ONES                  0xa0)   /* all 1's */
286    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
287    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
288    (PPERM_SRC1                  0x00)   /* use first source byte */
289    (PPERM_SRC2                  0x10)   /* use second source byte */
290    ])
291
292 ;; Registers by name.
293 (define_constants
294   [(AX_REG                       0)
295    (DX_REG                       1)
296    (CX_REG                       2)
297    (BX_REG                       3)
298    (SI_REG                       4)
299    (DI_REG                       5)
300    (BP_REG                       6)
301    (SP_REG                       7)
302    (ST0_REG                      8)
303    (ST1_REG                      9)
304    (ST2_REG                     10)
305    (ST3_REG                     11)
306    (ST4_REG                     12)
307    (ST5_REG                     13)
308    (ST6_REG                     14)
309    (ST7_REG                     15)
310    (FLAGS_REG                   17)
311    (FPSR_REG                    18)
312    (FPCR_REG                    19)
313    (XMM0_REG                    21)
314    (XMM1_REG                    22)
315    (XMM2_REG                    23)
316    (XMM3_REG                    24)
317    (XMM4_REG                    25)
318    (XMM5_REG                    26)
319    (XMM6_REG                    27)
320    (XMM7_REG                    28)
321    (MM0_REG                     29)
322    (MM1_REG                     30)
323    (MM2_REG                     31)
324    (MM3_REG                     32)
325    (MM4_REG                     33)
326    (MM5_REG                     34)
327    (MM6_REG                     35)
328    (MM7_REG                     36)
329    (R8_REG                      37)
330    (R9_REG                      38)
331    (R10_REG                     39)
332    (R11_REG                     40)
333    (R12_REG                     41)
334    (R13_REG                     42)
335    (XMM8_REG                    45)
336    (XMM9_REG                    46)
337    (XMM10_REG                   47)
338    (XMM11_REG                   48)
339    (XMM12_REG                   49)
340    (XMM13_REG                   50)
341    (XMM14_REG                   51)
342    (XMM15_REG                   52)
343   ])
344
345 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
346 ;; from i386.c.
347
348 ;; In C guard expressions, put expressions which may be compile-time
349 ;; constants first.  This allows for better optimization.  For
350 ;; example, write "TARGET_64BIT && reload_completed", not
351 ;; "reload_completed && TARGET_64BIT".
352
353 \f
354 ;; Processor type.
355 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
356                     generic64,amdfam10,bdver1"
357   (const (symbol_ref "ix86_schedule")))
358
359 ;; A basic instruction type.  Refinements due to arguments to be
360 ;; provided in other attributes.
361 (define_attr "type"
362   "other,multi,
363    alu,alu1,negnot,imov,imovx,lea,
364    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
365    icmp,test,ibr,setcc,icmov,
366    push,pop,call,callv,leave,
367    str,bitmanip,
368    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
369    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
370    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
371    ssemuladd,sse4arg,lwp,
372    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
373   (const_string "other"))
374
375 ;; Main data type used by the insn
376 (define_attr "mode"
377   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
378   (const_string "unknown"))
379
380 ;; The CPU unit operations uses.
381 (define_attr "unit" "integer,i387,sse,mmx,unknown"
382   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
383            (const_string "i387")
384          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
385                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
386                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
387            (const_string "sse")
388          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
389            (const_string "mmx")
390          (eq_attr "type" "other")
391            (const_string "unknown")]
392          (const_string "integer")))
393
394 ;; The (bounding maximum) length of an instruction immediate.
395 (define_attr "length_immediate" ""
396   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
397                           bitmanip")
398            (const_int 0)
399          (eq_attr "unit" "i387,sse,mmx")
400            (const_int 0)
401          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
402                           imul,icmp,push,pop")
403            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
404          (eq_attr "type" "imov,test")
405            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
406          (eq_attr "type" "call")
407            (if_then_else (match_operand 0 "constant_call_address_operand" "")
408              (const_int 4)
409              (const_int 0))
410          (eq_attr "type" "callv")
411            (if_then_else (match_operand 1 "constant_call_address_operand" "")
412              (const_int 4)
413              (const_int 0))
414          ;; We don't know the size before shorten_branches.  Expect
415          ;; the instruction to fit for better scheduling.
416          (eq_attr "type" "ibr")
417            (const_int 1)
418          ]
419          (symbol_ref "/* Update immediate_length and other attributes! */
420                       gcc_unreachable (),1")))
421
422 ;; The (bounding maximum) length of an instruction address.
423 (define_attr "length_address" ""
424   (cond [(eq_attr "type" "str,other,multi,fxch")
425            (const_int 0)
426          (and (eq_attr "type" "call")
427               (match_operand 0 "constant_call_address_operand" ""))
428              (const_int 0)
429          (and (eq_attr "type" "callv")
430               (match_operand 1 "constant_call_address_operand" ""))
431              (const_int 0)
432          ]
433          (symbol_ref "ix86_attr_length_address_default (insn)")))
434
435 ;; Set when length prefix is used.
436 (define_attr "prefix_data16" ""
437   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
438            (const_int 0)
439          (eq_attr "mode" "HI")
440            (const_int 1)
441          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
442            (const_int 1)
443         ]
444         (const_int 0)))
445
446 ;; Set when string REP prefix is used.
447 (define_attr "prefix_rep" ""
448   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
449            (const_int 0)
450          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
451            (const_int 1)
452         ]
453         (const_int 0)))
454
455 ;; Set when 0f opcode prefix is used.
456 (define_attr "prefix_0f" ""
457   (if_then_else
458     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
459          (eq_attr "unit" "sse,mmx"))
460     (const_int 1)
461     (const_int 0)))
462
463 ;; Set when REX opcode prefix is used.
464 (define_attr "prefix_rex" ""
465   (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
466            (const_int 0)
467          (and (eq_attr "mode" "DI")
468               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
469                    (eq_attr "unit" "!mmx")))
470            (const_int 1)
471          (and (eq_attr "mode" "QI")
472               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
473                   (const_int 0)))
474            (const_int 1)
475          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
476              (const_int 0))
477            (const_int 1)
478          (and (eq_attr "type" "imovx")
479               (match_operand:QI 1 "ext_QIreg_operand" ""))
480            (const_int 1)
481         ]
482         (const_int 0)))
483
484 ;; There are also additional prefixes in 3DNOW, SSSE3.
485 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
486 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
487 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
488 (define_attr "prefix_extra" ""
489   (cond [(eq_attr "type" "ssemuladd,sse4arg")
490            (const_int 2)
491          (eq_attr "type" "sseiadd1,ssecvt1")
492            (const_int 1)
493         ]
494         (const_int 0)))
495
496 ;; Prefix used: original, VEX or maybe VEX.
497 (define_attr "prefix" "orig,vex,maybe_vex"
498   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
499     (const_string "vex")
500     (const_string "orig")))
501
502 ;; VEX W bit is used.
503 (define_attr "prefix_vex_w" "" (const_int 0))
504
505 ;; The length of VEX prefix
506 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
507 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
508 ;; still prefix_0f 1, with prefix_extra 1.
509 (define_attr "length_vex" ""
510   (if_then_else (and (eq_attr "prefix_0f" "1")
511                      (eq_attr "prefix_extra" "0"))
512     (if_then_else (eq_attr "prefix_vex_w" "1")
513       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
514       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
515     (if_then_else (eq_attr "prefix_vex_w" "1")
516       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
517       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
518
519 ;; Set when modrm byte is used.
520 (define_attr "modrm" ""
521   (cond [(eq_attr "type" "str,leave")
522            (const_int 0)
523          (eq_attr "unit" "i387")
524            (const_int 0)
525          (and (eq_attr "type" "incdec")
526               (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
527                    (ior (match_operand:SI 1 "register_operand" "")
528                         (match_operand:HI 1 "register_operand" ""))))
529            (const_int 0)
530          (and (eq_attr "type" "push")
531               (not (match_operand 1 "memory_operand" "")))
532            (const_int 0)
533          (and (eq_attr "type" "pop")
534               (not (match_operand 0 "memory_operand" "")))
535            (const_int 0)
536          (and (eq_attr "type" "imov")
537               (and (not (eq_attr "mode" "DI"))
538                    (ior (and (match_operand 0 "register_operand" "")
539                              (match_operand 1 "immediate_operand" ""))
540                         (ior (and (match_operand 0 "ax_reg_operand" "")
541                                   (match_operand 1 "memory_displacement_only_operand" ""))
542                              (and (match_operand 0 "memory_displacement_only_operand" "")
543                                   (match_operand 1 "ax_reg_operand" ""))))))
544            (const_int 0)
545          (and (eq_attr "type" "call")
546               (match_operand 0 "constant_call_address_operand" ""))
547              (const_int 0)
548          (and (eq_attr "type" "callv")
549               (match_operand 1 "constant_call_address_operand" ""))
550              (const_int 0)
551          (and (eq_attr "type" "alu,alu1,icmp,test")
552               (match_operand 0 "ax_reg_operand" ""))
553              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
554          ]
555          (const_int 1)))
556
557 ;; The (bounding maximum) length of an instruction in bytes.
558 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
559 ;; Later we may want to split them and compute proper length as for
560 ;; other insns.
561 (define_attr "length" ""
562   (cond [(eq_attr "type" "other,multi,fistp,frndint")
563            (const_int 16)
564          (eq_attr "type" "fcmp")
565            (const_int 4)
566          (eq_attr "unit" "i387")
567            (plus (const_int 2)
568                  (plus (attr "prefix_data16")
569                        (attr "length_address")))
570          (ior (eq_attr "prefix" "vex")
571               (and (eq_attr "prefix" "maybe_vex")
572                     (ne (symbol_ref "TARGET_AVX") (const_int 0))))
573            (plus (attr "length_vex")
574                  (plus (attr "length_immediate")
575                        (plus (attr "modrm")
576                              (attr "length_address"))))]
577          (plus (plus (attr "modrm")
578                      (plus (attr "prefix_0f")
579                            (plus (attr "prefix_rex")
580                                  (plus (attr "prefix_extra")
581                                        (const_int 1)))))
582                (plus (attr "prefix_rep")
583                      (plus (attr "prefix_data16")
584                            (plus (attr "length_immediate")
585                                  (attr "length_address")))))))
586
587 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
588 ;; `store' if there is a simple memory reference therein, or `unknown'
589 ;; if the instruction is complex.
590
591 (define_attr "memory" "none,load,store,both,unknown"
592   (cond [(eq_attr "type" "other,multi,str,lwp")
593            (const_string "unknown")
594          (eq_attr "type" "lea,fcmov,fpspc")
595            (const_string "none")
596          (eq_attr "type" "fistp,leave")
597            (const_string "both")
598          (eq_attr "type" "frndint")
599            (const_string "load")
600          (eq_attr "type" "push")
601            (if_then_else (match_operand 1 "memory_operand" "")
602              (const_string "both")
603              (const_string "store"))
604          (eq_attr "type" "pop")
605            (if_then_else (match_operand 0 "memory_operand" "")
606              (const_string "both")
607              (const_string "load"))
608          (eq_attr "type" "setcc")
609            (if_then_else (match_operand 0 "memory_operand" "")
610              (const_string "store")
611              (const_string "none"))
612          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
613            (if_then_else (ior (match_operand 0 "memory_operand" "")
614                               (match_operand 1 "memory_operand" ""))
615              (const_string "load")
616              (const_string "none"))
617          (eq_attr "type" "ibr")
618            (if_then_else (match_operand 0 "memory_operand" "")
619              (const_string "load")
620              (const_string "none"))
621          (eq_attr "type" "call")
622            (if_then_else (match_operand 0 "constant_call_address_operand" "")
623              (const_string "none")
624              (const_string "load"))
625          (eq_attr "type" "callv")
626            (if_then_else (match_operand 1 "constant_call_address_operand" "")
627              (const_string "none")
628              (const_string "load"))
629          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
630               (match_operand 1 "memory_operand" ""))
631            (const_string "both")
632          (and (match_operand 0 "memory_operand" "")
633               (match_operand 1 "memory_operand" ""))
634            (const_string "both")
635          (match_operand 0 "memory_operand" "")
636            (const_string "store")
637          (match_operand 1 "memory_operand" "")
638            (const_string "load")
639          (and (eq_attr "type"
640                  "!alu1,negnot,ishift1,
641                    imov,imovx,icmp,test,bitmanip,
642                    fmov,fcmp,fsgn,
643                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
644                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
645               (match_operand 2 "memory_operand" ""))
646            (const_string "load")
647          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
648               (match_operand 3 "memory_operand" ""))
649            (const_string "load")
650         ]
651         (const_string "none")))
652
653 ;; Indicates if an instruction has both an immediate and a displacement.
654
655 (define_attr "imm_disp" "false,true,unknown"
656   (cond [(eq_attr "type" "other,multi")
657            (const_string "unknown")
658          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
659               (and (match_operand 0 "memory_displacement_operand" "")
660                    (match_operand 1 "immediate_operand" "")))
661            (const_string "true")
662          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
663               (and (match_operand 0 "memory_displacement_operand" "")
664                    (match_operand 2 "immediate_operand" "")))
665            (const_string "true")
666         ]
667         (const_string "false")))
668
669 ;; Indicates if an FP operation has an integer source.
670
671 (define_attr "fp_int_src" "false,true"
672   (const_string "false"))
673
674 ;; Defines rounding mode of an FP operation.
675
676 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
677   (const_string "any"))
678
679 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
680 (define_attr "use_carry" "0,1" (const_string "0"))
681
682 ;; Define attribute to indicate unaligned ssemov insns
683 (define_attr "movu" "0,1" (const_string "0"))
684
685 ;; Describe a user's asm statement.
686 (define_asm_attributes
687   [(set_attr "length" "128")
688    (set_attr "type" "multi")])
689
690 (define_code_iterator plusminus [plus minus])
691
692 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
693
694 ;; Base name for define_insn
695 (define_code_attr plusminus_insn
696   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
697    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
698
699 ;; Base name for insn mnemonic.
700 (define_code_attr plusminus_mnemonic
701   [(plus "add") (ss_plus "adds") (us_plus "addus")
702    (minus "sub") (ss_minus "subs") (us_minus "subus")])
703 (define_code_attr plusminus_carry_mnemonic
704   [(plus "adc") (minus "sbb")])
705
706 ;; Mark commutative operators as such in constraints.
707 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
708                         (minus "") (ss_minus "") (us_minus "")])
709
710 ;; Mapping of signed max and min
711 (define_code_iterator smaxmin [smax smin])
712
713 ;; Mapping of unsigned max and min
714 (define_code_iterator umaxmin [umax umin])
715
716 ;; Mapping of signed/unsigned max and min
717 (define_code_iterator maxmin [smax smin umax umin])
718
719 ;; Base name for integer and FP insn mnemonic
720 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
721                               (umax "maxu") (umin "minu")])
722 (define_code_attr maxmin_float [(smax "max") (smin "min")])
723
724 ;; Mapping of logic operators
725 (define_code_iterator any_logic [and ior xor])
726 (define_code_iterator any_or [ior xor])
727
728 ;; Base name for insn mnemonic.
729 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
730
731 ;; Mapping of shift-right operators
732 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
733
734 ;; Base name for define_insn
735 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
736
737 ;; Base name for insn mnemonic.
738 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
739
740 ;; Mapping of rotate operators
741 (define_code_iterator any_rotate [rotate rotatert])
742
743 ;; Base name for define_insn
744 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
745
746 ;; Base name for insn mnemonic.
747 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
748
749 ;; Mapping of abs neg operators
750 (define_code_iterator absneg [abs neg])
751
752 ;; Base name for x87 insn mnemonic.
753 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
754
755 ;; Used in signed and unsigned widening multiplications.
756 (define_code_iterator any_extend [sign_extend zero_extend])
757
758 ;; Various insn prefixes for signed and unsigned operations.
759 (define_code_attr u [(sign_extend "") (zero_extend "u")
760                      (div "") (udiv "u")])
761 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
762
763 ;; Used in signed and unsigned divisions.
764 (define_code_iterator any_div [div udiv])
765
766 ;; Instruction prefix for signed and unsigned operations.
767 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
768                              (div "i") (udiv "")])
769
770 ;; 64bit single word integer modes.
771 (define_mode_iterator SWI1248x [QI HI SI DI])
772
773 ;; 64bit single word integer modes without QImode and HImode.
774 (define_mode_iterator SWI48x [SI DI])
775
776 ;; Single word integer modes.
777 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
778
779 ;; Single word integer modes without SImode and DImode.
780 (define_mode_iterator SWI12 [QI HI])
781
782 ;; Single word integer modes without DImode.
783 (define_mode_iterator SWI124 [QI HI SI])
784
785 ;; Single word integer modes without QImode and DImode.
786 (define_mode_iterator SWI24 [HI SI])
787
788 ;; Single word integer modes without QImode.
789 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
790
791 ;; Single word integer modes without QImode and HImode.
792 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
793
794 ;; All math-dependant single and double word integer modes.
795 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
796                              (HI "TARGET_HIMODE_MATH")
797                              SI DI (TI "TARGET_64BIT")])
798
799 ;; Math-dependant single word integer modes.
800 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
801                             (HI "TARGET_HIMODE_MATH")
802                             SI (DI "TARGET_64BIT")])
803
804 ;; Math-dependant single word integer modes without DImode.
805 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
806                                (HI "TARGET_HIMODE_MATH")
807                                SI])
808
809 ;; Math-dependant single word integer modes without QImode.
810 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
811                                SI (DI "TARGET_64BIT")])
812
813 ;; Double word integer modes.
814 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
815                            (TI "TARGET_64BIT")])
816
817 ;; Double word integer modes as mode attribute.
818 (define_mode_attr DWI [(SI "DI") (DI "TI")])
819 (define_mode_attr dwi [(SI "di") (DI "ti")])
820
821 ;; Half mode for double word integer modes.
822 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
823                             (DI "TARGET_64BIT")])
824
825 ;; Instruction suffix for integer modes.
826 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
827
828 ;; Pointer size prefix for integer modes (Intel asm dialect)
829 (define_mode_attr iptrsize [(QI "BYTE")
830                             (HI "WORD")
831                             (SI "DWORD")
832                             (DI "QWORD")])
833
834 ;; Register class for integer modes.
835 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
836
837 ;; Immediate operand constraint for integer modes.
838 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
839
840 ;; General operand constraint for word modes.
841 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
842
843 ;; Immediate operand constraint for double integer modes.
844 (define_mode_attr di [(SI "iF") (DI "e")])
845
846 ;; Immediate operand constraint for shifts.
847 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
848
849 ;; General operand predicate for integer modes.
850 (define_mode_attr general_operand
851         [(QI "general_operand")
852          (HI "general_operand")
853          (SI "general_operand")
854          (DI "x86_64_general_operand")
855          (TI "x86_64_general_operand")])
856
857 ;; General sign/zero extend operand predicate for integer modes.
858 (define_mode_attr general_szext_operand
859         [(QI "general_operand")
860          (HI "general_operand")
861          (SI "general_operand")
862          (DI "x86_64_szext_general_operand")])
863
864 ;; Immediate operand predicate for integer modes.
865 (define_mode_attr immediate_operand
866         [(QI "immediate_operand")
867          (HI "immediate_operand")
868          (SI "immediate_operand")
869          (DI "x86_64_immediate_operand")])
870
871 ;; Nonmemory operand predicate for integer modes.
872 (define_mode_attr nonmemory_operand
873         [(QI "nonmemory_operand")
874          (HI "nonmemory_operand")
875          (SI "nonmemory_operand")
876          (DI "x86_64_nonmemory_operand")])
877
878 ;; Operand predicate for shifts.
879 (define_mode_attr shift_operand
880         [(QI "nonimmediate_operand")
881          (HI "nonimmediate_operand")
882          (SI "nonimmediate_operand")
883          (DI "shiftdi_operand")
884          (TI "register_operand")])
885
886 ;; Operand predicate for shift argument.
887 (define_mode_attr shift_immediate_operand
888         [(QI "const_1_to_31_operand")
889          (HI "const_1_to_31_operand")
890          (SI "const_1_to_31_operand")
891          (DI "const_1_to_63_operand")])
892
893 ;; Input operand predicate for arithmetic left shifts.
894 (define_mode_attr ashl_input_operand
895         [(QI "nonimmediate_operand")
896          (HI "nonimmediate_operand")
897          (SI "nonimmediate_operand")
898          (DI "ashldi_input_operand")
899          (TI "reg_or_pm1_operand")])
900
901 ;; SSE and x87 SFmode and DFmode floating point modes
902 (define_mode_iterator MODEF [SF DF])
903
904 ;; All x87 floating point modes
905 (define_mode_iterator X87MODEF [SF DF XF])
906
907 ;; All integer modes handled by x87 fisttp operator.
908 (define_mode_iterator X87MODEI [HI SI DI])
909
910 ;; All integer modes handled by integer x87 operators.
911 (define_mode_iterator X87MODEI12 [HI SI])
912
913 ;; All integer modes handled by SSE cvtts?2si* operators.
914 (define_mode_iterator SSEMODEI24 [SI DI])
915
916 ;; SSE asm suffix for floating point modes
917 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
918
919 ;; SSE vector mode corresponding to a scalar mode
920 (define_mode_attr ssevecmode
921   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
922
923 ;; Instruction suffix for REX 64bit operators.
924 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
925
926 ;; This mode iterator allows :P to be used for patterns that operate on
927 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
928 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
929 \f
930 ;; Scheduling descriptions
931
932 (include "pentium.md")
933 (include "ppro.md")
934 (include "k6.md")
935 (include "athlon.md")
936 (include "geode.md")
937 (include "atom.md")
938
939 \f
940 ;; Operand and operator predicates and constraints
941
942 (include "predicates.md")
943 (include "constraints.md")
944
945 \f
946 ;; Compare and branch/compare and store instructions.
947
948 (define_expand "cbranch<mode>4"
949   [(set (reg:CC FLAGS_REG)
950         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
951                     (match_operand:SDWIM 2 "<general_operand>" "")))
952    (set (pc) (if_then_else
953                (match_operator 0 "ordered_comparison_operator"
954                 [(reg:CC FLAGS_REG) (const_int 0)])
955                (label_ref (match_operand 3 "" ""))
956                (pc)))]
957   ""
958 {
959   if (MEM_P (operands[1]) && MEM_P (operands[2]))
960     operands[1] = force_reg (<MODE>mode, operands[1]);
961   ix86_expand_branch (GET_CODE (operands[0]),
962                       operands[1], operands[2], operands[3]);
963   DONE;
964 })
965
966 (define_expand "cstore<mode>4"
967   [(set (reg:CC FLAGS_REG)
968         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
969                     (match_operand:SWIM 3 "<general_operand>" "")))
970    (set (match_operand:QI 0 "register_operand" "")
971         (match_operator 1 "ordered_comparison_operator"
972           [(reg:CC FLAGS_REG) (const_int 0)]))]
973   ""
974 {
975   if (MEM_P (operands[2]) && MEM_P (operands[3]))
976     operands[2] = force_reg (<MODE>mode, operands[2]);
977   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
978                      operands[2], operands[3]);
979   DONE;
980 })
981
982 (define_expand "cmp<mode>_1"
983   [(set (reg:CC FLAGS_REG)
984         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
985                     (match_operand:SWI48 1 "<general_operand>" "")))])
986
987 (define_insn "*cmp<mode>_ccno_1"
988   [(set (reg FLAGS_REG)
989         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
990                  (match_operand:SWI 1 "const0_operand" "")))]
991   "ix86_match_ccmode (insn, CCNOmode)"
992   "@
993    test{<imodesuffix>}\t%0, %0
994    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
995   [(set_attr "type" "test,icmp")
996    (set_attr "length_immediate" "0,1")
997    (set_attr "mode" "<MODE>")])
998
999 (define_insn "*cmp<mode>_1"
1000   [(set (reg FLAGS_REG)
1001         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1002                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1003   "ix86_match_ccmode (insn, CCmode)"
1004   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1005   [(set_attr "type" "icmp")
1006    (set_attr "mode" "<MODE>")])
1007
1008 (define_insn "*cmp<mode>_minus_1"
1009   [(set (reg FLAGS_REG)
1010         (compare
1011           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1012                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1013           (const_int 0)))]
1014   "ix86_match_ccmode (insn, CCGOCmode)"
1015   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1016   [(set_attr "type" "icmp")
1017    (set_attr "mode" "<MODE>")])
1018
1019 (define_insn "*cmpqi_ext_1"
1020   [(set (reg FLAGS_REG)
1021         (compare
1022           (match_operand:QI 0 "general_operand" "Qm")
1023           (subreg:QI
1024             (zero_extract:SI
1025               (match_operand 1 "ext_register_operand" "Q")
1026               (const_int 8)
1027               (const_int 8)) 0)))]
1028   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1029   "cmp{b}\t{%h1, %0|%0, %h1}"
1030   [(set_attr "type" "icmp")
1031    (set_attr "mode" "QI")])
1032
1033 (define_insn "*cmpqi_ext_1_rex64"
1034   [(set (reg FLAGS_REG)
1035         (compare
1036           (match_operand:QI 0 "register_operand" "Q")
1037           (subreg:QI
1038             (zero_extract:SI
1039               (match_operand 1 "ext_register_operand" "Q")
1040               (const_int 8)
1041               (const_int 8)) 0)))]
1042   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1043   "cmp{b}\t{%h1, %0|%0, %h1}"
1044   [(set_attr "type" "icmp")
1045    (set_attr "mode" "QI")])
1046
1047 (define_insn "*cmpqi_ext_2"
1048   [(set (reg FLAGS_REG)
1049         (compare
1050           (subreg:QI
1051             (zero_extract:SI
1052               (match_operand 0 "ext_register_operand" "Q")
1053               (const_int 8)
1054               (const_int 8)) 0)
1055           (match_operand:QI 1 "const0_operand" "")))]
1056   "ix86_match_ccmode (insn, CCNOmode)"
1057   "test{b}\t%h0, %h0"
1058   [(set_attr "type" "test")
1059    (set_attr "length_immediate" "0")
1060    (set_attr "mode" "QI")])
1061
1062 (define_expand "cmpqi_ext_3"
1063   [(set (reg:CC FLAGS_REG)
1064         (compare:CC
1065           (subreg:QI
1066             (zero_extract:SI
1067               (match_operand 0 "ext_register_operand" "")
1068               (const_int 8)
1069               (const_int 8)) 0)
1070           (match_operand:QI 1 "immediate_operand" "")))])
1071
1072 (define_insn "*cmpqi_ext_3_insn"
1073   [(set (reg FLAGS_REG)
1074         (compare
1075           (subreg:QI
1076             (zero_extract:SI
1077               (match_operand 0 "ext_register_operand" "Q")
1078               (const_int 8)
1079               (const_int 8)) 0)
1080           (match_operand:QI 1 "general_operand" "Qmn")))]
1081   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1082   "cmp{b}\t{%1, %h0|%h0, %1}"
1083   [(set_attr "type" "icmp")
1084    (set_attr "modrm" "1")
1085    (set_attr "mode" "QI")])
1086
1087 (define_insn "*cmpqi_ext_3_insn_rex64"
1088   [(set (reg FLAGS_REG)
1089         (compare
1090           (subreg:QI
1091             (zero_extract:SI
1092               (match_operand 0 "ext_register_operand" "Q")
1093               (const_int 8)
1094               (const_int 8)) 0)
1095           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1096   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1097   "cmp{b}\t{%1, %h0|%h0, %1}"
1098   [(set_attr "type" "icmp")
1099    (set_attr "modrm" "1")
1100    (set_attr "mode" "QI")])
1101
1102 (define_insn "*cmpqi_ext_4"
1103   [(set (reg FLAGS_REG)
1104         (compare
1105           (subreg:QI
1106             (zero_extract:SI
1107               (match_operand 0 "ext_register_operand" "Q")
1108               (const_int 8)
1109               (const_int 8)) 0)
1110           (subreg:QI
1111             (zero_extract:SI
1112               (match_operand 1 "ext_register_operand" "Q")
1113               (const_int 8)
1114               (const_int 8)) 0)))]
1115   "ix86_match_ccmode (insn, CCmode)"
1116   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1117   [(set_attr "type" "icmp")
1118    (set_attr "mode" "QI")])
1119
1120 ;; These implement float point compares.
1121 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1122 ;; which would allow mix and match FP modes on the compares.  Which is what
1123 ;; the old patterns did, but with many more of them.
1124
1125 (define_expand "cbranchxf4"
1126   [(set (reg:CC FLAGS_REG)
1127         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1128                     (match_operand:XF 2 "nonmemory_operand" "")))
1129    (set (pc) (if_then_else
1130               (match_operator 0 "ix86_fp_comparison_operator"
1131                [(reg:CC FLAGS_REG)
1132                 (const_int 0)])
1133               (label_ref (match_operand 3 "" ""))
1134               (pc)))]
1135   "TARGET_80387"
1136 {
1137   ix86_expand_branch (GET_CODE (operands[0]),
1138                       operands[1], operands[2], operands[3]);
1139   DONE;
1140 })
1141
1142 (define_expand "cstorexf4"
1143   [(set (reg:CC FLAGS_REG)
1144         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1145                     (match_operand:XF 3 "nonmemory_operand" "")))
1146    (set (match_operand:QI 0 "register_operand" "")
1147               (match_operator 1 "ix86_fp_comparison_operator"
1148                [(reg:CC FLAGS_REG)
1149                 (const_int 0)]))]
1150   "TARGET_80387"
1151 {
1152   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1153                      operands[2], operands[3]);
1154   DONE;
1155 })
1156
1157 (define_expand "cbranch<mode>4"
1158   [(set (reg:CC FLAGS_REG)
1159         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1160                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1161    (set (pc) (if_then_else
1162               (match_operator 0 "ix86_fp_comparison_operator"
1163                [(reg:CC FLAGS_REG)
1164                 (const_int 0)])
1165               (label_ref (match_operand 3 "" ""))
1166               (pc)))]
1167   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1168 {
1169   ix86_expand_branch (GET_CODE (operands[0]),
1170                       operands[1], operands[2], operands[3]);
1171   DONE;
1172 })
1173
1174 (define_expand "cstore<mode>4"
1175   [(set (reg:CC FLAGS_REG)
1176         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1177                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1178    (set (match_operand:QI 0 "register_operand" "")
1179               (match_operator 1 "ix86_fp_comparison_operator"
1180                [(reg:CC FLAGS_REG)
1181                 (const_int 0)]))]
1182   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1183 {
1184   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1185                      operands[2], operands[3]);
1186   DONE;
1187 })
1188
1189 (define_expand "cbranchcc4"
1190   [(set (pc) (if_then_else
1191               (match_operator 0 "comparison_operator"
1192                [(match_operand 1 "flags_reg_operand" "")
1193                 (match_operand 2 "const0_operand" "")])
1194               (label_ref (match_operand 3 "" ""))
1195               (pc)))]
1196   ""
1197 {
1198   ix86_expand_branch (GET_CODE (operands[0]),
1199                       operands[1], operands[2], operands[3]);
1200   DONE;
1201 })
1202
1203 (define_expand "cstorecc4"
1204   [(set (match_operand:QI 0 "register_operand" "")
1205               (match_operator 1 "comparison_operator"
1206                [(match_operand 2 "flags_reg_operand" "")
1207                 (match_operand 3 "const0_operand" "")]))]
1208   ""
1209 {
1210   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1211                      operands[2], operands[3]);
1212   DONE;
1213 })
1214
1215
1216 ;; FP compares, step 1:
1217 ;; Set the FP condition codes.
1218 ;;
1219 ;; CCFPmode     compare with exceptions
1220 ;; CCFPUmode    compare with no exceptions
1221
1222 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1223 ;; used to manage the reg stack popping would not be preserved.
1224
1225 (define_insn "*cmpfp_0"
1226   [(set (match_operand:HI 0 "register_operand" "=a")
1227         (unspec:HI
1228           [(compare:CCFP
1229              (match_operand 1 "register_operand" "f")
1230              (match_operand 2 "const0_operand" ""))]
1231         UNSPEC_FNSTSW))]
1232   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1233    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1234   "* return output_fp_compare (insn, operands, 0, 0);"
1235   [(set_attr "type" "multi")
1236    (set_attr "unit" "i387")
1237    (set (attr "mode")
1238      (cond [(match_operand:SF 1 "" "")
1239               (const_string "SF")
1240             (match_operand:DF 1 "" "")
1241               (const_string "DF")
1242            ]
1243            (const_string "XF")))])
1244
1245 (define_insn_and_split "*cmpfp_0_cc"
1246   [(set (reg:CCFP FLAGS_REG)
1247         (compare:CCFP
1248           (match_operand 1 "register_operand" "f")
1249           (match_operand 2 "const0_operand" "")))
1250    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1251   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1252    && TARGET_SAHF && !TARGET_CMOVE
1253    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1254   "#"
1255   "&& reload_completed"
1256   [(set (match_dup 0)
1257         (unspec:HI
1258           [(compare:CCFP (match_dup 1)(match_dup 2))]
1259         UNSPEC_FNSTSW))
1260    (set (reg:CC FLAGS_REG)
1261         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1262   ""
1263   [(set_attr "type" "multi")
1264    (set_attr "unit" "i387")
1265    (set (attr "mode")
1266      (cond [(match_operand:SF 1 "" "")
1267               (const_string "SF")
1268             (match_operand:DF 1 "" "")
1269               (const_string "DF")
1270            ]
1271            (const_string "XF")))])
1272
1273 (define_insn "*cmpfp_xf"
1274   [(set (match_operand:HI 0 "register_operand" "=a")
1275         (unspec:HI
1276           [(compare:CCFP
1277              (match_operand:XF 1 "register_operand" "f")
1278              (match_operand:XF 2 "register_operand" "f"))]
1279           UNSPEC_FNSTSW))]
1280   "TARGET_80387"
1281   "* return output_fp_compare (insn, operands, 0, 0);"
1282   [(set_attr "type" "multi")
1283    (set_attr "unit" "i387")
1284    (set_attr "mode" "XF")])
1285
1286 (define_insn_and_split "*cmpfp_xf_cc"
1287   [(set (reg:CCFP FLAGS_REG)
1288         (compare:CCFP
1289           (match_operand:XF 1 "register_operand" "f")
1290           (match_operand:XF 2 "register_operand" "f")))
1291    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1292   "TARGET_80387
1293    && TARGET_SAHF && !TARGET_CMOVE"
1294   "#"
1295   "&& reload_completed"
1296   [(set (match_dup 0)
1297         (unspec:HI
1298           [(compare:CCFP (match_dup 1)(match_dup 2))]
1299         UNSPEC_FNSTSW))
1300    (set (reg:CC FLAGS_REG)
1301         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1302   ""
1303   [(set_attr "type" "multi")
1304    (set_attr "unit" "i387")
1305    (set_attr "mode" "XF")])
1306
1307 (define_insn "*cmpfp_<mode>"
1308   [(set (match_operand:HI 0 "register_operand" "=a")
1309         (unspec:HI
1310           [(compare:CCFP
1311              (match_operand:MODEF 1 "register_operand" "f")
1312              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1313           UNSPEC_FNSTSW))]
1314   "TARGET_80387"
1315   "* return output_fp_compare (insn, operands, 0, 0);"
1316   [(set_attr "type" "multi")
1317    (set_attr "unit" "i387")
1318    (set_attr "mode" "<MODE>")])
1319
1320 (define_insn_and_split "*cmpfp_<mode>_cc"
1321   [(set (reg:CCFP FLAGS_REG)
1322         (compare:CCFP
1323           (match_operand:MODEF 1 "register_operand" "f")
1324           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1325    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1326   "TARGET_80387
1327    && TARGET_SAHF && !TARGET_CMOVE"
1328   "#"
1329   "&& reload_completed"
1330   [(set (match_dup 0)
1331         (unspec:HI
1332           [(compare:CCFP (match_dup 1)(match_dup 2))]
1333         UNSPEC_FNSTSW))
1334    (set (reg:CC FLAGS_REG)
1335         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1336   ""
1337   [(set_attr "type" "multi")
1338    (set_attr "unit" "i387")
1339    (set_attr "mode" "<MODE>")])
1340
1341 (define_insn "*cmpfp_u"
1342   [(set (match_operand:HI 0 "register_operand" "=a")
1343         (unspec:HI
1344           [(compare:CCFPU
1345              (match_operand 1 "register_operand" "f")
1346              (match_operand 2 "register_operand" "f"))]
1347           UNSPEC_FNSTSW))]
1348   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1349    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1350   "* return output_fp_compare (insn, operands, 0, 1);"
1351   [(set_attr "type" "multi")
1352    (set_attr "unit" "i387")
1353    (set (attr "mode")
1354      (cond [(match_operand:SF 1 "" "")
1355               (const_string "SF")
1356             (match_operand:DF 1 "" "")
1357               (const_string "DF")
1358            ]
1359            (const_string "XF")))])
1360
1361 (define_insn_and_split "*cmpfp_u_cc"
1362   [(set (reg:CCFPU FLAGS_REG)
1363         (compare:CCFPU
1364           (match_operand 1 "register_operand" "f")
1365           (match_operand 2 "register_operand" "f")))
1366    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1367   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1368    && TARGET_SAHF && !TARGET_CMOVE
1369    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1370   "#"
1371   "&& reload_completed"
1372   [(set (match_dup 0)
1373         (unspec:HI
1374           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1375         UNSPEC_FNSTSW))
1376    (set (reg:CC FLAGS_REG)
1377         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1378   ""
1379   [(set_attr "type" "multi")
1380    (set_attr "unit" "i387")
1381    (set (attr "mode")
1382      (cond [(match_operand:SF 1 "" "")
1383               (const_string "SF")
1384             (match_operand:DF 1 "" "")
1385               (const_string "DF")
1386            ]
1387            (const_string "XF")))])
1388
1389 (define_insn "*cmpfp_<mode>"
1390   [(set (match_operand:HI 0 "register_operand" "=a")
1391         (unspec:HI
1392           [(compare:CCFP
1393              (match_operand 1 "register_operand" "f")
1394              (match_operator 3 "float_operator"
1395                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1396           UNSPEC_FNSTSW))]
1397   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1398    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1399    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1400   "* return output_fp_compare (insn, operands, 0, 0);"
1401   [(set_attr "type" "multi")
1402    (set_attr "unit" "i387")
1403    (set_attr "fp_int_src" "true")
1404    (set_attr "mode" "<MODE>")])
1405
1406 (define_insn_and_split "*cmpfp_<mode>_cc"
1407   [(set (reg:CCFP FLAGS_REG)
1408         (compare:CCFP
1409           (match_operand 1 "register_operand" "f")
1410           (match_operator 3 "float_operator"
1411             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1412    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1413   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1414    && TARGET_SAHF && !TARGET_CMOVE
1415    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1416    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1417   "#"
1418   "&& reload_completed"
1419   [(set (match_dup 0)
1420         (unspec:HI
1421           [(compare:CCFP
1422              (match_dup 1)
1423              (match_op_dup 3 [(match_dup 2)]))]
1424         UNSPEC_FNSTSW))
1425    (set (reg:CC FLAGS_REG)
1426         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1427   ""
1428   [(set_attr "type" "multi")
1429    (set_attr "unit" "i387")
1430    (set_attr "fp_int_src" "true")
1431    (set_attr "mode" "<MODE>")])
1432
1433 ;; FP compares, step 2
1434 ;; Move the fpsw to ax.
1435
1436 (define_insn "x86_fnstsw_1"
1437   [(set (match_operand:HI 0 "register_operand" "=a")
1438         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1439   "TARGET_80387"
1440   "fnstsw\t%0"
1441   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1442    (set_attr "mode" "SI")
1443    (set_attr "unit" "i387")])
1444
1445 ;; FP compares, step 3
1446 ;; Get ax into flags, general case.
1447
1448 (define_insn "x86_sahf_1"
1449   [(set (reg:CC FLAGS_REG)
1450         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1451                    UNSPEC_SAHF))]
1452   "TARGET_SAHF"
1453 {
1454 #ifndef HAVE_AS_IX86_SAHF
1455   if (TARGET_64BIT)
1456     return ASM_BYTE "0x9e";
1457   else
1458 #endif
1459   return "sahf";
1460 }
1461   [(set_attr "length" "1")
1462    (set_attr "athlon_decode" "vector")
1463    (set_attr "amdfam10_decode" "direct")
1464    (set_attr "mode" "SI")])
1465
1466 ;; Pentium Pro can do steps 1 through 3 in one go.
1467 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1468 (define_insn "*cmpfp_i_mixed"
1469   [(set (reg:CCFP FLAGS_REG)
1470         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1471                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1472   "TARGET_MIX_SSE_I387
1473    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1474    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1475   "* return output_fp_compare (insn, operands, 1, 0);"
1476   [(set_attr "type" "fcmp,ssecomi")
1477    (set_attr "prefix" "orig,maybe_vex")
1478    (set (attr "mode")
1479      (if_then_else (match_operand:SF 1 "" "")
1480         (const_string "SF")
1481         (const_string "DF")))
1482    (set (attr "prefix_rep")
1483         (if_then_else (eq_attr "type" "ssecomi")
1484                       (const_string "0")
1485                       (const_string "*")))
1486    (set (attr "prefix_data16")
1487         (cond [(eq_attr "type" "fcmp")
1488                  (const_string "*")
1489                (eq_attr "mode" "DF")
1490                  (const_string "1")
1491               ]
1492               (const_string "0")))
1493    (set_attr "athlon_decode" "vector")
1494    (set_attr "amdfam10_decode" "direct")])
1495
1496 (define_insn "*cmpfp_i_sse"
1497   [(set (reg:CCFP FLAGS_REG)
1498         (compare:CCFP (match_operand 0 "register_operand" "x")
1499                       (match_operand 1 "nonimmediate_operand" "xm")))]
1500   "TARGET_SSE_MATH
1501    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1502    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1503   "* return output_fp_compare (insn, operands, 1, 0);"
1504   [(set_attr "type" "ssecomi")
1505    (set_attr "prefix" "maybe_vex")
1506    (set (attr "mode")
1507      (if_then_else (match_operand:SF 1 "" "")
1508         (const_string "SF")
1509         (const_string "DF")))
1510    (set_attr "prefix_rep" "0")
1511    (set (attr "prefix_data16")
1512         (if_then_else (eq_attr "mode" "DF")
1513                       (const_string "1")
1514                       (const_string "0")))
1515    (set_attr "athlon_decode" "vector")
1516    (set_attr "amdfam10_decode" "direct")])
1517
1518 (define_insn "*cmpfp_i_i387"
1519   [(set (reg:CCFP FLAGS_REG)
1520         (compare:CCFP (match_operand 0 "register_operand" "f")
1521                       (match_operand 1 "register_operand" "f")))]
1522   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1523    && TARGET_CMOVE
1524    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1525    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1526   "* return output_fp_compare (insn, operands, 1, 0);"
1527   [(set_attr "type" "fcmp")
1528    (set (attr "mode")
1529      (cond [(match_operand:SF 1 "" "")
1530               (const_string "SF")
1531             (match_operand:DF 1 "" "")
1532               (const_string "DF")
1533            ]
1534            (const_string "XF")))
1535    (set_attr "athlon_decode" "vector")
1536    (set_attr "amdfam10_decode" "direct")])
1537
1538 (define_insn "*cmpfp_iu_mixed"
1539   [(set (reg:CCFPU FLAGS_REG)
1540         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1541                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1542   "TARGET_MIX_SSE_I387
1543    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1544    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1545   "* return output_fp_compare (insn, operands, 1, 1);"
1546   [(set_attr "type" "fcmp,ssecomi")
1547    (set_attr "prefix" "orig,maybe_vex")
1548    (set (attr "mode")
1549      (if_then_else (match_operand:SF 1 "" "")
1550         (const_string "SF")
1551         (const_string "DF")))
1552    (set (attr "prefix_rep")
1553         (if_then_else (eq_attr "type" "ssecomi")
1554                       (const_string "0")
1555                       (const_string "*")))
1556    (set (attr "prefix_data16")
1557         (cond [(eq_attr "type" "fcmp")
1558                  (const_string "*")
1559                (eq_attr "mode" "DF")
1560                  (const_string "1")
1561               ]
1562               (const_string "0")))
1563    (set_attr "athlon_decode" "vector")
1564    (set_attr "amdfam10_decode" "direct")])
1565
1566 (define_insn "*cmpfp_iu_sse"
1567   [(set (reg:CCFPU FLAGS_REG)
1568         (compare:CCFPU (match_operand 0 "register_operand" "x")
1569                        (match_operand 1 "nonimmediate_operand" "xm")))]
1570   "TARGET_SSE_MATH
1571    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1572    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1573   "* return output_fp_compare (insn, operands, 1, 1);"
1574   [(set_attr "type" "ssecomi")
1575    (set_attr "prefix" "maybe_vex")
1576    (set (attr "mode")
1577      (if_then_else (match_operand:SF 1 "" "")
1578         (const_string "SF")
1579         (const_string "DF")))
1580    (set_attr "prefix_rep" "0")
1581    (set (attr "prefix_data16")
1582         (if_then_else (eq_attr "mode" "DF")
1583                       (const_string "1")
1584                       (const_string "0")))
1585    (set_attr "athlon_decode" "vector")
1586    (set_attr "amdfam10_decode" "direct")])
1587
1588 (define_insn "*cmpfp_iu_387"
1589   [(set (reg:CCFPU FLAGS_REG)
1590         (compare:CCFPU (match_operand 0 "register_operand" "f")
1591                        (match_operand 1 "register_operand" "f")))]
1592   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1593    && TARGET_CMOVE
1594    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1595    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1596   "* return output_fp_compare (insn, operands, 1, 1);"
1597   [(set_attr "type" "fcmp")
1598    (set (attr "mode")
1599      (cond [(match_operand:SF 1 "" "")
1600               (const_string "SF")
1601             (match_operand:DF 1 "" "")
1602               (const_string "DF")
1603            ]
1604            (const_string "XF")))
1605    (set_attr "athlon_decode" "vector")
1606    (set_attr "amdfam10_decode" "direct")])
1607 \f
1608 ;; Push/pop instructions.
1609
1610 (define_insn "*pushdi2_rex64"
1611   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1612         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1613   "TARGET_64BIT"
1614   "@
1615    push{q}\t%1
1616    #"
1617   [(set_attr "type" "push,multi")
1618    (set_attr "mode" "DI")])
1619
1620 ;; Convert impossible pushes of immediate to existing instructions.
1621 ;; First try to get scratch register and go through it.  In case this
1622 ;; fails, push sign extended lower part first and then overwrite
1623 ;; upper part by 32bit move.
1624 (define_peephole2
1625   [(match_scratch:DI 2 "r")
1626    (set (match_operand:DI 0 "push_operand" "")
1627         (match_operand:DI 1 "immediate_operand" ""))]
1628   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1629    && !x86_64_immediate_operand (operands[1], DImode)"
1630   [(set (match_dup 2) (match_dup 1))
1631    (set (match_dup 0) (match_dup 2))])
1632
1633 ;; We need to define this as both peepholer and splitter for case
1634 ;; peephole2 pass is not run.
1635 ;; "&& 1" is needed to keep it from matching the previous pattern.
1636 (define_peephole2
1637   [(set (match_operand:DI 0 "push_operand" "")
1638         (match_operand:DI 1 "immediate_operand" ""))]
1639   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1640    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1641   [(set (match_dup 0) (match_dup 1))
1642    (set (match_dup 2) (match_dup 3))]
1643 {
1644   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1645
1646   operands[1] = gen_lowpart (DImode, operands[2]);
1647   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1648                                                    GEN_INT (4)));
1649 })
1650
1651 (define_split
1652   [(set (match_operand:DI 0 "push_operand" "")
1653         (match_operand:DI 1 "immediate_operand" ""))]
1654   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1655                     ? epilogue_completed : reload_completed)
1656    && !symbolic_operand (operands[1], DImode)
1657    && !x86_64_immediate_operand (operands[1], DImode)"
1658   [(set (match_dup 0) (match_dup 1))
1659    (set (match_dup 2) (match_dup 3))]
1660 {
1661   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1662
1663   operands[1] = gen_lowpart (DImode, operands[2]);
1664   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1665                                                    GEN_INT (4)));
1666 })
1667
1668 (define_insn "*pushdi2"
1669   [(set (match_operand:DI 0 "push_operand" "=<")
1670         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1671   "!TARGET_64BIT"
1672   "#")
1673
1674 (define_split
1675   [(set (match_operand:DI 0 "push_operand" "")
1676         (match_operand:DI 1 "general_operand" ""))]
1677   "!TARGET_64BIT && reload_completed
1678    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1679   [(const_int 0)]
1680   "ix86_split_long_move (operands); DONE;")
1681
1682 (define_insn "*pushsi2"
1683   [(set (match_operand:SI 0 "push_operand" "=<")
1684         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1685   "!TARGET_64BIT"
1686   "push{l}\t%1"
1687   [(set_attr "type" "push")
1688    (set_attr "mode" "SI")])
1689
1690 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1691 ;; "push a byte/word".  But actually we use pushl, which has the effect
1692 ;; of rounding the amount pushed up to a word.
1693
1694 ;; For TARGET_64BIT we always round up to 8 bytes.
1695 (define_insn "*push<mode>2_rex64"
1696   [(set (match_operand:SWI124 0 "push_operand" "=X")
1697         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1698   "TARGET_64BIT"
1699   "push{q}\t%q1"
1700   [(set_attr "type" "push")
1701    (set_attr "mode" "DI")])
1702
1703 (define_insn "*push<mode>2"
1704   [(set (match_operand:SWI12 0 "push_operand" "=X")
1705         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1706   "!TARGET_64BIT"
1707   "push{l}\t%k1"
1708   [(set_attr "type" "push")
1709    (set_attr "mode" "SI")])
1710
1711 (define_insn "*push<mode>2_prologue"
1712   [(set (match_operand:P 0 "push_operand" "=<")
1713         (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1714    (clobber (mem:BLK (scratch)))]
1715   ""
1716   "push{<imodesuffix>}\t%1"
1717   [(set_attr "type" "push")
1718    (set_attr "mode" "<MODE>")])
1719
1720 (define_insn "*pop<mode>1"
1721   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1722         (match_operand:P 1 "pop_operand" ">"))]
1723   ""
1724   "pop{<imodesuffix>}\t%0"
1725   [(set_attr "type" "pop")
1726    (set_attr "mode" "<MODE>")])
1727
1728 (define_insn "*pop<mode>1_epilogue"
1729   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1730         (match_operand:P 1 "pop_operand" ">"))
1731    (clobber (mem:BLK (scratch)))]
1732   ""
1733   "pop{<imodesuffix>}\t%0"
1734   [(set_attr "type" "pop")
1735    (set_attr "mode" "<MODE>")])
1736 \f
1737 ;; Move instructions.
1738
1739 (define_expand "movoi"
1740   [(set (match_operand:OI 0 "nonimmediate_operand" "")
1741         (match_operand:OI 1 "general_operand" ""))]
1742   "TARGET_AVX"
1743   "ix86_expand_move (OImode, operands); DONE;")
1744
1745 (define_expand "movti"
1746   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1747         (match_operand:TI 1 "nonimmediate_operand" ""))]
1748   "TARGET_64BIT || TARGET_SSE"
1749 {
1750   if (TARGET_64BIT)
1751     ix86_expand_move (TImode, operands);
1752   else if (push_operand (operands[0], TImode))
1753     ix86_expand_push (TImode, operands[1]);
1754   else
1755     ix86_expand_vector_move (TImode, operands);
1756   DONE;
1757 })
1758
1759 ;; This expands to what emit_move_complex would generate if we didn't
1760 ;; have a movti pattern.  Having this avoids problems with reload on
1761 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1762 ;; to have around all the time.
1763 (define_expand "movcdi"
1764   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1765         (match_operand:CDI 1 "general_operand" ""))]
1766   ""
1767 {
1768   if (push_operand (operands[0], CDImode))
1769     emit_move_complex_push (CDImode, operands[0], operands[1]);
1770   else
1771     emit_move_complex_parts (operands[0], operands[1]);
1772   DONE;
1773 })
1774
1775 (define_expand "mov<mode>"
1776   [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1777         (match_operand:SWI1248x 1 "general_operand" ""))]
1778   ""
1779   "ix86_expand_move (<MODE>mode, operands); DONE;")
1780
1781 (define_insn "*mov<mode>_xor"
1782   [(set (match_operand:SWI48 0 "register_operand" "=r")
1783         (match_operand:SWI48 1 "const0_operand" ""))
1784    (clobber (reg:CC FLAGS_REG))]
1785   "reload_completed"
1786   "xor{l}\t%k0, %k0"
1787   [(set_attr "type" "alu1")
1788    (set_attr "mode" "SI")
1789    (set_attr "length_immediate" "0")])
1790
1791 (define_insn "*mov<mode>_or"
1792   [(set (match_operand:SWI48 0 "register_operand" "=r")
1793         (match_operand:SWI48 1 "const_int_operand" ""))
1794    (clobber (reg:CC FLAGS_REG))]
1795   "reload_completed
1796    && operands[1] == constm1_rtx"
1797   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1798   [(set_attr "type" "alu1")
1799    (set_attr "mode" "<MODE>")
1800    (set_attr "length_immediate" "1")])
1801
1802 (define_insn "*movoi_internal_avx"
1803   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1804         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1805   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1806 {
1807   switch (which_alternative)
1808     {
1809     case 0:
1810       return "vxorps\t%0, %0, %0";
1811     case 1:
1812     case 2:
1813       if (misaligned_operand (operands[0], OImode)
1814           || misaligned_operand (operands[1], OImode))
1815         return "vmovdqu\t{%1, %0|%0, %1}";
1816       else
1817         return "vmovdqa\t{%1, %0|%0, %1}";
1818     default:
1819       gcc_unreachable ();
1820     }
1821 }
1822   [(set_attr "type" "sselog1,ssemov,ssemov")
1823    (set_attr "prefix" "vex")
1824    (set_attr "mode" "OI")])
1825
1826 (define_insn "*movti_internal_rex64"
1827   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1828         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1829   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1830 {
1831   switch (which_alternative)
1832     {
1833     case 0:
1834     case 1:
1835       return "#";
1836     case 2:
1837       if (get_attr_mode (insn) == MODE_V4SF)
1838         return "%vxorps\t%0, %d0";
1839       else
1840         return "%vpxor\t%0, %d0";
1841     case 3:
1842     case 4:
1843       /* TDmode values are passed as TImode on the stack.  Moving them
1844          to stack may result in unaligned memory access.  */
1845       if (misaligned_operand (operands[0], TImode)
1846           || misaligned_operand (operands[1], TImode))
1847         {
1848           if (get_attr_mode (insn) == MODE_V4SF)
1849             return "%vmovups\t{%1, %0|%0, %1}";
1850          else
1851            return "%vmovdqu\t{%1, %0|%0, %1}";
1852         }
1853       else
1854         {
1855           if (get_attr_mode (insn) == MODE_V4SF)
1856             return "%vmovaps\t{%1, %0|%0, %1}";
1857          else
1858            return "%vmovdqa\t{%1, %0|%0, %1}";
1859         }
1860     default:
1861       gcc_unreachable ();
1862     }
1863 }
1864   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1865    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1866    (set (attr "mode")
1867         (cond [(eq_attr "alternative" "2,3")
1868                  (if_then_else
1869                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1870                        (const_int 0))
1871                    (const_string "V4SF")
1872                    (const_string "TI"))
1873                (eq_attr "alternative" "4")
1874                  (if_then_else
1875                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1876                             (const_int 0))
1877                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1878                             (const_int 0)))
1879                    (const_string "V4SF")
1880                    (const_string "TI"))]
1881                (const_string "DI")))])
1882
1883 (define_split
1884   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1885         (match_operand:TI 1 "general_operand" ""))]
1886   "reload_completed
1887    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1888   [(const_int 0)]
1889   "ix86_split_long_move (operands); DONE;")
1890
1891 (define_insn "*movti_internal_sse"
1892   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1893         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1894   "TARGET_SSE && !TARGET_64BIT
1895    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1896 {
1897   switch (which_alternative)
1898     {
1899     case 0:
1900       if (get_attr_mode (insn) == MODE_V4SF)
1901         return "%vxorps\t%0, %d0";
1902       else
1903         return "%vpxor\t%0, %d0";
1904     case 1:
1905     case 2:
1906       /* TDmode values are passed as TImode on the stack.  Moving them
1907          to stack may result in unaligned memory access.  */
1908       if (misaligned_operand (operands[0], TImode)
1909           || misaligned_operand (operands[1], TImode))
1910         {
1911           if (get_attr_mode (insn) == MODE_V4SF)
1912             return "%vmovups\t{%1, %0|%0, %1}";
1913          else
1914            return "%vmovdqu\t{%1, %0|%0, %1}";
1915         }
1916       else
1917         {
1918           if (get_attr_mode (insn) == MODE_V4SF)
1919             return "%vmovaps\t{%1, %0|%0, %1}";
1920          else
1921            return "%vmovdqa\t{%1, %0|%0, %1}";
1922         }
1923     default:
1924       gcc_unreachable ();
1925     }
1926 }
1927   [(set_attr "type" "sselog1,ssemov,ssemov")
1928    (set_attr "prefix" "maybe_vex")
1929    (set (attr "mode")
1930         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1931                     (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1932                         (const_int 0)))
1933                  (const_string "V4SF")
1934                (and (eq_attr "alternative" "2")
1935                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1936                         (const_int 0)))
1937                  (const_string "V4SF")]
1938               (const_string "TI")))])
1939
1940 (define_insn "*movdi_internal_rex64"
1941   [(set (match_operand:DI 0 "nonimmediate_operand"
1942           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1943         (match_operand:DI 1 "general_operand"
1944           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
1945   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1946 {
1947   switch (get_attr_type (insn))
1948     {
1949     case TYPE_SSECVT:
1950       if (SSE_REG_P (operands[0]))
1951         return "movq2dq\t{%1, %0|%0, %1}";
1952       else
1953         return "movdq2q\t{%1, %0|%0, %1}";
1954
1955     case TYPE_SSEMOV:
1956       if (TARGET_AVX)
1957         {
1958           if (get_attr_mode (insn) == MODE_TI)
1959             return "vmovdqa\t{%1, %0|%0, %1}";
1960           else
1961             return "vmovq\t{%1, %0|%0, %1}";
1962         }
1963
1964       if (get_attr_mode (insn) == MODE_TI)
1965         return "movdqa\t{%1, %0|%0, %1}";
1966       /* FALLTHRU */
1967
1968     case TYPE_MMXMOV:
1969       /* Moves from and into integer register is done using movd
1970          opcode with REX prefix.  */
1971       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1972         return "movd\t{%1, %0|%0, %1}";
1973       return "movq\t{%1, %0|%0, %1}";
1974
1975     case TYPE_SSELOG1:
1976       return "%vpxor\t%0, %d0";
1977
1978     case TYPE_MMX:
1979       return "pxor\t%0, %0";
1980
1981     case TYPE_MULTI:
1982       return "#";
1983
1984     case TYPE_LEA:
1985       return "lea{q}\t{%a1, %0|%0, %a1}";
1986
1987     default:
1988       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1989       if (get_attr_mode (insn) == MODE_SI)
1990         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1991       else if (which_alternative == 2)
1992         return "movabs{q}\t{%1, %0|%0, %1}";
1993       else
1994         return "mov{q}\t{%1, %0|%0, %1}";
1995     }
1996 }
1997   [(set (attr "type")
1998      (cond [(eq_attr "alternative" "5")
1999               (const_string "mmx")
2000             (eq_attr "alternative" "6,7,8,9,10")
2001               (const_string "mmxmov")
2002             (eq_attr "alternative" "11")
2003               (const_string "sselog1")
2004             (eq_attr "alternative" "12,13,14,15,16")
2005               (const_string "ssemov")
2006             (eq_attr "alternative" "17,18")
2007               (const_string "ssecvt")
2008             (eq_attr "alternative" "4")
2009               (const_string "multi")
2010             (match_operand:DI 1 "pic_32bit_operand" "")
2011               (const_string "lea")
2012            ]
2013            (const_string "imov")))
2014    (set (attr "modrm")
2015      (if_then_else
2016        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2017          (const_string "0")
2018          (const_string "*")))
2019    (set (attr "length_immediate")
2020      (if_then_else
2021        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2022          (const_string "8")
2023          (const_string "*")))
2024    (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2025    (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2026    (set (attr "prefix")
2027      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2028        (const_string "maybe_vex")
2029        (const_string "orig")))
2030    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2031
2032 ;; Convert impossible stores of immediate to existing instructions.
2033 ;; First try to get scratch register and go through it.  In case this
2034 ;; fails, move by 32bit parts.
2035 (define_peephole2
2036   [(match_scratch:DI 2 "r")
2037    (set (match_operand:DI 0 "memory_operand" "")
2038         (match_operand:DI 1 "immediate_operand" ""))]
2039   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2040    && !x86_64_immediate_operand (operands[1], DImode)"
2041   [(set (match_dup 2) (match_dup 1))
2042    (set (match_dup 0) (match_dup 2))])
2043
2044 ;; We need to define this as both peepholer and splitter for case
2045 ;; peephole2 pass is not run.
2046 ;; "&& 1" is needed to keep it from matching the previous pattern.
2047 (define_peephole2
2048   [(set (match_operand:DI 0 "memory_operand" "")
2049         (match_operand:DI 1 "immediate_operand" ""))]
2050   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2051    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2052   [(set (match_dup 2) (match_dup 3))
2053    (set (match_dup 4) (match_dup 5))]
2054   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2055
2056 (define_split
2057   [(set (match_operand:DI 0 "memory_operand" "")
2058         (match_operand:DI 1 "immediate_operand" ""))]
2059   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2060                     ? epilogue_completed : reload_completed)
2061    && !symbolic_operand (operands[1], DImode)
2062    && !x86_64_immediate_operand (operands[1], DImode)"
2063   [(set (match_dup 2) (match_dup 3))
2064    (set (match_dup 4) (match_dup 5))]
2065   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2066
2067 (define_insn "*movdi_internal"
2068   [(set (match_operand:DI 0 "nonimmediate_operand"
2069                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2070         (match_operand:DI 1 "general_operand"
2071                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2072   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2073   "@
2074    #
2075    #
2076    pxor\t%0, %0
2077    movq\t{%1, %0|%0, %1}
2078    movq\t{%1, %0|%0, %1}
2079    %vpxor\t%0, %d0
2080    %vmovq\t{%1, %0|%0, %1}
2081    %vmovdqa\t{%1, %0|%0, %1}
2082    %vmovq\t{%1, %0|%0, %1}
2083    xorps\t%0, %0
2084    movlps\t{%1, %0|%0, %1}
2085    movaps\t{%1, %0|%0, %1}
2086    movlps\t{%1, %0|%0, %1}"
2087   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2088    (set (attr "prefix")
2089      (if_then_else (eq_attr "alternative" "5,6,7,8")
2090        (const_string "vex")
2091        (const_string "orig")))
2092    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2093
2094 (define_split
2095   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2096         (match_operand:DI 1 "general_operand" ""))]
2097   "!TARGET_64BIT && reload_completed
2098    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2099    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2100   [(const_int 0)]
2101   "ix86_split_long_move (operands); DONE;")
2102
2103 (define_insn "*movsi_internal"
2104   [(set (match_operand:SI 0 "nonimmediate_operand"
2105                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2106         (match_operand:SI 1 "general_operand"
2107                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
2108   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2109 {
2110   switch (get_attr_type (insn))
2111     {
2112     case TYPE_SSELOG1:
2113       if (get_attr_mode (insn) == MODE_TI)
2114         return "%vpxor\t%0, %d0";
2115       return "%vxorps\t%0, %d0";
2116
2117     case TYPE_SSEMOV:
2118       switch (get_attr_mode (insn))
2119         {
2120         case MODE_TI:
2121           return "%vmovdqa\t{%1, %0|%0, %1}";
2122         case MODE_V4SF:
2123           return "%vmovaps\t{%1, %0|%0, %1}";
2124         case MODE_SI:
2125           return "%vmovd\t{%1, %0|%0, %1}";
2126         case MODE_SF:
2127           return "%vmovss\t{%1, %0|%0, %1}";
2128         default:
2129           gcc_unreachable ();
2130         }
2131
2132     case TYPE_MMX:
2133       return "pxor\t%0, %0";
2134
2135     case TYPE_MMXMOV:
2136       if (get_attr_mode (insn) == MODE_DI)
2137         return "movq\t{%1, %0|%0, %1}";
2138       return "movd\t{%1, %0|%0, %1}";
2139
2140     case TYPE_LEA:
2141       return "lea{l}\t{%a1, %0|%0, %a1}";
2142
2143     default:
2144       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2145       return "mov{l}\t{%1, %0|%0, %1}";
2146     }
2147 }
2148   [(set (attr "type")
2149      (cond [(eq_attr "alternative" "2")
2150               (const_string "mmx")
2151             (eq_attr "alternative" "3,4,5")
2152               (const_string "mmxmov")
2153             (eq_attr "alternative" "6")
2154               (const_string "sselog1")
2155             (eq_attr "alternative" "7,8,9,10,11")
2156               (const_string "ssemov")
2157             (match_operand:DI 1 "pic_32bit_operand" "")
2158               (const_string "lea")
2159            ]
2160            (const_string "imov")))
2161    (set (attr "prefix")
2162      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2163        (const_string "orig")
2164        (const_string "maybe_vex")))
2165    (set (attr "prefix_data16")
2166      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2167        (const_string "1")
2168        (const_string "*")))
2169    (set (attr "mode")
2170      (cond [(eq_attr "alternative" "2,3")
2171               (const_string "DI")
2172             (eq_attr "alternative" "6,7")
2173               (if_then_else
2174                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2175                 (const_string "V4SF")
2176                 (const_string "TI"))
2177             (and (eq_attr "alternative" "8,9,10,11")
2178                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2179               (const_string "SF")
2180            ]
2181            (const_string "SI")))])
2182
2183 (define_insn "*movhi_internal"
2184   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2185         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2186   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2187 {
2188   switch (get_attr_type (insn))
2189     {
2190     case TYPE_IMOVX:
2191       /* movzwl is faster than movw on p2 due to partial word stalls,
2192          though not as fast as an aligned movl.  */
2193       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2194     default:
2195       if (get_attr_mode (insn) == MODE_SI)
2196         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2197       else
2198         return "mov{w}\t{%1, %0|%0, %1}";
2199     }
2200 }
2201   [(set (attr "type")
2202      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2203                 (const_int 0))
2204               (const_string "imov")
2205             (and (eq_attr "alternative" "0")
2206                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2207                           (const_int 0))
2208                       (eq (symbol_ref "TARGET_HIMODE_MATH")
2209                           (const_int 0))))
2210               (const_string "imov")
2211             (and (eq_attr "alternative" "1,2")
2212                  (match_operand:HI 1 "aligned_operand" ""))
2213               (const_string "imov")
2214             (and (ne (symbol_ref "TARGET_MOVX")
2215                      (const_int 0))
2216                  (eq_attr "alternative" "0,2"))
2217               (const_string "imovx")
2218            ]
2219            (const_string "imov")))
2220     (set (attr "mode")
2221       (cond [(eq_attr "type" "imovx")
2222                (const_string "SI")
2223              (and (eq_attr "alternative" "1,2")
2224                   (match_operand:HI 1 "aligned_operand" ""))
2225                (const_string "SI")
2226              (and (eq_attr "alternative" "0")
2227                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2228                            (const_int 0))
2229                        (eq (symbol_ref "TARGET_HIMODE_MATH")
2230                            (const_int 0))))
2231                (const_string "SI")
2232             ]
2233             (const_string "HI")))])
2234
2235 ;; Situation is quite tricky about when to choose full sized (SImode) move
2236 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2237 ;; partial register dependency machines (such as AMD Athlon), where QImode
2238 ;; moves issue extra dependency and for partial register stalls machines
2239 ;; that don't use QImode patterns (and QImode move cause stall on the next
2240 ;; instruction).
2241 ;;
2242 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2243 ;; register stall machines with, where we use QImode instructions, since
2244 ;; partial register stall can be caused there.  Then we use movzx.
2245 (define_insn "*movqi_internal"
2246   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2247         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2248   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2249 {
2250   switch (get_attr_type (insn))
2251     {
2252     case TYPE_IMOVX:
2253       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2254       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2255     default:
2256       if (get_attr_mode (insn) == MODE_SI)
2257         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2258       else
2259         return "mov{b}\t{%1, %0|%0, %1}";
2260     }
2261 }
2262   [(set (attr "type")
2263      (cond [(and (eq_attr "alternative" "5")
2264                  (not (match_operand:QI 1 "aligned_operand" "")))
2265               (const_string "imovx")
2266             (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2267                 (const_int 0))
2268               (const_string "imov")
2269             (and (eq_attr "alternative" "3")
2270                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2271                           (const_int 0))
2272                       (eq (symbol_ref "TARGET_QIMODE_MATH")
2273                           (const_int 0))))
2274               (const_string "imov")
2275             (eq_attr "alternative" "3,5")
2276               (const_string "imovx")
2277             (and (ne (symbol_ref "TARGET_MOVX")
2278                      (const_int 0))
2279                  (eq_attr "alternative" "2"))
2280               (const_string "imovx")
2281            ]
2282            (const_string "imov")))
2283    (set (attr "mode")
2284       (cond [(eq_attr "alternative" "3,4,5")
2285                (const_string "SI")
2286              (eq_attr "alternative" "6")
2287                (const_string "QI")
2288              (eq_attr "type" "imovx")
2289                (const_string "SI")
2290              (and (eq_attr "type" "imov")
2291                   (and (eq_attr "alternative" "0,1")
2292                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2293                                 (const_int 0))
2294                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2295                                      (const_int 0))
2296                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2297                                      (const_int 0))))))
2298                (const_string "SI")
2299              ;; Avoid partial register stalls when not using QImode arithmetic
2300              (and (eq_attr "type" "imov")
2301                   (and (eq_attr "alternative" "0,1")
2302                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2303                                 (const_int 0))
2304                             (eq (symbol_ref "TARGET_QIMODE_MATH")
2305                                 (const_int 0)))))
2306                (const_string "SI")
2307            ]
2308            (const_string "QI")))])
2309
2310 ;; Stores and loads of ax to arbitrary constant address.
2311 ;; We fake an second form of instruction to force reload to load address
2312 ;; into register when rax is not available
2313 (define_insn "*movabs<mode>_1"
2314   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2315         (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2316   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2317   "@
2318    movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2319    mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2320   [(set_attr "type" "imov")
2321    (set_attr "modrm" "0,*")
2322    (set_attr "length_address" "8,0")
2323    (set_attr "length_immediate" "0,*")
2324    (set_attr "memory" "store")
2325    (set_attr "mode" "<MODE>")])
2326
2327 (define_insn "*movabs<mode>_2"
2328   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2329         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2330   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2331   "@
2332    movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2333    mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2334   [(set_attr "type" "imov")
2335    (set_attr "modrm" "0,*")
2336    (set_attr "length_address" "8,0")
2337    (set_attr "length_immediate" "0")
2338    (set_attr "memory" "load")
2339    (set_attr "mode" "<MODE>")])
2340
2341 (define_insn "*swap<mode>"
2342   [(set (match_operand:SWI48 0 "register_operand" "+r")
2343         (match_operand:SWI48 1 "register_operand" "+r"))
2344    (set (match_dup 1)
2345         (match_dup 0))]
2346   ""
2347   "xchg{<imodesuffix>}\t%1, %0"
2348   [(set_attr "type" "imov")
2349    (set_attr "mode" "<MODE>")
2350    (set_attr "pent_pair" "np")
2351    (set_attr "athlon_decode" "vector")
2352    (set_attr "amdfam10_decode" "double")])
2353
2354 (define_insn "*swap<mode>_1"
2355   [(set (match_operand:SWI12 0 "register_operand" "+r")
2356         (match_operand:SWI12 1 "register_operand" "+r"))
2357    (set (match_dup 1)
2358         (match_dup 0))]
2359   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2360   "xchg{l}\t%k1, %k0"
2361   [(set_attr "type" "imov")
2362    (set_attr "mode" "SI")
2363    (set_attr "pent_pair" "np")
2364    (set_attr "athlon_decode" "vector")
2365    (set_attr "amdfam10_decode" "double")])
2366
2367 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2368 ;; is disabled for AMDFAM10
2369 (define_insn "*swap<mode>_2"
2370   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2371         (match_operand:SWI12 1 "register_operand" "+<r>"))
2372    (set (match_dup 1)
2373         (match_dup 0))]
2374   "TARGET_PARTIAL_REG_STALL"
2375   "xchg{<imodesuffix>}\t%1, %0"
2376   [(set_attr "type" "imov")
2377    (set_attr "mode" "<MODE>")
2378    (set_attr "pent_pair" "np")
2379    (set_attr "athlon_decode" "vector")])
2380
2381 (define_expand "movstrict<mode>"
2382   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2383         (match_operand:SWI12 1 "general_operand" ""))]
2384   ""
2385 {
2386   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2387     FAIL;
2388   /* Don't generate memory->memory moves, go through a register */
2389   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2390     operands[1] = force_reg (<MODE>mode, operands[1]);
2391 })
2392
2393 (define_insn "*movstrict<mode>_1"
2394   [(set (strict_low_part
2395           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2396         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2397   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2398    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2399   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2400   [(set_attr "type" "imov")
2401    (set_attr "mode" "<MODE>")])
2402
2403 (define_insn "*movstrict<mode>_xor"
2404   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2405         (match_operand:SWI12 1 "const0_operand" ""))
2406    (clobber (reg:CC FLAGS_REG))]
2407   "reload_completed"
2408   "xor{<imodesuffix>}\t%0, %0"
2409   [(set_attr "type" "alu1")
2410    (set_attr "mode" "<MODE>")
2411    (set_attr "length_immediate" "0")])
2412
2413 (define_insn "*mov<mode>_extv_1"
2414   [(set (match_operand:SWI24 0 "register_operand" "=R")
2415         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2416                             (const_int 8)
2417                             (const_int 8)))]
2418   ""
2419   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2420   [(set_attr "type" "imovx")
2421    (set_attr "mode" "SI")])
2422
2423 (define_insn "*movqi_extv_1_rex64"
2424   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2425         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2426                          (const_int 8)
2427                          (const_int 8)))]
2428   "TARGET_64BIT"
2429 {
2430   switch (get_attr_type (insn))
2431     {
2432     case TYPE_IMOVX:
2433       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2434     default:
2435       return "mov{b}\t{%h1, %0|%0, %h1}";
2436     }
2437 }
2438   [(set (attr "type")
2439      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2440                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2441                              (ne (symbol_ref "TARGET_MOVX")
2442                                  (const_int 0))))
2443         (const_string "imovx")
2444         (const_string "imov")))
2445    (set (attr "mode")
2446      (if_then_else (eq_attr "type" "imovx")
2447         (const_string "SI")
2448         (const_string "QI")))])
2449
2450 (define_insn "*movqi_extv_1"
2451   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2452         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2453                          (const_int 8)
2454                          (const_int 8)))]
2455   "!TARGET_64BIT"
2456 {
2457   switch (get_attr_type (insn))
2458     {
2459     case TYPE_IMOVX:
2460       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2461     default:
2462       return "mov{b}\t{%h1, %0|%0, %h1}";
2463     }
2464 }
2465   [(set (attr "type")
2466      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2467                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2468                              (ne (symbol_ref "TARGET_MOVX")
2469                                  (const_int 0))))
2470         (const_string "imovx")
2471         (const_string "imov")))
2472    (set (attr "mode")
2473      (if_then_else (eq_attr "type" "imovx")
2474         (const_string "SI")
2475         (const_string "QI")))])
2476
2477 (define_insn "*mov<mode>_extzv_1"
2478   [(set (match_operand:SWI48 0 "register_operand" "=R")
2479         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2480                             (const_int 8)
2481                             (const_int 8)))]
2482   ""
2483   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2484   [(set_attr "type" "imovx")
2485    (set_attr "mode" "SI")])
2486
2487 (define_insn "*movqi_extzv_2_rex64"
2488   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2489         (subreg:QI
2490           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2491                            (const_int 8)
2492                            (const_int 8)) 0))]
2493   "TARGET_64BIT"
2494 {
2495   switch (get_attr_type (insn))
2496     {
2497     case TYPE_IMOVX:
2498       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2499     default:
2500       return "mov{b}\t{%h1, %0|%0, %h1}";
2501     }
2502 }
2503   [(set (attr "type")
2504      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2505                         (ne (symbol_ref "TARGET_MOVX")
2506                             (const_int 0)))
2507         (const_string "imovx")
2508         (const_string "imov")))
2509    (set (attr "mode")
2510      (if_then_else (eq_attr "type" "imovx")
2511         (const_string "SI")
2512         (const_string "QI")))])
2513
2514 (define_insn "*movqi_extzv_2"
2515   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2516         (subreg:QI
2517           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2518                            (const_int 8)
2519                            (const_int 8)) 0))]
2520   "!TARGET_64BIT"
2521 {
2522   switch (get_attr_type (insn))
2523     {
2524     case TYPE_IMOVX:
2525       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2526     default:
2527       return "mov{b}\t{%h1, %0|%0, %h1}";
2528     }
2529 }
2530   [(set (attr "type")
2531      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2532                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2533                              (ne (symbol_ref "TARGET_MOVX")
2534                                  (const_int 0))))
2535         (const_string "imovx")
2536         (const_string "imov")))
2537    (set (attr "mode")
2538      (if_then_else (eq_attr "type" "imovx")
2539         (const_string "SI")
2540         (const_string "QI")))])
2541
2542 (define_expand "mov<mode>_insv_1"
2543   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2544                             (const_int 8)
2545                             (const_int 8))
2546         (match_operand:SWI48 1 "nonmemory_operand" ""))])
2547
2548 (define_insn "*mov<mode>_insv_1_rex64"
2549   [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2550                              (const_int 8)
2551                              (const_int 8))
2552         (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2553   "TARGET_64BIT"
2554   "mov{b}\t{%b1, %h0|%h0, %b1}"
2555   [(set_attr "type" "imov")
2556    (set_attr "mode" "QI")])
2557
2558 (define_insn "*movsi_insv_1"
2559   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2560                          (const_int 8)
2561                          (const_int 8))
2562         (match_operand:SI 1 "general_operand" "Qmn"))]
2563   "!TARGET_64BIT"
2564   "mov{b}\t{%b1, %h0|%h0, %b1}"
2565   [(set_attr "type" "imov")
2566    (set_attr "mode" "QI")])
2567
2568 (define_insn "*movqi_insv_2"
2569   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2570                          (const_int 8)
2571                          (const_int 8))
2572         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2573                      (const_int 8)))]
2574   ""
2575   "mov{b}\t{%h1, %h0|%h0, %h1}"
2576   [(set_attr "type" "imov")
2577    (set_attr "mode" "QI")])
2578 \f
2579 ;; Floating point push instructions.
2580
2581 (define_insn "*pushtf"
2582   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2583         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2584   "TARGET_SSE2"
2585 {
2586   /* This insn should be already split before reg-stack.  */
2587   gcc_unreachable ();
2588 }
2589   [(set_attr "type" "multi")
2590    (set_attr "unit" "sse,*,*")
2591    (set_attr "mode" "TF,SI,SI")])
2592
2593 (define_split
2594   [(set (match_operand:TF 0 "push_operand" "")
2595         (match_operand:TF 1 "sse_reg_operand" ""))]
2596   "TARGET_SSE2 && reload_completed"
2597   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2598    (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2599
2600 (define_split
2601   [(set (match_operand:TF 0 "push_operand" "")
2602         (match_operand:TF 1 "general_operand" ""))]
2603   "TARGET_SSE2 && reload_completed
2604    && !SSE_REG_P (operands[1])"
2605   [(const_int 0)]
2606   "ix86_split_long_move (operands); DONE;")
2607
2608 (define_insn "*pushxf"
2609   [(set (match_operand:XF 0 "push_operand" "=<,<")
2610         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2611   "optimize_function_for_speed_p (cfun)"
2612 {
2613   /* This insn should be already split before reg-stack.  */
2614   gcc_unreachable ();
2615 }
2616   [(set_attr "type" "multi")
2617    (set_attr "unit" "i387,*")
2618    (set_attr "mode" "XF,SI")])
2619
2620 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2621 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2622 ;; Pushing using integer instructions is longer except for constants
2623 ;; and direct memory references (assuming that any given constant is pushed
2624 ;; only once, but this ought to be handled elsewhere).
2625
2626 (define_insn "*pushxf_nointeger"
2627   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2628         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2629   "optimize_function_for_size_p (cfun)"
2630 {
2631   /* This insn should be already split before reg-stack.  */
2632   gcc_unreachable ();
2633 }
2634   [(set_attr "type" "multi")
2635    (set_attr "unit" "i387,*,*")
2636    (set_attr "mode" "XF,SI,SI")])
2637
2638 (define_split
2639   [(set (match_operand:XF 0 "push_operand" "")
2640         (match_operand:XF 1 "fp_register_operand" ""))]
2641   "reload_completed"
2642   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2643    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2644   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2645
2646 (define_split
2647   [(set (match_operand:XF 0 "push_operand" "")
2648         (match_operand:XF 1 "general_operand" ""))]
2649   "reload_completed
2650    && !FP_REG_P (operands[1])"
2651   [(const_int 0)]
2652   "ix86_split_long_move (operands); DONE;")
2653
2654 (define_insn "*pushdf"
2655   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2656         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2657   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2658 {
2659   /* This insn should be already split before reg-stack.  */
2660   gcc_unreachable ();
2661 }
2662   [(set_attr "type" "multi")
2663    (set_attr "unit" "i387,*,*")
2664    (set_attr "mode" "DF,SI,DF")])
2665
2666 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2667 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2668 ;; On the average, pushdf using integers can be still shorter.  Allow this
2669 ;; pattern for optimize_size too.
2670
2671 (define_insn "*pushdf_nointeger"
2672   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2673         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2674   "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
2675 {
2676   /* This insn should be already split before reg-stack.  */
2677   gcc_unreachable ();
2678 }
2679   [(set_attr "type" "multi")
2680    (set_attr "unit" "i387,*,*,*")
2681    (set_attr "mode" "DF,SI,SI,DF")])
2682
2683 ;; %%% Kill this when call knows how to work this out.
2684 (define_split
2685   [(set (match_operand:DF 0 "push_operand" "")
2686         (match_operand:DF 1 "any_fp_register_operand" ""))]
2687   "reload_completed"
2688   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2689    (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2690
2691 (define_split
2692   [(set (match_operand:DF 0 "push_operand" "")
2693         (match_operand:DF 1 "general_operand" ""))]
2694   "reload_completed
2695    && !ANY_FP_REG_P (operands[1])"
2696   [(const_int 0)]
2697   "ix86_split_long_move (operands); DONE;")
2698
2699 (define_insn "*pushsf_rex64"
2700   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2701         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2702   "TARGET_64BIT"
2703 {
2704   /* Anything else should be already split before reg-stack.  */
2705   gcc_assert (which_alternative == 1);
2706   return "push{q}\t%q1";
2707 }
2708   [(set_attr "type" "multi,push,multi")
2709    (set_attr "unit" "i387,*,*")
2710    (set_attr "mode" "SF,DI,SF")])
2711
2712 (define_insn "*pushsf"
2713   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2714         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2715   "!TARGET_64BIT"
2716 {
2717   /* Anything else should be already split before reg-stack.  */
2718   gcc_assert (which_alternative == 1);
2719   return "push{l}\t%1";
2720 }
2721   [(set_attr "type" "multi,push,multi")
2722    (set_attr "unit" "i387,*,*")
2723    (set_attr "mode" "SF,SI,SF")])
2724
2725 (define_split
2726   [(set (match_operand:SF 0 "push_operand" "")
2727         (match_operand:SF 1 "memory_operand" ""))]
2728   "reload_completed
2729    && MEM_P (operands[1])
2730    && (operands[2] = find_constant_src (insn))"
2731   [(set (match_dup 0)
2732         (match_dup 2))])
2733
2734 ;; %%% Kill this when call knows how to work this out.
2735 (define_split
2736   [(set (match_operand:SF 0 "push_operand" "")
2737         (match_operand:SF 1 "any_fp_register_operand" ""))]
2738   "reload_completed"
2739   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2740    (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2741   "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2742 \f
2743 ;; Floating point move instructions.
2744
2745 (define_expand "movtf"
2746   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2747         (match_operand:TF 1 "nonimmediate_operand" ""))]
2748   "TARGET_SSE2"
2749 {
2750   ix86_expand_move (TFmode, operands);
2751   DONE;
2752 })
2753
2754 (define_expand "mov<mode>"
2755   [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2756         (match_operand:X87MODEF 1 "general_operand" ""))]
2757   ""
2758   "ix86_expand_move (<MODE>mode, operands); DONE;")
2759
2760 (define_insn "*movtf_internal"
2761   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2762         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2763   "TARGET_SSE2
2764    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2765 {
2766   switch (which_alternative)
2767     {
2768     case 0:
2769     case 1:
2770       if (get_attr_mode (insn) == MODE_V4SF)
2771         return "%vmovaps\t{%1, %0|%0, %1}";
2772       else
2773         return "%vmovdqa\t{%1, %0|%0, %1}";
2774     case 2:
2775       if (get_attr_mode (insn) == MODE_V4SF)
2776         return "%vxorps\t%0, %d0";
2777       else
2778         return "%vpxor\t%0, %d0";
2779     case 3:
2780     case 4:
2781         return "#";
2782     default:
2783       gcc_unreachable ();
2784     }
2785 }
2786   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2787    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2788    (set (attr "mode")
2789         (cond [(eq_attr "alternative" "0,2")
2790                  (if_then_else
2791                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2792                        (const_int 0))
2793                    (const_string "V4SF")
2794                    (const_string "TI"))
2795                (eq_attr "alternative" "1")
2796                  (if_then_else
2797                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2798                             (const_int 0))
2799                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2800                             (const_int 0)))
2801                    (const_string "V4SF")
2802                    (const_string "TI"))]
2803                (const_string "DI")))])
2804
2805 (define_split
2806   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2807         (match_operand:TF 1 "general_operand" ""))]
2808   "reload_completed
2809    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2810   [(const_int 0)]
2811   "ix86_split_long_move (operands); DONE;")
2812
2813 (define_insn "*movxf_internal"
2814   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2815         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2816   "optimize_function_for_speed_p (cfun)
2817    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2818    && (reload_in_progress || reload_completed
2819        || GET_CODE (operands[1]) != CONST_DOUBLE
2820        || memory_operand (operands[0], XFmode))"
2821 {
2822   switch (which_alternative)
2823     {
2824     case 0:
2825     case 1:
2826       return output_387_reg_move (insn, operands);
2827
2828     case 2:
2829       return standard_80387_constant_opcode (operands[1]);
2830
2831     case 3: case 4:
2832       return "#";
2833
2834     default:
2835       gcc_unreachable ();
2836     }
2837 }
2838   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2839    (set_attr "mode" "XF,XF,XF,SI,SI")])
2840
2841 ;; Do not use integer registers when optimizing for size
2842 (define_insn "*movxf_internal_nointeger"
2843   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2844         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2845   "optimize_function_for_size_p (cfun)
2846    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2847    && (reload_in_progress || reload_completed
2848        || standard_80387_constant_p (operands[1])
2849        || GET_CODE (operands[1]) != CONST_DOUBLE
2850        || memory_operand (operands[0], XFmode))"
2851 {
2852   switch (which_alternative)
2853     {
2854     case 0:
2855     case 1:
2856       return output_387_reg_move (insn, operands);
2857
2858     case 2:
2859       return standard_80387_constant_opcode (operands[1]);
2860
2861     case 3: case 4:
2862       return "#";
2863     default:
2864       gcc_unreachable ();
2865     }
2866 }
2867   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2868    (set_attr "mode" "XF,XF,XF,SI,SI")])
2869
2870 (define_split
2871   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2872         (match_operand:XF 1 "general_operand" ""))]
2873   "reload_completed
2874    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2875    && ! (FP_REG_P (operands[0]) ||
2876          (GET_CODE (operands[0]) == SUBREG
2877           && FP_REG_P (SUBREG_REG (operands[0]))))
2878    && ! (FP_REG_P (operands[1]) ||
2879          (GET_CODE (operands[1]) == SUBREG
2880           && FP_REG_P (SUBREG_REG (operands[1]))))"
2881   [(const_int 0)]
2882   "ix86_split_long_move (operands); DONE;")
2883
2884 (define_insn "*movdf_internal_rex64"
2885   [(set (match_operand:DF 0 "nonimmediate_operand"
2886                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2887         (match_operand:DF 1 "general_operand"
2888                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2889   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2890    && (reload_in_progress || reload_completed
2891        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2892        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2893            && optimize_function_for_size_p (cfun)
2894            && standard_80387_constant_p (operands[1]))
2895        || GET_CODE (operands[1]) != CONST_DOUBLE
2896        || memory_operand (operands[0], DFmode))"
2897 {
2898   switch (which_alternative)
2899     {
2900     case 0:
2901     case 1:
2902       return output_387_reg_move (insn, operands);
2903
2904     case 2:
2905       return standard_80387_constant_opcode (operands[1]);
2906
2907     case 3:
2908     case 4:
2909       return "#";
2910
2911     case 5:
2912       switch (get_attr_mode (insn))
2913         {
2914         case MODE_V4SF:
2915           return "%vxorps\t%0, %d0";
2916         case MODE_V2DF:
2917           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2918             return "%vxorps\t%0, %d0";
2919           else
2920             return "%vxorpd\t%0, %d0";
2921         case MODE_TI:
2922           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2923             return "%vxorps\t%0, %d0";
2924           else
2925             return "%vpxor\t%0, %d0";
2926         default:
2927           gcc_unreachable ();
2928         }
2929     case 6:
2930     case 7:
2931     case 8:
2932       switch (get_attr_mode (insn))
2933         {
2934         case MODE_V4SF:
2935           return "%vmovaps\t{%1, %0|%0, %1}";
2936         case MODE_V2DF:
2937           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2938             return "%vmovaps\t{%1, %0|%0, %1}";
2939           else
2940             return "%vmovapd\t{%1, %0|%0, %1}";
2941         case MODE_TI:
2942           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2943             return "%vmovaps\t{%1, %0|%0, %1}";
2944           else
2945             return "%vmovdqa\t{%1, %0|%0, %1}";
2946         case MODE_DI:
2947           return "%vmovq\t{%1, %0|%0, %1}";
2948         case MODE_DF:
2949           if (TARGET_AVX)
2950             {
2951               if (REG_P (operands[0]) && REG_P (operands[1]))
2952                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2953               else
2954                 return "vmovsd\t{%1, %0|%0, %1}";
2955             }
2956           else
2957             return "movsd\t{%1, %0|%0, %1}";
2958         case MODE_V1DF:
2959           return "%vmovlpd\t{%1, %d0|%d0, %1}";
2960         case MODE_V2SF:
2961           return "%vmovlps\t{%1, %d0|%d0, %1}";
2962         default:
2963           gcc_unreachable ();
2964         }
2965
2966     case 9:
2967     case 10:
2968     return "%vmovd\t{%1, %0|%0, %1}";
2969
2970     default:
2971       gcc_unreachable();
2972     }
2973 }
2974   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2975    (set (attr "prefix")
2976      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
2977        (const_string "orig")
2978        (const_string "maybe_vex")))
2979    (set (attr "prefix_data16")
2980      (if_then_else (eq_attr "mode" "V1DF")
2981        (const_string "1")
2982        (const_string "*")))
2983    (set (attr "mode")
2984         (cond [(eq_attr "alternative" "0,1,2")
2985                  (const_string "DF")
2986                (eq_attr "alternative" "3,4,9,10")
2987                  (const_string "DI")
2988
2989                /* For SSE1, we have many fewer alternatives.  */
2990                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2991                  (cond [(eq_attr "alternative" "5,6")
2992                           (const_string "V4SF")
2993                        ]
2994                    (const_string "V2SF"))
2995
2996                /* xorps is one byte shorter.  */
2997                (eq_attr "alternative" "5")
2998                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2999                             (const_int 0))
3000                           (const_string "V4SF")
3001                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3002                             (const_int 0))
3003                           (const_string "TI")
3004                        ]
3005                        (const_string "V2DF"))
3006
3007                /* For architectures resolving dependencies on
3008                   whole SSE registers use APD move to break dependency
3009                   chains, otherwise use short move to avoid extra work.
3010
3011                   movaps encodes one byte shorter.  */
3012                (eq_attr "alternative" "6")
3013                  (cond
3014                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3015                         (const_int 0))
3016                       (const_string "V4SF")
3017                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3018                         (const_int 0))
3019                       (const_string "V2DF")
3020                    ]
3021                    (const_string "DF"))
3022                /* For architectures resolving dependencies on register
3023                   parts we may avoid extra work to zero out upper part
3024                   of register.  */
3025                (eq_attr "alternative" "7")
3026                  (if_then_else
3027                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3028                        (const_int 0))
3029                    (const_string "V1DF")
3030                    (const_string "DF"))
3031               ]
3032               (const_string "DF")))])
3033
3034 (define_insn "*movdf_internal"
3035   [(set (match_operand:DF 0 "nonimmediate_operand"
3036                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3037         (match_operand:DF 1 "general_operand"
3038                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3039   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3040    && optimize_function_for_speed_p (cfun)
3041    && TARGET_INTEGER_DFMODE_MOVES
3042    && (reload_in_progress || reload_completed
3043        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3044        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3045            && optimize_function_for_size_p (cfun)
3046            && standard_80387_constant_p (operands[1]))
3047        || GET_CODE (operands[1]) != CONST_DOUBLE
3048        || memory_operand (operands[0], DFmode))"
3049 {
3050   switch (which_alternative)
3051     {
3052     case 0:
3053     case 1:
3054       return output_387_reg_move (insn, operands);
3055
3056     case 2:
3057       return standard_80387_constant_opcode (operands[1]);
3058
3059     case 3:
3060     case 4:
3061       return "#";
3062
3063     case 5:
3064       switch (get_attr_mode (insn))
3065         {
3066         case MODE_V4SF:
3067           return "xorps\t%0, %0";
3068         case MODE_V2DF:
3069           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3070             return "xorps\t%0, %0";
3071           else
3072             return "xorpd\t%0, %0";
3073         case MODE_TI:
3074           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3075             return "xorps\t%0, %0";
3076           else
3077             return "pxor\t%0, %0";
3078         default:
3079           gcc_unreachable ();
3080         }
3081     case 6:
3082     case 7:
3083     case 8:
3084       switch (get_attr_mode (insn))
3085         {
3086         case MODE_V4SF:
3087           return "movaps\t{%1, %0|%0, %1}";
3088         case MODE_V2DF:
3089           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3090             return "movaps\t{%1, %0|%0, %1}";
3091           else
3092             return "movapd\t{%1, %0|%0, %1}";
3093         case MODE_TI:
3094           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3095             return "movaps\t{%1, %0|%0, %1}";
3096           else
3097             return "movdqa\t{%1, %0|%0, %1}";
3098         case MODE_DI:
3099           return "movq\t{%1, %0|%0, %1}";
3100         case MODE_DF:
3101           return "movsd\t{%1, %0|%0, %1}";
3102         case MODE_V1DF:
3103           return "movlpd\t{%1, %0|%0, %1}";
3104         case MODE_V2SF:
3105           return "movlps\t{%1, %0|%0, %1}";
3106         default:
3107           gcc_unreachable ();
3108         }
3109
3110     default:
3111       gcc_unreachable();
3112     }
3113 }
3114   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3115    (set (attr "prefix_data16")
3116      (if_then_else (eq_attr "mode" "V1DF")
3117        (const_string "1")
3118        (const_string "*")))
3119    (set (attr "mode")
3120         (cond [(eq_attr "alternative" "0,1,2")
3121                  (const_string "DF")
3122                (eq_attr "alternative" "3,4")
3123                  (const_string "SI")
3124
3125                /* For SSE1, we have many fewer alternatives.  */
3126                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3127                  (cond [(eq_attr "alternative" "5,6")
3128                           (const_string "V4SF")
3129                        ]
3130                    (const_string "V2SF"))
3131
3132                /* xorps is one byte shorter.  */
3133                (eq_attr "alternative" "5")
3134                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3135                             (const_int 0))
3136                           (const_string "V4SF")
3137                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3138                             (const_int 0))
3139                           (const_string "TI")
3140                        ]
3141                        (const_string "V2DF"))
3142
3143                /* For architectures resolving dependencies on
3144                   whole SSE registers use APD move to break dependency
3145                   chains, otherwise use short move to avoid extra work.
3146
3147                   movaps encodes one byte shorter.  */
3148                (eq_attr "alternative" "6")
3149                  (cond
3150                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3151                         (const_int 0))
3152                       (const_string "V4SF")
3153                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3154                         (const_int 0))
3155                       (const_string "V2DF")
3156                    ]
3157                    (const_string "DF"))
3158                /* For architectures resolving dependencies on register
3159                   parts we may avoid extra work to zero out upper part
3160                   of register.  */
3161                (eq_attr "alternative" "7")
3162                  (if_then_else
3163                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3164                        (const_int 0))
3165                    (const_string "V1DF")
3166                    (const_string "DF"))
3167               ]
3168               (const_string "DF")))])
3169
3170 ;; Moving is usually shorter when only FP registers are used. This separate
3171 ;; movdf pattern avoids the use of integer registers for FP operations
3172 ;; when optimizing for size.
3173
3174 (define_insn "*movdf_internal_nointeger"
3175   [(set (match_operand:DF 0 "nonimmediate_operand"
3176                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
3177         (match_operand:DF 1 "general_operand"
3178                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
3179   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3180    && ((optimize_function_for_size_p (cfun)
3181        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3182    && (reload_in_progress || reload_completed
3183        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3184        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3185            && optimize_function_for_size_p (cfun)
3186            && !memory_operand (operands[0], DFmode)
3187            && standard_80387_constant_p (operands[1]))
3188        || GET_CODE (operands[1]) != CONST_DOUBLE
3189        || ((optimize_function_for_size_p (cfun)
3190             || !TARGET_MEMORY_MISMATCH_STALL
3191             || reload_in_progress || reload_completed)
3192            && memory_operand (operands[0], DFmode)))"
3193 {
3194   switch (which_alternative)
3195     {
3196     case 0:
3197     case 1:
3198       return output_387_reg_move (insn, operands);
3199
3200     case 2:
3201       return standard_80387_constant_opcode (operands[1]);
3202
3203     case 3:
3204     case 4:
3205       return "#";
3206
3207     case 5:
3208       switch (get_attr_mode (insn))
3209         {
3210         case MODE_V4SF:
3211           return "%vxorps\t%0, %d0";
3212         case MODE_V2DF:
3213           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3214             return "%vxorps\t%0, %d0";
3215           else
3216             return "%vxorpd\t%0, %d0";
3217         case MODE_TI:
3218           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3219             return "%vxorps\t%0, %d0";
3220           else
3221             return "%vpxor\t%0, %d0";
3222         default:
3223           gcc_unreachable ();
3224         }
3225     case 6:
3226     case 7:
3227     case 8:
3228       switch (get_attr_mode (insn))
3229         {
3230         case MODE_V4SF:
3231           return "%vmovaps\t{%1, %0|%0, %1}";
3232         case MODE_V2DF:
3233           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3234             return "%vmovaps\t{%1, %0|%0, %1}";
3235           else
3236             return "%vmovapd\t{%1, %0|%0, %1}";
3237         case MODE_TI:
3238           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3239             return "%vmovaps\t{%1, %0|%0, %1}";
3240           else
3241             return "%vmovdqa\t{%1, %0|%0, %1}";
3242         case MODE_DI:
3243           return "%vmovq\t{%1, %0|%0, %1}";
3244         case MODE_DF:
3245           if (TARGET_AVX)
3246             {
3247               if (REG_P (operands[0]) && REG_P (operands[1]))
3248                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3249               else
3250                 return "vmovsd\t{%1, %0|%0, %1}";
3251             }
3252           else
3253             return "movsd\t{%1, %0|%0, %1}";
3254         case MODE_V1DF:
3255           if (TARGET_AVX)
3256             {
3257               if (REG_P (operands[0]))
3258                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3259               else
3260                 return "vmovlpd\t{%1, %0|%0, %1}";
3261             }
3262           else
3263             return "movlpd\t{%1, %0|%0, %1}";
3264         case MODE_V2SF:
3265           if (TARGET_AVX)
3266             {
3267               if (REG_P (operands[0]))
3268                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3269               else
3270                 return "vmovlps\t{%1, %0|%0, %1}";
3271             }
3272           else
3273             return "movlps\t{%1, %0|%0, %1}";
3274         default:
3275           gcc_unreachable ();
3276         }
3277
3278     default:
3279       gcc_unreachable ();
3280     }
3281 }
3282   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3283    (set (attr "prefix")
3284      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3285        (const_string "orig")
3286        (const_string "maybe_vex")))
3287    (set (attr "prefix_data16")
3288      (if_then_else (eq_attr "mode" "V1DF")
3289        (const_string "1")
3290        (const_string "*")))
3291    (set (attr "mode")
3292         (cond [(eq_attr "alternative" "0,1,2")
3293                  (const_string "DF")
3294                (eq_attr "alternative" "3,4")
3295                  (const_string "SI")
3296
3297                /* For SSE1, we have many fewer alternatives.  */
3298                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3299                  (cond [(eq_attr "alternative" "5,6")
3300                           (const_string "V4SF")
3301                        ]
3302                    (const_string "V2SF"))
3303
3304                /* xorps is one byte shorter.  */
3305                (eq_attr "alternative" "5")
3306                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3307                             (const_int 0))
3308                           (const_string "V4SF")
3309                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3310                             (const_int 0))
3311                           (const_string "TI")
3312                        ]
3313                        (const_string "V2DF"))
3314
3315                /* For architectures resolving dependencies on
3316                   whole SSE registers use APD move to break dependency
3317                   chains, otherwise use short move to avoid extra work.
3318
3319                   movaps encodes one byte shorter.  */
3320                (eq_attr "alternative" "6")
3321                  (cond
3322                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3323                         (const_int 0))
3324                       (const_string "V4SF")
3325                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3326                         (const_int 0))
3327                       (const_string "V2DF")
3328                    ]
3329                    (const_string "DF"))
3330                /* For architectures resolving dependencies on register
3331                   parts we may avoid extra work to zero out upper part
3332                   of register.  */
3333                (eq_attr "alternative" "7")
3334                  (if_then_else
3335                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3336                        (const_int 0))
3337                    (const_string "V1DF")
3338                    (const_string "DF"))
3339               ]
3340               (const_string "DF")))])
3341
3342 (define_split
3343   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3344         (match_operand:DF 1 "general_operand" ""))]
3345   "reload_completed
3346    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3347    && ! (ANY_FP_REG_P (operands[0]) ||
3348          (GET_CODE (operands[0]) == SUBREG
3349           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3350    && ! (ANY_FP_REG_P (operands[1]) ||
3351          (GET_CODE (operands[1]) == SUBREG
3352           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3353   [(const_int 0)]
3354   "ix86_split_long_move (operands); DONE;")
3355
3356 (define_insn "*movsf_internal"
3357   [(set (match_operand:SF 0 "nonimmediate_operand"
3358           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3359         (match_operand:SF 1 "general_operand"
3360           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
3361   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3362    && (reload_in_progress || reload_completed
3363        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3364        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3365            && standard_80387_constant_p (operands[1]))
3366        || GET_CODE (operands[1]) != CONST_DOUBLE
3367        || memory_operand (operands[0], SFmode))"
3368 {
3369   switch (which_alternative)
3370     {
3371     case 0:
3372     case 1:
3373       return output_387_reg_move (insn, operands);
3374
3375     case 2:
3376       return standard_80387_constant_opcode (operands[1]);
3377
3378     case 3:
3379     case 4:
3380       return "mov{l}\t{%1, %0|%0, %1}";
3381     case 5:
3382       if (get_attr_mode (insn) == MODE_TI)
3383         return "%vpxor\t%0, %d0";
3384       else
3385         return "%vxorps\t%0, %d0";
3386     case 6:
3387       if (get_attr_mode (insn) == MODE_V4SF)
3388         return "%vmovaps\t{%1, %0|%0, %1}";
3389       else
3390         return "%vmovss\t{%1, %d0|%d0, %1}";
3391     case 7:
3392       if (TARGET_AVX)
3393         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3394                                    : "vmovss\t{%1, %0|%0, %1}";
3395       else
3396         return "movss\t{%1, %0|%0, %1}";
3397     case 8:
3398       return "%vmovss\t{%1, %0|%0, %1}";
3399
3400     case 9: case 10: case 14: case 15:
3401       return "movd\t{%1, %0|%0, %1}";
3402     case 12: case 13:
3403       return "%vmovd\t{%1, %0|%0, %1}";
3404
3405     case 11:
3406       return "movq\t{%1, %0|%0, %1}";
3407
3408     default:
3409       gcc_unreachable ();
3410     }
3411 }
3412   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3413    (set (attr "prefix")
3414      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3415        (const_string "maybe_vex")
3416        (const_string "orig")))
3417    (set (attr "mode")
3418         (cond [(eq_attr "alternative" "3,4,9,10")
3419                  (const_string "SI")
3420                (eq_attr "alternative" "5")
3421                  (if_then_else
3422                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3423                                  (const_int 0))
3424                              (ne (symbol_ref "TARGET_SSE2")
3425                                  (const_int 0)))
3426                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3427                             (const_int 0)))
3428                    (const_string "TI")
3429                    (const_string "V4SF"))
3430                /* For architectures resolving dependencies on
3431                   whole SSE registers use APS move to break dependency
3432                   chains, otherwise use short move to avoid extra work.
3433
3434                   Do the same for architectures resolving dependencies on
3435                   the parts.  While in DF mode it is better to always handle
3436                   just register parts, the SF mode is different due to lack
3437                   of instructions to load just part of the register.  It is
3438                   better to maintain the whole registers in single format
3439                   to avoid problems on using packed logical operations.  */
3440                (eq_attr "alternative" "6")
3441                  (if_then_else
3442                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3443                             (const_int 0))
3444                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3445                             (const_int 0)))
3446                    (const_string "V4SF")
3447                    (const_string "SF"))
3448                (eq_attr "alternative" "11")
3449                  (const_string "DI")]
3450                (const_string "SF")))])
3451
3452 (define_split
3453   [(set (match_operand 0 "register_operand" "")
3454         (match_operand 1 "memory_operand" ""))]
3455   "reload_completed
3456    && MEM_P (operands[1])
3457    && (GET_MODE (operands[0]) == TFmode
3458        || GET_MODE (operands[0]) == XFmode
3459        || GET_MODE (operands[0]) == DFmode
3460        || GET_MODE (operands[0]) == SFmode)
3461    && (operands[2] = find_constant_src (insn))"
3462   [(set (match_dup 0) (match_dup 2))]
3463 {
3464   rtx c = operands[2];
3465   rtx r = operands[0];
3466
3467   if (GET_CODE (r) == SUBREG)
3468     r = SUBREG_REG (r);
3469
3470   if (SSE_REG_P (r))
3471     {
3472       if (!standard_sse_constant_p (c))
3473         FAIL;
3474     }
3475   else if (FP_REG_P (r))
3476     {
3477       if (!standard_80387_constant_p (c))
3478         FAIL;
3479     }
3480   else if (MMX_REG_P (r))
3481     FAIL;
3482 })
3483
3484 (define_split
3485   [(set (match_operand 0 "register_operand" "")
3486         (float_extend (match_operand 1 "memory_operand" "")))]
3487   "reload_completed
3488    && MEM_P (operands[1])
3489    && (GET_MODE (operands[0]) == TFmode
3490        || GET_MODE (operands[0]) == XFmode
3491        || GET_MODE (operands[0]) == DFmode
3492        || GET_MODE (operands[0]) == SFmode)
3493    && (operands[2] = find_constant_src (insn))"
3494   [(set (match_dup 0) (match_dup 2))]
3495 {
3496   rtx c = operands[2];
3497   rtx r = operands[0];
3498
3499   if (GET_CODE (r) == SUBREG)
3500     r = SUBREG_REG (r);
3501
3502   if (SSE_REG_P (r))
3503     {
3504       if (!standard_sse_constant_p (c))
3505         FAIL;
3506     }
3507   else if (FP_REG_P (r))
3508     {
3509       if (!standard_80387_constant_p (c))
3510         FAIL;
3511     }
3512   else if (MMX_REG_P (r))
3513     FAIL;
3514 })
3515
3516 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3517 (define_split
3518   [(set (match_operand:X87MODEF 0 "register_operand" "")
3519         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3520   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3521    && (standard_80387_constant_p (operands[1]) == 8
3522        || standard_80387_constant_p (operands[1]) == 9)"
3523   [(set (match_dup 0)(match_dup 1))
3524    (set (match_dup 0)
3525         (neg:X87MODEF (match_dup 0)))]
3526 {
3527   REAL_VALUE_TYPE r;
3528
3529   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3530   if (real_isnegzero (&r))
3531     operands[1] = CONST0_RTX (<MODE>mode);
3532   else
3533     operands[1] = CONST1_RTX (<MODE>mode);
3534 })
3535
3536 (define_insn "swapxf"
3537   [(set (match_operand:XF 0 "register_operand" "+f")
3538         (match_operand:XF 1 "register_operand" "+f"))
3539    (set (match_dup 1)
3540         (match_dup 0))]
3541   "TARGET_80387"
3542 {
3543   if (STACK_TOP_P (operands[0]))
3544     return "fxch\t%1";
3545   else
3546     return "fxch\t%0";
3547 }
3548   [(set_attr "type" "fxch")
3549    (set_attr "mode" "XF")])
3550
3551 (define_insn "*swap<mode>"
3552   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3553         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3554    (set (match_dup 1)
3555         (match_dup 0))]
3556   "TARGET_80387 || reload_completed"
3557 {
3558   if (STACK_TOP_P (operands[0]))
3559     return "fxch\t%1";
3560   else
3561     return "fxch\t%0";
3562 }
3563   [(set_attr "type" "fxch")
3564    (set_attr "mode" "<MODE>")])
3565 \f
3566 ;; Zero extension instructions
3567
3568 (define_expand "zero_extendsidi2"
3569   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3570         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3571   ""
3572 {
3573   if (!TARGET_64BIT)
3574     {
3575       emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3576       DONE;
3577     }
3578 })
3579
3580 (define_insn "*zero_extendsidi2_rex64"
3581   [(set (match_operand:DI 0 "nonimmediate_operand"  "=r,o,?*Ym,?*y,?*Yi,*Y2")
3582         (zero_extend:DI
3583          (match_operand:SI 1 "nonimmediate_operand" "rm,0,r   ,m  ,r   ,m")))]
3584   "TARGET_64BIT"
3585   "@
3586    mov\t{%k1, %k0|%k0, %k1}
3587    #
3588    movd\t{%1, %0|%0, %1}
3589    movd\t{%1, %0|%0, %1}
3590    %vmovd\t{%1, %0|%0, %1}
3591    %vmovd\t{%1, %0|%0, %1}"
3592   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3593    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3594    (set_attr "prefix_0f" "0,*,*,*,*,*")
3595    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3596
3597 (define_split
3598   [(set (match_operand:DI 0 "memory_operand" "")
3599         (zero_extend:DI (match_dup 0)))]
3600   "TARGET_64BIT"
3601   [(set (match_dup 4) (const_int 0))]
3602   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3603
3604 ;; %%% Kill me once multi-word ops are sane.
3605 (define_insn "zero_extendsidi2_1"
3606   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3607         (zero_extend:DI
3608          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3609    (clobber (reg:CC FLAGS_REG))]
3610   "!TARGET_64BIT"
3611   "@
3612    #
3613    #
3614    #
3615    movd\t{%1, %0|%0, %1}
3616    movd\t{%1, %0|%0, %1}
3617    %vmovd\t{%1, %0|%0, %1}
3618    %vmovd\t{%1, %0|%0, %1}"
3619   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3620    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3621    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3622
3623 (define_split
3624   [(set (match_operand:DI 0 "register_operand" "")
3625         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3626    (clobber (reg:CC FLAGS_REG))]
3627   "!TARGET_64BIT && reload_completed
3628    && true_regnum (operands[0]) == true_regnum (operands[1])"
3629   [(set (match_dup 4) (const_int 0))]
3630   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3631
3632 (define_split
3633   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3634         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3635    (clobber (reg:CC FLAGS_REG))]
3636   "!TARGET_64BIT && reload_completed
3637    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3638   [(set (match_dup 3) (match_dup 1))
3639    (set (match_dup 4) (const_int 0))]
3640   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3641
3642 (define_insn "zero_extend<mode>di2"
3643   [(set (match_operand:DI 0 "register_operand" "=r")
3644         (zero_extend:DI
3645          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3646   "TARGET_64BIT"
3647   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3648   [(set_attr "type" "imovx")
3649    (set_attr "mode" "SI")])
3650
3651 (define_expand "zero_extendhisi2"
3652   [(set (match_operand:SI 0 "register_operand" "")
3653         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3654   ""
3655 {
3656   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3657     {
3658       operands[1] = force_reg (HImode, operands[1]);
3659       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3660       DONE;
3661     }
3662 })
3663
3664 (define_insn_and_split "zero_extendhisi2_and"
3665   [(set (match_operand:SI 0 "register_operand" "=r")
3666         (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3667    (clobber (reg:CC FLAGS_REG))]
3668   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3669   "#"
3670   "&& reload_completed"
3671   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3672               (clobber (reg:CC FLAGS_REG))])]
3673   ""
3674   [(set_attr "type" "alu1")
3675    (set_attr "mode" "SI")])
3676
3677 (define_insn "*zero_extendhisi2_movzwl"
3678   [(set (match_operand:SI 0 "register_operand" "=r")
3679         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3680   "!TARGET_ZERO_EXTEND_WITH_AND
3681    || optimize_function_for_size_p (cfun)"
3682   "movz{wl|x}\t{%1, %0|%0, %1}"
3683   [(set_attr "type" "imovx")
3684    (set_attr "mode" "SI")])
3685
3686 (define_expand "zero_extendqi<mode>2"
3687   [(parallel
3688     [(set (match_operand:SWI24 0 "register_operand" "")
3689           (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3690      (clobber (reg:CC FLAGS_REG))])])
3691
3692 (define_insn "*zero_extendqi<mode>2_and"
3693   [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3694         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3695    (clobber (reg:CC FLAGS_REG))]
3696   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3697   "#"
3698   [(set_attr "type" "alu1")
3699    (set_attr "mode" "<MODE>")])
3700
3701 ;; When source and destination does not overlap, clear destination
3702 ;; first and then do the movb
3703 (define_split
3704   [(set (match_operand:SWI24 0 "register_operand" "")
3705         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3706    (clobber (reg:CC FLAGS_REG))]
3707   "reload_completed
3708    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3709    && ANY_QI_REG_P (operands[0])
3710    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3711    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3712   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3713 {
3714   operands[2] = gen_lowpart (QImode, operands[0]);
3715   ix86_expand_clear (operands[0]);
3716 })
3717
3718 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3719   [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3720         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3721    (clobber (reg:CC FLAGS_REG))]
3722   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3723   "#"
3724   [(set_attr "type" "imovx,alu1")
3725    (set_attr "mode" "<MODE>")])
3726
3727 ;; For the movzbl case strip only the clobber
3728 (define_split
3729   [(set (match_operand:SWI24 0 "register_operand" "")
3730         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3731    (clobber (reg:CC FLAGS_REG))]
3732   "reload_completed
3733    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3734    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3735   [(set (match_dup 0)
3736         (zero_extend:SWI24 (match_dup 1)))])
3737
3738 ; zero extend to SImode to avoid partial register stalls
3739 (define_insn "*zero_extendqi<mode>2_movzbl"
3740   [(set (match_operand:SWI24 0 "register_operand" "=r")
3741         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3742   "reload_completed
3743    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3744   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3745   [(set_attr "type" "imovx")
3746    (set_attr "mode" "SI")])
3747
3748 ;; Rest is handled by single and.
3749 (define_split
3750   [(set (match_operand:SWI24 0 "register_operand" "")
3751         (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3752    (clobber (reg:CC FLAGS_REG))]
3753   "reload_completed
3754    && true_regnum (operands[0]) == true_regnum (operands[1])"
3755   [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3756               (clobber (reg:CC FLAGS_REG))])])
3757 \f
3758 ;; Sign extension instructions
3759
3760 (define_expand "extendsidi2"
3761   [(set (match_operand:DI 0 "register_operand" "")
3762         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3763   ""
3764 {
3765   if (!TARGET_64BIT)
3766     {
3767       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3768       DONE;
3769     }
3770 })
3771
3772 (define_insn "*extendsidi2_rex64"
3773   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3774         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3775   "TARGET_64BIT"
3776   "@
3777    {cltq|cdqe}
3778    movs{lq|x}\t{%1, %0|%0, %1}"
3779   [(set_attr "type" "imovx")
3780    (set_attr "mode" "DI")
3781    (set_attr "prefix_0f" "0")
3782    (set_attr "modrm" "0,1")])
3783
3784 (define_insn "extendsidi2_1"
3785   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3786         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3787    (clobber (reg:CC FLAGS_REG))
3788    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3789   "!TARGET_64BIT"
3790   "#")
3791
3792 ;; Extend to memory case when source register does die.
3793 (define_split
3794   [(set (match_operand:DI 0 "memory_operand" "")
3795         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3796    (clobber (reg:CC FLAGS_REG))
3797    (clobber (match_operand:SI 2 "register_operand" ""))]
3798   "(reload_completed
3799     && dead_or_set_p (insn, operands[1])
3800     && !reg_mentioned_p (operands[1], operands[0]))"
3801   [(set (match_dup 3) (match_dup 1))
3802    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3803               (clobber (reg:CC FLAGS_REG))])
3804    (set (match_dup 4) (match_dup 1))]
3805   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3806
3807 ;; Extend to memory case when source register does not die.
3808 (define_split
3809   [(set (match_operand:DI 0 "memory_operand" "")
3810         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3811    (clobber (reg:CC FLAGS_REG))
3812    (clobber (match_operand:SI 2 "register_operand" ""))]
3813   "reload_completed"
3814   [(const_int 0)]
3815 {
3816   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3817
3818   emit_move_insn (operands[3], operands[1]);
3819
3820   /* Generate a cltd if possible and doing so it profitable.  */
3821   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3822       && true_regnum (operands[1]) == AX_REG
3823       && true_regnum (operands[2]) == DX_REG)
3824     {
3825       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3826     }
3827   else
3828     {
3829       emit_move_insn (operands[2], operands[1]);
3830       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3831     }
3832   emit_move_insn (operands[4], operands[2]);
3833   DONE;
3834 })
3835
3836 ;; Extend to register case.  Optimize case where source and destination
3837 ;; registers match and cases where we can use cltd.
3838 (define_split
3839   [(set (match_operand:DI 0 "register_operand" "")
3840         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3841    (clobber (reg:CC FLAGS_REG))
3842    (clobber (match_scratch:SI 2 ""))]
3843   "reload_completed"
3844   [(const_int 0)]
3845 {
3846   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3847
3848   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3849     emit_move_insn (operands[3], operands[1]);
3850
3851   /* Generate a cltd if possible and doing so it profitable.  */
3852   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3853       && true_regnum (operands[3]) == AX_REG
3854       && true_regnum (operands[4]) == DX_REG)
3855     {
3856       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3857       DONE;
3858     }
3859
3860   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3861     emit_move_insn (operands[4], operands[1]);
3862
3863   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3864   DONE;
3865 })
3866
3867 (define_insn "extend<mode>di2"
3868   [(set (match_operand:DI 0 "register_operand" "=r")
3869         (sign_extend:DI
3870          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3871   "TARGET_64BIT"
3872   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3873   [(set_attr "type" "imovx")
3874    (set_attr "mode" "DI")])
3875
3876 (define_insn "extendhisi2"
3877   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3878         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3879   ""
3880 {
3881   switch (get_attr_prefix_0f (insn))
3882     {
3883     case 0:
3884       return "{cwtl|cwde}";
3885     default:
3886       return "movs{wl|x}\t{%1, %0|%0, %1}";
3887     }
3888 }
3889   [(set_attr "type" "imovx")
3890    (set_attr "mode" "SI")
3891    (set (attr "prefix_0f")
3892      ;; movsx is short decodable while cwtl is vector decoded.
3893      (if_then_else (and (eq_attr "cpu" "!k6")
3894                         (eq_attr "alternative" "0"))
3895         (const_string "0")
3896         (const_string "1")))
3897    (set (attr "modrm")
3898      (if_then_else (eq_attr "prefix_0f" "0")
3899         (const_string "0")
3900         (const_string "1")))])
3901
3902 (define_insn "*extendhisi2_zext"
3903   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3904         (zero_extend:DI
3905          (sign_extend:SI
3906           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3907   "TARGET_64BIT"
3908 {
3909   switch (get_attr_prefix_0f (insn))
3910     {
3911     case 0:
3912       return "{cwtl|cwde}";
3913     default:
3914       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3915     }
3916 }
3917   [(set_attr "type" "imovx")
3918    (set_attr "mode" "SI")
3919    (set (attr "prefix_0f")
3920      ;; movsx is short decodable while cwtl is vector decoded.
3921      (if_then_else (and (eq_attr "cpu" "!k6")
3922                         (eq_attr "alternative" "0"))
3923         (const_string "0")
3924         (const_string "1")))
3925    (set (attr "modrm")
3926      (if_then_else (eq_attr "prefix_0f" "0")
3927         (const_string "0")
3928         (const_string "1")))])
3929
3930 (define_insn "extendqisi2"
3931   [(set (match_operand:SI 0 "register_operand" "=r")
3932         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3933   ""
3934   "movs{bl|x}\t{%1, %0|%0, %1}"
3935    [(set_attr "type" "imovx")
3936     (set_attr "mode" "SI")])
3937
3938 (define_insn "*extendqisi2_zext"
3939   [(set (match_operand:DI 0 "register_operand" "=r")
3940         (zero_extend:DI
3941           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3942   "TARGET_64BIT"
3943   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3944    [(set_attr "type" "imovx")
3945     (set_attr "mode" "SI")])
3946
3947 (define_insn "extendqihi2"
3948   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3949         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3950   ""
3951 {
3952   switch (get_attr_prefix_0f (insn))
3953     {
3954     case 0:
3955       return "{cbtw|cbw}";
3956     default:
3957       return "movs{bw|x}\t{%1, %0|%0, %1}";
3958     }
3959 }
3960   [(set_attr "type" "imovx")
3961    (set_attr "mode" "HI")
3962    (set (attr "prefix_0f")
3963      ;; movsx is short decodable while cwtl is vector decoded.
3964      (if_then_else (and (eq_attr "cpu" "!k6")
3965                         (eq_attr "alternative" "0"))
3966         (const_string "0")
3967         (const_string "1")))
3968    (set (attr "modrm")
3969      (if_then_else (eq_attr "prefix_0f" "0")
3970         (const_string "0")
3971         (const_string "1")))])
3972 \f
3973 ;; Conversions between float and double.
3974
3975 ;; These are all no-ops in the model used for the 80387.
3976 ;; So just emit moves.
3977
3978 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3979 (define_split
3980   [(set (match_operand:DF 0 "push_operand" "")
3981         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3982   "reload_completed"
3983   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3984    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3985
3986 (define_split
3987   [(set (match_operand:XF 0 "push_operand" "")
3988         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3989   "reload_completed"
3990   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3991    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3992   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3993
3994 (define_expand "extendsfdf2"
3995   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3996         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3997   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3998 {
3999   /* ??? Needed for compress_float_constant since all fp constants
4000      are LEGITIMATE_CONSTANT_P.  */
4001   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4002     {
4003       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4004           && standard_80387_constant_p (operands[1]) > 0)
4005         {
4006           operands[1] = simplify_const_unary_operation
4007             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4008           emit_move_insn_1 (operands[0], operands[1]);
4009           DONE;
4010         }
4011       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4012     }
4013 })
4014
4015 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4016    cvtss2sd:
4017       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4018       cvtps2pd xmm2,xmm1
4019    We do the conversion post reload to avoid producing of 128bit spills
4020    that might lead to ICE on 32bit target.  The sequence unlikely combine
4021    anyway.  */
4022 (define_split
4023   [(set (match_operand:DF 0 "register_operand" "")
4024         (float_extend:DF
4025           (match_operand:SF 1 "nonimmediate_operand" "")))]
4026   "TARGET_USE_VECTOR_FP_CONVERTS
4027    && optimize_insn_for_speed_p ()
4028    && reload_completed && SSE_REG_P (operands[0])"
4029    [(set (match_dup 2)
4030          (float_extend:V2DF
4031            (vec_select:V2SF
4032              (match_dup 3)
4033              (parallel [(const_int 0) (const_int 1)]))))]
4034 {
4035   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4036   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4037   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4038      Try to avoid move when unpacking can be done in source.  */
4039   if (REG_P (operands[1]))
4040     {
4041       /* If it is unsafe to overwrite upper half of source, we need
4042          to move to destination and unpack there.  */
4043       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4044            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4045           && true_regnum (operands[0]) != true_regnum (operands[1]))
4046         {
4047           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4048           emit_move_insn (tmp, operands[1]);
4049         }
4050       else
4051         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4052       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4053                                              operands[3]));
4054     }
4055   else
4056     emit_insn (gen_vec_setv4sf_0 (operands[3],
4057                                   CONST0_RTX (V4SFmode), operands[1]));
4058 })
4059
4060 (define_insn "*extendsfdf2_mixed"
4061   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4062         (float_extend:DF
4063           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4064   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4065 {
4066   switch (which_alternative)
4067     {
4068     case 0:
4069     case 1:
4070       return output_387_reg_move (insn, operands);
4071
4072     case 2:
4073       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4074
4075     default:
4076       gcc_unreachable ();
4077     }
4078 }
4079   [(set_attr "type" "fmov,fmov,ssecvt")
4080    (set_attr "prefix" "orig,orig,maybe_vex")
4081    (set_attr "mode" "SF,XF,DF")])
4082
4083 (define_insn "*extendsfdf2_sse"
4084   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4085         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4086   "TARGET_SSE2 && TARGET_SSE_MATH"
4087   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4088   [(set_attr "type" "ssecvt")
4089    (set_attr "prefix" "maybe_vex")
4090    (set_attr "mode" "DF")])
4091
4092 (define_insn "*extendsfdf2_i387"
4093   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4094         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4095   "TARGET_80387"
4096   "* return output_387_reg_move (insn, operands);"
4097   [(set_attr "type" "fmov")
4098    (set_attr "mode" "SF,XF")])
4099
4100 (define_expand "extend<mode>xf2"
4101   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4102         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4103   "TARGET_80387"
4104 {
4105   /* ??? Needed for compress_float_constant since all fp constants
4106      are LEGITIMATE_CONSTANT_P.  */
4107   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4108     {
4109       if (standard_80387_constant_p (operands[1]) > 0)
4110         {
4111           operands[1] = simplify_const_unary_operation
4112             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4113           emit_move_insn_1 (operands[0], operands[1]);
4114           DONE;
4115         }
4116       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4117     }
4118 })
4119
4120 (define_insn "*extend<mode>xf2_i387"
4121   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4122         (float_extend:XF
4123           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4124   "TARGET_80387"
4125   "* return output_387_reg_move (insn, operands);"
4126   [(set_attr "type" "fmov")
4127    (set_attr "mode" "<MODE>,XF")])
4128
4129 ;; %%% This seems bad bad news.
4130 ;; This cannot output into an f-reg because there is no way to be sure
4131 ;; of truncating in that case.  Otherwise this is just like a simple move
4132 ;; insn.  So we pretend we can output to a reg in order to get better
4133 ;; register preferencing, but we really use a stack slot.
4134
4135 ;; Conversion from DFmode to SFmode.
4136
4137 (define_expand "truncdfsf2"
4138   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4139         (float_truncate:SF
4140           (match_operand:DF 1 "nonimmediate_operand" "")))]
4141   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4142 {
4143   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4144     ;
4145   else if (flag_unsafe_math_optimizations)
4146     ;
4147   else
4148     {
4149       enum ix86_stack_slot slot = (virtuals_instantiated
4150                                    ? SLOT_TEMP
4151                                    : SLOT_VIRTUAL);
4152       rtx temp = assign_386_stack_local (SFmode, slot);
4153       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4154       DONE;
4155     }
4156 })
4157
4158 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4159    cvtsd2ss:
4160       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4161       cvtpd2ps xmm2,xmm1
4162    We do the conversion post reload to avoid producing of 128bit spills
4163    that might lead to ICE on 32bit target.  The sequence unlikely combine
4164    anyway.  */
4165 (define_split
4166   [(set (match_operand:SF 0 "register_operand" "")
4167         (float_truncate:SF
4168           (match_operand:DF 1 "nonimmediate_operand" "")))]
4169   "TARGET_USE_VECTOR_FP_CONVERTS
4170    && optimize_insn_for_speed_p ()
4171    && reload_completed && SSE_REG_P (operands[0])"
4172    [(set (match_dup 2)
4173          (vec_concat:V4SF
4174            (float_truncate:V2SF
4175              (match_dup 4))
4176            (match_dup 3)))]
4177 {
4178   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4179   operands[3] = CONST0_RTX (V2SFmode);
4180   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4181   /* Use movsd for loading from memory, unpcklpd for registers.
4182      Try to avoid move when unpacking can be done in source, or SSE3
4183      movddup is available.  */
4184   if (REG_P (operands[1]))
4185     {
4186       if (!TARGET_SSE3
4187           && true_regnum (operands[0]) != true_regnum (operands[1])
4188           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4189               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4190         {
4191           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4192           emit_move_insn (tmp, operands[1]);
4193           operands[1] = tmp;
4194         }
4195       else if (!TARGET_SSE3)
4196         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4197       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4198     }
4199   else
4200     emit_insn (gen_sse2_loadlpd (operands[4],
4201                                  CONST0_RTX (V2DFmode), operands[1]));
4202 })
4203
4204 (define_expand "truncdfsf2_with_temp"
4205   [(parallel [(set (match_operand:SF 0 "" "")
4206                    (float_truncate:SF (match_operand:DF 1 "" "")))
4207               (clobber (match_operand:SF 2 "" ""))])])
4208
4209 (define_insn "*truncdfsf_fast_mixed"
4210   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4211         (float_truncate:SF
4212           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4213   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4214 {
4215   switch (which_alternative)
4216     {
4217     case 0:
4218       return output_387_reg_move (insn, operands);
4219     case 1:
4220       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4221     default:
4222       gcc_unreachable ();
4223     }
4224 }
4225   [(set_attr "type" "fmov,ssecvt")
4226    (set_attr "prefix" "orig,maybe_vex")
4227    (set_attr "mode" "SF")])
4228
4229 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4230 ;; because nothing we do here is unsafe.
4231 (define_insn "*truncdfsf_fast_sse"
4232   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4233         (float_truncate:SF
4234           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4235   "TARGET_SSE2 && TARGET_SSE_MATH"
4236   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4237   [(set_attr "type" "ssecvt")
4238    (set_attr "prefix" "maybe_vex")
4239    (set_attr "mode" "SF")])
4240
4241 (define_insn "*truncdfsf_fast_i387"
4242   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4243         (float_truncate:SF
4244           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4245   "TARGET_80387 && flag_unsafe_math_optimizations"
4246   "* return output_387_reg_move (insn, operands);"
4247   [(set_attr "type" "fmov")
4248    (set_attr "mode" "SF")])
4249
4250 (define_insn "*truncdfsf_mixed"
4251   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4252         (float_truncate:SF
4253           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4254    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4255   "TARGET_MIX_SSE_I387"
4256 {
4257   switch (which_alternative)
4258     {
4259     case 0:
4260       return output_387_reg_move (insn, operands);
4261     case 1:
4262       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4263
4264     default:
4265       return "#";
4266     }
4267 }
4268   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4269    (set_attr "unit" "*,*,i387,i387,i387")
4270    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4271    (set_attr "mode" "SF")])
4272
4273 (define_insn "*truncdfsf_i387"
4274   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4275         (float_truncate:SF
4276           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4277    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4278   "TARGET_80387"
4279 {
4280   switch (which_alternative)
4281     {
4282     case 0:
4283       return output_387_reg_move (insn, operands);
4284
4285     default:
4286       return "#";
4287     }
4288 }
4289   [(set_attr "type" "fmov,multi,multi,multi")
4290    (set_attr "unit" "*,i387,i387,i387")
4291    (set_attr "mode" "SF")])
4292
4293 (define_insn "*truncdfsf2_i387_1"
4294   [(set (match_operand:SF 0 "memory_operand" "=m")
4295         (float_truncate:SF
4296           (match_operand:DF 1 "register_operand" "f")))]
4297   "TARGET_80387
4298    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4299    && !TARGET_MIX_SSE_I387"
4300   "* return output_387_reg_move (insn, operands);"
4301   [(set_attr "type" "fmov")
4302    (set_attr "mode" "SF")])
4303
4304 (define_split
4305   [(set (match_operand:SF 0 "register_operand" "")
4306         (float_truncate:SF
4307          (match_operand:DF 1 "fp_register_operand" "")))
4308    (clobber (match_operand 2 "" ""))]
4309   "reload_completed"
4310   [(set (match_dup 2) (match_dup 1))
4311    (set (match_dup 0) (match_dup 2))]
4312   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4313
4314 ;; Conversion from XFmode to {SF,DF}mode
4315
4316 (define_expand "truncxf<mode>2"
4317   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4318                    (float_truncate:MODEF
4319                      (match_operand:XF 1 "register_operand" "")))
4320               (clobber (match_dup 2))])]
4321   "TARGET_80387"
4322 {
4323   if (flag_unsafe_math_optimizations)
4324     {
4325       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4326       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4327       if (reg != operands[0])
4328         emit_move_insn (operands[0], reg);
4329       DONE;
4330     }
4331   else
4332     {
4333       enum ix86_stack_slot slot = (virtuals_instantiated
4334                                    ? SLOT_TEMP
4335                                    : SLOT_VIRTUAL);
4336       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4337     }
4338 })
4339
4340 (define_insn "*truncxfsf2_mixed"
4341   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4342         (float_truncate:SF
4343           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4344    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4345   "TARGET_80387"
4346 {
4347   gcc_assert (!which_alternative);
4348   return output_387_reg_move (insn, operands);
4349 }
4350   [(set_attr "type" "fmov,multi,multi,multi")
4351    (set_attr "unit" "*,i387,i387,i387")
4352    (set_attr "mode" "SF")])
4353
4354 (define_insn "*truncxfdf2_mixed"
4355   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4356         (float_truncate:DF
4357           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4358    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4359   "TARGET_80387"
4360 {
4361   gcc_assert (!which_alternative);
4362   return output_387_reg_move (insn, operands);
4363 }
4364   [(set_attr "type" "fmov,multi,multi,multi")
4365    (set_attr "unit" "*,i387,i387,i387")
4366    (set_attr "mode" "DF")])
4367
4368 (define_insn "truncxf<mode>2_i387_noop"
4369   [(set (match_operand:MODEF 0 "register_operand" "=f")
4370         (float_truncate:MODEF
4371           (match_operand:XF 1 "register_operand" "f")))]
4372   "TARGET_80387 && flag_unsafe_math_optimizations"
4373   "* return output_387_reg_move (insn, operands);"
4374   [(set_attr "type" "fmov")
4375    (set_attr "mode" "<MODE>")])
4376
4377 (define_insn "*truncxf<mode>2_i387"
4378   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4379         (float_truncate:MODEF
4380           (match_operand:XF 1 "register_operand" "f")))]
4381   "TARGET_80387"
4382   "* return output_387_reg_move (insn, operands);"
4383   [(set_attr "type" "fmov")
4384    (set_attr "mode" "<MODE>")])
4385
4386 (define_split
4387   [(set (match_operand:MODEF 0 "register_operand" "")
4388         (float_truncate:MODEF
4389           (match_operand:XF 1 "register_operand" "")))
4390    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4391   "TARGET_80387 && reload_completed"
4392   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4393    (set (match_dup 0) (match_dup 2))])
4394
4395 (define_split
4396   [(set (match_operand:MODEF 0 "memory_operand" "")
4397         (float_truncate:MODEF
4398           (match_operand:XF 1 "register_operand" "")))
4399    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4400   "TARGET_80387"
4401   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4402 \f
4403 ;; Signed conversion to DImode.
4404
4405 (define_expand "fix_truncxfdi2"
4406   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4407                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4408               (clobber (reg:CC FLAGS_REG))])]
4409   "TARGET_80387"
4410 {
4411   if (TARGET_FISTTP)
4412    {
4413      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4414      DONE;
4415    }
4416 })
4417
4418 (define_expand "fix_trunc<mode>di2"
4419   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4420                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4421               (clobber (reg:CC FLAGS_REG))])]
4422   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4423 {
4424   if (TARGET_FISTTP
4425       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4426    {
4427      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4428      DONE;
4429    }
4430   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4431    {
4432      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4433      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4434      if (out != operands[0])
4435         emit_move_insn (operands[0], out);
4436      DONE;
4437    }
4438 })
4439
4440 ;; Signed conversion to SImode.
4441
4442 (define_expand "fix_truncxfsi2"
4443   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4444                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4445               (clobber (reg:CC FLAGS_REG))])]
4446   "TARGET_80387"
4447 {
4448   if (TARGET_FISTTP)
4449    {
4450      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4451      DONE;
4452    }
4453 })
4454
4455 (define_expand "fix_trunc<mode>si2"
4456   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4457                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4458               (clobber (reg:CC FLAGS_REG))])]
4459   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4460 {
4461   if (TARGET_FISTTP
4462       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4463    {
4464      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4465      DONE;
4466    }
4467   if (SSE_FLOAT_MODE_P (<MODE>mode))
4468    {
4469      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4470      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4471      if (out != operands[0])
4472         emit_move_insn (operands[0], out);
4473      DONE;
4474    }
4475 })
4476
4477 ;; Signed conversion to HImode.
4478
4479 (define_expand "fix_trunc<mode>hi2"
4480   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4481                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4482               (clobber (reg:CC FLAGS_REG))])]
4483   "TARGET_80387
4484    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4485 {
4486   if (TARGET_FISTTP)
4487    {
4488      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4489      DONE;
4490    }
4491 })
4492
4493 ;; Unsigned conversion to SImode.
4494
4495 (define_expand "fixuns_trunc<mode>si2"
4496   [(parallel
4497     [(set (match_operand:SI 0 "register_operand" "")
4498           (unsigned_fix:SI
4499             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4500      (use (match_dup 2))
4501      (clobber (match_scratch:<ssevecmode> 3 ""))
4502      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4503   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4504 {
4505   enum machine_mode mode = <MODE>mode;
4506   enum machine_mode vecmode = <ssevecmode>mode;
4507   REAL_VALUE_TYPE TWO31r;
4508   rtx two31;
4509
4510   if (optimize_insn_for_size_p ())
4511     FAIL;
4512
4513   real_ldexp (&TWO31r, &dconst1, 31);
4514   two31 = const_double_from_real_value (TWO31r, mode);
4515   two31 = ix86_build_const_vector (mode, true, two31);
4516   operands[2] = force_reg (vecmode, two31);
4517 })
4518
4519 (define_insn_and_split "*fixuns_trunc<mode>_1"
4520   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4521         (unsigned_fix:SI
4522           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4523    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4524    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4525    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4526   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4527    && optimize_function_for_speed_p (cfun)"
4528   "#"
4529   "&& reload_completed"
4530   [(const_int 0)]
4531 {
4532   ix86_split_convert_uns_si_sse (operands);
4533   DONE;
4534 })
4535
4536 ;; Unsigned conversion to HImode.
4537 ;; Without these patterns, we'll try the unsigned SI conversion which
4538 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4539
4540 (define_expand "fixuns_trunc<mode>hi2"
4541   [(set (match_dup 2)
4542         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4543    (set (match_operand:HI 0 "nonimmediate_operand" "")
4544         (subreg:HI (match_dup 2) 0))]
4545   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4546   "operands[2] = gen_reg_rtx (SImode);")
4547
4548 ;; When SSE is available, it is always faster to use it!
4549 (define_insn "fix_trunc<mode>di_sse"
4550   [(set (match_operand:DI 0 "register_operand" "=r,r")
4551         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4552   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4553    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4554   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4555   [(set_attr "type" "sseicvt")
4556    (set_attr "prefix" "maybe_vex")
4557    (set_attr "prefix_rex" "1")
4558    (set_attr "mode" "<MODE>")
4559    (set_attr "athlon_decode" "double,vector")
4560    (set_attr "amdfam10_decode" "double,double")])
4561
4562 (define_insn "fix_trunc<mode>si_sse"
4563   [(set (match_operand:SI 0 "register_operand" "=r,r")
4564         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4565   "SSE_FLOAT_MODE_P (<MODE>mode)
4566    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4567   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4568   [(set_attr "type" "sseicvt")
4569    (set_attr "prefix" "maybe_vex")
4570    (set_attr "mode" "<MODE>")
4571    (set_attr "athlon_decode" "double,vector")
4572    (set_attr "amdfam10_decode" "double,double")])
4573
4574 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4575 (define_peephole2
4576   [(set (match_operand:MODEF 0 "register_operand" "")
4577         (match_operand:MODEF 1 "memory_operand" ""))
4578    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4579         (fix:SSEMODEI24 (match_dup 0)))]
4580   "TARGET_SHORTEN_X87_SSE
4581    && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4582    && peep2_reg_dead_p (2, operands[0])"
4583   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
4584
4585 ;; Avoid vector decoded forms of the instruction.
4586 (define_peephole2
4587   [(match_scratch:DF 2 "Y2")
4588    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4589         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4590   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4591   [(set (match_dup 2) (match_dup 1))
4592    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4593
4594 (define_peephole2
4595   [(match_scratch:SF 2 "x")
4596    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4597         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4598   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4599   [(set (match_dup 2) (match_dup 1))
4600    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4601
4602 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4603   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4604         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4605   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4606    && TARGET_FISTTP
4607    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4608          && (TARGET_64BIT || <MODE>mode != DImode))
4609         && TARGET_SSE_MATH)
4610    && can_create_pseudo_p ()"
4611   "#"
4612   "&& 1"
4613   [(const_int 0)]
4614 {
4615   if (memory_operand (operands[0], VOIDmode))
4616     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4617   else
4618     {
4619       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4620       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4621                                                             operands[1],
4622                                                             operands[2]));
4623     }
4624   DONE;
4625 }
4626   [(set_attr "type" "fisttp")
4627    (set_attr "mode" "<MODE>")])
4628
4629 (define_insn "fix_trunc<mode>_i387_fisttp"
4630   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4631         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4632    (clobber (match_scratch:XF 2 "=&1f"))]
4633   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4634    && TARGET_FISTTP
4635    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4636          && (TARGET_64BIT || <MODE>mode != DImode))
4637         && TARGET_SSE_MATH)"
4638   "* return output_fix_trunc (insn, operands, 1);"
4639   [(set_attr "type" "fisttp")
4640    (set_attr "mode" "<MODE>")])
4641
4642 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4643   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4644         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4645    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4646    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4647   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4648    && TARGET_FISTTP
4649    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4650         && (TARGET_64BIT || <MODE>mode != DImode))
4651         && TARGET_SSE_MATH)"
4652   "#"
4653   [(set_attr "type" "fisttp")
4654    (set_attr "mode" "<MODE>")])
4655
4656 (define_split
4657   [(set (match_operand:X87MODEI 0 "register_operand" "")
4658         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4659    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4660    (clobber (match_scratch 3 ""))]
4661   "reload_completed"
4662   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4663               (clobber (match_dup 3))])
4664    (set (match_dup 0) (match_dup 2))])
4665
4666 (define_split
4667   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4668         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4669    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4670    (clobber (match_scratch 3 ""))]
4671   "reload_completed"
4672   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4673               (clobber (match_dup 3))])])
4674
4675 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4676 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4677 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4678 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4679 ;; function in i386.c.
4680 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4681   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4682         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4683    (clobber (reg:CC FLAGS_REG))]
4684   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4685    && !TARGET_FISTTP
4686    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4687          && (TARGET_64BIT || <MODE>mode != DImode))
4688    && can_create_pseudo_p ()"
4689   "#"
4690   "&& 1"
4691   [(const_int 0)]
4692 {
4693   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4694
4695   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4696   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4697   if (memory_operand (operands[0], VOIDmode))
4698     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4699                                          operands[2], operands[3]));
4700   else
4701     {
4702       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4703       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4704                                                      operands[2], operands[3],
4705                                                      operands[4]));
4706     }
4707   DONE;
4708 }
4709   [(set_attr "type" "fistp")
4710    (set_attr "i387_cw" "trunc")
4711    (set_attr "mode" "<MODE>")])
4712
4713 (define_insn "fix_truncdi_i387"
4714   [(set (match_operand:DI 0 "memory_operand" "=m")
4715         (fix:DI (match_operand 1 "register_operand" "f")))
4716    (use (match_operand:HI 2 "memory_operand" "m"))
4717    (use (match_operand:HI 3 "memory_operand" "m"))
4718    (clobber (match_scratch:XF 4 "=&1f"))]
4719   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4720    && !TARGET_FISTTP
4721    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4722   "* return output_fix_trunc (insn, operands, 0);"
4723   [(set_attr "type" "fistp")
4724    (set_attr "i387_cw" "trunc")
4725    (set_attr "mode" "DI")])
4726
4727 (define_insn "fix_truncdi_i387_with_temp"
4728   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4729         (fix:DI (match_operand 1 "register_operand" "f,f")))
4730    (use (match_operand:HI 2 "memory_operand" "m,m"))
4731    (use (match_operand:HI 3 "memory_operand" "m,m"))
4732    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4733    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4734   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4735    && !TARGET_FISTTP
4736    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4737   "#"
4738   [(set_attr "type" "fistp")
4739    (set_attr "i387_cw" "trunc")
4740    (set_attr "mode" "DI")])
4741
4742 (define_split
4743   [(set (match_operand:DI 0 "register_operand" "")
4744         (fix:DI (match_operand 1 "register_operand" "")))
4745    (use (match_operand:HI 2 "memory_operand" ""))
4746    (use (match_operand:HI 3 "memory_operand" ""))
4747    (clobber (match_operand:DI 4 "memory_operand" ""))
4748    (clobber (match_scratch 5 ""))]
4749   "reload_completed"
4750   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4751               (use (match_dup 2))
4752               (use (match_dup 3))
4753               (clobber (match_dup 5))])
4754    (set (match_dup 0) (match_dup 4))])
4755
4756 (define_split
4757   [(set (match_operand:DI 0 "memory_operand" "")
4758         (fix:DI (match_operand 1 "register_operand" "")))
4759    (use (match_operand:HI 2 "memory_operand" ""))
4760    (use (match_operand:HI 3 "memory_operand" ""))
4761    (clobber (match_operand:DI 4 "memory_operand" ""))
4762    (clobber (match_scratch 5 ""))]
4763   "reload_completed"
4764   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4765               (use (match_dup 2))
4766               (use (match_dup 3))
4767               (clobber (match_dup 5))])])
4768
4769 (define_insn "fix_trunc<mode>_i387"
4770   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4771         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4772    (use (match_operand:HI 2 "memory_operand" "m"))
4773    (use (match_operand:HI 3 "memory_operand" "m"))]
4774   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4775    && !TARGET_FISTTP
4776    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4777   "* return output_fix_trunc (insn, operands, 0);"
4778   [(set_attr "type" "fistp")
4779    (set_attr "i387_cw" "trunc")
4780    (set_attr "mode" "<MODE>")])
4781
4782 (define_insn "fix_trunc<mode>_i387_with_temp"
4783   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4784         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4785    (use (match_operand:HI 2 "memory_operand" "m,m"))
4786    (use (match_operand:HI 3 "memory_operand" "m,m"))
4787    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4788   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4789    && !TARGET_FISTTP
4790    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4791   "#"
4792   [(set_attr "type" "fistp")
4793    (set_attr "i387_cw" "trunc")
4794    (set_attr "mode" "<MODE>")])
4795
4796 (define_split
4797   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4798         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4799    (use (match_operand:HI 2 "memory_operand" ""))
4800    (use (match_operand:HI 3 "memory_operand" ""))
4801    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4802   "reload_completed"
4803   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4804               (use (match_dup 2))
4805               (use (match_dup 3))])
4806    (set (match_dup 0) (match_dup 4))])
4807
4808 (define_split
4809   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4810         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4811    (use (match_operand:HI 2 "memory_operand" ""))
4812    (use (match_operand:HI 3 "memory_operand" ""))
4813    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4814   "reload_completed"
4815   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4816               (use (match_dup 2))
4817               (use (match_dup 3))])])
4818
4819 (define_insn "x86_fnstcw_1"
4820   [(set (match_operand:HI 0 "memory_operand" "=m")
4821         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4822   "TARGET_80387"
4823   "fnstcw\t%0"
4824   [(set (attr "length")
4825         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4826    (set_attr "mode" "HI")
4827    (set_attr "unit" "i387")])
4828
4829 (define_insn "x86_fldcw_1"
4830   [(set (reg:HI FPCR_REG)
4831         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4832   "TARGET_80387"
4833   "fldcw\t%0"
4834   [(set (attr "length")
4835         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4836    (set_attr "mode" "HI")
4837    (set_attr "unit" "i387")
4838    (set_attr "athlon_decode" "vector")
4839    (set_attr "amdfam10_decode" "vector")])
4840 \f
4841 ;; Conversion between fixed point and floating point.
4842
4843 ;; Even though we only accept memory inputs, the backend _really_
4844 ;; wants to be able to do this between registers.
4845
4846 (define_expand "floathi<mode>2"
4847   [(set (match_operand:X87MODEF 0 "register_operand" "")
4848         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4849   "TARGET_80387
4850    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4851        || TARGET_MIX_SSE_I387)")
4852
4853 ;; Pre-reload splitter to add memory clobber to the pattern.
4854 (define_insn_and_split "*floathi<mode>2_1"
4855   [(set (match_operand:X87MODEF 0 "register_operand" "")
4856         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4857   "TARGET_80387
4858    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4859        || TARGET_MIX_SSE_I387)
4860    && can_create_pseudo_p ()"
4861   "#"
4862   "&& 1"
4863   [(parallel [(set (match_dup 0)
4864               (float:X87MODEF (match_dup 1)))
4865    (clobber (match_dup 2))])]
4866   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4867
4868 (define_insn "*floathi<mode>2_i387_with_temp"
4869   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4870         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4871   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4872   "TARGET_80387
4873    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4874        || TARGET_MIX_SSE_I387)"
4875   "#"
4876   [(set_attr "type" "fmov,multi")
4877    (set_attr "mode" "<MODE>")
4878    (set_attr "unit" "*,i387")
4879    (set_attr "fp_int_src" "true")])
4880
4881 (define_insn "*floathi<mode>2_i387"
4882   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4883         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4884   "TARGET_80387
4885    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4886        || TARGET_MIX_SSE_I387)"
4887   "fild%Z1\t%1"
4888   [(set_attr "type" "fmov")
4889    (set_attr "mode" "<MODE>")
4890    (set_attr "fp_int_src" "true")])
4891
4892 (define_split
4893   [(set (match_operand:X87MODEF 0 "register_operand" "")
4894         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4895    (clobber (match_operand:HI 2 "memory_operand" ""))]
4896   "TARGET_80387
4897    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4898        || TARGET_MIX_SSE_I387)
4899    && reload_completed"
4900   [(set (match_dup 2) (match_dup 1))
4901    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4902
4903 (define_split
4904   [(set (match_operand:X87MODEF 0 "register_operand" "")
4905         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4906    (clobber (match_operand:HI 2 "memory_operand" ""))]
4907    "TARGET_80387
4908     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4909         || TARGET_MIX_SSE_I387)
4910     && reload_completed"
4911   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4912
4913 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4914   [(set (match_operand:X87MODEF 0 "register_operand" "")
4915         (float:X87MODEF
4916           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4917   "TARGET_80387
4918    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4919        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4920 {
4921   if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4922         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4923       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
4924     {
4925       rtx reg = gen_reg_rtx (XFmode);
4926       rtx insn;
4927
4928       emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
4929
4930       if (<X87MODEF:MODE>mode == SFmode)
4931         insn = gen_truncxfsf2 (operands[0], reg);
4932       else if (<X87MODEF:MODE>mode == DFmode)
4933         insn = gen_truncxfdf2 (operands[0], reg);
4934       else
4935         gcc_unreachable ();
4936
4937       emit_insn (insn);
4938       DONE;
4939     }
4940 })
4941
4942 ;; Pre-reload splitter to add memory clobber to the pattern.
4943 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4944   [(set (match_operand:X87MODEF 0 "register_operand" "")
4945         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4946   "((TARGET_80387
4947      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
4948      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4949            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4950          || TARGET_MIX_SSE_I387))
4951     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4952         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4953         && ((<SSEMODEI24:MODE>mode == SImode
4954              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4955              && optimize_function_for_speed_p (cfun)
4956              && flag_trapping_math)
4957             || !(TARGET_INTER_UNIT_CONVERSIONS
4958                  || optimize_function_for_size_p (cfun)))))
4959    && can_create_pseudo_p ()"
4960   "#"
4961   "&& 1"
4962   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4963               (clobber (match_dup 2))])]
4964 {
4965   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4966
4967   /* Avoid store forwarding (partial memory) stall penalty
4968      by passing DImode value through XMM registers.  */
4969   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
4970       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4971       && optimize_function_for_speed_p (cfun))
4972     {
4973       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4974                                                             operands[1],
4975                                                             operands[2]));
4976       DONE;
4977     }
4978 })
4979
4980 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4981   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4982         (float:MODEF
4983           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4984    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4985   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4986    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4987   "#"
4988   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4989    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4990    (set_attr "unit" "*,i387,*,*,*")
4991    (set_attr "athlon_decode" "*,*,double,direct,double")
4992    (set_attr "amdfam10_decode" "*,*,vector,double,double")
4993    (set_attr "fp_int_src" "true")])
4994
4995 (define_insn "*floatsi<mode>2_vector_mixed"
4996   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4997         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4998   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4999    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5000   "@
5001    fild%Z1\t%1
5002    #"
5003   [(set_attr "type" "fmov,sseicvt")
5004    (set_attr "mode" "<MODE>,<ssevecmode>")
5005    (set_attr "unit" "i387,*")
5006    (set_attr "athlon_decode" "*,direct")
5007    (set_attr "amdfam10_decode" "*,double")
5008    (set_attr "fp_int_src" "true")])
5009
5010 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5011   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5012         (float:MODEF
5013           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5014   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5015   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5016    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5017   "#"
5018   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5019    (set_attr "mode" "<MODEF:MODE>")
5020    (set_attr "unit" "*,i387,*,*")
5021    (set_attr "athlon_decode" "*,*,double,direct")
5022    (set_attr "amdfam10_decode" "*,*,vector,double")
5023    (set_attr "fp_int_src" "true")])
5024
5025 (define_split
5026   [(set (match_operand:MODEF 0 "register_operand" "")
5027         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5028    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5029   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5030    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5031    && TARGET_INTER_UNIT_CONVERSIONS
5032    && reload_completed
5033    && (SSE_REG_P (operands[0])
5034        || (GET_CODE (operands[0]) == SUBREG
5035            && SSE_REG_P (operands[0])))"
5036   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5037
5038 (define_split
5039   [(set (match_operand:MODEF 0 "register_operand" "")
5040         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5041    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5042   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5043    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5044    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5045    && reload_completed
5046    && (SSE_REG_P (operands[0])
5047        || (GET_CODE (operands[0]) == SUBREG
5048            && SSE_REG_P (operands[0])))"
5049   [(set (match_dup 2) (match_dup 1))
5050    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5051
5052 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5053   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5054         (float:MODEF
5055           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5056   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5057    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5058    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5059   "@
5060    fild%Z1\t%1
5061    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5062    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5063   [(set_attr "type" "fmov,sseicvt,sseicvt")
5064    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5065    (set_attr "mode" "<MODEF:MODE>")
5066    (set (attr "prefix_rex")
5067      (if_then_else
5068        (and (eq_attr "prefix" "maybe_vex")
5069             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5070        (const_string "1")
5071        (const_string "*")))
5072    (set_attr "unit" "i387,*,*")
5073    (set_attr "athlon_decode" "*,double,direct")
5074    (set_attr "amdfam10_decode" "*,vector,double")
5075    (set_attr "fp_int_src" "true")])
5076
5077 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5078   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5079         (float:MODEF
5080           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5081   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5082    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5083    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5084   "@
5085    fild%Z1\t%1
5086    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5087   [(set_attr "type" "fmov,sseicvt")
5088    (set_attr "prefix" "orig,maybe_vex")
5089    (set_attr "mode" "<MODEF:MODE>")
5090    (set (attr "prefix_rex")
5091      (if_then_else
5092        (and (eq_attr "prefix" "maybe_vex")
5093             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5094        (const_string "1")
5095        (const_string "*")))
5096    (set_attr "athlon_decode" "*,direct")
5097    (set_attr "amdfam10_decode" "*,double")
5098    (set_attr "fp_int_src" "true")])
5099
5100 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5101   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5102         (float:MODEF
5103           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5104    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5105   "TARGET_SSE2 && TARGET_SSE_MATH
5106    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5107   "#"
5108   [(set_attr "type" "sseicvt")
5109    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5110    (set_attr "athlon_decode" "double,direct,double")
5111    (set_attr "amdfam10_decode" "vector,double,double")
5112    (set_attr "fp_int_src" "true")])
5113
5114 (define_insn "*floatsi<mode>2_vector_sse"
5115   [(set (match_operand:MODEF 0 "register_operand" "=x")
5116         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5117   "TARGET_SSE2 && TARGET_SSE_MATH
5118    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5119   "#"
5120   [(set_attr "type" "sseicvt")
5121    (set_attr "mode" "<MODE>")
5122    (set_attr "athlon_decode" "direct")
5123    (set_attr "amdfam10_decode" "double")
5124    (set_attr "fp_int_src" "true")])
5125
5126 (define_split
5127   [(set (match_operand:MODEF 0 "register_operand" "")
5128         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5129    (clobber (match_operand:SI 2 "memory_operand" ""))]
5130   "TARGET_SSE2 && TARGET_SSE_MATH
5131    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5132    && reload_completed
5133    && (SSE_REG_P (operands[0])
5134        || (GET_CODE (operands[0]) == SUBREG
5135            && SSE_REG_P (operands[0])))"
5136   [(const_int 0)]
5137 {
5138   rtx op1 = operands[1];
5139
5140   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5141                                      <MODE>mode, 0);
5142   if (GET_CODE (op1) == SUBREG)
5143     op1 = SUBREG_REG (op1);
5144
5145   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5146     {
5147       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5148       emit_insn (gen_sse2_loadld (operands[4],
5149                                   CONST0_RTX (V4SImode), operands[1]));
5150     }
5151   /* We can ignore possible trapping value in the
5152      high part of SSE register for non-trapping math. */
5153   else if (SSE_REG_P (op1) && !flag_trapping_math)
5154     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5155   else
5156     {
5157       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5158       emit_move_insn (operands[2], operands[1]);
5159       emit_insn (gen_sse2_loadld (operands[4],
5160                                   CONST0_RTX (V4SImode), operands[2]));
5161     }
5162   emit_insn
5163     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5164   DONE;
5165 })
5166
5167 (define_split
5168   [(set (match_operand:MODEF 0 "register_operand" "")
5169         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5170    (clobber (match_operand:SI 2 "memory_operand" ""))]
5171   "TARGET_SSE2 && TARGET_SSE_MATH
5172    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5173    && reload_completed
5174    && (SSE_REG_P (operands[0])
5175        || (GET_CODE (operands[0]) == SUBREG
5176            && SSE_REG_P (operands[0])))"
5177   [(const_int 0)]
5178 {
5179   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5180                                      <MODE>mode, 0);
5181   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5182
5183   emit_insn (gen_sse2_loadld (operands[4],
5184                               CONST0_RTX (V4SImode), operands[1]));
5185   emit_insn
5186     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5187   DONE;
5188 })
5189
5190 (define_split
5191   [(set (match_operand:MODEF 0 "register_operand" "")
5192         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5193   "TARGET_SSE2 && TARGET_SSE_MATH
5194    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5195    && reload_completed
5196    && (SSE_REG_P (operands[0])
5197        || (GET_CODE (operands[0]) == SUBREG
5198            && SSE_REG_P (operands[0])))"
5199   [(const_int 0)]
5200 {
5201   rtx op1 = operands[1];
5202
5203   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5204                                      <MODE>mode, 0);
5205   if (GET_CODE (op1) == SUBREG)
5206     op1 = SUBREG_REG (op1);
5207
5208   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5209     {
5210       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5211       emit_insn (gen_sse2_loadld (operands[4],
5212                                   CONST0_RTX (V4SImode), operands[1]));
5213     }
5214   /* We can ignore possible trapping value in the
5215      high part of SSE register for non-trapping math. */
5216   else if (SSE_REG_P (op1) && !flag_trapping_math)
5217     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5218   else
5219     gcc_unreachable ();
5220   emit_insn
5221     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5222   DONE;
5223 })
5224
5225 (define_split
5226   [(set (match_operand:MODEF 0 "register_operand" "")
5227         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5228   "TARGET_SSE2 && TARGET_SSE_MATH
5229    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5230    && reload_completed
5231    && (SSE_REG_P (operands[0])
5232        || (GET_CODE (operands[0]) == SUBREG
5233            && SSE_REG_P (operands[0])))"
5234   [(const_int 0)]
5235 {
5236   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5237                                      <MODE>mode, 0);
5238   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5239
5240   emit_insn (gen_sse2_loadld (operands[4],
5241                               CONST0_RTX (V4SImode), operands[1]));
5242   emit_insn
5243     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5244   DONE;
5245 })
5246
5247 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5248   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5249         (float:MODEF
5250           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5251   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5252   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5253    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5254   "#"
5255   [(set_attr "type" "sseicvt")
5256    (set_attr "mode" "<MODEF:MODE>")
5257    (set_attr "athlon_decode" "double,direct")
5258    (set_attr "amdfam10_decode" "vector,double")
5259    (set_attr "fp_int_src" "true")])
5260
5261 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5262   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5263         (float:MODEF
5264           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5265   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5266    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5267    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5268   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5269   [(set_attr "type" "sseicvt")
5270    (set_attr "prefix" "maybe_vex")
5271    (set_attr "mode" "<MODEF:MODE>")
5272    (set (attr "prefix_rex")
5273      (if_then_else
5274        (and (eq_attr "prefix" "maybe_vex")
5275             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5276        (const_string "1")
5277        (const_string "*")))
5278    (set_attr "athlon_decode" "double,direct")
5279    (set_attr "amdfam10_decode" "vector,double")
5280    (set_attr "fp_int_src" "true")])
5281
5282 (define_split
5283   [(set (match_operand:MODEF 0 "register_operand" "")
5284         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5285    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5286   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5287    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5288    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5289    && reload_completed
5290    && (SSE_REG_P (operands[0])
5291        || (GET_CODE (operands[0]) == SUBREG
5292            && SSE_REG_P (operands[0])))"
5293   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5294
5295 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5296   [(set (match_operand:MODEF 0 "register_operand" "=x")
5297         (float:MODEF
5298           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5299   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5300    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5301    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5302   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5303   [(set_attr "type" "sseicvt")
5304    (set_attr "prefix" "maybe_vex")
5305    (set_attr "mode" "<MODEF:MODE>")
5306    (set (attr "prefix_rex")
5307      (if_then_else
5308        (and (eq_attr "prefix" "maybe_vex")
5309             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5310        (const_string "1")
5311        (const_string "*")))
5312    (set_attr "athlon_decode" "direct")
5313    (set_attr "amdfam10_decode" "double")
5314    (set_attr "fp_int_src" "true")])
5315
5316 (define_split
5317   [(set (match_operand:MODEF 0 "register_operand" "")
5318         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5319    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5320   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5321    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5322    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5323    && reload_completed
5324    && (SSE_REG_P (operands[0])
5325        || (GET_CODE (operands[0]) == SUBREG
5326            && SSE_REG_P (operands[0])))"
5327   [(set (match_dup 2) (match_dup 1))
5328    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5329
5330 (define_split
5331   [(set (match_operand:MODEF 0 "register_operand" "")
5332         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5333    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5334   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5335    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5336    && reload_completed
5337    && (SSE_REG_P (operands[0])
5338        || (GET_CODE (operands[0]) == SUBREG
5339            && SSE_REG_P (operands[0])))"
5340   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5341
5342 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5343   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5344         (float:X87MODEF
5345           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5346   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5347   "TARGET_80387
5348    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5349   "@
5350    fild%Z1\t%1
5351    #"
5352   [(set_attr "type" "fmov,multi")
5353    (set_attr "mode" "<X87MODEF:MODE>")
5354    (set_attr "unit" "*,i387")
5355    (set_attr "fp_int_src" "true")])
5356
5357 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5358   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5359         (float:X87MODEF
5360           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5361   "TARGET_80387
5362    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5363   "fild%Z1\t%1"
5364   [(set_attr "type" "fmov")
5365    (set_attr "mode" "<X87MODEF:MODE>")
5366    (set_attr "fp_int_src" "true")])
5367
5368 (define_split
5369   [(set (match_operand:X87MODEF 0 "register_operand" "")
5370         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5371    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5372   "TARGET_80387
5373    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5374    && reload_completed
5375    && FP_REG_P (operands[0])"
5376   [(set (match_dup 2) (match_dup 1))
5377    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5378
5379 (define_split
5380   [(set (match_operand:X87MODEF 0 "register_operand" "")
5381         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5382    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5383   "TARGET_80387
5384    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5385    && reload_completed
5386    && FP_REG_P (operands[0])"
5387   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5388
5389 ;; Avoid store forwarding (partial memory) stall penalty
5390 ;; by passing DImode value through XMM registers.  */
5391
5392 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5393   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5394         (float:X87MODEF
5395           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5396    (clobber (match_scratch:V4SI 3 "=X,x"))
5397    (clobber (match_scratch:V4SI 4 "=X,x"))
5398    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5399   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5400    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5401    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5402   "#"
5403   [(set_attr "type" "multi")
5404    (set_attr "mode" "<X87MODEF:MODE>")
5405    (set_attr "unit" "i387")
5406    (set_attr "fp_int_src" "true")])
5407
5408 (define_split
5409   [(set (match_operand:X87MODEF 0 "register_operand" "")
5410         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5411    (clobber (match_scratch:V4SI 3 ""))
5412    (clobber (match_scratch:V4SI 4 ""))
5413    (clobber (match_operand:DI 2 "memory_operand" ""))]
5414   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5415    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5416    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5417    && reload_completed
5418    && FP_REG_P (operands[0])"
5419   [(set (match_dup 2) (match_dup 3))
5420    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5421 {
5422   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5423      Assemble the 64-bit DImode value in an xmm register.  */
5424   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5425                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5426   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5427                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5428   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5429                                          operands[4]));
5430
5431   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5432 })
5433
5434 (define_split
5435   [(set (match_operand:X87MODEF 0 "register_operand" "")
5436         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5437    (clobber (match_scratch:V4SI 3 ""))
5438    (clobber (match_scratch:V4SI 4 ""))
5439    (clobber (match_operand:DI 2 "memory_operand" ""))]
5440   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5441    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5442    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5443    && reload_completed
5444    && FP_REG_P (operands[0])"
5445   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5446
5447 ;; Avoid store forwarding (partial memory) stall penalty by extending
5448 ;; SImode value to DImode through XMM register instead of pushing two
5449 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5450 ;; targets benefit from this optimization. Also note that fild
5451 ;; loads from memory only.
5452
5453 (define_insn "*floatunssi<mode>2_1"
5454   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5455         (unsigned_float:X87MODEF
5456           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5457    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5458    (clobber (match_scratch:SI 3 "=X,x"))]
5459   "!TARGET_64BIT
5460    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5461    && TARGET_SSE"
5462   "#"
5463   [(set_attr "type" "multi")
5464    (set_attr "mode" "<MODE>")])
5465
5466 (define_split
5467   [(set (match_operand:X87MODEF 0 "register_operand" "")
5468         (unsigned_float:X87MODEF
5469           (match_operand:SI 1 "register_operand" "")))
5470    (clobber (match_operand:DI 2 "memory_operand" ""))
5471    (clobber (match_scratch:SI 3 ""))]
5472   "!TARGET_64BIT
5473    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5474    && TARGET_SSE
5475    && reload_completed"
5476   [(set (match_dup 2) (match_dup 1))
5477    (set (match_dup 0)
5478         (float:X87MODEF (match_dup 2)))]
5479   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5480
5481 (define_split
5482   [(set (match_operand:X87MODEF 0 "register_operand" "")
5483         (unsigned_float:X87MODEF
5484           (match_operand:SI 1 "memory_operand" "")))
5485    (clobber (match_operand:DI 2 "memory_operand" ""))
5486    (clobber (match_scratch:SI 3 ""))]
5487   "!TARGET_64BIT
5488    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5489    && TARGET_SSE
5490    && reload_completed"
5491   [(set (match_dup 2) (match_dup 3))
5492    (set (match_dup 0)
5493         (float:X87MODEF (match_dup 2)))]
5494 {
5495   emit_move_insn (operands[3], operands[1]);
5496   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5497 })
5498
5499 (define_expand "floatunssi<mode>2"
5500   [(parallel
5501      [(set (match_operand:X87MODEF 0 "register_operand" "")
5502            (unsigned_float:X87MODEF
5503              (match_operand:SI 1 "nonimmediate_operand" "")))
5504       (clobber (match_dup 2))
5505       (clobber (match_scratch:SI 3 ""))])]
5506   "!TARGET_64BIT
5507    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5508         && TARGET_SSE)
5509        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5510 {
5511   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5512     {
5513       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5514       DONE;
5515     }
5516   else
5517     {
5518       enum ix86_stack_slot slot = (virtuals_instantiated
5519                                    ? SLOT_TEMP
5520                                    : SLOT_VIRTUAL);
5521       operands[2] = assign_386_stack_local (DImode, slot);
5522     }
5523 })
5524
5525 (define_expand "floatunsdisf2"
5526   [(use (match_operand:SF 0 "register_operand" ""))
5527    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5528   "TARGET_64BIT && TARGET_SSE_MATH"
5529   "x86_emit_floatuns (operands); DONE;")
5530
5531 (define_expand "floatunsdidf2"
5532   [(use (match_operand:DF 0 "register_operand" ""))
5533    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5534   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5535    && TARGET_SSE2 && TARGET_SSE_MATH"
5536 {
5537   if (TARGET_64BIT)
5538     x86_emit_floatuns (operands);
5539   else
5540     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5541   DONE;
5542 })
5543 \f
5544 ;; Add instructions
5545
5546 (define_expand "add<mode>3"
5547   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5548         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5549                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5550   ""
5551   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5552
5553 (define_insn_and_split "*add<dwi>3_doubleword"
5554   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5555         (plus:<DWI>
5556           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5557           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5558    (clobber (reg:CC FLAGS_REG))]
5559   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5560   "#"
5561   "reload_completed"
5562   [(parallel [(set (reg:CC FLAGS_REG)
5563                    (unspec:CC [(match_dup 1) (match_dup 2)]
5564                               UNSPEC_ADD_CARRY))
5565               (set (match_dup 0)
5566                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5567    (parallel [(set (match_dup 3)
5568                    (plus:DWIH
5569                      (match_dup 4)
5570                      (plus:DWIH
5571                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5572                        (match_dup 5))))
5573               (clobber (reg:CC FLAGS_REG))])]
5574   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5575
5576 (define_insn "*add<mode>3_cc"
5577   [(set (reg:CC FLAGS_REG)
5578         (unspec:CC
5579           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5580            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5581           UNSPEC_ADD_CARRY))
5582    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5583         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5584   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5585   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5586   [(set_attr "type" "alu")
5587    (set_attr "mode" "<MODE>")])
5588
5589 (define_insn "addqi3_cc"
5590   [(set (reg:CC FLAGS_REG)
5591         (unspec:CC
5592           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5593            (match_operand:QI 2 "general_operand" "qn,qm")]
5594           UNSPEC_ADD_CARRY))
5595    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5596         (plus:QI (match_dup 1) (match_dup 2)))]
5597   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5598   "add{b}\t{%2, %0|%0, %2}"
5599   [(set_attr "type" "alu")
5600    (set_attr "mode" "QI")])
5601
5602 (define_insn "*lea_1"
5603   [(set (match_operand:P 0 "register_operand" "=r")
5604         (match_operand:P 1 "no_seg_address_operand" "p"))]
5605   ""
5606   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5607   [(set_attr "type" "lea")
5608    (set_attr "mode" "<MODE>")])
5609
5610 (define_insn "*lea_2"
5611   [(set (match_operand:SI 0 "register_operand" "=r")
5612         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5613   "TARGET_64BIT"
5614   "lea{l}\t{%a1, %0|%0, %a1}"
5615   [(set_attr "type" "lea")
5616    (set_attr "mode" "SI")])
5617
5618 (define_insn "*lea_2_zext"
5619   [(set (match_operand:DI 0 "register_operand" "=r")
5620         (zero_extend:DI
5621           (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5622   "TARGET_64BIT"
5623   "lea{l}\t{%a1, %k0|%k0, %a1}"
5624   [(set_attr "type" "lea")
5625    (set_attr "mode" "SI")])
5626
5627 (define_insn "*add<mode>_1"
5628   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5629         (plus:SWI48
5630           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5631           (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5632    (clobber (reg:CC FLAGS_REG))]
5633   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5634 {
5635   switch (get_attr_type (insn))
5636     {
5637     case TYPE_LEA:
5638       return "#";
5639
5640     case TYPE_INCDEC:
5641       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5642       if (operands[2] == const1_rtx)
5643         return "inc{<imodesuffix>}\t%0";
5644       else
5645         {
5646           gcc_assert (operands[2] == constm1_rtx);
5647           return "dec{<imodesuffix>}\t%0";
5648         }
5649
5650     default:
5651       /* For most processors, ADD is faster than LEA.  This alternative
5652          was added to use ADD as much as possible.  */
5653       if (which_alternative == 2)
5654         {
5655           rtx tmp;
5656           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5657         }
5658         
5659       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5660       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5661         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5662
5663       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5664     }
5665 }
5666   [(set (attr "type")
5667      (cond [(eq_attr "alternative" "3")
5668               (const_string "lea")
5669             (match_operand:SWI48 2 "incdec_operand" "")
5670               (const_string "incdec")
5671            ]
5672            (const_string "alu")))
5673    (set (attr "length_immediate")
5674       (if_then_else
5675         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5676         (const_string "1")
5677         (const_string "*")))
5678    (set_attr "mode" "<MODE>")])
5679
5680 ;; It may seem that nonimmediate operand is proper one for operand 1.
5681 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5682 ;; we take care in ix86_binary_operator_ok to not allow two memory
5683 ;; operands so proper swapping will be done in reload.  This allow
5684 ;; patterns constructed from addsi_1 to match.
5685
5686 (define_insn "*addsi_1_zext"
5687   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5688         (zero_extend:DI
5689           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5690                    (match_operand:SI 2 "general_operand" "g,0,li"))))
5691    (clobber (reg:CC FLAGS_REG))]
5692   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5693 {
5694   switch (get_attr_type (insn))
5695     {
5696     case TYPE_LEA:
5697       return "#";
5698
5699     case TYPE_INCDEC:
5700       if (operands[2] == const1_rtx)
5701         return "inc{l}\t%k0";
5702       else
5703         {
5704           gcc_assert (operands[2] == constm1_rtx);
5705           return "dec{l}\t%k0";
5706         }
5707
5708     default:
5709       /* For most processors, ADD is faster than LEA.  This alternative
5710          was added to use ADD as much as possible.  */
5711       if (which_alternative == 1)
5712         {
5713           rtx tmp;
5714           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5715         }
5716
5717       if (x86_maybe_negate_const_int (&operands[2], SImode))
5718         return "sub{l}\t{%2, %k0|%k0, %2}";
5719
5720       return "add{l}\t{%2, %k0|%k0, %2}";
5721     }
5722 }
5723   [(set (attr "type")
5724      (cond [(eq_attr "alternative" "2")
5725               (const_string "lea")
5726             (match_operand:SI 2 "incdec_operand" "")
5727               (const_string "incdec")
5728            ]
5729            (const_string "alu")))
5730    (set (attr "length_immediate")
5731       (if_then_else
5732         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5733         (const_string "1")
5734         (const_string "*")))
5735    (set_attr "mode" "SI")])
5736
5737 (define_insn "*addhi_1"
5738   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5739         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5740                  (match_operand:HI 2 "general_operand" "rn,rm")))
5741    (clobber (reg:CC FLAGS_REG))]
5742   "TARGET_PARTIAL_REG_STALL
5743    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5744 {
5745   switch (get_attr_type (insn))
5746     {
5747     case TYPE_INCDEC:
5748       if (operands[2] == const1_rtx)
5749         return "inc{w}\t%0";
5750       else
5751         {
5752           gcc_assert (operands[2] == constm1_rtx);
5753           return "dec{w}\t%0";
5754         }
5755
5756     default:
5757       if (x86_maybe_negate_const_int (&operands[2], HImode))
5758         return "sub{w}\t{%2, %0|%0, %2}";
5759
5760       return "add{w}\t{%2, %0|%0, %2}";
5761     }
5762 }
5763   [(set (attr "type")
5764      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5765         (const_string "incdec")
5766         (const_string "alu")))
5767    (set (attr "length_immediate")
5768       (if_then_else
5769         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5770         (const_string "1")
5771         (const_string "*")))
5772    (set_attr "mode" "HI")])
5773
5774 (define_insn "*addhi_1_lea"
5775   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5776         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5777                  (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5778    (clobber (reg:CC FLAGS_REG))]
5779   "!TARGET_PARTIAL_REG_STALL
5780    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5781 {
5782   switch (get_attr_type (insn))
5783     {
5784     case TYPE_LEA:
5785       return "#";
5786
5787     case TYPE_INCDEC:
5788       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5789       if (operands[2] == const1_rtx)
5790         return "inc{w}\t%0";
5791       else
5792         {
5793           gcc_assert (operands[2] == constm1_rtx);
5794           return "dec{w}\t%0";
5795         }
5796
5797     default:
5798       /* For most processors, ADD is faster than LEA.  This alternative
5799          was added to use ADD as much as possible.  */
5800       if (which_alternative == 2)
5801         {
5802           rtx tmp;
5803           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5804         }
5805
5806       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5807       if (x86_maybe_negate_const_int (&operands[2], HImode))
5808         return "sub{w}\t{%2, %0|%0, %2}";
5809
5810       return "add{w}\t{%2, %0|%0, %2}";
5811     }
5812 }
5813   [(set (attr "type")
5814      (cond [(eq_attr "alternative" "3")
5815               (const_string "lea")
5816             (match_operand:HI 2 "incdec_operand" "")
5817               (const_string "incdec")
5818            ]
5819            (const_string "alu")))
5820    (set (attr "length_immediate")
5821       (if_then_else
5822         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5823         (const_string "1")
5824         (const_string "*")))
5825    (set_attr "mode" "HI,HI,HI,SI")])
5826
5827 ;; %%% Potential partial reg stall on alternative 2.  What to do?
5828 (define_insn "*addqi_1"
5829   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5830         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5831                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5832    (clobber (reg:CC FLAGS_REG))]
5833   "TARGET_PARTIAL_REG_STALL
5834    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5835 {
5836   int widen = (which_alternative == 2);
5837   switch (get_attr_type (insn))
5838     {
5839     case TYPE_INCDEC:
5840       if (operands[2] == const1_rtx)
5841         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5842       else
5843         {
5844           gcc_assert (operands[2] == constm1_rtx);
5845           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5846         }
5847
5848     default:
5849       if (x86_maybe_negate_const_int (&operands[2], QImode))
5850         {
5851           if (widen)
5852             return "sub{l}\t{%2, %k0|%k0, %2}";
5853           else
5854             return "sub{b}\t{%2, %0|%0, %2}";
5855         }
5856       if (widen)
5857         return "add{l}\t{%k2, %k0|%k0, %k2}";
5858       else
5859         return "add{b}\t{%2, %0|%0, %2}";
5860     }
5861 }
5862   [(set (attr "type")
5863      (if_then_else (match_operand:QI 2 "incdec_operand" "")
5864         (const_string "incdec")
5865         (const_string "alu")))
5866    (set (attr "length_immediate")
5867       (if_then_else
5868         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5869         (const_string "1")
5870         (const_string "*")))
5871    (set_attr "mode" "QI,QI,SI")])
5872
5873 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5874 (define_insn "*addqi_1_lea"
5875   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5876         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5877                  (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5878    (clobber (reg:CC FLAGS_REG))]
5879   "!TARGET_PARTIAL_REG_STALL
5880    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5881 {
5882   int widen = (which_alternative == 3 || which_alternative == 4);
5883
5884   switch (get_attr_type (insn))
5885     {
5886     case TYPE_LEA:
5887       return "#";
5888
5889     case TYPE_INCDEC:
5890       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5891       if (operands[2] == const1_rtx)
5892         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5893       else
5894         {
5895           gcc_assert (operands[2] == constm1_rtx);
5896           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5897         }
5898
5899     default:
5900       /* For most processors, ADD is faster than LEA.  These alternatives
5901          were added to use ADD as much as possible.  */
5902       if (which_alternative == 2 || which_alternative == 4)
5903         {
5904           rtx tmp;
5905           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5906         }
5907
5908       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5909       if (x86_maybe_negate_const_int (&operands[2], QImode))
5910         {
5911           if (widen)
5912             return "sub{l}\t{%2, %k0|%k0, %2}";
5913           else
5914             return "sub{b}\t{%2, %0|%0, %2}";
5915         }
5916       if (widen)
5917         return "add{l}\t{%k2, %k0|%k0, %k2}";
5918       else
5919         return "add{b}\t{%2, %0|%0, %2}";
5920     }
5921 }
5922   [(set (attr "type")
5923      (cond [(eq_attr "alternative" "5")
5924               (const_string "lea")
5925             (match_operand:QI 2 "incdec_operand" "")
5926               (const_string "incdec")
5927            ]
5928            (const_string "alu")))
5929    (set (attr "length_immediate")
5930       (if_then_else
5931         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5932         (const_string "1")
5933         (const_string "*")))
5934    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5935
5936 (define_insn "*addqi_1_slp"
5937   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5938         (plus:QI (match_dup 0)
5939                  (match_operand:QI 1 "general_operand" "qn,qnm")))
5940    (clobber (reg:CC FLAGS_REG))]
5941   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5942    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5943 {
5944   switch (get_attr_type (insn))
5945     {
5946     case TYPE_INCDEC:
5947       if (operands[1] == const1_rtx)
5948         return "inc{b}\t%0";
5949       else
5950         {
5951           gcc_assert (operands[1] == constm1_rtx);
5952           return "dec{b}\t%0";
5953         }
5954
5955     default:
5956       if (x86_maybe_negate_const_int (&operands[1], QImode))
5957         return "sub{b}\t{%1, %0|%0, %1}";
5958
5959       return "add{b}\t{%1, %0|%0, %1}";
5960     }
5961 }
5962   [(set (attr "type")
5963      (if_then_else (match_operand:QI 1 "incdec_operand" "")
5964         (const_string "incdec")
5965         (const_string "alu1")))
5966    (set (attr "memory")
5967      (if_then_else (match_operand 1 "memory_operand" "")
5968         (const_string "load")
5969         (const_string "none")))
5970    (set_attr "mode" "QI")])
5971
5972 ;; Convert lea to the lea pattern to avoid flags dependency.
5973 (define_split
5974   [(set (match_operand 0 "register_operand" "")
5975         (plus (match_operand 1 "register_operand" "")
5976               (match_operand 2 "nonmemory_operand" "")))
5977    (clobber (reg:CC FLAGS_REG))]
5978   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5979   [(const_int 0)]
5980 {
5981   rtx pat;
5982   enum machine_mode mode = GET_MODE (operands[0]);
5983
5984   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5985      may confuse gen_lowpart.  */
5986   if (mode != Pmode)
5987     {
5988       operands[1] = gen_lowpart (Pmode, operands[1]);
5989       operands[2] = gen_lowpart (Pmode, operands[2]);
5990     }
5991
5992   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5993
5994   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5995     operands[0] = gen_lowpart (SImode, operands[0]);
5996
5997   if (TARGET_64BIT && mode != Pmode)
5998     pat = gen_rtx_SUBREG (SImode, pat, 0);
5999
6000   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6001   DONE;
6002 })
6003
6004 ;; Convert lea to the lea pattern to avoid flags dependency.
6005 ;; ??? This pattern handles immediate operands that do not satisfy immediate
6006 ;; operand predicate (LEGITIMATE_CONSTANT_P) in the previous pattern.
6007 (define_split
6008   [(set (match_operand:DI 0 "register_operand" "")
6009         (plus:DI (match_operand:DI 1 "register_operand" "")
6010                  (match_operand:DI 2 "x86_64_immediate_operand" "")))
6011    (clobber (reg:CC FLAGS_REG))]
6012   "TARGET_64BIT && reload_completed 
6013    && true_regnum (operands[0]) != true_regnum (operands[1])"
6014   [(set (match_dup 0)
6015         (plus:DI (match_dup 1) (match_dup 2)))])
6016
6017 ;; Convert lea to the lea pattern to avoid flags dependency.
6018 (define_split
6019   [(set (match_operand:DI 0 "register_operand" "")
6020         (zero_extend:DI
6021           (plus:SI (match_operand:SI 1 "register_operand" "")
6022                    (match_operand:SI 2 "nonmemory_operand" ""))))
6023    (clobber (reg:CC FLAGS_REG))]
6024   "TARGET_64BIT && reload_completed
6025    && ix86_lea_for_add_ok (insn, operands)"
6026   [(set (match_dup 0)
6027         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6028 {
6029   operands[1] = gen_lowpart (DImode, operands[1]);
6030   operands[2] = gen_lowpart (DImode, operands[2]);
6031 })
6032
6033 (define_insn "*add<mode>_2"
6034   [(set (reg FLAGS_REG)
6035         (compare
6036           (plus:SWI
6037             (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6038             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6039           (const_int 0)))
6040    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6041         (plus:SWI (match_dup 1) (match_dup 2)))]
6042   "ix86_match_ccmode (insn, CCGOCmode)
6043    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6044 {
6045   switch (get_attr_type (insn))
6046     {
6047     case TYPE_INCDEC:
6048       if (operands[2] == const1_rtx)
6049         return "inc{<imodesuffix>}\t%0";
6050       else
6051         {
6052           gcc_assert (operands[2] == constm1_rtx);
6053           return "dec{<imodesuffix>}\t%0";
6054         }
6055
6056     default:
6057       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6058         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6059
6060       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6061     }
6062 }
6063   [(set (attr "type")
6064      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6065         (const_string "incdec")
6066         (const_string "alu")))
6067    (set (attr "length_immediate")
6068       (if_then_else
6069         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6070         (const_string "1")
6071         (const_string "*")))
6072    (set_attr "mode" "<MODE>")])
6073
6074 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6075 (define_insn "*addsi_2_zext"
6076   [(set (reg FLAGS_REG)
6077         (compare
6078           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6079                    (match_operand:SI 2 "general_operand" "g"))
6080           (const_int 0)))
6081    (set (match_operand:DI 0 "register_operand" "=r")
6082         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6083   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6084    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6085 {
6086   switch (get_attr_type (insn))
6087     {
6088     case TYPE_INCDEC:
6089       if (operands[2] == const1_rtx)
6090         return "inc{l}\t%k0";
6091       else
6092         {
6093           gcc_assert (operands[2] == constm1_rtx);
6094           return "dec{l}\t%k0";
6095         }
6096
6097     default:
6098       if (x86_maybe_negate_const_int (&operands[2], SImode))
6099         return "sub{l}\t{%2, %k0|%k0, %2}";
6100
6101       return "add{l}\t{%2, %k0|%k0, %2}";
6102     }
6103 }
6104   [(set (attr "type")
6105      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6106         (const_string "incdec")
6107         (const_string "alu")))
6108    (set (attr "length_immediate")
6109       (if_then_else
6110         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6111         (const_string "1")
6112         (const_string "*")))
6113    (set_attr "mode" "SI")])
6114
6115 (define_insn "*add<mode>_3"
6116   [(set (reg FLAGS_REG)
6117         (compare
6118           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6119           (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6120    (clobber (match_scratch:SWI 0 "=<r>"))]
6121   "ix86_match_ccmode (insn, CCZmode)
6122    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6123 {
6124   switch (get_attr_type (insn))
6125     {
6126     case TYPE_INCDEC:
6127       if (operands[2] == const1_rtx)
6128         return "inc{<imodesuffix>}\t%0";
6129       else
6130         {
6131           gcc_assert (operands[2] == constm1_rtx);
6132           return "dec{<imodesuffix>}\t%0";
6133         }
6134
6135     default:
6136       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6137         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6138
6139       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6140     }
6141 }
6142   [(set (attr "type")
6143      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6144         (const_string "incdec")
6145         (const_string "alu")))
6146    (set (attr "length_immediate")
6147       (if_then_else
6148         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6149         (const_string "1")
6150         (const_string "*")))
6151    (set_attr "mode" "<MODE>")])
6152
6153 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6154 (define_insn "*addsi_3_zext"
6155   [(set (reg FLAGS_REG)
6156         (compare
6157           (neg:SI (match_operand:SI 2 "general_operand" "g"))
6158           (match_operand:SI 1 "nonimmediate_operand" "%0")))
6159    (set (match_operand:DI 0 "register_operand" "=r")
6160         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6161   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6162    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6163 {
6164   switch (get_attr_type (insn))
6165     {
6166     case TYPE_INCDEC:
6167       if (operands[2] == const1_rtx)
6168         return "inc{l}\t%k0";
6169       else
6170         {
6171           gcc_assert (operands[2] == constm1_rtx);
6172           return "dec{l}\t%k0";
6173         }
6174
6175     default:
6176       if (x86_maybe_negate_const_int (&operands[2], SImode))
6177         return "sub{l}\t{%2, %k0|%k0, %2}";
6178
6179       return "add{l}\t{%2, %k0|%k0, %2}";
6180     }
6181 }
6182   [(set (attr "type")
6183      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6184         (const_string "incdec")
6185         (const_string "alu")))
6186    (set (attr "length_immediate")
6187       (if_then_else
6188         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6189         (const_string "1")
6190         (const_string "*")))
6191    (set_attr "mode" "SI")])
6192
6193 ; For comparisons against 1, -1 and 128, we may generate better code
6194 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6195 ; is matched then.  We can't accept general immediate, because for
6196 ; case of overflows,  the result is messed up.
6197 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6198 ; only for comparisons not depending on it.
6199
6200 (define_insn "*adddi_4"
6201   [(set (reg FLAGS_REG)
6202         (compare
6203           (match_operand:DI 1 "nonimmediate_operand" "0")
6204           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6205    (clobber (match_scratch:DI 0 "=rm"))]
6206   "TARGET_64BIT
6207    && ix86_match_ccmode (insn, CCGCmode)"
6208 {
6209   switch (get_attr_type (insn))
6210     {
6211     case TYPE_INCDEC:
6212       if (operands[2] == constm1_rtx)
6213         return "inc{q}\t%0";
6214       else
6215         {
6216           gcc_assert (operands[2] == const1_rtx);
6217           return "dec{q}\t%0";
6218         }
6219
6220     default:
6221       if (x86_maybe_negate_const_int (&operands[2], DImode))
6222         return "add{q}\t{%2, %0|%0, %2}";
6223
6224       return "sub{q}\t{%2, %0|%0, %2}";
6225     }
6226 }
6227   [(set (attr "type")
6228      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6229         (const_string "incdec")
6230         (const_string "alu")))
6231    (set (attr "length_immediate")
6232       (if_then_else
6233         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6234         (const_string "1")
6235         (const_string "*")))
6236    (set_attr "mode" "DI")])
6237
6238 ; For comparisons against 1, -1 and 128, we may generate better code
6239 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6240 ; is matched then.  We can't accept general immediate, because for
6241 ; case of overflows,  the result is messed up.
6242 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6243 ; only for comparisons not depending on it.
6244
6245 (define_insn "*add<mode>_4"
6246   [(set (reg FLAGS_REG)
6247         (compare
6248           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6249           (match_operand:SWI124 2 "const_int_operand" "n")))
6250    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6251   "ix86_match_ccmode (insn, CCGCmode)"
6252 {
6253   switch (get_attr_type (insn))
6254     {
6255     case TYPE_INCDEC:
6256       if (operands[2] == constm1_rtx)
6257         return "inc{<imodesuffix>}\t%0";
6258       else
6259         {
6260           gcc_assert (operands[2] == const1_rtx);
6261           return "dec{<imodesuffix>}\t%0";
6262         }
6263
6264     default:
6265       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6266         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6267
6268       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6269     }
6270 }
6271   [(set (attr "type")
6272      (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6273         (const_string "incdec")
6274         (const_string "alu")))
6275    (set (attr "length_immediate")
6276       (if_then_else
6277         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6278         (const_string "1")
6279         (const_string "*")))
6280    (set_attr "mode" "<MODE>")])
6281
6282 (define_insn "*add<mode>_5"
6283   [(set (reg FLAGS_REG)
6284         (compare
6285           (plus:SWI
6286             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6287             (match_operand:SWI 2 "<general_operand>" "<g>"))
6288           (const_int 0)))
6289    (clobber (match_scratch:SWI 0 "=<r>"))]
6290   "ix86_match_ccmode (insn, CCGOCmode)
6291    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6292 {
6293   switch (get_attr_type (insn))
6294     {
6295     case TYPE_INCDEC:
6296       if (operands[2] == const1_rtx)
6297         return "inc{<imodesuffix>}\t%0";
6298       else
6299         {
6300           gcc_assert (operands[2] == constm1_rtx);
6301           return "dec{<imodesuffix>}\t%0";
6302         }
6303
6304     default:
6305       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6306         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6307
6308       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6309     }
6310 }
6311   [(set (attr "type")
6312      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6313         (const_string "incdec")
6314         (const_string "alu")))
6315    (set (attr "length_immediate")
6316       (if_then_else
6317         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6318         (const_string "1")
6319         (const_string "*")))
6320    (set_attr "mode" "<MODE>")])
6321
6322 (define_insn "*addqi_ext_1_rex64"
6323   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6324                          (const_int 8)
6325                          (const_int 8))
6326         (plus:SI
6327           (zero_extract:SI
6328             (match_operand 1 "ext_register_operand" "0")
6329             (const_int 8)
6330             (const_int 8))
6331           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6332    (clobber (reg:CC FLAGS_REG))]
6333   "TARGET_64BIT"
6334 {
6335   switch (get_attr_type (insn))
6336     {
6337     case TYPE_INCDEC:
6338       if (operands[2] == const1_rtx)
6339         return "inc{b}\t%h0";
6340       else
6341         {
6342           gcc_assert (operands[2] == constm1_rtx);
6343           return "dec{b}\t%h0";
6344         }
6345
6346     default:
6347       return "add{b}\t{%2, %h0|%h0, %2}";
6348     }
6349 }
6350   [(set (attr "type")
6351      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6352         (const_string "incdec")
6353         (const_string "alu")))
6354    (set_attr "modrm" "1")
6355    (set_attr "mode" "QI")])
6356
6357 (define_insn "addqi_ext_1"
6358   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6359                          (const_int 8)
6360                          (const_int 8))
6361         (plus:SI
6362           (zero_extract:SI
6363             (match_operand 1 "ext_register_operand" "0")
6364             (const_int 8)
6365             (const_int 8))
6366           (match_operand:QI 2 "general_operand" "Qmn")))
6367    (clobber (reg:CC FLAGS_REG))]
6368   "!TARGET_64BIT"
6369 {
6370   switch (get_attr_type (insn))
6371     {
6372     case TYPE_INCDEC:
6373       if (operands[2] == const1_rtx)
6374         return "inc{b}\t%h0";
6375       else
6376         {
6377           gcc_assert (operands[2] == constm1_rtx);
6378           return "dec{b}\t%h0";
6379         }
6380
6381     default:
6382       return "add{b}\t{%2, %h0|%h0, %2}";
6383     }
6384 }
6385   [(set (attr "type")
6386      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6387         (const_string "incdec")
6388         (const_string "alu")))
6389    (set_attr "modrm" "1")
6390    (set_attr "mode" "QI")])
6391
6392 (define_insn "*addqi_ext_2"
6393   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6394                          (const_int 8)
6395                          (const_int 8))
6396         (plus:SI
6397           (zero_extract:SI
6398             (match_operand 1 "ext_register_operand" "%0")
6399             (const_int 8)
6400             (const_int 8))
6401           (zero_extract:SI
6402             (match_operand 2 "ext_register_operand" "Q")
6403             (const_int 8)
6404             (const_int 8))))
6405    (clobber (reg:CC FLAGS_REG))]
6406   ""
6407   "add{b}\t{%h2, %h0|%h0, %h2}"
6408   [(set_attr "type" "alu")
6409    (set_attr "mode" "QI")])
6410
6411 ;; The lea patterns for non-Pmodes needs to be matched by
6412 ;; several insns converted to real lea by splitters.
6413
6414 (define_insn_and_split "*lea_general_1"
6415   [(set (match_operand 0 "register_operand" "=r")
6416         (plus (plus (match_operand 1 "index_register_operand" "l")
6417                     (match_operand 2 "register_operand" "r"))
6418               (match_operand 3 "immediate_operand" "i")))]
6419   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6420     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6421    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6422    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6423    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6424    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6425        || GET_MODE (operands[3]) == VOIDmode)"
6426   "#"
6427   "&& reload_completed"
6428   [(const_int 0)]
6429 {
6430   rtx pat;
6431   operands[0] = gen_lowpart (SImode, operands[0]);
6432   operands[1] = gen_lowpart (Pmode, operands[1]);
6433   operands[2] = gen_lowpart (Pmode, operands[2]);
6434   operands[3] = gen_lowpart (Pmode, operands[3]);
6435   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6436                       operands[3]);
6437   if (Pmode != SImode)
6438     pat = gen_rtx_SUBREG (SImode, pat, 0);
6439   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6440   DONE;
6441 }
6442   [(set_attr "type" "lea")
6443    (set_attr "mode" "SI")])
6444
6445 (define_insn_and_split "*lea_general_1_zext"
6446   [(set (match_operand:DI 0 "register_operand" "=r")
6447         (zero_extend:DI
6448           (plus:SI (plus:SI
6449                      (match_operand:SI 1 "index_register_operand" "l")
6450                      (match_operand:SI 2 "register_operand" "r"))
6451                    (match_operand:SI 3 "immediate_operand" "i"))))]
6452   "TARGET_64BIT"
6453   "#"
6454   "&& reload_completed"
6455   [(set (match_dup 0)
6456         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6457                                                      (match_dup 2))
6458                                             (match_dup 3)) 0)))]
6459 {
6460   operands[1] = gen_lowpart (Pmode, operands[1]);
6461   operands[2] = gen_lowpart (Pmode, operands[2]);
6462   operands[3] = gen_lowpart (Pmode, operands[3]);
6463 }
6464   [(set_attr "type" "lea")
6465    (set_attr "mode" "SI")])
6466
6467 (define_insn_and_split "*lea_general_2"
6468   [(set (match_operand 0 "register_operand" "=r")
6469         (plus (mult (match_operand 1 "index_register_operand" "l")
6470                     (match_operand 2 "const248_operand" "i"))
6471               (match_operand 3 "nonmemory_operand" "ri")))]
6472   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6473     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6474    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6475    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6476    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6477        || GET_MODE (operands[3]) == VOIDmode)"
6478   "#"
6479   "&& reload_completed"
6480   [(const_int 0)]
6481 {
6482   rtx pat;
6483   operands[0] = gen_lowpart (SImode, operands[0]);
6484   operands[1] = gen_lowpart (Pmode, operands[1]);
6485   operands[3] = gen_lowpart (Pmode, operands[3]);
6486   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6487                       operands[3]);
6488   if (Pmode != SImode)
6489     pat = gen_rtx_SUBREG (SImode, pat, 0);
6490   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6491   DONE;
6492 }
6493   [(set_attr "type" "lea")
6494    (set_attr "mode" "SI")])
6495
6496 (define_insn_and_split "*lea_general_2_zext"
6497   [(set (match_operand:DI 0 "register_operand" "=r")
6498         (zero_extend:DI
6499           (plus:SI (mult:SI
6500                      (match_operand:SI 1 "index_register_operand" "l")
6501                      (match_operand:SI 2 "const248_operand" "n"))
6502                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6503   "TARGET_64BIT"
6504   "#"
6505   "&& reload_completed"
6506   [(set (match_dup 0)
6507         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6508                                                      (match_dup 2))
6509                                             (match_dup 3)) 0)))]
6510 {
6511   operands[1] = gen_lowpart (Pmode, operands[1]);
6512   operands[3] = gen_lowpart (Pmode, operands[3]);
6513 }
6514   [(set_attr "type" "lea")
6515    (set_attr "mode" "SI")])
6516
6517 (define_insn_and_split "*lea_general_3"
6518   [(set (match_operand 0 "register_operand" "=r")
6519         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6520                           (match_operand 2 "const248_operand" "i"))
6521                     (match_operand 3 "register_operand" "r"))
6522               (match_operand 4 "immediate_operand" "i")))]
6523   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6524     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6525    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6526    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6527    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6528   "#"
6529   "&& reload_completed"
6530   [(const_int 0)]
6531 {
6532   rtx pat;
6533   operands[0] = gen_lowpart (SImode, operands[0]);
6534   operands[1] = gen_lowpart (Pmode, operands[1]);
6535   operands[3] = gen_lowpart (Pmode, operands[3]);
6536   operands[4] = gen_lowpart (Pmode, operands[4]);
6537   pat = gen_rtx_PLUS (Pmode,
6538                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6539                                                          operands[2]),
6540                                     operands[3]),
6541                       operands[4]);
6542   if (Pmode != SImode)
6543     pat = gen_rtx_SUBREG (SImode, pat, 0);
6544   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6545   DONE;
6546 }
6547   [(set_attr "type" "lea")
6548    (set_attr "mode" "SI")])
6549
6550 (define_insn_and_split "*lea_general_3_zext"
6551   [(set (match_operand:DI 0 "register_operand" "=r")
6552         (zero_extend:DI
6553           (plus:SI (plus:SI
6554                      (mult:SI
6555                        (match_operand:SI 1 "index_register_operand" "l")
6556                        (match_operand:SI 2 "const248_operand" "n"))
6557                      (match_operand:SI 3 "register_operand" "r"))
6558                    (match_operand:SI 4 "immediate_operand" "i"))))]
6559   "TARGET_64BIT"
6560   "#"
6561   "&& reload_completed"
6562   [(set (match_dup 0)
6563         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6564                                                               (match_dup 2))
6565                                                      (match_dup 3))
6566                                             (match_dup 4)) 0)))]
6567 {
6568   operands[1] = gen_lowpart (Pmode, operands[1]);
6569   operands[3] = gen_lowpart (Pmode, operands[3]);
6570   operands[4] = gen_lowpart (Pmode, operands[4]);
6571 }
6572   [(set_attr "type" "lea")
6573    (set_attr "mode" "SI")])
6574 \f
6575 ;; Subtract instructions
6576
6577 (define_expand "sub<mode>3"
6578   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6579         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6580                      (match_operand:SDWIM 2 "<general_operand>" "")))]
6581   ""
6582   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6583
6584 (define_insn_and_split "*sub<dwi>3_doubleword"
6585   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6586         (minus:<DWI>
6587           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6588           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6589    (clobber (reg:CC FLAGS_REG))]
6590   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6591   "#"
6592   "reload_completed"
6593   [(parallel [(set (reg:CC FLAGS_REG)
6594                    (compare:CC (match_dup 1) (match_dup 2)))
6595               (set (match_dup 0)
6596                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6597    (parallel [(set (match_dup 3)
6598                    (minus:DWIH
6599                      (match_dup 4)
6600                      (plus:DWIH
6601                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6602                        (match_dup 5))))
6603               (clobber (reg:CC FLAGS_REG))])]
6604   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6605
6606 (define_insn "*sub<mode>_1"
6607   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6608         (minus:SWI
6609           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6610           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6611    (clobber (reg:CC FLAGS_REG))]
6612   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6613   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6614   [(set_attr "type" "alu")
6615    (set_attr "mode" "<MODE>")])
6616
6617 (define_insn "*subsi_1_zext"
6618   [(set (match_operand:DI 0 "register_operand" "=r")
6619         (zero_extend:DI
6620           (minus:SI (match_operand:SI 1 "register_operand" "0")
6621                     (match_operand:SI 2 "general_operand" "g"))))
6622    (clobber (reg:CC FLAGS_REG))]
6623   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6624   "sub{l}\t{%2, %k0|%k0, %2}"
6625   [(set_attr "type" "alu")
6626    (set_attr "mode" "SI")])
6627
6628 (define_insn "*subqi_1_slp"
6629   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6630         (minus:QI (match_dup 0)
6631                   (match_operand:QI 1 "general_operand" "qn,qm")))
6632    (clobber (reg:CC FLAGS_REG))]
6633   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6634    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6635   "sub{b}\t{%1, %0|%0, %1}"
6636   [(set_attr "type" "alu1")
6637    (set_attr "mode" "QI")])
6638
6639 (define_insn "*sub<mode>_2"
6640   [(set (reg FLAGS_REG)
6641         (compare
6642           (minus:SWI
6643             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6644             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6645           (const_int 0)))
6646    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6647         (minus:SWI (match_dup 1) (match_dup 2)))]
6648   "ix86_match_ccmode (insn, CCGOCmode)
6649    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6650   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6651   [(set_attr "type" "alu")
6652    (set_attr "mode" "<MODE>")])
6653
6654 (define_insn "*subsi_2_zext"
6655   [(set (reg FLAGS_REG)
6656         (compare
6657           (minus:SI (match_operand:SI 1 "register_operand" "0")
6658                     (match_operand:SI 2 "general_operand" "g"))
6659           (const_int 0)))
6660    (set (match_operand:DI 0 "register_operand" "=r")
6661         (zero_extend:DI
6662           (minus:SI (match_dup 1)
6663                     (match_dup 2))))]
6664   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6665    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6666   "sub{l}\t{%2, %k0|%k0, %2}"
6667   [(set_attr "type" "alu")
6668    (set_attr "mode" "SI")])
6669
6670 (define_insn "*sub<mode>_3"
6671   [(set (reg FLAGS_REG)
6672         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6673                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6674    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6675         (minus:SWI (match_dup 1) (match_dup 2)))]
6676   "ix86_match_ccmode (insn, CCmode)
6677    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6678   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6679   [(set_attr "type" "alu")
6680    (set_attr "mode" "<MODE>")])
6681
6682 (define_insn "*subsi_3_zext"
6683   [(set (reg FLAGS_REG)
6684         (compare (match_operand:SI 1 "register_operand" "0")
6685                  (match_operand:SI 2 "general_operand" "g")))
6686    (set (match_operand:DI 0 "register_operand" "=r")
6687         (zero_extend:DI
6688           (minus:SI (match_dup 1)
6689                     (match_dup 2))))]
6690   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6691    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6692   "sub{l}\t{%2, %1|%1, %2}"
6693   [(set_attr "type" "alu")
6694    (set_attr "mode" "SI")])
6695 \f
6696 ;; Add with carry and subtract with borrow
6697
6698 (define_expand "<plusminus_insn><mode>3_carry"
6699   [(parallel
6700     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6701           (plusminus:SWI
6702             (match_operand:SWI 1 "nonimmediate_operand" "")
6703             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6704                        [(match_operand 3 "flags_reg_operand" "")
6705                         (const_int 0)])
6706                       (match_operand:SWI 2 "<general_operand>" ""))))
6707      (clobber (reg:CC FLAGS_REG))])]
6708   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6709
6710 (define_insn "*<plusminus_insn><mode>3_carry"
6711   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6712         (plusminus:SWI
6713           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6714           (plus:SWI
6715             (match_operator 3 "ix86_carry_flag_operator"
6716              [(reg FLAGS_REG) (const_int 0)])
6717             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6718    (clobber (reg:CC FLAGS_REG))]
6719   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6720   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6721   [(set_attr "type" "alu")
6722    (set_attr "use_carry" "1")
6723    (set_attr "pent_pair" "pu")
6724    (set_attr "mode" "<MODE>")])
6725
6726 (define_insn "*addsi3_carry_zext"
6727   [(set (match_operand:DI 0 "register_operand" "=r")
6728         (zero_extend:DI
6729           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6730                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6731                              [(reg FLAGS_REG) (const_int 0)])
6732                             (match_operand:SI 2 "general_operand" "g")))))
6733    (clobber (reg:CC FLAGS_REG))]
6734   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6735   "adc{l}\t{%2, %k0|%k0, %2}"
6736   [(set_attr "type" "alu")
6737    (set_attr "use_carry" "1")
6738    (set_attr "pent_pair" "pu")
6739    (set_attr "mode" "SI")])
6740
6741 (define_insn "*subsi3_carry_zext"
6742   [(set (match_operand:DI 0 "register_operand" "=r")
6743         (zero_extend:DI
6744           (minus:SI (match_operand:SI 1 "register_operand" "0")
6745                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6746                               [(reg FLAGS_REG) (const_int 0)])
6747                              (match_operand:SI 2 "general_operand" "g")))))
6748    (clobber (reg:CC FLAGS_REG))]
6749   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6750   "sbb{l}\t{%2, %k0|%k0, %2}"
6751   [(set_attr "type" "alu")
6752    (set_attr "pent_pair" "pu")
6753    (set_attr "mode" "SI")])
6754 \f
6755 ;; Overflow setting add and subtract instructions
6756
6757 (define_insn "*add<mode>3_cconly_overflow"
6758   [(set (reg:CCC FLAGS_REG)
6759         (compare:CCC
6760           (plus:SWI
6761             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6762             (match_operand:SWI 2 "<general_operand>" "<g>"))
6763           (match_dup 1)))
6764    (clobber (match_scratch:SWI 0 "=<r>"))]
6765   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6766   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6767   [(set_attr "type" "alu")
6768    (set_attr "mode" "<MODE>")])
6769
6770 (define_insn "*sub<mode>3_cconly_overflow"
6771   [(set (reg:CCC FLAGS_REG)
6772         (compare:CCC
6773           (minus:SWI
6774             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6775             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6776           (match_dup 0)))]
6777   ""
6778   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6779   [(set_attr "type" "icmp")
6780    (set_attr "mode" "<MODE>")])
6781
6782 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6783   [(set (reg:CCC FLAGS_REG)
6784         (compare:CCC
6785             (plusminus:SWI
6786                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6787                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6788             (match_dup 1)))
6789    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6790         (plusminus:SWI (match_dup 1) (match_dup 2)))]
6791   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6792   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6793   [(set_attr "type" "alu")
6794    (set_attr "mode" "<MODE>")])
6795
6796 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6797   [(set (reg:CCC FLAGS_REG)
6798         (compare:CCC
6799           (plusminus:SI
6800             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6801             (match_operand:SI 2 "general_operand" "g"))
6802           (match_dup 1)))
6803    (set (match_operand:DI 0 "register_operand" "=r")
6804         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6805   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6806   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6807   [(set_attr "type" "alu")
6808    (set_attr "mode" "SI")])
6809
6810 ;; The patterns that match these are at the end of this file.
6811
6812 (define_expand "<plusminus_insn>xf3"
6813   [(set (match_operand:XF 0 "register_operand" "")
6814         (plusminus:XF
6815           (match_operand:XF 1 "register_operand" "")
6816           (match_operand:XF 2 "register_operand" "")))]
6817   "TARGET_80387")
6818
6819 (define_expand "<plusminus_insn><mode>3"
6820   [(set (match_operand:MODEF 0 "register_operand" "")
6821         (plusminus:MODEF
6822           (match_operand:MODEF 1 "register_operand" "")
6823           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6824   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6825     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6826 \f
6827 ;; Multiply instructions
6828
6829 (define_expand "mul<mode>3"
6830   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6831                    (mult:SWIM248
6832                      (match_operand:SWIM248 1 "register_operand" "")
6833                      (match_operand:SWIM248 2 "<general_operand>" "")))
6834               (clobber (reg:CC FLAGS_REG))])])
6835
6836 (define_expand "mulqi3"
6837   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6838                    (mult:QI
6839                      (match_operand:QI 1 "register_operand" "")
6840                      (match_operand:QI 2 "nonimmediate_operand" "")))
6841               (clobber (reg:CC FLAGS_REG))])]
6842   "TARGET_QIMODE_MATH")
6843
6844 ;; On AMDFAM10
6845 ;; IMUL reg32/64, reg32/64, imm8        Direct
6846 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6847 ;; IMUL reg32/64, reg32/64, imm32       Direct
6848 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6849 ;; IMUL reg32/64, reg32/64              Direct
6850 ;; IMUL reg32/64, mem32/64              Direct
6851
6852 (define_insn "*mul<mode>3_1"
6853   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6854         (mult:SWI48
6855           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6856           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6857    (clobber (reg:CC FLAGS_REG))]
6858   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6859   "@
6860    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6861    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6862    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6863   [(set_attr "type" "imul")
6864    (set_attr "prefix_0f" "0,0,1")
6865    (set (attr "athlon_decode")
6866         (cond [(eq_attr "cpu" "athlon")
6867                   (const_string "vector")
6868                (eq_attr "alternative" "1")
6869                   (const_string "vector")
6870                (and (eq_attr "alternative" "2")
6871                     (match_operand 1 "memory_operand" ""))
6872                   (const_string "vector")]
6873               (const_string "direct")))
6874    (set (attr "amdfam10_decode")
6875         (cond [(and (eq_attr "alternative" "0,1")
6876                     (match_operand 1 "memory_operand" ""))
6877                   (const_string "vector")]
6878               (const_string "direct")))
6879    (set_attr "mode" "<MODE>")])
6880
6881 (define_insn "*mulsi3_1_zext"
6882   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6883         (zero_extend:DI
6884           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6885                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6886    (clobber (reg:CC FLAGS_REG))]
6887   "TARGET_64BIT
6888    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6889   "@
6890    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6891    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6892    imul{l}\t{%2, %k0|%k0, %2}"
6893   [(set_attr "type" "imul")
6894    (set_attr "prefix_0f" "0,0,1")
6895    (set (attr "athlon_decode")
6896         (cond [(eq_attr "cpu" "athlon")
6897                   (const_string "vector")
6898                (eq_attr "alternative" "1")
6899                   (const_string "vector")
6900                (and (eq_attr "alternative" "2")
6901                     (match_operand 1 "memory_operand" ""))
6902                   (const_string "vector")]
6903               (const_string "direct")))
6904    (set (attr "amdfam10_decode")
6905         (cond [(and (eq_attr "alternative" "0,1")
6906                     (match_operand 1 "memory_operand" ""))
6907                   (const_string "vector")]
6908               (const_string "direct")))
6909    (set_attr "mode" "SI")])
6910
6911 ;; On AMDFAM10
6912 ;; IMUL reg16, reg16, imm8      VectorPath
6913 ;; IMUL reg16, mem16, imm8      VectorPath
6914 ;; IMUL reg16, reg16, imm16     VectorPath
6915 ;; IMUL reg16, mem16, imm16     VectorPath
6916 ;; IMUL reg16, reg16            Direct
6917 ;; IMUL reg16, mem16            Direct
6918
6919 (define_insn "*mulhi3_1"
6920   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6921         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6922                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6923    (clobber (reg:CC FLAGS_REG))]
6924   "TARGET_HIMODE_MATH
6925    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6926   "@
6927    imul{w}\t{%2, %1, %0|%0, %1, %2}
6928    imul{w}\t{%2, %1, %0|%0, %1, %2}
6929    imul{w}\t{%2, %0|%0, %2}"
6930   [(set_attr "type" "imul")
6931    (set_attr "prefix_0f" "0,0,1")
6932    (set (attr "athlon_decode")
6933         (cond [(eq_attr "cpu" "athlon")
6934                   (const_string "vector")
6935                (eq_attr "alternative" "1,2")
6936                   (const_string "vector")]
6937               (const_string "direct")))
6938    (set (attr "amdfam10_decode")
6939         (cond [(eq_attr "alternative" "0,1")
6940                   (const_string "vector")]
6941               (const_string "direct")))
6942    (set_attr "mode" "HI")])
6943
6944 ;;On AMDFAM10
6945 ;; MUL reg8     Direct
6946 ;; MUL mem8     Direct
6947
6948 (define_insn "*mulqi3_1"
6949   [(set (match_operand:QI 0 "register_operand" "=a")
6950         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6951                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6952    (clobber (reg:CC FLAGS_REG))]
6953   "TARGET_QIMODE_MATH
6954    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6955   "mul{b}\t%2"
6956   [(set_attr "type" "imul")
6957    (set_attr "length_immediate" "0")
6958    (set (attr "athlon_decode")
6959      (if_then_else (eq_attr "cpu" "athlon")
6960         (const_string "vector")
6961         (const_string "direct")))
6962    (set_attr "amdfam10_decode" "direct")
6963    (set_attr "mode" "QI")])
6964
6965 (define_expand "<u>mul<mode><dwi>3"
6966   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6967                    (mult:<DWI>
6968                      (any_extend:<DWI>
6969                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
6970                      (any_extend:<DWI>
6971                        (match_operand:DWIH 2 "register_operand" ""))))
6972               (clobber (reg:CC FLAGS_REG))])])
6973
6974 (define_expand "<u>mulqihi3"
6975   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6976                    (mult:HI
6977                      (any_extend:HI
6978                        (match_operand:QI 1 "nonimmediate_operand" ""))
6979                      (any_extend:HI
6980                        (match_operand:QI 2 "register_operand" ""))))
6981               (clobber (reg:CC FLAGS_REG))])]
6982   "TARGET_QIMODE_MATH")
6983
6984 (define_insn "*<u>mul<mode><dwi>3_1"
6985   [(set (match_operand:<DWI> 0 "register_operand" "=A")
6986         (mult:<DWI>
6987           (any_extend:<DWI>
6988             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6989           (any_extend:<DWI>
6990             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6991    (clobber (reg:CC FLAGS_REG))]
6992   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6993   "<sgnprefix>mul{<imodesuffix>}\t%2"
6994   [(set_attr "type" "imul")
6995    (set_attr "length_immediate" "0")
6996    (set (attr "athlon_decode")
6997      (if_then_else (eq_attr "cpu" "athlon")
6998         (const_string "vector")
6999         (const_string "double")))
7000    (set_attr "amdfam10_decode" "double")
7001    (set_attr "mode" "<MODE>")])
7002
7003 (define_insn "*<u>mulqihi3_1"
7004   [(set (match_operand:HI 0 "register_operand" "=a")
7005         (mult:HI
7006           (any_extend:HI
7007             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7008           (any_extend:HI
7009             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7010    (clobber (reg:CC FLAGS_REG))]
7011   "TARGET_QIMODE_MATH
7012    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7013   "<sgnprefix>mul{b}\t%2"
7014   [(set_attr "type" "imul")
7015    (set_attr "length_immediate" "0")
7016    (set (attr "athlon_decode")
7017      (if_then_else (eq_attr "cpu" "athlon")
7018         (const_string "vector")
7019         (const_string "direct")))
7020    (set_attr "amdfam10_decode" "direct")
7021    (set_attr "mode" "QI")])
7022
7023 (define_expand "<s>mul<mode>3_highpart"
7024   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7025                    (truncate:SWI48
7026                      (lshiftrt:<DWI>
7027                        (mult:<DWI>
7028                          (any_extend:<DWI>
7029                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
7030                          (any_extend:<DWI>
7031                            (match_operand:SWI48 2 "register_operand" "")))
7032                        (match_dup 4))))
7033               (clobber (match_scratch:SWI48 3 ""))
7034               (clobber (reg:CC FLAGS_REG))])]
7035   ""
7036   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7037
7038 (define_insn "*<s>muldi3_highpart_1"
7039   [(set (match_operand:DI 0 "register_operand" "=d")
7040         (truncate:DI
7041           (lshiftrt:TI
7042             (mult:TI
7043               (any_extend:TI
7044                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7045               (any_extend:TI
7046                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7047             (const_int 64))))
7048    (clobber (match_scratch:DI 3 "=1"))
7049    (clobber (reg:CC FLAGS_REG))]
7050   "TARGET_64BIT
7051    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7052   "<sgnprefix>mul{q}\t%2"
7053   [(set_attr "type" "imul")
7054    (set_attr "length_immediate" "0")
7055    (set (attr "athlon_decode")
7056      (if_then_else (eq_attr "cpu" "athlon")
7057         (const_string "vector")
7058         (const_string "double")))
7059    (set_attr "amdfam10_decode" "double")
7060    (set_attr "mode" "DI")])
7061
7062 (define_insn "*<s>mulsi3_highpart_1"
7063   [(set (match_operand:SI 0 "register_operand" "=d")
7064         (truncate:SI
7065           (lshiftrt:DI
7066             (mult:DI
7067               (any_extend:DI
7068                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7069               (any_extend:DI
7070                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7071             (const_int 32))))
7072    (clobber (match_scratch:SI 3 "=1"))
7073    (clobber (reg:CC FLAGS_REG))]
7074   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7075   "<sgnprefix>mul{l}\t%2"
7076   [(set_attr "type" "imul")
7077    (set_attr "length_immediate" "0")
7078    (set (attr "athlon_decode")
7079      (if_then_else (eq_attr "cpu" "athlon")
7080         (const_string "vector")
7081         (const_string "double")))
7082    (set_attr "amdfam10_decode" "double")
7083    (set_attr "mode" "SI")])
7084
7085 (define_insn "*<s>mulsi3_highpart_zext"
7086   [(set (match_operand:DI 0 "register_operand" "=d")
7087         (zero_extend:DI (truncate:SI
7088           (lshiftrt:DI
7089             (mult:DI (any_extend:DI
7090                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7091                      (any_extend:DI
7092                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7093             (const_int 32)))))
7094    (clobber (match_scratch:SI 3 "=1"))
7095    (clobber (reg:CC FLAGS_REG))]
7096   "TARGET_64BIT
7097    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7098   "<sgnprefix>mul{l}\t%2"
7099   [(set_attr "type" "imul")
7100    (set_attr "length_immediate" "0")
7101    (set (attr "athlon_decode")
7102      (if_then_else (eq_attr "cpu" "athlon")
7103         (const_string "vector")
7104         (const_string "double")))
7105    (set_attr "amdfam10_decode" "double")
7106    (set_attr "mode" "SI")])
7107
7108 ;; The patterns that match these are at the end of this file.
7109
7110 (define_expand "mulxf3"
7111   [(set (match_operand:XF 0 "register_operand" "")
7112         (mult:XF (match_operand:XF 1 "register_operand" "")
7113                  (match_operand:XF 2 "register_operand" "")))]
7114   "TARGET_80387")
7115
7116 (define_expand "mul<mode>3"
7117   [(set (match_operand:MODEF 0 "register_operand" "")
7118         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7119                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7120   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7121     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7122 \f
7123 ;; Divide instructions
7124
7125 ;; The patterns that match these are at the end of this file.
7126
7127 (define_expand "divxf3"
7128   [(set (match_operand:XF 0 "register_operand" "")
7129         (div:XF (match_operand:XF 1 "register_operand" "")
7130                 (match_operand:XF 2 "register_operand" "")))]
7131   "TARGET_80387")
7132
7133 (define_expand "divdf3"
7134   [(set (match_operand:DF 0 "register_operand" "")
7135         (div:DF (match_operand:DF 1 "register_operand" "")
7136                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7137    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7138     || (TARGET_SSE2 && TARGET_SSE_MATH)")
7139
7140 (define_expand "divsf3"
7141   [(set (match_operand:SF 0 "register_operand" "")
7142         (div:SF (match_operand:SF 1 "register_operand" "")
7143                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7144   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7145     || TARGET_SSE_MATH"
7146 {
7147   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7148       && flag_finite_math_only && !flag_trapping_math
7149       && flag_unsafe_math_optimizations)
7150     {
7151       ix86_emit_swdivsf (operands[0], operands[1],
7152                          operands[2], SFmode);
7153       DONE;
7154     }
7155 })
7156 \f
7157 ;; Divmod instructions.
7158
7159 (define_expand "divmod<mode>4"
7160   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7161                    (div:SWIM248
7162                      (match_operand:SWIM248 1 "register_operand" "")
7163                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7164               (set (match_operand:SWIM248 3 "register_operand" "")
7165                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7166               (clobber (reg:CC FLAGS_REG))])])
7167
7168 ;; Split with 8bit unsigned divide:
7169 ;;      if (dividend an divisor are in [0-255])
7170 ;;         use 8bit unsigned integer divide
7171 ;;       else
7172 ;;         use original integer divide
7173 (define_split
7174   [(set (match_operand:SWI48 0 "register_operand" "")
7175         (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7176                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7177    (set (match_operand:SWI48 1 "register_operand" "")
7178         (mod:SWI48 (match_dup 2) (match_dup 3)))
7179    (clobber (reg:CC FLAGS_REG))]
7180   "TARGET_USE_8BIT_IDIV
7181    && TARGET_QIMODE_MATH
7182    && can_create_pseudo_p ()
7183    && !optimize_insn_for_size_p ()"
7184   [(const_int 0)]
7185   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7186
7187 (define_insn_and_split "divmod<mode>4_1"
7188   [(set (match_operand:SWI48 0 "register_operand" "=a")
7189         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7190                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7191    (set (match_operand:SWI48 1 "register_operand" "=&d")
7192         (mod:SWI48 (match_dup 2) (match_dup 3)))
7193    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7194    (clobber (reg:CC FLAGS_REG))]
7195   ""
7196   "#"
7197   "reload_completed"
7198   [(parallel [(set (match_dup 1)
7199                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7200               (clobber (reg:CC FLAGS_REG))])
7201    (parallel [(set (match_dup 0)
7202                    (div:SWI48 (match_dup 2) (match_dup 3)))
7203               (set (match_dup 1)
7204                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7205               (use (match_dup 1))
7206               (clobber (reg:CC FLAGS_REG))])]
7207 {
7208   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7209
7210   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7211     operands[4] = operands[2];
7212   else
7213     {
7214       /* Avoid use of cltd in favor of a mov+shift.  */
7215       emit_move_insn (operands[1], operands[2]);
7216       operands[4] = operands[1];
7217     }
7218 }
7219   [(set_attr "type" "multi")
7220    (set_attr "mode" "<MODE>")])
7221
7222 (define_insn_and_split "*divmod<mode>4"
7223   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7224         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7225                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7226    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7227         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7228    (clobber (reg:CC FLAGS_REG))]
7229   ""
7230   "#"
7231   "reload_completed"
7232   [(parallel [(set (match_dup 1)
7233                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7234               (clobber (reg:CC FLAGS_REG))])
7235    (parallel [(set (match_dup 0)
7236                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7237               (set (match_dup 1)
7238                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7239               (use (match_dup 1))
7240               (clobber (reg:CC FLAGS_REG))])]
7241 {
7242   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7243
7244   if (<MODE>mode != HImode
7245       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7246     operands[4] = operands[2];
7247   else
7248     {
7249       /* Avoid use of cltd in favor of a mov+shift.  */
7250       emit_move_insn (operands[1], operands[2]);
7251       operands[4] = operands[1];
7252     }
7253 }
7254   [(set_attr "type" "multi")
7255    (set_attr "mode" "<MODE>")])
7256
7257 (define_insn "*divmod<mode>4_noext"
7258   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7259         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7260                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7261    (set (match_operand:SWIM248 1 "register_operand" "=d")
7262         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7263    (use (match_operand:SWIM248 4 "register_operand" "1"))
7264    (clobber (reg:CC FLAGS_REG))]
7265   ""
7266   "idiv{<imodesuffix>}\t%3"
7267   [(set_attr "type" "idiv")
7268    (set_attr "mode" "<MODE>")])
7269
7270 (define_expand "divmodqi4"
7271   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7272                    (div:QI
7273                      (match_operand:QI 1 "register_operand" "")
7274                      (match_operand:QI 2 "nonimmediate_operand" "")))
7275               (set (match_operand:QI 3 "register_operand" "")
7276                    (mod:QI (match_dup 1) (match_dup 2)))
7277               (clobber (reg:CC FLAGS_REG))])]
7278   "TARGET_QIMODE_MATH"
7279 {
7280   rtx div, mod, insn;
7281   rtx tmp0, tmp1;
7282   
7283   tmp0 = gen_reg_rtx (HImode);
7284   tmp1 = gen_reg_rtx (HImode);
7285
7286   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7287      in AX.  */
7288   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7289   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7290
7291   /* Extract remainder from AH.  */
7292   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7293   insn = emit_move_insn (operands[3], tmp1);
7294
7295   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7296   set_unique_reg_note (insn, REG_EQUAL, mod);
7297
7298   /* Extract quotient from AL.  */
7299   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7300
7301   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7302   set_unique_reg_note (insn, REG_EQUAL, div);
7303
7304   DONE;
7305 })
7306
7307 ;; Divide AX by r/m8, with result stored in
7308 ;; AL <- Quotient
7309 ;; AH <- Remainder
7310 ;; Change div/mod to HImode and extend the second argument to HImode
7311 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7312 ;; combine may fail.
7313 (define_insn "divmodhiqi3"
7314   [(set (match_operand:HI 0 "register_operand" "=a")
7315         (ior:HI
7316           (ashift:HI
7317             (zero_extend:HI
7318               (truncate:QI
7319                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7320                         (sign_extend:HI
7321                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7322             (const_int 8))
7323           (zero_extend:HI
7324             (truncate:QI
7325               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7326    (clobber (reg:CC FLAGS_REG))]
7327   "TARGET_QIMODE_MATH"
7328   "idiv{b}\t%2"
7329   [(set_attr "type" "idiv")
7330    (set_attr "mode" "QI")])
7331
7332 (define_expand "udivmod<mode>4"
7333   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7334                    (udiv:SWIM248
7335                      (match_operand:SWIM248 1 "register_operand" "")
7336                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7337               (set (match_operand:SWIM248 3 "register_operand" "")
7338                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7339               (clobber (reg:CC FLAGS_REG))])])
7340
7341 ;; Split with 8bit unsigned divide:
7342 ;;      if (dividend an divisor are in [0-255])
7343 ;;         use 8bit unsigned integer divide
7344 ;;       else
7345 ;;         use original integer divide
7346 (define_split
7347   [(set (match_operand:SWI48 0 "register_operand" "")
7348         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7349                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7350    (set (match_operand:SWI48 1 "register_operand" "")
7351         (umod:SWI48 (match_dup 2) (match_dup 3)))
7352    (clobber (reg:CC FLAGS_REG))]
7353   "TARGET_USE_8BIT_IDIV
7354    && TARGET_QIMODE_MATH
7355    && can_create_pseudo_p ()
7356    && !optimize_insn_for_size_p ()"
7357   [(const_int 0)]
7358   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7359
7360 (define_insn_and_split "udivmod<mode>4_1"
7361   [(set (match_operand:SWI48 0 "register_operand" "=a")
7362         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7363                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7364    (set (match_operand:SWI48 1 "register_operand" "=&d")
7365         (umod:SWI48 (match_dup 2) (match_dup 3)))
7366    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7367    (clobber (reg:CC FLAGS_REG))]
7368   ""
7369   "#"
7370   "reload_completed"
7371   [(set (match_dup 1) (const_int 0))
7372    (parallel [(set (match_dup 0)
7373                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7374               (set (match_dup 1)
7375                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7376               (use (match_dup 1))
7377               (clobber (reg:CC FLAGS_REG))])]
7378   ""
7379   [(set_attr "type" "multi")
7380    (set_attr "mode" "<MODE>")])
7381
7382 (define_insn_and_split "*udivmod<mode>4"
7383   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7384         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7385                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7386    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7387         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7388    (clobber (reg:CC FLAGS_REG))]
7389   ""
7390   "#"
7391   "reload_completed"
7392   [(set (match_dup 1) (const_int 0))
7393    (parallel [(set (match_dup 0)
7394                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7395               (set (match_dup 1)
7396                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7397               (use (match_dup 1))
7398               (clobber (reg:CC FLAGS_REG))])]
7399   ""
7400   [(set_attr "type" "multi")
7401    (set_attr "mode" "<MODE>")])
7402
7403 (define_insn "*udivmod<mode>4_noext"
7404   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7405         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7406                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7407    (set (match_operand:SWIM248 1 "register_operand" "=d")
7408         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7409    (use (match_operand:SWIM248 4 "register_operand" "1"))
7410    (clobber (reg:CC FLAGS_REG))]
7411   ""
7412   "div{<imodesuffix>}\t%3"
7413   [(set_attr "type" "idiv")
7414    (set_attr "mode" "<MODE>")])
7415
7416 (define_expand "udivmodqi4"
7417   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7418                    (udiv:QI
7419                      (match_operand:QI 1 "register_operand" "")
7420                      (match_operand:QI 2 "nonimmediate_operand" "")))
7421               (set (match_operand:QI 3 "register_operand" "")
7422                    (umod:QI (match_dup 1) (match_dup 2)))
7423               (clobber (reg:CC FLAGS_REG))])]
7424   "TARGET_QIMODE_MATH"
7425 {
7426   rtx div, mod, insn;
7427   rtx tmp0, tmp1;
7428   
7429   tmp0 = gen_reg_rtx (HImode);
7430   tmp1 = gen_reg_rtx (HImode);
7431
7432   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7433      in AX.  */
7434   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7435   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7436
7437   /* Extract remainder from AH.  */
7438   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7439   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7440   insn = emit_move_insn (operands[3], tmp1);
7441
7442   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7443   set_unique_reg_note (insn, REG_EQUAL, mod);
7444
7445   /* Extract quotient from AL.  */
7446   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7447
7448   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7449   set_unique_reg_note (insn, REG_EQUAL, div);
7450
7451   DONE;
7452 })
7453
7454 (define_insn "udivmodhiqi3"
7455   [(set (match_operand:HI 0 "register_operand" "=a")
7456         (ior:HI
7457           (ashift:HI
7458             (zero_extend:HI
7459               (truncate:QI
7460                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7461                         (zero_extend:HI
7462                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7463             (const_int 8))
7464           (zero_extend:HI
7465             (truncate:QI
7466               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7467    (clobber (reg:CC FLAGS_REG))]
7468   "TARGET_QIMODE_MATH"
7469   "div{b}\t%2"
7470   [(set_attr "type" "idiv")
7471    (set_attr "mode" "QI")])
7472
7473 ;; We cannot use div/idiv for double division, because it causes
7474 ;; "division by zero" on the overflow and that's not what we expect
7475 ;; from truncate.  Because true (non truncating) double division is
7476 ;; never generated, we can't create this insn anyway.
7477 ;
7478 ;(define_insn ""
7479 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7480 ;       (truncate:SI
7481 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7482 ;                  (zero_extend:DI
7483 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7484 ;   (set (match_operand:SI 3 "register_operand" "=d")
7485 ;       (truncate:SI
7486 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7487 ;   (clobber (reg:CC FLAGS_REG))]
7488 ;  ""
7489 ;  "div{l}\t{%2, %0|%0, %2}"
7490 ;  [(set_attr "type" "idiv")])
7491 \f
7492 ;;- Logical AND instructions
7493
7494 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7495 ;; Note that this excludes ah.
7496
7497 (define_expand "testsi_ccno_1"
7498   [(set (reg:CCNO FLAGS_REG)
7499         (compare:CCNO
7500           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7501                   (match_operand:SI 1 "nonmemory_operand" ""))
7502           (const_int 0)))])
7503
7504 (define_expand "testqi_ccz_1"
7505   [(set (reg:CCZ FLAGS_REG)
7506         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7507                              (match_operand:QI 1 "nonmemory_operand" ""))
7508                  (const_int 0)))])
7509
7510 (define_expand "testdi_ccno_1"
7511   [(set (reg:CCNO FLAGS_REG)
7512         (compare:CCNO
7513           (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7514                   (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7515           (const_int 0)))]
7516   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7517
7518 (define_insn "*testdi_1"
7519   [(set (reg FLAGS_REG)
7520         (compare
7521          (and:DI
7522           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7523           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7524          (const_int 0)))]
7525   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7526    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7527   "@
7528    test{l}\t{%k1, %k0|%k0, %k1}
7529    test{l}\t{%k1, %k0|%k0, %k1}
7530    test{q}\t{%1, %0|%0, %1}
7531    test{q}\t{%1, %0|%0, %1}
7532    test{q}\t{%1, %0|%0, %1}"
7533   [(set_attr "type" "test")
7534    (set_attr "modrm" "0,1,0,1,1")
7535    (set_attr "mode" "SI,SI,DI,DI,DI")])
7536
7537 (define_insn "*testqi_1_maybe_si"
7538   [(set (reg FLAGS_REG)
7539         (compare
7540           (and:QI
7541             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7542             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7543           (const_int 0)))]
7544    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7545     && ix86_match_ccmode (insn,
7546                          CONST_INT_P (operands[1])
7547                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7548 {
7549   if (which_alternative == 3)
7550     {
7551       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7552         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7553       return "test{l}\t{%1, %k0|%k0, %1}";
7554     }
7555   return "test{b}\t{%1, %0|%0, %1}";
7556 }
7557   [(set_attr "type" "test")
7558    (set_attr "modrm" "0,1,1,1")
7559    (set_attr "mode" "QI,QI,QI,SI")
7560    (set_attr "pent_pair" "uv,np,uv,np")])
7561
7562 (define_insn "*test<mode>_1"
7563   [(set (reg FLAGS_REG)
7564         (compare
7565          (and:SWI124
7566           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7567           (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7568          (const_int 0)))]
7569   "ix86_match_ccmode (insn, CCNOmode)
7570    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7571   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7572   [(set_attr "type" "test")
7573    (set_attr "modrm" "0,1,1")
7574    (set_attr "mode" "<MODE>")
7575    (set_attr "pent_pair" "uv,np,uv")])
7576
7577 (define_expand "testqi_ext_ccno_0"
7578   [(set (reg:CCNO FLAGS_REG)
7579         (compare:CCNO
7580           (and:SI
7581             (zero_extract:SI
7582               (match_operand 0 "ext_register_operand" "")
7583               (const_int 8)
7584               (const_int 8))
7585             (match_operand 1 "const_int_operand" ""))
7586           (const_int 0)))])
7587
7588 (define_insn "*testqi_ext_0"
7589   [(set (reg FLAGS_REG)
7590         (compare
7591           (and:SI
7592             (zero_extract:SI
7593               (match_operand 0 "ext_register_operand" "Q")
7594               (const_int 8)
7595               (const_int 8))
7596             (match_operand 1 "const_int_operand" "n"))
7597           (const_int 0)))]
7598   "ix86_match_ccmode (insn, CCNOmode)"
7599   "test{b}\t{%1, %h0|%h0, %1}"
7600   [(set_attr "type" "test")
7601    (set_attr "mode" "QI")
7602    (set_attr "length_immediate" "1")
7603    (set_attr "modrm" "1")
7604    (set_attr "pent_pair" "np")])
7605
7606 (define_insn "*testqi_ext_1_rex64"
7607   [(set (reg FLAGS_REG)
7608         (compare
7609           (and:SI
7610             (zero_extract:SI
7611               (match_operand 0 "ext_register_operand" "Q")
7612               (const_int 8)
7613               (const_int 8))
7614             (zero_extend:SI
7615               (match_operand:QI 1 "register_operand" "Q")))
7616           (const_int 0)))]
7617   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7618   "test{b}\t{%1, %h0|%h0, %1}"
7619   [(set_attr "type" "test")
7620    (set_attr "mode" "QI")])
7621
7622 (define_insn "*testqi_ext_1"
7623   [(set (reg FLAGS_REG)
7624         (compare
7625           (and:SI
7626             (zero_extract:SI
7627               (match_operand 0 "ext_register_operand" "Q")
7628               (const_int 8)
7629               (const_int 8))
7630             (zero_extend:SI
7631               (match_operand:QI 1 "general_operand" "Qm")))
7632           (const_int 0)))]
7633   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7634   "test{b}\t{%1, %h0|%h0, %1}"
7635   [(set_attr "type" "test")
7636    (set_attr "mode" "QI")])
7637
7638 (define_insn "*testqi_ext_2"
7639   [(set (reg FLAGS_REG)
7640         (compare
7641           (and:SI
7642             (zero_extract:SI
7643               (match_operand 0 "ext_register_operand" "Q")
7644               (const_int 8)
7645               (const_int 8))
7646             (zero_extract:SI
7647               (match_operand 1 "ext_register_operand" "Q")
7648               (const_int 8)
7649               (const_int 8)))
7650           (const_int 0)))]
7651   "ix86_match_ccmode (insn, CCNOmode)"
7652   "test{b}\t{%h1, %h0|%h0, %h1}"
7653   [(set_attr "type" "test")
7654    (set_attr "mode" "QI")])
7655
7656 (define_insn "*testqi_ext_3_rex64"
7657   [(set (reg FLAGS_REG)
7658         (compare (zero_extract:DI
7659                    (match_operand 0 "nonimmediate_operand" "rm")
7660                    (match_operand:DI 1 "const_int_operand" "")
7661                    (match_operand:DI 2 "const_int_operand" ""))
7662                  (const_int 0)))]
7663   "TARGET_64BIT
7664    && ix86_match_ccmode (insn, CCNOmode)
7665    && INTVAL (operands[1]) > 0
7666    && INTVAL (operands[2]) >= 0
7667    /* Ensure that resulting mask is zero or sign extended operand.  */
7668    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7669        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7670            && INTVAL (operands[1]) > 32))
7671    && (GET_MODE (operands[0]) == SImode
7672        || GET_MODE (operands[0]) == DImode
7673        || GET_MODE (operands[0]) == HImode
7674        || GET_MODE (operands[0]) == QImode)"
7675   "#")
7676
7677 ;; Combine likes to form bit extractions for some tests.  Humor it.
7678 (define_insn "*testqi_ext_3"
7679   [(set (reg FLAGS_REG)
7680         (compare (zero_extract:SI
7681                    (match_operand 0 "nonimmediate_operand" "rm")
7682                    (match_operand:SI 1 "const_int_operand" "")
7683                    (match_operand:SI 2 "const_int_operand" ""))
7684                  (const_int 0)))]
7685   "ix86_match_ccmode (insn, CCNOmode)
7686    && INTVAL (operands[1]) > 0
7687    && INTVAL (operands[2]) >= 0
7688    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7689    && (GET_MODE (operands[0]) == SImode
7690        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7691        || GET_MODE (operands[0]) == HImode
7692        || GET_MODE (operands[0]) == QImode)"
7693   "#")
7694
7695 (define_split
7696   [(set (match_operand 0 "flags_reg_operand" "")
7697         (match_operator 1 "compare_operator"
7698           [(zero_extract
7699              (match_operand 2 "nonimmediate_operand" "")
7700              (match_operand 3 "const_int_operand" "")
7701              (match_operand 4 "const_int_operand" ""))
7702            (const_int 0)]))]
7703   "ix86_match_ccmode (insn, CCNOmode)"
7704   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7705 {
7706   rtx val = operands[2];
7707   HOST_WIDE_INT len = INTVAL (operands[3]);
7708   HOST_WIDE_INT pos = INTVAL (operands[4]);
7709   HOST_WIDE_INT mask;
7710   enum machine_mode mode, submode;
7711
7712   mode = GET_MODE (val);
7713   if (MEM_P (val))
7714     {
7715       /* ??? Combine likes to put non-volatile mem extractions in QImode
7716          no matter the size of the test.  So find a mode that works.  */
7717       if (! MEM_VOLATILE_P (val))
7718         {
7719           mode = smallest_mode_for_size (pos + len, MODE_INT);
7720           val = adjust_address (val, mode, 0);
7721         }
7722     }
7723   else if (GET_CODE (val) == SUBREG
7724            && (submode = GET_MODE (SUBREG_REG (val)),
7725                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7726            && pos + len <= GET_MODE_BITSIZE (submode)
7727            && GET_MODE_CLASS (submode) == MODE_INT)
7728     {
7729       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7730       mode = submode;
7731       val = SUBREG_REG (val);
7732     }
7733   else if (mode == HImode && pos + len <= 8)
7734     {
7735       /* Small HImode tests can be converted to QImode.  */
7736       mode = QImode;
7737       val = gen_lowpart (QImode, val);
7738     }
7739
7740   if (len == HOST_BITS_PER_WIDE_INT)
7741     mask = -1;
7742   else
7743     mask = ((HOST_WIDE_INT)1 << len) - 1;
7744   mask <<= pos;
7745
7746   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7747 })
7748
7749 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7750 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7751 ;; this is relatively important trick.
7752 ;; Do the conversion only post-reload to avoid limiting of the register class
7753 ;; to QI regs.
7754 (define_split
7755   [(set (match_operand 0 "flags_reg_operand" "")
7756         (match_operator 1 "compare_operator"
7757           [(and (match_operand 2 "register_operand" "")
7758                 (match_operand 3 "const_int_operand" ""))
7759            (const_int 0)]))]
7760    "reload_completed
7761     && QI_REG_P (operands[2])
7762     && GET_MODE (operands[2]) != QImode
7763     && ((ix86_match_ccmode (insn, CCZmode)
7764          && !(INTVAL (operands[3]) & ~(255 << 8)))
7765         || (ix86_match_ccmode (insn, CCNOmode)
7766             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7767   [(set (match_dup 0)
7768         (match_op_dup 1
7769           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7770                    (match_dup 3))
7771            (const_int 0)]))]
7772   "operands[2] = gen_lowpart (SImode, operands[2]);
7773    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7774
7775 (define_split
7776   [(set (match_operand 0 "flags_reg_operand" "")
7777         (match_operator 1 "compare_operator"
7778           [(and (match_operand 2 "nonimmediate_operand" "")
7779                 (match_operand 3 "const_int_operand" ""))
7780            (const_int 0)]))]
7781    "reload_completed
7782     && GET_MODE (operands[2]) != QImode
7783     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7784     && ((ix86_match_ccmode (insn, CCZmode)
7785          && !(INTVAL (operands[3]) & ~255))
7786         || (ix86_match_ccmode (insn, CCNOmode)
7787             && !(INTVAL (operands[3]) & ~127)))"
7788   [(set (match_dup 0)
7789         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7790                          (const_int 0)]))]
7791   "operands[2] = gen_lowpart (QImode, operands[2]);
7792    operands[3] = gen_lowpart (QImode, operands[3]);")
7793
7794 ;; %%% This used to optimize known byte-wide and operations to memory,
7795 ;; and sometimes to QImode registers.  If this is considered useful,
7796 ;; it should be done with splitters.
7797
7798 (define_expand "and<mode>3"
7799   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7800         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7801                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7802   ""
7803   "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7804
7805 (define_insn "*anddi_1"
7806   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7807         (and:DI
7808          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7809          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7810    (clobber (reg:CC FLAGS_REG))]
7811   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7812 {
7813   switch (get_attr_type (insn))
7814     {
7815     case TYPE_IMOVX:
7816       {
7817         enum machine_mode mode;
7818
7819         gcc_assert (CONST_INT_P (operands[2]));
7820         if (INTVAL (operands[2]) == 0xff)
7821           mode = QImode;
7822         else
7823           {
7824             gcc_assert (INTVAL (operands[2]) == 0xffff);
7825             mode = HImode;
7826           }
7827
7828         operands[1] = gen_lowpart (mode, operands[1]);
7829         if (mode == QImode)
7830           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7831         else
7832           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7833       }
7834
7835     default:
7836       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7837       if (get_attr_mode (insn) == MODE_SI)
7838         return "and{l}\t{%k2, %k0|%k0, %k2}";
7839       else
7840         return "and{q}\t{%2, %0|%0, %2}";
7841     }
7842 }
7843   [(set_attr "type" "alu,alu,alu,imovx")
7844    (set_attr "length_immediate" "*,*,*,0")
7845    (set (attr "prefix_rex")
7846      (if_then_else
7847        (and (eq_attr "type" "imovx")
7848             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7849                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
7850        (const_string "1")
7851        (const_string "*")))
7852    (set_attr "mode" "SI,DI,DI,SI")])
7853
7854 (define_insn "*andsi_1"
7855   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7856         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7857                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7858    (clobber (reg:CC FLAGS_REG))]
7859   "ix86_binary_operator_ok (AND, SImode, operands)"
7860 {
7861   switch (get_attr_type (insn))
7862     {
7863     case TYPE_IMOVX:
7864       {
7865         enum machine_mode mode;
7866
7867         gcc_assert (CONST_INT_P (operands[2]));
7868         if (INTVAL (operands[2]) == 0xff)
7869           mode = QImode;
7870         else
7871           {
7872             gcc_assert (INTVAL (operands[2]) == 0xffff);
7873             mode = HImode;
7874           }
7875
7876         operands[1] = gen_lowpart (mode, operands[1]);
7877         if (mode == QImode)
7878           return "movz{bl|x}\t{%1, %0|%0, %1}";
7879         else
7880           return "movz{wl|x}\t{%1, %0|%0, %1}";
7881       }
7882
7883     default:
7884       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7885       return "and{l}\t{%2, %0|%0, %2}";
7886     }
7887 }
7888   [(set_attr "type" "alu,alu,imovx")
7889    (set (attr "prefix_rex")
7890      (if_then_else
7891        (and (eq_attr "type" "imovx")
7892             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7893                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
7894        (const_string "1")
7895        (const_string "*")))
7896    (set_attr "length_immediate" "*,*,0")
7897    (set_attr "mode" "SI")])
7898
7899 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7900 (define_insn "*andsi_1_zext"
7901   [(set (match_operand:DI 0 "register_operand" "=r")
7902         (zero_extend:DI
7903           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7904                   (match_operand:SI 2 "general_operand" "g"))))
7905    (clobber (reg:CC FLAGS_REG))]
7906   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7907   "and{l}\t{%2, %k0|%k0, %2}"
7908   [(set_attr "type" "alu")
7909    (set_attr "mode" "SI")])
7910
7911 (define_insn "*andhi_1"
7912   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7913         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7914                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7915    (clobber (reg:CC FLAGS_REG))]
7916   "ix86_binary_operator_ok (AND, HImode, operands)"
7917 {
7918   switch (get_attr_type (insn))
7919     {
7920     case TYPE_IMOVX:
7921       gcc_assert (CONST_INT_P (operands[2]));
7922       gcc_assert (INTVAL (operands[2]) == 0xff);
7923       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7924
7925     default:
7926       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7927
7928       return "and{w}\t{%2, %0|%0, %2}";
7929     }
7930 }
7931   [(set_attr "type" "alu,alu,imovx")
7932    (set_attr "length_immediate" "*,*,0")
7933    (set (attr "prefix_rex")
7934      (if_then_else
7935        (and (eq_attr "type" "imovx")
7936             (match_operand 1 "ext_QIreg_nomode_operand" ""))
7937        (const_string "1")
7938        (const_string "*")))
7939    (set_attr "mode" "HI,HI,SI")])
7940
7941 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7942 (define_insn "*andqi_1"
7943   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7944         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7945                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7946    (clobber (reg:CC FLAGS_REG))]
7947   "ix86_binary_operator_ok (AND, QImode, operands)"
7948   "@
7949    and{b}\t{%2, %0|%0, %2}
7950    and{b}\t{%2, %0|%0, %2}
7951    and{l}\t{%k2, %k0|%k0, %k2}"
7952   [(set_attr "type" "alu")
7953    (set_attr "mode" "QI,QI,SI")])
7954
7955 (define_insn "*andqi_1_slp"
7956   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7957         (and:QI (match_dup 0)
7958                 (match_operand:QI 1 "general_operand" "qn,qmn")))
7959    (clobber (reg:CC FLAGS_REG))]
7960   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7961    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7962   "and{b}\t{%1, %0|%0, %1}"
7963   [(set_attr "type" "alu1")
7964    (set_attr "mode" "QI")])
7965
7966 (define_split
7967   [(set (match_operand 0 "register_operand" "")
7968         (and (match_dup 0)
7969              (const_int -65536)))
7970    (clobber (reg:CC FLAGS_REG))]
7971   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7972     || optimize_function_for_size_p (cfun)"
7973   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7974   "operands[1] = gen_lowpart (HImode, operands[0]);")
7975
7976 (define_split
7977   [(set (match_operand 0 "ext_register_operand" "")
7978         (and (match_dup 0)
7979              (const_int -256)))
7980    (clobber (reg:CC FLAGS_REG))]
7981   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7982    && reload_completed"
7983   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7984   "operands[1] = gen_lowpart (QImode, operands[0]);")
7985
7986 (define_split
7987   [(set (match_operand 0 "ext_register_operand" "")
7988         (and (match_dup 0)
7989              (const_int -65281)))
7990    (clobber (reg:CC FLAGS_REG))]
7991   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7992    && reload_completed"
7993   [(parallel [(set (zero_extract:SI (match_dup 0)
7994                                     (const_int 8)
7995                                     (const_int 8))
7996                    (xor:SI
7997                      (zero_extract:SI (match_dup 0)
7998                                       (const_int 8)
7999                                       (const_int 8))
8000                      (zero_extract:SI (match_dup 0)
8001                                       (const_int 8)
8002                                       (const_int 8))))
8003               (clobber (reg:CC FLAGS_REG))])]
8004   "operands[0] = gen_lowpart (SImode, operands[0]);")
8005
8006 (define_insn "*anddi_2"
8007   [(set (reg FLAGS_REG)
8008         (compare
8009          (and:DI
8010           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8011           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8012          (const_int 0)))
8013    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8014         (and:DI (match_dup 1) (match_dup 2)))]
8015   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8016    && ix86_binary_operator_ok (AND, DImode, operands)"
8017   "@
8018    and{l}\t{%k2, %k0|%k0, %k2}
8019    and{q}\t{%2, %0|%0, %2}
8020    and{q}\t{%2, %0|%0, %2}"
8021   [(set_attr "type" "alu")
8022    (set_attr "mode" "SI,DI,DI")])
8023
8024 (define_insn "*andqi_2_maybe_si"
8025   [(set (reg FLAGS_REG)
8026         (compare (and:QI
8027                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8028                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8029                  (const_int 0)))
8030    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8031         (and:QI (match_dup 1) (match_dup 2)))]
8032   "ix86_binary_operator_ok (AND, QImode, operands)
8033    && ix86_match_ccmode (insn,
8034                          CONST_INT_P (operands[2])
8035                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8036 {
8037   if (which_alternative == 2)
8038     {
8039       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8040         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8041       return "and{l}\t{%2, %k0|%k0, %2}";
8042     }
8043   return "and{b}\t{%2, %0|%0, %2}";
8044 }
8045   [(set_attr "type" "alu")
8046    (set_attr "mode" "QI,QI,SI")])
8047
8048 (define_insn "*and<mode>_2"
8049   [(set (reg FLAGS_REG)
8050         (compare (and:SWI124
8051                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8052                   (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8053                  (const_int 0)))
8054    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8055         (and:SWI124 (match_dup 1) (match_dup 2)))]
8056   "ix86_match_ccmode (insn, CCNOmode)
8057    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8058   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8059   [(set_attr "type" "alu")
8060    (set_attr "mode" "<MODE>")])
8061
8062 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8063 (define_insn "*andsi_2_zext"
8064   [(set (reg FLAGS_REG)
8065         (compare (and:SI
8066                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8067                   (match_operand:SI 2 "general_operand" "g"))
8068                  (const_int 0)))
8069    (set (match_operand:DI 0 "register_operand" "=r")
8070         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8071   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8072    && ix86_binary_operator_ok (AND, SImode, operands)"
8073   "and{l}\t{%2, %k0|%k0, %2}"
8074   [(set_attr "type" "alu")
8075    (set_attr "mode" "SI")])
8076
8077 (define_insn "*andqi_2_slp"
8078   [(set (reg FLAGS_REG)
8079         (compare (and:QI
8080                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8081                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8082                  (const_int 0)))
8083    (set (strict_low_part (match_dup 0))
8084         (and:QI (match_dup 0) (match_dup 1)))]
8085   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8086    && ix86_match_ccmode (insn, CCNOmode)
8087    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8088   "and{b}\t{%1, %0|%0, %1}"
8089   [(set_attr "type" "alu1")
8090    (set_attr "mode" "QI")])
8091
8092 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8093 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8094 ;; for a QImode operand, which of course failed.
8095 (define_insn "andqi_ext_0"
8096   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8097                          (const_int 8)
8098                          (const_int 8))
8099         (and:SI
8100           (zero_extract:SI
8101             (match_operand 1 "ext_register_operand" "0")
8102             (const_int 8)
8103             (const_int 8))
8104           (match_operand 2 "const_int_operand" "n")))
8105    (clobber (reg:CC FLAGS_REG))]
8106   ""
8107   "and{b}\t{%2, %h0|%h0, %2}"
8108   [(set_attr "type" "alu")
8109    (set_attr "length_immediate" "1")
8110    (set_attr "modrm" "1")
8111    (set_attr "mode" "QI")])
8112
8113 ;; Generated by peephole translating test to and.  This shows up
8114 ;; often in fp comparisons.
8115 (define_insn "*andqi_ext_0_cc"
8116   [(set (reg FLAGS_REG)
8117         (compare
8118           (and:SI
8119             (zero_extract:SI
8120               (match_operand 1 "ext_register_operand" "0")
8121               (const_int 8)
8122               (const_int 8))
8123             (match_operand 2 "const_int_operand" "n"))
8124           (const_int 0)))
8125    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8126                          (const_int 8)
8127                          (const_int 8))
8128         (and:SI
8129           (zero_extract:SI
8130             (match_dup 1)
8131             (const_int 8)
8132             (const_int 8))
8133           (match_dup 2)))]
8134   "ix86_match_ccmode (insn, CCNOmode)"
8135   "and{b}\t{%2, %h0|%h0, %2}"
8136   [(set_attr "type" "alu")
8137    (set_attr "length_immediate" "1")
8138    (set_attr "modrm" "1")
8139    (set_attr "mode" "QI")])
8140
8141 (define_insn "*andqi_ext_1_rex64"
8142   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8143                          (const_int 8)
8144                          (const_int 8))
8145         (and:SI
8146           (zero_extract:SI
8147             (match_operand 1 "ext_register_operand" "0")
8148             (const_int 8)
8149             (const_int 8))
8150           (zero_extend:SI
8151             (match_operand 2 "ext_register_operand" "Q"))))
8152    (clobber (reg:CC FLAGS_REG))]
8153   "TARGET_64BIT"
8154   "and{b}\t{%2, %h0|%h0, %2}"
8155   [(set_attr "type" "alu")
8156    (set_attr "length_immediate" "0")
8157    (set_attr "mode" "QI")])
8158
8159 (define_insn "*andqi_ext_1"
8160   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8161                          (const_int 8)
8162                          (const_int 8))
8163         (and:SI
8164           (zero_extract:SI
8165             (match_operand 1 "ext_register_operand" "0")
8166             (const_int 8)
8167             (const_int 8))
8168           (zero_extend:SI
8169             (match_operand:QI 2 "general_operand" "Qm"))))
8170    (clobber (reg:CC FLAGS_REG))]
8171   "!TARGET_64BIT"
8172   "and{b}\t{%2, %h0|%h0, %2}"
8173   [(set_attr "type" "alu")
8174    (set_attr "length_immediate" "0")
8175    (set_attr "mode" "QI")])
8176
8177 (define_insn "*andqi_ext_2"
8178   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8179                          (const_int 8)
8180                          (const_int 8))
8181         (and:SI
8182           (zero_extract:SI
8183             (match_operand 1 "ext_register_operand" "%0")
8184             (const_int 8)
8185             (const_int 8))
8186           (zero_extract:SI
8187             (match_operand 2 "ext_register_operand" "Q")
8188             (const_int 8)
8189             (const_int 8))))
8190    (clobber (reg:CC FLAGS_REG))]
8191   ""
8192   "and{b}\t{%h2, %h0|%h0, %h2}"
8193   [(set_attr "type" "alu")
8194    (set_attr "length_immediate" "0")
8195    (set_attr "mode" "QI")])
8196
8197 ;; Convert wide AND instructions with immediate operand to shorter QImode
8198 ;; equivalents when possible.
8199 ;; Don't do the splitting with memory operands, since it introduces risk
8200 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8201 ;; for size, but that can (should?) be handled by generic code instead.
8202 (define_split
8203   [(set (match_operand 0 "register_operand" "")
8204         (and (match_operand 1 "register_operand" "")
8205              (match_operand 2 "const_int_operand" "")))
8206    (clobber (reg:CC FLAGS_REG))]
8207    "reload_completed
8208     && QI_REG_P (operands[0])
8209     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8210     && !(~INTVAL (operands[2]) & ~(255 << 8))
8211     && GET_MODE (operands[0]) != QImode"
8212   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8213                    (and:SI (zero_extract:SI (match_dup 1)
8214                                             (const_int 8) (const_int 8))
8215                            (match_dup 2)))
8216               (clobber (reg:CC FLAGS_REG))])]
8217   "operands[0] = gen_lowpart (SImode, operands[0]);
8218    operands[1] = gen_lowpart (SImode, operands[1]);
8219    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8220
8221 ;; Since AND can be encoded with sign extended immediate, this is only
8222 ;; profitable when 7th bit is not set.
8223 (define_split
8224   [(set (match_operand 0 "register_operand" "")
8225         (and (match_operand 1 "general_operand" "")
8226              (match_operand 2 "const_int_operand" "")))
8227    (clobber (reg:CC FLAGS_REG))]
8228    "reload_completed
8229     && ANY_QI_REG_P (operands[0])
8230     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8231     && !(~INTVAL (operands[2]) & ~255)
8232     && !(INTVAL (operands[2]) & 128)
8233     && GET_MODE (operands[0]) != QImode"
8234   [(parallel [(set (strict_low_part (match_dup 0))
8235                    (and:QI (match_dup 1)
8236                            (match_dup 2)))
8237               (clobber (reg:CC FLAGS_REG))])]
8238   "operands[0] = gen_lowpart (QImode, operands[0]);
8239    operands[1] = gen_lowpart (QImode, operands[1]);
8240    operands[2] = gen_lowpart (QImode, operands[2]);")
8241 \f
8242 ;; Logical inclusive and exclusive OR instructions
8243
8244 ;; %%% This used to optimize known byte-wide and operations to memory.
8245 ;; If this is considered useful, it should be done with splitters.
8246
8247 (define_expand "<code><mode>3"
8248   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8249         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8250                      (match_operand:SWIM 2 "<general_operand>" "")))]
8251   ""
8252   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8253
8254 (define_insn "*<code><mode>_1"
8255   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8256         (any_or:SWI248
8257          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8258          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8259    (clobber (reg:CC FLAGS_REG))]
8260   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8261   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8262   [(set_attr "type" "alu")
8263    (set_attr "mode" "<MODE>")])
8264
8265 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8266 (define_insn "*<code>qi_1"
8267   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8268         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8269                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8270    (clobber (reg:CC FLAGS_REG))]
8271   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8272   "@
8273    <logic>{b}\t{%2, %0|%0, %2}
8274    <logic>{b}\t{%2, %0|%0, %2}
8275    <logic>{l}\t{%k2, %k0|%k0, %k2}"
8276   [(set_attr "type" "alu")
8277    (set_attr "mode" "QI,QI,SI")])
8278
8279 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8280 (define_insn "*<code>si_1_zext"
8281   [(set (match_operand:DI 0 "register_operand" "=r")
8282         (zero_extend:DI
8283          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8284                     (match_operand:SI 2 "general_operand" "g"))))
8285    (clobber (reg:CC FLAGS_REG))]
8286   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8287   "<logic>{l}\t{%2, %k0|%k0, %2}"
8288   [(set_attr "type" "alu")
8289    (set_attr "mode" "SI")])
8290
8291 (define_insn "*<code>si_1_zext_imm"
8292   [(set (match_operand:DI 0 "register_operand" "=r")
8293         (any_or:DI
8294          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8295          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8296    (clobber (reg:CC FLAGS_REG))]
8297   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8298   "<logic>{l}\t{%2, %k0|%k0, %2}"
8299   [(set_attr "type" "alu")
8300    (set_attr "mode" "SI")])
8301
8302 (define_insn "*<code>qi_1_slp"
8303   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8304         (any_or:QI (match_dup 0)
8305                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8306    (clobber (reg:CC FLAGS_REG))]
8307   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8308    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8309   "<logic>{b}\t{%1, %0|%0, %1}"
8310   [(set_attr "type" "alu1")
8311    (set_attr "mode" "QI")])
8312
8313 (define_insn "*<code><mode>_2"
8314   [(set (reg FLAGS_REG)
8315         (compare (any_or:SWI
8316                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8317                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8318                  (const_int 0)))
8319    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8320         (any_or:SWI (match_dup 1) (match_dup 2)))]
8321   "ix86_match_ccmode (insn, CCNOmode)
8322    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8323   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8324   [(set_attr "type" "alu")
8325    (set_attr "mode" "<MODE>")])
8326
8327 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8328 ;; ??? Special case for immediate operand is missing - it is tricky.
8329 (define_insn "*<code>si_2_zext"
8330   [(set (reg FLAGS_REG)
8331         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8332                             (match_operand:SI 2 "general_operand" "g"))
8333                  (const_int 0)))
8334    (set (match_operand:DI 0 "register_operand" "=r")
8335         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8336   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8337    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8338   "<logic>{l}\t{%2, %k0|%k0, %2}"
8339   [(set_attr "type" "alu")
8340    (set_attr "mode" "SI")])
8341
8342 (define_insn "*<code>si_2_zext_imm"
8343   [(set (reg FLAGS_REG)
8344         (compare (any_or:SI
8345                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8346                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8347                  (const_int 0)))
8348    (set (match_operand:DI 0 "register_operand" "=r")
8349         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8350   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8351    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8352   "<logic>{l}\t{%2, %k0|%k0, %2}"
8353   [(set_attr "type" "alu")
8354    (set_attr "mode" "SI")])
8355
8356 (define_insn "*<code>qi_2_slp"
8357   [(set (reg FLAGS_REG)
8358         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8359                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8360                  (const_int 0)))
8361    (set (strict_low_part (match_dup 0))
8362         (any_or:QI (match_dup 0) (match_dup 1)))]
8363   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8364    && ix86_match_ccmode (insn, CCNOmode)
8365    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8366   "<logic>{b}\t{%1, %0|%0, %1}"
8367   [(set_attr "type" "alu1")
8368    (set_attr "mode" "QI")])
8369
8370 (define_insn "*<code><mode>_3"
8371   [(set (reg FLAGS_REG)
8372         (compare (any_or:SWI
8373                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8374                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8375                  (const_int 0)))
8376    (clobber (match_scratch:SWI 0 "=<r>"))]
8377   "ix86_match_ccmode (insn, CCNOmode)
8378    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8379   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8380   [(set_attr "type" "alu")
8381    (set_attr "mode" "<MODE>")])
8382
8383 (define_insn "*<code>qi_ext_0"
8384   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8385                          (const_int 8)
8386                          (const_int 8))
8387         (any_or:SI
8388           (zero_extract:SI
8389             (match_operand 1 "ext_register_operand" "0")
8390             (const_int 8)
8391             (const_int 8))
8392           (match_operand 2 "const_int_operand" "n")))
8393    (clobber (reg:CC FLAGS_REG))]
8394   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8395   "<logic>{b}\t{%2, %h0|%h0, %2}"
8396   [(set_attr "type" "alu")
8397    (set_attr "length_immediate" "1")
8398    (set_attr "modrm" "1")
8399    (set_attr "mode" "QI")])
8400
8401 (define_insn "*<code>qi_ext_1_rex64"
8402   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8403                          (const_int 8)
8404                          (const_int 8))
8405         (any_or:SI
8406           (zero_extract:SI
8407             (match_operand 1 "ext_register_operand" "0")
8408             (const_int 8)
8409             (const_int 8))
8410           (zero_extend:SI
8411             (match_operand 2 "ext_register_operand" "Q"))))
8412    (clobber (reg:CC FLAGS_REG))]
8413   "TARGET_64BIT
8414    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8415   "<logic>{b}\t{%2, %h0|%h0, %2}"
8416   [(set_attr "type" "alu")
8417    (set_attr "length_immediate" "0")
8418    (set_attr "mode" "QI")])
8419
8420 (define_insn "*<code>qi_ext_1"
8421   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8422                          (const_int 8)
8423                          (const_int 8))
8424         (any_or:SI
8425           (zero_extract:SI
8426             (match_operand 1 "ext_register_operand" "0")
8427             (const_int 8)
8428             (const_int 8))
8429           (zero_extend:SI
8430             (match_operand:QI 2 "general_operand" "Qm"))))
8431    (clobber (reg:CC FLAGS_REG))]
8432   "!TARGET_64BIT
8433    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8434   "<logic>{b}\t{%2, %h0|%h0, %2}"
8435   [(set_attr "type" "alu")
8436    (set_attr "length_immediate" "0")
8437    (set_attr "mode" "QI")])
8438
8439 (define_insn "*<code>qi_ext_2"
8440   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8441                          (const_int 8)
8442                          (const_int 8))
8443         (any_or:SI
8444           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8445                            (const_int 8)
8446                            (const_int 8))
8447           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8448                            (const_int 8)
8449                            (const_int 8))))
8450    (clobber (reg:CC FLAGS_REG))]
8451   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8452   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8453   [(set_attr "type" "alu")
8454    (set_attr "length_immediate" "0")
8455    (set_attr "mode" "QI")])
8456
8457 (define_split
8458   [(set (match_operand 0 "register_operand" "")
8459         (any_or (match_operand 1 "register_operand" "")
8460                 (match_operand 2 "const_int_operand" "")))
8461    (clobber (reg:CC FLAGS_REG))]
8462    "reload_completed
8463     && QI_REG_P (operands[0])
8464     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8465     && !(INTVAL (operands[2]) & ~(255 << 8))
8466     && GET_MODE (operands[0]) != QImode"
8467   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8468                    (any_or:SI (zero_extract:SI (match_dup 1)
8469                                                (const_int 8) (const_int 8))
8470                               (match_dup 2)))
8471               (clobber (reg:CC FLAGS_REG))])]
8472   "operands[0] = gen_lowpart (SImode, operands[0]);
8473    operands[1] = gen_lowpart (SImode, operands[1]);
8474    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8475
8476 ;; Since OR can be encoded with sign extended immediate, this is only
8477 ;; profitable when 7th bit is set.
8478 (define_split
8479   [(set (match_operand 0 "register_operand" "")
8480         (any_or (match_operand 1 "general_operand" "")
8481                 (match_operand 2 "const_int_operand" "")))
8482    (clobber (reg:CC FLAGS_REG))]
8483    "reload_completed
8484     && ANY_QI_REG_P (operands[0])
8485     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8486     && !(INTVAL (operands[2]) & ~255)
8487     && (INTVAL (operands[2]) & 128)
8488     && GET_MODE (operands[0]) != QImode"
8489   [(parallel [(set (strict_low_part (match_dup 0))
8490                    (any_or:QI (match_dup 1)
8491                               (match_dup 2)))
8492               (clobber (reg:CC FLAGS_REG))])]
8493   "operands[0] = gen_lowpart (QImode, operands[0]);
8494    operands[1] = gen_lowpart (QImode, operands[1]);
8495    operands[2] = gen_lowpart (QImode, operands[2]);")
8496
8497 (define_expand "xorqi_cc_ext_1"
8498   [(parallel [
8499      (set (reg:CCNO FLAGS_REG)
8500           (compare:CCNO
8501             (xor:SI
8502               (zero_extract:SI
8503                 (match_operand 1 "ext_register_operand" "")
8504                 (const_int 8)
8505                 (const_int 8))
8506               (match_operand:QI 2 "general_operand" ""))
8507             (const_int 0)))
8508      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8509                            (const_int 8)
8510                            (const_int 8))
8511           (xor:SI
8512             (zero_extract:SI
8513              (match_dup 1)
8514              (const_int 8)
8515              (const_int 8))
8516             (match_dup 2)))])])
8517
8518 (define_insn "*xorqi_cc_ext_1_rex64"
8519   [(set (reg FLAGS_REG)
8520         (compare
8521           (xor:SI
8522             (zero_extract:SI
8523               (match_operand 1 "ext_register_operand" "0")
8524               (const_int 8)
8525               (const_int 8))
8526             (match_operand:QI 2 "nonmemory_operand" "Qn"))
8527           (const_int 0)))
8528    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8529                          (const_int 8)
8530                          (const_int 8))
8531         (xor:SI
8532           (zero_extract:SI
8533            (match_dup 1)
8534            (const_int 8)
8535            (const_int 8))
8536           (match_dup 2)))]
8537   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8538   "xor{b}\t{%2, %h0|%h0, %2}"
8539   [(set_attr "type" "alu")
8540    (set_attr "modrm" "1")
8541    (set_attr "mode" "QI")])
8542
8543 (define_insn "*xorqi_cc_ext_1"
8544   [(set (reg FLAGS_REG)
8545         (compare
8546           (xor:SI
8547             (zero_extract:SI
8548               (match_operand 1 "ext_register_operand" "0")
8549               (const_int 8)
8550               (const_int 8))
8551             (match_operand:QI 2 "general_operand" "qmn"))
8552           (const_int 0)))
8553    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8554                          (const_int 8)
8555                          (const_int 8))
8556         (xor:SI
8557           (zero_extract:SI
8558            (match_dup 1)
8559            (const_int 8)
8560            (const_int 8))
8561           (match_dup 2)))]
8562   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8563   "xor{b}\t{%2, %h0|%h0, %2}"
8564   [(set_attr "type" "alu")
8565    (set_attr "modrm" "1")
8566    (set_attr "mode" "QI")])
8567 \f
8568 ;; Negation instructions
8569
8570 (define_expand "neg<mode>2"
8571   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8572         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8573   ""
8574   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8575
8576 (define_insn_and_split "*neg<dwi>2_doubleword"
8577   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8578         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8579    (clobber (reg:CC FLAGS_REG))]
8580   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8581   "#"
8582   "reload_completed"
8583   [(parallel
8584     [(set (reg:CCZ FLAGS_REG)
8585           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8586      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8587    (parallel
8588     [(set (match_dup 2)
8589           (plus:DWIH (match_dup 3)
8590                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8591                                 (const_int 0))))
8592      (clobber (reg:CC FLAGS_REG))])
8593    (parallel
8594     [(set (match_dup 2)
8595           (neg:DWIH (match_dup 2)))
8596      (clobber (reg:CC FLAGS_REG))])]
8597   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8598
8599 (define_insn "*neg<mode>2_1"
8600   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8601         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8602    (clobber (reg:CC FLAGS_REG))]
8603   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8604   "neg{<imodesuffix>}\t%0"
8605   [(set_attr "type" "negnot")
8606    (set_attr "mode" "<MODE>")])
8607
8608 ;; Combine is quite creative about this pattern.
8609 (define_insn "*negsi2_1_zext"
8610   [(set (match_operand:DI 0 "register_operand" "=r")
8611         (lshiftrt:DI
8612           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8613                              (const_int 32)))
8614         (const_int 32)))
8615    (clobber (reg:CC FLAGS_REG))]
8616   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8617   "neg{l}\t%k0"
8618   [(set_attr "type" "negnot")
8619    (set_attr "mode" "SI")])
8620
8621 ;; The problem with neg is that it does not perform (compare x 0),
8622 ;; it really performs (compare 0 x), which leaves us with the zero
8623 ;; flag being the only useful item.
8624
8625 (define_insn "*neg<mode>2_cmpz"
8626   [(set (reg:CCZ FLAGS_REG)
8627         (compare:CCZ
8628           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8629                    (const_int 0)))
8630    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8631         (neg:SWI (match_dup 1)))]
8632   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8633   "neg{<imodesuffix>}\t%0"
8634   [(set_attr "type" "negnot")
8635    (set_attr "mode" "<MODE>")])
8636
8637 (define_insn "*negsi2_cmpz_zext"
8638   [(set (reg:CCZ FLAGS_REG)
8639         (compare:CCZ
8640           (lshiftrt:DI
8641             (neg:DI (ashift:DI
8642                       (match_operand:DI 1 "register_operand" "0")
8643                       (const_int 32)))
8644             (const_int 32))
8645           (const_int 0)))
8646    (set (match_operand:DI 0 "register_operand" "=r")
8647         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8648                                         (const_int 32)))
8649                      (const_int 32)))]
8650   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8651   "neg{l}\t%k0"
8652   [(set_attr "type" "negnot")
8653    (set_attr "mode" "SI")])
8654
8655 ;; Changing of sign for FP values is doable using integer unit too.
8656
8657 (define_expand "<code><mode>2"
8658   [(set (match_operand:X87MODEF 0 "register_operand" "")
8659         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8660   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8661   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8662
8663 (define_insn "*absneg<mode>2_mixed"
8664   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8665         (match_operator:MODEF 3 "absneg_operator"
8666           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8667    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8668    (clobber (reg:CC FLAGS_REG))]
8669   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8670   "#")
8671
8672 (define_insn "*absneg<mode>2_sse"
8673   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8674         (match_operator:MODEF 3 "absneg_operator"
8675           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8676    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8677    (clobber (reg:CC FLAGS_REG))]
8678   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8679   "#")
8680
8681 (define_insn "*absneg<mode>2_i387"
8682   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8683         (match_operator:X87MODEF 3 "absneg_operator"
8684           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8685    (use (match_operand 2 "" ""))
8686    (clobber (reg:CC FLAGS_REG))]
8687   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8688   "#")
8689
8690 (define_expand "<code>tf2"
8691   [(set (match_operand:TF 0 "register_operand" "")
8692         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8693   "TARGET_SSE2"
8694   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8695
8696 (define_insn "*absnegtf2_sse"
8697   [(set (match_operand:TF 0 "register_operand" "=x,x")
8698         (match_operator:TF 3 "absneg_operator"
8699           [(match_operand:TF 1 "register_operand" "0,x")]))
8700    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8701    (clobber (reg:CC FLAGS_REG))]
8702   "TARGET_SSE2"
8703   "#")
8704
8705 ;; Splitters for fp abs and neg.
8706
8707 (define_split
8708   [(set (match_operand 0 "fp_register_operand" "")
8709         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8710    (use (match_operand 2 "" ""))
8711    (clobber (reg:CC FLAGS_REG))]
8712   "reload_completed"
8713   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8714
8715 (define_split
8716   [(set (match_operand 0 "register_operand" "")
8717         (match_operator 3 "absneg_operator"
8718           [(match_operand 1 "register_operand" "")]))
8719    (use (match_operand 2 "nonimmediate_operand" ""))
8720    (clobber (reg:CC FLAGS_REG))]
8721   "reload_completed && SSE_REG_P (operands[0])"
8722   [(set (match_dup 0) (match_dup 3))]
8723 {
8724   enum machine_mode mode = GET_MODE (operands[0]);
8725   enum machine_mode vmode = GET_MODE (operands[2]);
8726   rtx tmp;
8727
8728   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8729   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8730   if (operands_match_p (operands[0], operands[2]))
8731     {
8732       tmp = operands[1];
8733       operands[1] = operands[2];
8734       operands[2] = tmp;
8735     }
8736   if (GET_CODE (operands[3]) == ABS)
8737     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8738   else
8739     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8740   operands[3] = tmp;
8741 })
8742
8743 (define_split
8744   [(set (match_operand:SF 0 "register_operand" "")
8745         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8746    (use (match_operand:V4SF 2 "" ""))
8747    (clobber (reg:CC FLAGS_REG))]
8748   "reload_completed"
8749   [(parallel [(set (match_dup 0) (match_dup 1))
8750               (clobber (reg:CC FLAGS_REG))])]
8751 {
8752   rtx tmp;
8753   operands[0] = gen_lowpart (SImode, operands[0]);
8754   if (GET_CODE (operands[1]) == ABS)
8755     {
8756       tmp = gen_int_mode (0x7fffffff, SImode);
8757       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8758     }
8759   else
8760     {
8761       tmp = gen_int_mode (0x80000000, SImode);
8762       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8763     }
8764   operands[1] = tmp;
8765 })
8766
8767 (define_split
8768   [(set (match_operand:DF 0 "register_operand" "")
8769         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8770    (use (match_operand 2 "" ""))
8771    (clobber (reg:CC FLAGS_REG))]
8772   "reload_completed"
8773   [(parallel [(set (match_dup 0) (match_dup 1))
8774               (clobber (reg:CC FLAGS_REG))])]
8775 {
8776   rtx tmp;
8777   if (TARGET_64BIT)
8778     {
8779       tmp = gen_lowpart (DImode, operands[0]);
8780       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8781       operands[0] = tmp;
8782
8783       if (GET_CODE (operands[1]) == ABS)
8784         tmp = const0_rtx;
8785       else
8786         tmp = gen_rtx_NOT (DImode, tmp);
8787     }
8788   else
8789     {
8790       operands[0] = gen_highpart (SImode, operands[0]);
8791       if (GET_CODE (operands[1]) == ABS)
8792         {
8793           tmp = gen_int_mode (0x7fffffff, SImode);
8794           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8795         }
8796       else
8797         {
8798           tmp = gen_int_mode (0x80000000, SImode);
8799           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8800         }
8801     }
8802   operands[1] = tmp;
8803 })
8804
8805 (define_split
8806   [(set (match_operand:XF 0 "register_operand" "")
8807         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8808    (use (match_operand 2 "" ""))
8809    (clobber (reg:CC FLAGS_REG))]
8810   "reload_completed"
8811   [(parallel [(set (match_dup 0) (match_dup 1))
8812               (clobber (reg:CC FLAGS_REG))])]
8813 {
8814   rtx tmp;
8815   operands[0] = gen_rtx_REG (SImode,
8816                              true_regnum (operands[0])
8817                              + (TARGET_64BIT ? 1 : 2));
8818   if (GET_CODE (operands[1]) == ABS)
8819     {
8820       tmp = GEN_INT (0x7fff);
8821       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8822     }
8823   else
8824     {
8825       tmp = GEN_INT (0x8000);
8826       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8827     }
8828   operands[1] = tmp;
8829 })
8830
8831 ;; Conditionalize these after reload. If they match before reload, we
8832 ;; lose the clobber and ability to use integer instructions.
8833
8834 (define_insn "*<code><mode>2_1"
8835   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8836         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8837   "TARGET_80387
8838    && (reload_completed
8839        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8840   "f<absneg_mnemonic>"
8841   [(set_attr "type" "fsgn")
8842    (set_attr "mode" "<MODE>")])
8843
8844 (define_insn "*<code>extendsfdf2"
8845   [(set (match_operand:DF 0 "register_operand" "=f")
8846         (absneg:DF (float_extend:DF
8847                      (match_operand:SF 1 "register_operand" "0"))))]
8848   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8849   "f<absneg_mnemonic>"
8850   [(set_attr "type" "fsgn")
8851    (set_attr "mode" "DF")])
8852
8853 (define_insn "*<code>extendsfxf2"
8854   [(set (match_operand:XF 0 "register_operand" "=f")
8855         (absneg:XF (float_extend:XF
8856                      (match_operand:SF 1 "register_operand" "0"))))]
8857   "TARGET_80387"
8858   "f<absneg_mnemonic>"
8859   [(set_attr "type" "fsgn")
8860    (set_attr "mode" "XF")])
8861
8862 (define_insn "*<code>extenddfxf2"
8863   [(set (match_operand:XF 0 "register_operand" "=f")
8864         (absneg:XF (float_extend:XF
8865                      (match_operand:DF 1 "register_operand" "0"))))]
8866   "TARGET_80387"
8867   "f<absneg_mnemonic>"
8868   [(set_attr "type" "fsgn")
8869    (set_attr "mode" "XF")])
8870
8871 ;; Copysign instructions
8872
8873 (define_mode_iterator CSGNMODE [SF DF TF])
8874 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8875
8876 (define_expand "copysign<mode>3"
8877   [(match_operand:CSGNMODE 0 "register_operand" "")
8878    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8879    (match_operand:CSGNMODE 2 "register_operand" "")]
8880   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8881    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8882   "ix86_expand_copysign (operands); DONE;")
8883
8884 (define_insn_and_split "copysign<mode>3_const"
8885   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8886         (unspec:CSGNMODE
8887           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8888            (match_operand:CSGNMODE 2 "register_operand" "0")
8889            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8890           UNSPEC_COPYSIGN))]
8891   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8892    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8893   "#"
8894   "&& reload_completed"
8895   [(const_int 0)]
8896   "ix86_split_copysign_const (operands); DONE;")
8897
8898 (define_insn "copysign<mode>3_var"
8899   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8900         (unspec:CSGNMODE
8901           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8902            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8903            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8904            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8905           UNSPEC_COPYSIGN))
8906    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8907   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8908    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8909   "#")
8910
8911 (define_split
8912   [(set (match_operand:CSGNMODE 0 "register_operand" "")
8913         (unspec:CSGNMODE
8914           [(match_operand:CSGNMODE 2 "register_operand" "")
8915            (match_operand:CSGNMODE 3 "register_operand" "")
8916            (match_operand:<CSGNVMODE> 4 "" "")
8917            (match_operand:<CSGNVMODE> 5 "" "")]
8918           UNSPEC_COPYSIGN))
8919    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8920   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8921     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8922    && reload_completed"
8923   [(const_int 0)]
8924   "ix86_split_copysign_var (operands); DONE;")
8925 \f
8926 ;; One complement instructions
8927
8928 (define_expand "one_cmpl<mode>2"
8929   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8930         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8931   ""
8932   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8933
8934 (define_insn "*one_cmpl<mode>2_1"
8935   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8936         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8937   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8938   "not{<imodesuffix>}\t%0"
8939   [(set_attr "type" "negnot")
8940    (set_attr "mode" "<MODE>")])
8941
8942 ;; %%% Potential partial reg stall on alternative 1.  What to do?
8943 (define_insn "*one_cmplqi2_1"
8944   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8945         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8946   "ix86_unary_operator_ok (NOT, QImode, operands)"
8947   "@
8948    not{b}\t%0
8949    not{l}\t%k0"
8950   [(set_attr "type" "negnot")
8951    (set_attr "mode" "QI,SI")])
8952
8953 ;; ??? Currently never generated - xor is used instead.
8954 (define_insn "*one_cmplsi2_1_zext"
8955   [(set (match_operand:DI 0 "register_operand" "=r")
8956         (zero_extend:DI
8957           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8958   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8959   "not{l}\t%k0"
8960   [(set_attr "type" "negnot")
8961    (set_attr "mode" "SI")])
8962
8963 (define_insn "*one_cmpl<mode>2_2"
8964   [(set (reg FLAGS_REG)
8965         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8966                  (const_int 0)))
8967    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8968         (not:SWI (match_dup 1)))]
8969   "ix86_match_ccmode (insn, CCNOmode)
8970    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8971   "#"
8972   [(set_attr "type" "alu1")
8973    (set_attr "mode" "<MODE>")])
8974
8975 (define_split
8976   [(set (match_operand 0 "flags_reg_operand" "")
8977         (match_operator 2 "compare_operator"
8978           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8979            (const_int 0)]))
8980    (set (match_operand:SWI 1 "nonimmediate_operand" "")
8981         (not:SWI (match_dup 3)))]
8982   "ix86_match_ccmode (insn, CCNOmode)"
8983   [(parallel [(set (match_dup 0)
8984                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8985                                     (const_int 0)]))
8986               (set (match_dup 1)
8987                    (xor:SWI (match_dup 3) (const_int -1)))])])
8988
8989 ;; ??? Currently never generated - xor is used instead.
8990 (define_insn "*one_cmplsi2_2_zext"
8991   [(set (reg FLAGS_REG)
8992         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8993                  (const_int 0)))
8994    (set (match_operand:DI 0 "register_operand" "=r")
8995         (zero_extend:DI (not:SI (match_dup 1))))]
8996   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8997    && ix86_unary_operator_ok (NOT, SImode, operands)"
8998   "#"
8999   [(set_attr "type" "alu1")
9000    (set_attr "mode" "SI")])
9001
9002 (define_split
9003   [(set (match_operand 0 "flags_reg_operand" "")
9004         (match_operator 2 "compare_operator"
9005           [(not:SI (match_operand:SI 3 "register_operand" ""))
9006            (const_int 0)]))
9007    (set (match_operand:DI 1 "register_operand" "")
9008         (zero_extend:DI (not:SI (match_dup 3))))]
9009   "ix86_match_ccmode (insn, CCNOmode)"
9010   [(parallel [(set (match_dup 0)
9011                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9012                                     (const_int 0)]))
9013               (set (match_dup 1)
9014                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9015 \f
9016 ;; Shift instructions
9017
9018 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9019 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9020 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9021 ;; from the assembler input.
9022 ;;
9023 ;; This instruction shifts the target reg/mem as usual, but instead of
9024 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9025 ;; is a left shift double, bits are taken from the high order bits of
9026 ;; reg, else if the insn is a shift right double, bits are taken from the
9027 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9028 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9029 ;;
9030 ;; Since sh[lr]d does not change the `reg' operand, that is done
9031 ;; separately, making all shifts emit pairs of shift double and normal
9032 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9033 ;; support a 63 bit shift, each shift where the count is in a reg expands
9034 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9035 ;;
9036 ;; If the shift count is a constant, we need never emit more than one
9037 ;; shift pair, instead using moves and sign extension for counts greater
9038 ;; than 31.
9039
9040 (define_expand "ashl<mode>3"
9041   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9042         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9043                       (match_operand:QI 2 "nonmemory_operand" "")))]
9044   ""
9045   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9046
9047 (define_insn "*ashl<mode>3_doubleword"
9048   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9049         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9050                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9051    (clobber (reg:CC FLAGS_REG))]
9052   ""
9053   "#"
9054   [(set_attr "type" "multi")])
9055
9056 (define_split
9057   [(set (match_operand:DWI 0 "register_operand" "")
9058         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9059                     (match_operand:QI 2 "nonmemory_operand" "")))
9060    (clobber (reg:CC FLAGS_REG))]
9061   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9062   [(const_int 0)]
9063   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9064
9065 ;; By default we don't ask for a scratch register, because when DWImode
9066 ;; values are manipulated, registers are already at a premium.  But if
9067 ;; we have one handy, we won't turn it away.
9068
9069 (define_peephole2
9070   [(match_scratch:DWIH 3 "r")
9071    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9072                    (ashift:<DWI>
9073                      (match_operand:<DWI> 1 "nonmemory_operand" "")
9074                      (match_operand:QI 2 "nonmemory_operand" "")))
9075               (clobber (reg:CC FLAGS_REG))])
9076    (match_dup 3)]
9077   "TARGET_CMOVE"
9078   [(const_int 0)]
9079   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9080
9081 (define_insn "x86_64_shld"
9082   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9083         (ior:DI (ashift:DI (match_dup 0)
9084                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9085                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9086                   (minus:QI (const_int 64) (match_dup 2)))))
9087    (clobber (reg:CC FLAGS_REG))]
9088   "TARGET_64BIT"
9089   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9090   [(set_attr "type" "ishift")
9091    (set_attr "prefix_0f" "1")
9092    (set_attr "mode" "DI")
9093    (set_attr "athlon_decode" "vector")
9094    (set_attr "amdfam10_decode" "vector")])
9095
9096 (define_insn "x86_shld"
9097   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9098         (ior:SI (ashift:SI (match_dup 0)
9099                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9100                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9101                   (minus:QI (const_int 32) (match_dup 2)))))
9102    (clobber (reg:CC FLAGS_REG))]
9103   ""
9104   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9105   [(set_attr "type" "ishift")
9106    (set_attr "prefix_0f" "1")
9107    (set_attr "mode" "SI")
9108    (set_attr "pent_pair" "np")
9109    (set_attr "athlon_decode" "vector")
9110    (set_attr "amdfam10_decode" "vector")])
9111
9112 (define_expand "x86_shift<mode>_adj_1"
9113   [(set (reg:CCZ FLAGS_REG)
9114         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9115                              (match_dup 4))
9116                      (const_int 0)))
9117    (set (match_operand:SWI48 0 "register_operand" "")
9118         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9119                             (match_operand:SWI48 1 "register_operand" "")
9120                             (match_dup 0)))
9121    (set (match_dup 1)
9122         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9123                             (match_operand:SWI48 3 "register_operand" "r")
9124                             (match_dup 1)))]
9125   "TARGET_CMOVE"
9126   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9127
9128 (define_expand "x86_shift<mode>_adj_2"
9129   [(use (match_operand:SWI48 0 "register_operand" ""))
9130    (use (match_operand:SWI48 1 "register_operand" ""))
9131    (use (match_operand:QI 2 "register_operand" ""))]
9132   ""
9133 {
9134   rtx label = gen_label_rtx ();
9135   rtx tmp;
9136
9137   emit_insn (gen_testqi_ccz_1 (operands[2],
9138                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9139
9140   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9141   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9142   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9143                               gen_rtx_LABEL_REF (VOIDmode, label),
9144                               pc_rtx);
9145   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9146   JUMP_LABEL (tmp) = label;
9147
9148   emit_move_insn (operands[0], operands[1]);
9149   ix86_expand_clear (operands[1]);
9150
9151   emit_label (label);
9152   LABEL_NUSES (label) = 1;
9153
9154   DONE;
9155 })
9156
9157 (define_insn "*ashl<mode>3_1"
9158   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9159         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9160                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9161    (clobber (reg:CC FLAGS_REG))]
9162   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9163 {
9164   switch (get_attr_type (insn))
9165     {
9166     case TYPE_LEA:
9167       return "#";
9168
9169     case TYPE_ALU:
9170       gcc_assert (operands[2] == const1_rtx);
9171       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9172       return "add{<imodesuffix>}\t%0, %0";
9173
9174     default:
9175       if (operands[2] == const1_rtx
9176           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9177         return "sal{<imodesuffix>}\t%0";
9178       else
9179         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9180     }
9181 }
9182   [(set (attr "type")
9183      (cond [(eq_attr "alternative" "1")
9184               (const_string "lea")
9185             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9186                           (const_int 0))
9187                       (match_operand 0 "register_operand" ""))
9188                  (match_operand 2 "const1_operand" ""))
9189               (const_string "alu")
9190            ]
9191            (const_string "ishift")))
9192    (set (attr "length_immediate")
9193      (if_then_else
9194        (ior (eq_attr "type" "alu")
9195             (and (eq_attr "type" "ishift")
9196                  (and (match_operand 2 "const1_operand" "")
9197                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9198                           (const_int 0)))))
9199        (const_string "0")
9200        (const_string "*")))
9201    (set_attr "mode" "<MODE>")])
9202
9203 (define_insn "*ashlsi3_1_zext"
9204   [(set (match_operand:DI 0 "register_operand" "=r,r")
9205         (zero_extend:DI
9206           (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9207                      (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9208    (clobber (reg:CC FLAGS_REG))]
9209   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9210 {
9211   switch (get_attr_type (insn))
9212     {
9213     case TYPE_LEA:
9214       return "#";
9215
9216     case TYPE_ALU:
9217       gcc_assert (operands[2] == const1_rtx);
9218       return "add{l}\t%k0, %k0";
9219
9220     default:
9221       if (operands[2] == const1_rtx
9222           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9223         return "sal{l}\t%k0";
9224       else
9225         return "sal{l}\t{%2, %k0|%k0, %2}";
9226     }
9227 }
9228   [(set (attr "type")
9229      (cond [(eq_attr "alternative" "1")
9230               (const_string "lea")
9231             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9232                      (const_int 0))
9233                  (match_operand 2 "const1_operand" ""))
9234               (const_string "alu")
9235            ]
9236            (const_string "ishift")))
9237    (set (attr "length_immediate")
9238      (if_then_else
9239        (ior (eq_attr "type" "alu")
9240             (and (eq_attr "type" "ishift")
9241                  (and (match_operand 2 "const1_operand" "")
9242                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9243                           (const_int 0)))))
9244        (const_string "0")
9245        (const_string "*")))
9246    (set_attr "mode" "SI")])
9247
9248 (define_insn "*ashlhi3_1"
9249   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9250         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9251                    (match_operand:QI 2 "nonmemory_operand" "cI")))
9252    (clobber (reg:CC FLAGS_REG))]
9253   "TARGET_PARTIAL_REG_STALL
9254    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9255 {
9256   switch (get_attr_type (insn))
9257     {
9258     case TYPE_ALU:
9259       gcc_assert (operands[2] == const1_rtx);
9260       return "add{w}\t%0, %0";
9261
9262     default:
9263       if (operands[2] == const1_rtx
9264           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9265         return "sal{w}\t%0";
9266       else
9267         return "sal{w}\t{%2, %0|%0, %2}";
9268     }
9269 }
9270   [(set (attr "type")
9271      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9272                           (const_int 0))
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                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9284                           (const_int 0)))))
9285        (const_string "0")
9286        (const_string "*")))
9287    (set_attr "mode" "HI")])
9288
9289 (define_insn "*ashlhi3_1_lea"
9290   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9291         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9292                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9293    (clobber (reg:CC FLAGS_REG))]
9294   "!TARGET_PARTIAL_REG_STALL
9295    && ix86_binary_operator_ok (ASHIFT, HImode, 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       return "add{w}\t%0, %0";
9305
9306     default:
9307       if (operands[2] == const1_rtx
9308           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9309         return "sal{w}\t%0";
9310       else
9311         return "sal{w}\t{%2, %0|%0, %2}";
9312     }
9313 }
9314   [(set (attr "type")
9315      (cond [(eq_attr "alternative" "1")
9316               (const_string "lea")
9317             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9318                           (const_int 0))
9319                       (match_operand 0 "register_operand" ""))
9320                  (match_operand 2 "const1_operand" ""))
9321               (const_string "alu")
9322            ]
9323            (const_string "ishift")))
9324    (set (attr "length_immediate")
9325      (if_then_else
9326        (ior (eq_attr "type" "alu")
9327             (and (eq_attr "type" "ishift")
9328                  (and (match_operand 2 "const1_operand" "")
9329                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9330                           (const_int 0)))))
9331        (const_string "0")
9332        (const_string "*")))
9333    (set_attr "mode" "HI,SI")])
9334
9335 (define_insn "*ashlqi3_1"
9336   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9337         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9338                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9339    (clobber (reg:CC FLAGS_REG))]
9340   "TARGET_PARTIAL_REG_STALL
9341    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9342 {
9343   switch (get_attr_type (insn))
9344     {
9345     case TYPE_ALU:
9346       gcc_assert (operands[2] == const1_rtx);
9347       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9348         return "add{l}\t%k0, %k0";
9349       else
9350         return "add{b}\t%0, %0";
9351
9352     default:
9353       if (operands[2] == const1_rtx
9354           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9355         {
9356           if (get_attr_mode (insn) == MODE_SI)
9357             return "sal{l}\t%k0";
9358           else
9359             return "sal{b}\t%0";
9360         }
9361       else
9362         {
9363           if (get_attr_mode (insn) == MODE_SI)
9364             return "sal{l}\t{%2, %k0|%k0, %2}";
9365           else
9366             return "sal{b}\t{%2, %0|%0, %2}";
9367         }
9368     }
9369 }
9370   [(set (attr "type")
9371      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9372                           (const_int 0))
9373                       (match_operand 0 "register_operand" ""))
9374                  (match_operand 2 "const1_operand" ""))
9375               (const_string "alu")
9376            ]
9377            (const_string "ishift")))
9378    (set (attr "length_immediate")
9379      (if_then_else
9380        (ior (eq_attr "type" "alu")
9381             (and (eq_attr "type" "ishift")
9382                  (and (match_operand 2 "const1_operand" "")
9383                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9384                           (const_int 0)))))
9385        (const_string "0")
9386        (const_string "*")))
9387    (set_attr "mode" "QI,SI")])
9388
9389 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9390 (define_insn "*ashlqi3_1_lea"
9391   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9392         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9393                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9394    (clobber (reg:CC FLAGS_REG))]
9395   "!TARGET_PARTIAL_REG_STALL
9396    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9397 {
9398   switch (get_attr_type (insn))
9399     {
9400     case TYPE_LEA:
9401       return "#";
9402
9403     case TYPE_ALU:
9404       gcc_assert (operands[2] == const1_rtx);
9405       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9406         return "add{l}\t%k0, %k0";
9407       else
9408         return "add{b}\t%0, %0";
9409
9410     default:
9411       if (operands[2] == const1_rtx
9412           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9413         {
9414           if (get_attr_mode (insn) == MODE_SI)
9415             return "sal{l}\t%k0";
9416           else
9417             return "sal{b}\t%0";
9418         }
9419       else
9420         {
9421           if (get_attr_mode (insn) == MODE_SI)
9422             return "sal{l}\t{%2, %k0|%k0, %2}";
9423           else
9424             return "sal{b}\t{%2, %0|%0, %2}";
9425         }
9426     }
9427 }
9428   [(set (attr "type")
9429      (cond [(eq_attr "alternative" "2")
9430               (const_string "lea")
9431             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9432                           (const_int 0))
9433                       (match_operand 0 "register_operand" ""))
9434                  (match_operand 2 "const1_operand" ""))
9435               (const_string "alu")
9436            ]
9437            (const_string "ishift")))
9438    (set (attr "length_immediate")
9439      (if_then_else
9440        (ior (eq_attr "type" "alu")
9441             (and (eq_attr "type" "ishift")
9442                  (and (match_operand 2 "const1_operand" "")
9443                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9444                           (const_int 0)))))
9445        (const_string "0")
9446        (const_string "*")))
9447    (set_attr "mode" "QI,SI,SI")])
9448
9449 (define_insn "*ashlqi3_1_slp"
9450   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9451         (ashift:QI (match_dup 0)
9452                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9453    (clobber (reg:CC FLAGS_REG))]
9454   "(optimize_function_for_size_p (cfun)
9455     || !TARGET_PARTIAL_FLAG_REG_STALL
9456     || (operands[1] == const1_rtx
9457         && (TARGET_SHIFT1
9458             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9459 {
9460   switch (get_attr_type (insn))
9461     {
9462     case TYPE_ALU:
9463       gcc_assert (operands[1] == const1_rtx);
9464       return "add{b}\t%0, %0";
9465
9466     default:
9467       if (operands[1] == const1_rtx
9468           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9469         return "sal{b}\t%0";
9470       else
9471         return "sal{b}\t{%1, %0|%0, %1}";
9472     }
9473 }
9474   [(set (attr "type")
9475      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9476                           (const_int 0))
9477                       (match_operand 0 "register_operand" ""))
9478                  (match_operand 1 "const1_operand" ""))
9479               (const_string "alu")
9480            ]
9481            (const_string "ishift1")))
9482    (set (attr "length_immediate")
9483      (if_then_else
9484        (ior (eq_attr "type" "alu")
9485             (and (eq_attr "type" "ishift1")
9486                  (and (match_operand 1 "const1_operand" "")
9487                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9488                           (const_int 0)))))
9489        (const_string "0")
9490        (const_string "*")))
9491    (set_attr "mode" "QI")])
9492
9493 ;; Convert lea to the lea pattern to avoid flags dependency.
9494 (define_split
9495   [(set (match_operand 0 "register_operand" "")
9496         (ashift (match_operand 1 "index_register_operand" "")
9497                 (match_operand:QI 2 "const_int_operand" "")))
9498    (clobber (reg:CC FLAGS_REG))]
9499   "reload_completed
9500    && true_regnum (operands[0]) != true_regnum (operands[1])"
9501   [(const_int 0)]
9502 {
9503   rtx pat;
9504   enum machine_mode mode = GET_MODE (operands[0]);
9505
9506   if (mode != Pmode)
9507     operands[1] = gen_lowpart (Pmode, operands[1]);
9508   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9509
9510   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9511
9512   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9513     operands[0] = gen_lowpart (SImode, operands[0]);
9514
9515   if (TARGET_64BIT && mode != Pmode)
9516     pat = gen_rtx_SUBREG (SImode, pat, 0);
9517
9518   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9519   DONE;
9520 })
9521
9522 ;; Convert lea to the lea pattern to avoid flags dependency.
9523 (define_split
9524   [(set (match_operand:DI 0 "register_operand" "")
9525         (zero_extend:DI
9526           (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9527                      (match_operand:QI 2 "const_int_operand" ""))))
9528    (clobber (reg:CC FLAGS_REG))]
9529   "TARGET_64BIT && reload_completed
9530    && true_regnum (operands[0]) != true_regnum (operands[1])"
9531   [(set (match_dup 0)
9532         (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9533 {
9534   operands[1] = gen_lowpart (DImode, operands[1]);
9535   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9536 })
9537
9538 ;; This pattern can't accept a variable shift count, since shifts by
9539 ;; zero don't affect the flags.  We assume that shifts by constant
9540 ;; zero are optimized away.
9541 (define_insn "*ashl<mode>3_cmp"
9542   [(set (reg FLAGS_REG)
9543         (compare
9544           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9545                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9546           (const_int 0)))
9547    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9548         (ashift:SWI (match_dup 1) (match_dup 2)))]
9549   "(optimize_function_for_size_p (cfun)
9550     || !TARGET_PARTIAL_FLAG_REG_STALL
9551     || (operands[2] == const1_rtx
9552         && (TARGET_SHIFT1
9553             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9554    && ix86_match_ccmode (insn, CCGOCmode)
9555    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9556 {
9557   switch (get_attr_type (insn))
9558     {
9559     case TYPE_ALU:
9560       gcc_assert (operands[2] == const1_rtx);
9561       return "add{<imodesuffix>}\t%0, %0";
9562
9563     default:
9564       if (operands[2] == const1_rtx
9565           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9566         return "sal{<imodesuffix>}\t%0";
9567       else
9568         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9569     }
9570 }
9571   [(set (attr "type")
9572      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9573                           (const_int 0))
9574                       (match_operand 0 "register_operand" ""))
9575                  (match_operand 2 "const1_operand" ""))
9576               (const_string "alu")
9577            ]
9578            (const_string "ishift")))
9579    (set (attr "length_immediate")
9580      (if_then_else
9581        (ior (eq_attr "type" "alu")
9582             (and (eq_attr "type" "ishift")
9583                  (and (match_operand 2 "const1_operand" "")
9584                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9585                           (const_int 0)))))
9586        (const_string "0")
9587        (const_string "*")))
9588    (set_attr "mode" "<MODE>")])
9589
9590 (define_insn "*ashlsi3_cmp_zext"
9591   [(set (reg FLAGS_REG)
9592         (compare
9593           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9594                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9595           (const_int 0)))
9596    (set (match_operand:DI 0 "register_operand" "=r")
9597         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9598   "TARGET_64BIT
9599    && (optimize_function_for_size_p (cfun)
9600        || !TARGET_PARTIAL_FLAG_REG_STALL
9601        || (operands[2] == const1_rtx
9602            && (TARGET_SHIFT1
9603                || TARGET_DOUBLE_WITH_ADD)))
9604    && ix86_match_ccmode (insn, CCGOCmode)
9605    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9606 {
9607   switch (get_attr_type (insn))
9608     {
9609     case TYPE_ALU:
9610       gcc_assert (operands[2] == const1_rtx);
9611       return "add{l}\t%k0, %k0";
9612
9613     default:
9614       if (operands[2] == const1_rtx
9615           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9616         return "sal{l}\t%k0";
9617       else
9618         return "sal{l}\t{%2, %k0|%k0, %2}";
9619     }
9620 }
9621   [(set (attr "type")
9622      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9623                      (const_int 0))
9624                  (match_operand 2 "const1_operand" ""))
9625               (const_string "alu")
9626            ]
9627            (const_string "ishift")))
9628    (set (attr "length_immediate")
9629      (if_then_else
9630        (ior (eq_attr "type" "alu")
9631             (and (eq_attr "type" "ishift")
9632                  (and (match_operand 2 "const1_operand" "")
9633                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9634                           (const_int 0)))))
9635        (const_string "0")
9636        (const_string "*")))
9637    (set_attr "mode" "SI")])
9638
9639 (define_insn "*ashl<mode>3_cconly"
9640   [(set (reg FLAGS_REG)
9641         (compare
9642           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9643                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9644           (const_int 0)))
9645    (clobber (match_scratch:SWI 0 "=<r>"))]
9646   "(optimize_function_for_size_p (cfun)
9647     || !TARGET_PARTIAL_FLAG_REG_STALL
9648     || (operands[2] == const1_rtx
9649         && (TARGET_SHIFT1
9650             || TARGET_DOUBLE_WITH_ADD)))
9651    && ix86_match_ccmode (insn, CCGOCmode)
9652    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9653 {
9654   switch (get_attr_type (insn))
9655     {
9656     case TYPE_ALU:
9657       gcc_assert (operands[2] == const1_rtx);
9658       return "add{<imodesuffix>}\t%0, %0";
9659
9660     default:
9661       if (operands[2] == const1_rtx
9662           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9663         return "sal{<imodesuffix>}\t%0";
9664       else
9665         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9666     }
9667 }
9668   [(set (attr "type")
9669      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9670                           (const_int 0))
9671                       (match_operand 0 "register_operand" ""))
9672                  (match_operand 2 "const1_operand" ""))
9673               (const_string "alu")
9674            ]
9675            (const_string "ishift")))
9676    (set (attr "length_immediate")
9677      (if_then_else
9678        (ior (eq_attr "type" "alu")
9679             (and (eq_attr "type" "ishift")
9680                  (and (match_operand 2 "const1_operand" "")
9681                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9682                           (const_int 0)))))
9683        (const_string "0")
9684        (const_string "*")))
9685    (set_attr "mode" "<MODE>")])
9686
9687 ;; See comment above `ashl<mode>3' about how this works.
9688
9689 (define_expand "<shiftrt_insn><mode>3"
9690   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9691         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9692                            (match_operand:QI 2 "nonmemory_operand" "")))]
9693   ""
9694   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9695
9696 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9697   [(set (match_operand:DWI 0 "register_operand" "=r")
9698         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9699                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9700    (clobber (reg:CC FLAGS_REG))]
9701   ""
9702   "#"
9703   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9704   [(const_int 0)]
9705   "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9706   [(set_attr "type" "multi")])
9707
9708 ;; By default we don't ask for a scratch register, because when DWImode
9709 ;; values are manipulated, registers are already at a premium.  But if
9710 ;; we have one handy, we won't turn it away.
9711
9712 (define_peephole2
9713   [(match_scratch:DWIH 3 "r")
9714    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9715                    (any_shiftrt:<DWI>
9716                      (match_operand:<DWI> 1 "register_operand" "")
9717                      (match_operand:QI 2 "nonmemory_operand" "")))
9718               (clobber (reg:CC FLAGS_REG))])
9719    (match_dup 3)]
9720   "TARGET_CMOVE"
9721   [(const_int 0)]
9722   "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9723
9724 (define_insn "x86_64_shrd"
9725   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9726         (ior:DI (ashiftrt:DI (match_dup 0)
9727                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9728                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9729                   (minus:QI (const_int 64) (match_dup 2)))))
9730    (clobber (reg:CC FLAGS_REG))]
9731   "TARGET_64BIT"
9732   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9733   [(set_attr "type" "ishift")
9734    (set_attr "prefix_0f" "1")
9735    (set_attr "mode" "DI")
9736    (set_attr "athlon_decode" "vector")
9737    (set_attr "amdfam10_decode" "vector")])
9738
9739 (define_insn "x86_shrd"
9740   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9741         (ior:SI (ashiftrt:SI (match_dup 0)
9742                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9743                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9744                   (minus:QI (const_int 32) (match_dup 2)))))
9745    (clobber (reg:CC FLAGS_REG))]
9746   ""
9747   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9748   [(set_attr "type" "ishift")
9749    (set_attr "prefix_0f" "1")
9750    (set_attr "mode" "SI")
9751    (set_attr "pent_pair" "np")
9752    (set_attr "athlon_decode" "vector")
9753    (set_attr "amdfam10_decode" "vector")])
9754
9755 (define_insn "ashrdi3_cvt"
9756   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9757         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9758                      (match_operand:QI 2 "const_int_operand" "")))
9759    (clobber (reg:CC FLAGS_REG))]
9760   "TARGET_64BIT && INTVAL (operands[2]) == 63
9761    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9762    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9763   "@
9764    {cqto|cqo}
9765    sar{q}\t{%2, %0|%0, %2}"
9766   [(set_attr "type" "imovx,ishift")
9767    (set_attr "prefix_0f" "0,*")
9768    (set_attr "length_immediate" "0,*")
9769    (set_attr "modrm" "0,1")
9770    (set_attr "mode" "DI")])
9771
9772 (define_insn "ashrsi3_cvt"
9773   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9774         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9775                      (match_operand:QI 2 "const_int_operand" "")))
9776    (clobber (reg:CC FLAGS_REG))]
9777   "INTVAL (operands[2]) == 31
9778    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9779    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9780   "@
9781    {cltd|cdq}
9782    sar{l}\t{%2, %0|%0, %2}"
9783   [(set_attr "type" "imovx,ishift")
9784    (set_attr "prefix_0f" "0,*")
9785    (set_attr "length_immediate" "0,*")
9786    (set_attr "modrm" "0,1")
9787    (set_attr "mode" "SI")])
9788
9789 (define_insn "*ashrsi3_cvt_zext"
9790   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9791         (zero_extend:DI
9792           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9793                        (match_operand:QI 2 "const_int_operand" ""))))
9794    (clobber (reg:CC FLAGS_REG))]
9795   "TARGET_64BIT && INTVAL (operands[2]) == 31
9796    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9797    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9798   "@
9799    {cltd|cdq}
9800    sar{l}\t{%2, %k0|%k0, %2}"
9801   [(set_attr "type" "imovx,ishift")
9802    (set_attr "prefix_0f" "0,*")
9803    (set_attr "length_immediate" "0,*")
9804    (set_attr "modrm" "0,1")
9805    (set_attr "mode" "SI")])
9806
9807 (define_expand "x86_shift<mode>_adj_3"
9808   [(use (match_operand:SWI48 0 "register_operand" ""))
9809    (use (match_operand:SWI48 1 "register_operand" ""))
9810    (use (match_operand:QI 2 "register_operand" ""))]
9811   ""
9812 {
9813   rtx label = gen_label_rtx ();
9814   rtx tmp;
9815
9816   emit_insn (gen_testqi_ccz_1 (operands[2],
9817                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9818
9819   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9820   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9821   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9822                               gen_rtx_LABEL_REF (VOIDmode, label),
9823                               pc_rtx);
9824   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9825   JUMP_LABEL (tmp) = label;
9826
9827   emit_move_insn (operands[0], operands[1]);
9828   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9829                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9830   emit_label (label);
9831   LABEL_NUSES (label) = 1;
9832
9833   DONE;
9834 })
9835
9836 (define_insn "*<shiftrt_insn><mode>3_1"
9837   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9838         (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9839                          (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9840    (clobber (reg:CC FLAGS_REG))]
9841   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9842 {
9843   if (operands[2] == const1_rtx
9844       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9845     return "<shiftrt>{<imodesuffix>}\t%0";
9846   else
9847     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9848 }
9849   [(set_attr "type" "ishift")
9850    (set (attr "length_immediate")
9851      (if_then_else
9852        (and (match_operand 2 "const1_operand" "")
9853             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9854                 (const_int 0)))
9855        (const_string "0")
9856        (const_string "*")))
9857    (set_attr "mode" "<MODE>")])
9858
9859 (define_insn "*<shiftrt_insn>si3_1_zext"
9860   [(set (match_operand:DI 0 "register_operand" "=r")
9861         (zero_extend:DI
9862           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9863                           (match_operand:QI 2 "nonmemory_operand" "cI"))))
9864    (clobber (reg:CC FLAGS_REG))]
9865   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9866 {
9867   if (operands[2] == const1_rtx
9868       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9869     return "<shiftrt>{l}\t%k0";
9870   else
9871     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9872 }
9873   [(set_attr "type" "ishift")
9874    (set (attr "length_immediate")
9875      (if_then_else
9876        (and (match_operand 2 "const1_operand" "")
9877             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9878                 (const_int 0)))
9879        (const_string "0")
9880        (const_string "*")))
9881    (set_attr "mode" "SI")])
9882
9883 (define_insn "*<shiftrt_insn>qi3_1_slp"
9884   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9885         (any_shiftrt:QI (match_dup 0)
9886                         (match_operand:QI 1 "nonmemory_operand" "cI")))
9887    (clobber (reg:CC FLAGS_REG))]
9888   "(optimize_function_for_size_p (cfun)
9889     || !TARGET_PARTIAL_REG_STALL
9890     || (operands[1] == const1_rtx
9891         && TARGET_SHIFT1))"
9892 {
9893   if (operands[1] == const1_rtx
9894       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9895     return "<shiftrt>{b}\t%0";
9896   else
9897     return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9898 }
9899   [(set_attr "type" "ishift1")
9900    (set (attr "length_immediate")
9901      (if_then_else
9902        (and (match_operand 1 "const1_operand" "")
9903             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9904                 (const_int 0)))
9905        (const_string "0")
9906        (const_string "*")))
9907    (set_attr "mode" "QI")])
9908
9909 ;; This pattern can't accept a variable shift count, since shifts by
9910 ;; zero don't affect the flags.  We assume that shifts by constant
9911 ;; zero are optimized away.
9912 (define_insn "*<shiftrt_insn><mode>3_cmp"
9913   [(set (reg FLAGS_REG)
9914         (compare
9915           (any_shiftrt:SWI
9916             (match_operand:SWI 1 "nonimmediate_operand" "0")
9917             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9918           (const_int 0)))
9919    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9920         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9921   "(optimize_function_for_size_p (cfun)
9922     || !TARGET_PARTIAL_FLAG_REG_STALL
9923     || (operands[2] == const1_rtx
9924         && TARGET_SHIFT1))
9925    && ix86_match_ccmode (insn, CCGOCmode)
9926    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9927 {
9928   if (operands[2] == const1_rtx
9929       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9930     return "<shiftrt>{<imodesuffix>}\t%0";
9931   else
9932     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9933 }
9934   [(set_attr "type" "ishift")
9935    (set (attr "length_immediate")
9936      (if_then_else
9937        (and (match_operand 2 "const1_operand" "")
9938             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9939                 (const_int 0)))
9940        (const_string "0")
9941        (const_string "*")))
9942    (set_attr "mode" "<MODE>")])
9943
9944 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9945   [(set (reg FLAGS_REG)
9946         (compare
9947           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9948                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
9949           (const_int 0)))
9950    (set (match_operand:DI 0 "register_operand" "=r")
9951         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9952   "TARGET_64BIT
9953    && (optimize_function_for_size_p (cfun)
9954        || !TARGET_PARTIAL_FLAG_REG_STALL
9955        || (operands[2] == const1_rtx
9956            && TARGET_SHIFT1))
9957    && ix86_match_ccmode (insn, CCGOCmode)
9958    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9959 {
9960   if (operands[2] == const1_rtx
9961       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9962     return "<shiftrt>{l}\t%k0";
9963   else
9964     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9965 }
9966   [(set_attr "type" "ishift")
9967    (set (attr "length_immediate")
9968      (if_then_else
9969        (and (match_operand 2 "const1_operand" "")
9970             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9971                 (const_int 0)))
9972        (const_string "0")
9973        (const_string "*")))
9974    (set_attr "mode" "SI")])
9975
9976 (define_insn "*<shiftrt_insn><mode>3_cconly"
9977   [(set (reg FLAGS_REG)
9978         (compare
9979           (any_shiftrt:SWI
9980             (match_operand:SWI 1 "nonimmediate_operand" "0")
9981             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9982           (const_int 0)))
9983    (clobber (match_scratch:SWI 0 "=<r>"))]
9984   "(optimize_function_for_size_p (cfun)
9985     || !TARGET_PARTIAL_FLAG_REG_STALL
9986     || (operands[2] == const1_rtx
9987         && TARGET_SHIFT1))
9988    && ix86_match_ccmode (insn, CCGOCmode)
9989    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9990 {
9991   if (operands[2] == const1_rtx
9992       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9993     return "<shiftrt>{<imodesuffix>}\t%0";
9994   else
9995     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9996 }
9997   [(set_attr "type" "ishift")
9998    (set (attr "length_immediate")
9999      (if_then_else
10000        (and (match_operand 2 "const1_operand" "")
10001             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10002                 (const_int 0)))
10003        (const_string "0")
10004        (const_string "*")))
10005    (set_attr "mode" "<MODE>")])
10006 \f
10007 ;; Rotate instructions
10008
10009 (define_expand "<rotate_insn>ti3"
10010   [(set (match_operand:TI 0 "register_operand" "")
10011         (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10012                        (match_operand:QI 2 "nonmemory_operand" "")))]
10013   "TARGET_64BIT"
10014 {
10015   if (const_1_to_63_operand (operands[2], VOIDmode))
10016     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10017                 (operands[0], operands[1], operands[2]));
10018   else
10019     FAIL;
10020
10021   DONE;
10022 })
10023
10024 (define_expand "<rotate_insn>di3"
10025   [(set (match_operand:DI 0 "shiftdi_operand" "")
10026         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10027                        (match_operand:QI 2 "nonmemory_operand" "")))]
10028  ""
10029 {
10030   if (TARGET_64BIT)
10031     ix86_expand_binary_operator (<CODE>, DImode, operands);
10032   else if (const_1_to_31_operand (operands[2], VOIDmode))
10033     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10034                 (operands[0], operands[1], operands[2]));
10035   else
10036     FAIL;
10037
10038   DONE;
10039 })
10040
10041 (define_expand "<rotate_insn><mode>3"
10042   [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10043         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10044                             (match_operand:QI 2 "nonmemory_operand" "")))]
10045   ""
10046   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10047
10048 ;; Implement rotation using two double-precision
10049 ;; shift instructions and a scratch register.
10050
10051 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10052  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10053        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10054                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10055   (clobber (reg:CC FLAGS_REG))
10056   (clobber (match_scratch:DWIH 3 "=&r"))]
10057  ""
10058  "#"
10059  "reload_completed"
10060  [(set (match_dup 3) (match_dup 4))
10061   (parallel
10062    [(set (match_dup 4)
10063          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10064                    (lshiftrt:DWIH (match_dup 5)
10065                                   (minus:QI (match_dup 6) (match_dup 2)))))
10066     (clobber (reg:CC FLAGS_REG))])
10067   (parallel
10068    [(set (match_dup 5)
10069          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10070                    (lshiftrt:DWIH (match_dup 3)
10071                                   (minus:QI (match_dup 6) (match_dup 2)))))
10072     (clobber (reg:CC FLAGS_REG))])]
10073 {
10074   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10075
10076   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10077 })
10078
10079 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10080  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10081        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10082                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10083   (clobber (reg:CC FLAGS_REG))
10084   (clobber (match_scratch:DWIH 3 "=&r"))]
10085  ""
10086  "#"
10087  "reload_completed"
10088  [(set (match_dup 3) (match_dup 4))
10089   (parallel
10090    [(set (match_dup 4)
10091          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10092                    (ashift:DWIH (match_dup 5)
10093                                 (minus:QI (match_dup 6) (match_dup 2)))))
10094     (clobber (reg:CC FLAGS_REG))])
10095   (parallel
10096    [(set (match_dup 5)
10097          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10098                    (ashift:DWIH (match_dup 3)
10099                                 (minus:QI (match_dup 6) (match_dup 2)))))
10100     (clobber (reg:CC FLAGS_REG))])]
10101 {
10102   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10103
10104   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10105 })
10106
10107 (define_insn "*<rotate_insn><mode>3_1"
10108   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10109         (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10110                         (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10111    (clobber (reg:CC FLAGS_REG))]
10112   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10113 {
10114   if (operands[2] == const1_rtx
10115       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10116     return "<rotate>{<imodesuffix>}\t%0";
10117   else
10118     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10119 }
10120   [(set_attr "type" "rotate")
10121    (set (attr "length_immediate")
10122      (if_then_else
10123        (and (match_operand 2 "const1_operand" "")
10124             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10125                 (const_int 0)))
10126        (const_string "0")
10127        (const_string "*")))
10128    (set_attr "mode" "<MODE>")])
10129
10130 (define_insn "*<rotate_insn>si3_1_zext"
10131   [(set (match_operand:DI 0 "register_operand" "=r")
10132         (zero_extend:DI
10133           (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10134                          (match_operand:QI 2 "nonmemory_operand" "cI"))))
10135    (clobber (reg:CC FLAGS_REG))]
10136   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10137 {
10138     if (operands[2] == const1_rtx
10139         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10140     return "<rotate>{l}\t%k0";
10141   else
10142     return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10143 }
10144   [(set_attr "type" "rotate")
10145    (set (attr "length_immediate")
10146      (if_then_else
10147        (and (match_operand 2 "const1_operand" "")
10148             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10149                 (const_int 0)))
10150        (const_string "0")
10151        (const_string "*")))
10152    (set_attr "mode" "SI")])
10153
10154 (define_insn "*<rotate_insn>qi3_1_slp"
10155   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10156         (any_rotate:QI (match_dup 0)
10157                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10158    (clobber (reg:CC FLAGS_REG))]
10159   "(optimize_function_for_size_p (cfun)
10160     || !TARGET_PARTIAL_REG_STALL
10161     || (operands[1] == const1_rtx
10162         && TARGET_SHIFT1))"
10163 {
10164   if (operands[1] == const1_rtx
10165       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10166     return "<rotate>{b}\t%0";
10167   else
10168     return "<rotate>{b}\t{%1, %0|%0, %1}";
10169 }
10170   [(set_attr "type" "rotate1")
10171    (set (attr "length_immediate")
10172      (if_then_else
10173        (and (match_operand 1 "const1_operand" "")
10174             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10175                 (const_int 0)))
10176        (const_string "0")
10177        (const_string "*")))
10178    (set_attr "mode" "QI")])
10179
10180 (define_split
10181  [(set (match_operand:HI 0 "register_operand" "")
10182        (any_rotate:HI (match_dup 0) (const_int 8)))
10183   (clobber (reg:CC FLAGS_REG))]
10184  "reload_completed
10185   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10186  [(parallel [(set (strict_low_part (match_dup 0))
10187                   (bswap:HI (match_dup 0)))
10188              (clobber (reg:CC FLAGS_REG))])])
10189 \f
10190 ;; Bit set / bit test instructions
10191
10192 (define_expand "extv"
10193   [(set (match_operand:SI 0 "register_operand" "")
10194         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10195                          (match_operand:SI 2 "const8_operand" "")
10196                          (match_operand:SI 3 "const8_operand" "")))]
10197   ""
10198 {
10199   /* Handle extractions from %ah et al.  */
10200   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10201     FAIL;
10202
10203   /* From mips.md: extract_bit_field doesn't verify that our source
10204      matches the predicate, so check it again here.  */
10205   if (! ext_register_operand (operands[1], VOIDmode))
10206     FAIL;
10207 })
10208
10209 (define_expand "extzv"
10210   [(set (match_operand:SI 0 "register_operand" "")
10211         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10212                          (match_operand:SI 2 "const8_operand" "")
10213                          (match_operand:SI 3 "const8_operand" "")))]
10214   ""
10215 {
10216   /* Handle extractions from %ah et al.  */
10217   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10218     FAIL;
10219
10220   /* From mips.md: extract_bit_field doesn't verify that our source
10221      matches the predicate, so check it again here.  */
10222   if (! ext_register_operand (operands[1], VOIDmode))
10223     FAIL;
10224 })
10225
10226 (define_expand "insv"
10227   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10228                       (match_operand 1 "const8_operand" "")
10229                       (match_operand 2 "const8_operand" ""))
10230         (match_operand 3 "register_operand" ""))]
10231   ""
10232 {
10233   rtx (*gen_mov_insv_1) (rtx, rtx);
10234
10235   /* Handle insertions to %ah et al.  */
10236   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10237     FAIL;
10238
10239   /* From mips.md: insert_bit_field doesn't verify that our source
10240      matches the predicate, so check it again here.  */
10241   if (! ext_register_operand (operands[0], VOIDmode))
10242     FAIL;
10243
10244   gen_mov_insv_1 = (TARGET_64BIT
10245                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10246
10247   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10248   DONE;
10249 })
10250
10251 ;; %%% bts, btr, btc, bt.
10252 ;; In general these instructions are *slow* when applied to memory,
10253 ;; since they enforce atomic operation.  When applied to registers,
10254 ;; it depends on the cpu implementation.  They're never faster than
10255 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10256 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10257 ;; within the instruction itself, so operating on bits in the high
10258 ;; 32-bits of a register becomes easier.
10259 ;;
10260 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10261 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10262 ;; negdf respectively, so they can never be disabled entirely.
10263
10264 (define_insn "*btsq"
10265   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10266                          (const_int 1)
10267                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10268         (const_int 1))
10269    (clobber (reg:CC FLAGS_REG))]
10270   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10271   "bts{q}\t{%1, %0|%0, %1}"
10272   [(set_attr "type" "alu1")
10273    (set_attr "prefix_0f" "1")
10274    (set_attr "mode" "DI")])
10275
10276 (define_insn "*btrq"
10277   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10278                          (const_int 1)
10279                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10280         (const_int 0))
10281    (clobber (reg:CC FLAGS_REG))]
10282   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10283   "btr{q}\t{%1, %0|%0, %1}"
10284   [(set_attr "type" "alu1")
10285    (set_attr "prefix_0f" "1")
10286    (set_attr "mode" "DI")])
10287
10288 (define_insn "*btcq"
10289   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10290                          (const_int 1)
10291                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10292         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10293    (clobber (reg:CC FLAGS_REG))]
10294   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10295   "btc{q}\t{%1, %0|%0, %1}"
10296   [(set_attr "type" "alu1")
10297    (set_attr "prefix_0f" "1")
10298    (set_attr "mode" "DI")])
10299
10300 ;; Allow Nocona to avoid these instructions if a register is available.
10301
10302 (define_peephole2
10303   [(match_scratch:DI 2 "r")
10304    (parallel [(set (zero_extract:DI
10305                      (match_operand:DI 0 "register_operand" "")
10306                      (const_int 1)
10307                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10308                    (const_int 1))
10309               (clobber (reg:CC FLAGS_REG))])]
10310   "TARGET_64BIT && !TARGET_USE_BT"
10311   [(const_int 0)]
10312 {
10313   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10314   rtx op1;
10315
10316   if (HOST_BITS_PER_WIDE_INT >= 64)
10317     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10318   else if (i < HOST_BITS_PER_WIDE_INT)
10319     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10320   else
10321     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10322
10323   op1 = immed_double_const (lo, hi, DImode);
10324   if (i >= 31)
10325     {
10326       emit_move_insn (operands[2], op1);
10327       op1 = operands[2];
10328     }
10329
10330   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10331   DONE;
10332 })
10333
10334 (define_peephole2
10335   [(match_scratch:DI 2 "r")
10336    (parallel [(set (zero_extract:DI
10337                      (match_operand:DI 0 "register_operand" "")
10338                      (const_int 1)
10339                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10340                    (const_int 0))
10341               (clobber (reg:CC FLAGS_REG))])]
10342   "TARGET_64BIT && !TARGET_USE_BT"
10343   [(const_int 0)]
10344 {
10345   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10346   rtx op1;
10347
10348   if (HOST_BITS_PER_WIDE_INT >= 64)
10349     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10350   else if (i < HOST_BITS_PER_WIDE_INT)
10351     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10352   else
10353     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10354
10355   op1 = immed_double_const (~lo, ~hi, DImode);
10356   if (i >= 32)
10357     {
10358       emit_move_insn (operands[2], op1);
10359       op1 = operands[2];
10360     }
10361
10362   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10363   DONE;
10364 })
10365
10366 (define_peephole2
10367   [(match_scratch:DI 2 "r")
10368    (parallel [(set (zero_extract:DI
10369                      (match_operand:DI 0 "register_operand" "")
10370                      (const_int 1)
10371                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10372               (not:DI (zero_extract:DI
10373                         (match_dup 0) (const_int 1) (match_dup 1))))
10374               (clobber (reg:CC FLAGS_REG))])]
10375   "TARGET_64BIT && !TARGET_USE_BT"
10376   [(const_int 0)]
10377 {
10378   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10379   rtx op1;
10380
10381   if (HOST_BITS_PER_WIDE_INT >= 64)
10382     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10383   else if (i < HOST_BITS_PER_WIDE_INT)
10384     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10385   else
10386     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10387
10388   op1 = immed_double_const (lo, hi, DImode);
10389   if (i >= 31)
10390     {
10391       emit_move_insn (operands[2], op1);
10392       op1 = operands[2];
10393     }
10394
10395   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10396   DONE;
10397 })
10398
10399 (define_insn "*bt<mode>"
10400   [(set (reg:CCC FLAGS_REG)
10401         (compare:CCC
10402           (zero_extract:SWI48
10403             (match_operand:SWI48 0 "register_operand" "r")
10404             (const_int 1)
10405             (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10406           (const_int 0)))]
10407   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10408   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10409   [(set_attr "type" "alu1")
10410    (set_attr "prefix_0f" "1")
10411    (set_attr "mode" "<MODE>")])
10412 \f
10413 ;; Store-flag instructions.
10414
10415 ;; For all sCOND expanders, also expand the compare or test insn that
10416 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10417
10418 (define_insn_and_split "*setcc_di_1"
10419   [(set (match_operand:DI 0 "register_operand" "=q")
10420         (match_operator:DI 1 "ix86_comparison_operator"
10421           [(reg FLAGS_REG) (const_int 0)]))]
10422   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10423   "#"
10424   "&& reload_completed"
10425   [(set (match_dup 2) (match_dup 1))
10426    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10427 {
10428   PUT_MODE (operands[1], QImode);
10429   operands[2] = gen_lowpart (QImode, operands[0]);
10430 })
10431
10432 (define_insn_and_split "*setcc_si_1_and"
10433   [(set (match_operand:SI 0 "register_operand" "=q")
10434         (match_operator:SI 1 "ix86_comparison_operator"
10435           [(reg FLAGS_REG) (const_int 0)]))
10436    (clobber (reg:CC FLAGS_REG))]
10437   "!TARGET_PARTIAL_REG_STALL
10438    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10439   "#"
10440   "&& reload_completed"
10441   [(set (match_dup 2) (match_dup 1))
10442    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10443               (clobber (reg:CC FLAGS_REG))])]
10444 {
10445   PUT_MODE (operands[1], QImode);
10446   operands[2] = gen_lowpart (QImode, operands[0]);
10447 })
10448
10449 (define_insn_and_split "*setcc_si_1_movzbl"
10450   [(set (match_operand:SI 0 "register_operand" "=q")
10451         (match_operator:SI 1 "ix86_comparison_operator"
10452           [(reg FLAGS_REG) (const_int 0)]))]
10453   "!TARGET_PARTIAL_REG_STALL
10454    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10455   "#"
10456   "&& reload_completed"
10457   [(set (match_dup 2) (match_dup 1))
10458    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10459 {
10460   PUT_MODE (operands[1], QImode);
10461   operands[2] = gen_lowpart (QImode, operands[0]);
10462 })
10463
10464 (define_insn "*setcc_qi"
10465   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10466         (match_operator:QI 1 "ix86_comparison_operator"
10467           [(reg FLAGS_REG) (const_int 0)]))]
10468   ""
10469   "set%C1\t%0"
10470   [(set_attr "type" "setcc")
10471    (set_attr "mode" "QI")])
10472
10473 (define_insn "*setcc_qi_slp"
10474   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10475         (match_operator:QI 1 "ix86_comparison_operator"
10476           [(reg FLAGS_REG) (const_int 0)]))]
10477   ""
10478   "set%C1\t%0"
10479   [(set_attr "type" "setcc")
10480    (set_attr "mode" "QI")])
10481
10482 ;; In general it is not safe to assume too much about CCmode registers,
10483 ;; so simplify-rtx stops when it sees a second one.  Under certain
10484 ;; conditions this is safe on x86, so help combine not create
10485 ;;
10486 ;;      seta    %al
10487 ;;      testb   %al, %al
10488 ;;      sete    %al
10489
10490 (define_split
10491   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10492         (ne:QI (match_operator 1 "ix86_comparison_operator"
10493                  [(reg FLAGS_REG) (const_int 0)])
10494             (const_int 0)))]
10495   ""
10496   [(set (match_dup 0) (match_dup 1))]
10497   "PUT_MODE (operands[1], QImode);")
10498
10499 (define_split
10500   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10501         (ne:QI (match_operator 1 "ix86_comparison_operator"
10502                  [(reg FLAGS_REG) (const_int 0)])
10503             (const_int 0)))]
10504   ""
10505   [(set (match_dup 0) (match_dup 1))]
10506   "PUT_MODE (operands[1], QImode);")
10507
10508 (define_split
10509   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10510         (eq:QI (match_operator 1 "ix86_comparison_operator"
10511                  [(reg FLAGS_REG) (const_int 0)])
10512             (const_int 0)))]
10513   ""
10514   [(set (match_dup 0) (match_dup 1))]
10515 {
10516   rtx new_op1 = copy_rtx (operands[1]);
10517   operands[1] = new_op1;
10518   PUT_MODE (new_op1, QImode);
10519   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10520                                              GET_MODE (XEXP (new_op1, 0))));
10521
10522   /* Make sure that (a) the CCmode we have for the flags is strong
10523      enough for the reversed compare or (b) we have a valid FP compare.  */
10524   if (! ix86_comparison_operator (new_op1, VOIDmode))
10525     FAIL;
10526 })
10527
10528 (define_split
10529   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10530         (eq:QI (match_operator 1 "ix86_comparison_operator"
10531                  [(reg FLAGS_REG) (const_int 0)])
10532             (const_int 0)))]
10533   ""
10534   [(set (match_dup 0) (match_dup 1))]
10535 {
10536   rtx new_op1 = copy_rtx (operands[1]);
10537   operands[1] = new_op1;
10538   PUT_MODE (new_op1, QImode);
10539   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10540                                              GET_MODE (XEXP (new_op1, 0))));
10541
10542   /* Make sure that (a) the CCmode we have for the flags is strong
10543      enough for the reversed compare or (b) we have a valid FP compare.  */
10544   if (! ix86_comparison_operator (new_op1, VOIDmode))
10545     FAIL;
10546 })
10547
10548 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10549 ;; subsequent logical operations are used to imitate conditional moves.
10550 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10551 ;; it directly.
10552
10553 (define_insn "*avx_setcc<mode>"
10554   [(set (match_operand:MODEF 0 "register_operand" "=x")
10555         (match_operator:MODEF 1 "avx_comparison_float_operator"
10556           [(match_operand:MODEF 2 "register_operand" "x")
10557            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10558   "TARGET_AVX"
10559   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
10560   [(set_attr "type" "ssecmp")
10561    (set_attr "prefix" "vex")
10562    (set_attr "length_immediate" "1")
10563    (set_attr "mode" "<MODE>")])
10564
10565 (define_insn "*sse_setcc<mode>"
10566   [(set (match_operand:MODEF 0 "register_operand" "=x")
10567         (match_operator:MODEF 1 "sse_comparison_operator"
10568           [(match_operand:MODEF 2 "register_operand" "0")
10569            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10570   "SSE_FLOAT_MODE_P (<MODE>mode)"
10571   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
10572   [(set_attr "type" "ssecmp")
10573    (set_attr "length_immediate" "1")
10574    (set_attr "mode" "<MODE>")])
10575 \f
10576 ;; Basic conditional jump instructions.
10577 ;; We ignore the overflow flag for signed branch instructions.
10578
10579 (define_insn "*jcc_1"
10580   [(set (pc)
10581         (if_then_else (match_operator 1 "ix86_comparison_operator"
10582                                       [(reg FLAGS_REG) (const_int 0)])
10583                       (label_ref (match_operand 0 "" ""))
10584                       (pc)))]
10585   ""
10586   "%+j%C1\t%l0"
10587   [(set_attr "type" "ibr")
10588    (set_attr "modrm" "0")
10589    (set (attr "length")
10590            (if_then_else (and (ge (minus (match_dup 0) (pc))
10591                                   (const_int -126))
10592                               (lt (minus (match_dup 0) (pc))
10593                                   (const_int 128)))
10594              (const_int 2)
10595              (const_int 6)))])
10596
10597 (define_insn "*jcc_2"
10598   [(set (pc)
10599         (if_then_else (match_operator 1 "ix86_comparison_operator"
10600                                       [(reg FLAGS_REG) (const_int 0)])
10601                       (pc)
10602                       (label_ref (match_operand 0 "" ""))))]
10603   ""
10604   "%+j%c1\t%l0"
10605   [(set_attr "type" "ibr")
10606    (set_attr "modrm" "0")
10607    (set (attr "length")
10608            (if_then_else (and (ge (minus (match_dup 0) (pc))
10609                                   (const_int -126))
10610                               (lt (minus (match_dup 0) (pc))
10611                                   (const_int 128)))
10612              (const_int 2)
10613              (const_int 6)))])
10614
10615 ;; In general it is not safe to assume too much about CCmode registers,
10616 ;; so simplify-rtx stops when it sees a second one.  Under certain
10617 ;; conditions this is safe on x86, so help combine not create
10618 ;;
10619 ;;      seta    %al
10620 ;;      testb   %al, %al
10621 ;;      je      Lfoo
10622
10623 (define_split
10624   [(set (pc)
10625         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10626                                       [(reg FLAGS_REG) (const_int 0)])
10627                           (const_int 0))
10628                       (label_ref (match_operand 1 "" ""))
10629                       (pc)))]
10630   ""
10631   [(set (pc)
10632         (if_then_else (match_dup 0)
10633                       (label_ref (match_dup 1))
10634                       (pc)))]
10635   "PUT_MODE (operands[0], VOIDmode);")
10636
10637 (define_split
10638   [(set (pc)
10639         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10640                                       [(reg FLAGS_REG) (const_int 0)])
10641                           (const_int 0))
10642                       (label_ref (match_operand 1 "" ""))
10643                       (pc)))]
10644   ""
10645   [(set (pc)
10646         (if_then_else (match_dup 0)
10647                       (label_ref (match_dup 1))
10648                       (pc)))]
10649 {
10650   rtx new_op0 = copy_rtx (operands[0]);
10651   operands[0] = new_op0;
10652   PUT_MODE (new_op0, VOIDmode);
10653   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10654                                              GET_MODE (XEXP (new_op0, 0))));
10655
10656   /* Make sure that (a) the CCmode we have for the flags is strong
10657      enough for the reversed compare or (b) we have a valid FP compare.  */
10658   if (! ix86_comparison_operator (new_op0, VOIDmode))
10659     FAIL;
10660 })
10661
10662 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10663 ;; pass generates from shift insn with QImode operand.  Actually, the mode
10664 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10665 ;; appropriate modulo of the bit offset value.
10666
10667 (define_insn_and_split "*jcc_bt<mode>"
10668   [(set (pc)
10669         (if_then_else (match_operator 0 "bt_comparison_operator"
10670                         [(zero_extract:SWI48
10671                            (match_operand:SWI48 1 "register_operand" "r")
10672                            (const_int 1)
10673                            (zero_extend:SI
10674                              (match_operand:QI 2 "register_operand" "r")))
10675                          (const_int 0)])
10676                       (label_ref (match_operand 3 "" ""))
10677                       (pc)))
10678    (clobber (reg:CC FLAGS_REG))]
10679   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10680   "#"
10681   "&& 1"
10682   [(set (reg:CCC FLAGS_REG)
10683         (compare:CCC
10684           (zero_extract:SWI48
10685             (match_dup 1)
10686             (const_int 1)
10687             (match_dup 2))
10688           (const_int 0)))
10689    (set (pc)
10690         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10691                       (label_ref (match_dup 3))
10692                       (pc)))]
10693 {
10694   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10695
10696   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10697 })
10698
10699 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10700 ;; also for DImode, this is what combine produces.
10701 (define_insn_and_split "*jcc_bt<mode>_mask"
10702   [(set (pc)
10703         (if_then_else (match_operator 0 "bt_comparison_operator"
10704                         [(zero_extract:SWI48
10705                            (match_operand:SWI48 1 "register_operand" "r")
10706                            (const_int 1)
10707                            (and:SI
10708                              (match_operand:SI 2 "register_operand" "r")
10709                              (match_operand:SI 3 "const_int_operand" "n")))])
10710                       (label_ref (match_operand 4 "" ""))
10711                       (pc)))
10712    (clobber (reg:CC FLAGS_REG))]
10713   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10714    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10715       == GET_MODE_BITSIZE (<MODE>mode)-1"
10716   "#"
10717   "&& 1"
10718   [(set (reg:CCC FLAGS_REG)
10719         (compare:CCC
10720           (zero_extract:SWI48
10721             (match_dup 1)
10722             (const_int 1)
10723             (match_dup 2))
10724           (const_int 0)))
10725    (set (pc)
10726         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10727                       (label_ref (match_dup 4))
10728                       (pc)))]
10729 {
10730   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10731
10732   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10733 })
10734
10735 (define_insn_and_split "*jcc_btsi_1"
10736   [(set (pc)
10737         (if_then_else (match_operator 0 "bt_comparison_operator"
10738                         [(and:SI
10739                            (lshiftrt:SI
10740                              (match_operand:SI 1 "register_operand" "r")
10741                              (match_operand:QI 2 "register_operand" "r"))
10742                            (const_int 1))
10743                          (const_int 0)])
10744                       (label_ref (match_operand 3 "" ""))
10745                       (pc)))
10746    (clobber (reg:CC FLAGS_REG))]
10747   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10748   "#"
10749   "&& 1"
10750   [(set (reg:CCC FLAGS_REG)
10751         (compare:CCC
10752           (zero_extract:SI
10753             (match_dup 1)
10754             (const_int 1)
10755             (match_dup 2))
10756           (const_int 0)))
10757    (set (pc)
10758         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10759                       (label_ref (match_dup 3))
10760                       (pc)))]
10761 {
10762   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10763
10764   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10765 })
10766
10767 ;; avoid useless masking of bit offset operand
10768 (define_insn_and_split "*jcc_btsi_mask_1"
10769   [(set (pc)
10770         (if_then_else
10771           (match_operator 0 "bt_comparison_operator"
10772             [(and:SI
10773                (lshiftrt:SI
10774                  (match_operand:SI 1 "register_operand" "r")
10775                  (subreg:QI
10776                    (and:SI
10777                      (match_operand:SI 2 "register_operand" "r")
10778                      (match_operand:SI 3 "const_int_operand" "n")) 0))
10779                (const_int 1))
10780              (const_int 0)])
10781           (label_ref (match_operand 4 "" ""))
10782           (pc)))
10783    (clobber (reg:CC FLAGS_REG))]
10784   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10785    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10786   "#"
10787   "&& 1"
10788   [(set (reg:CCC FLAGS_REG)
10789         (compare:CCC
10790           (zero_extract:SI
10791             (match_dup 1)
10792             (const_int 1)
10793             (match_dup 2))
10794           (const_int 0)))
10795    (set (pc)
10796         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10797                       (label_ref (match_dup 4))
10798                       (pc)))]
10799   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10800
10801 ;; Define combination compare-and-branch fp compare instructions to help
10802 ;; combine.
10803
10804 (define_insn "*fp_jcc_1_387"
10805   [(set (pc)
10806         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10807                         [(match_operand 1 "register_operand" "f")
10808                          (match_operand 2 "nonimmediate_operand" "fm")])
10809           (label_ref (match_operand 3 "" ""))
10810           (pc)))
10811    (clobber (reg:CCFP FPSR_REG))
10812    (clobber (reg:CCFP FLAGS_REG))
10813    (clobber (match_scratch:HI 4 "=a"))]
10814   "TARGET_80387
10815    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10816    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10817    && SELECT_CC_MODE (GET_CODE (operands[0]),
10818                       operands[1], operands[2]) == CCFPmode
10819    && !TARGET_CMOVE"
10820   "#")
10821
10822 (define_insn "*fp_jcc_1r_387"
10823   [(set (pc)
10824         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10825                         [(match_operand 1 "register_operand" "f")
10826                          (match_operand 2 "nonimmediate_operand" "fm")])
10827           (pc)
10828           (label_ref (match_operand 3 "" ""))))
10829    (clobber (reg:CCFP FPSR_REG))
10830    (clobber (reg:CCFP FLAGS_REG))
10831    (clobber (match_scratch:HI 4 "=a"))]
10832   "TARGET_80387
10833    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10834    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10835    && SELECT_CC_MODE (GET_CODE (operands[0]),
10836                       operands[1], operands[2]) == CCFPmode
10837    && !TARGET_CMOVE"
10838   "#")
10839
10840 (define_insn "*fp_jcc_2_387"
10841   [(set (pc)
10842         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10843                         [(match_operand 1 "register_operand" "f")
10844                          (match_operand 2 "register_operand" "f")])
10845           (label_ref (match_operand 3 "" ""))
10846           (pc)))
10847    (clobber (reg:CCFP FPSR_REG))
10848    (clobber (reg:CCFP FLAGS_REG))
10849    (clobber (match_scratch:HI 4 "=a"))]
10850   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10851    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10852    && !TARGET_CMOVE"
10853   "#")
10854
10855 (define_insn "*fp_jcc_2r_387"
10856   [(set (pc)
10857         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10858                         [(match_operand 1 "register_operand" "f")
10859                          (match_operand 2 "register_operand" "f")])
10860           (pc)
10861           (label_ref (match_operand 3 "" ""))))
10862    (clobber (reg:CCFP FPSR_REG))
10863    (clobber (reg:CCFP FLAGS_REG))
10864    (clobber (match_scratch:HI 4 "=a"))]
10865   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10866    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10867    && !TARGET_CMOVE"
10868   "#")
10869
10870 (define_insn "*fp_jcc_3_387"
10871   [(set (pc)
10872         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10873                         [(match_operand 1 "register_operand" "f")
10874                          (match_operand 2 "const0_operand" "")])
10875           (label_ref (match_operand 3 "" ""))
10876           (pc)))
10877    (clobber (reg:CCFP FPSR_REG))
10878    (clobber (reg:CCFP FLAGS_REG))
10879    (clobber (match_scratch:HI 4 "=a"))]
10880   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10881    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10882    && SELECT_CC_MODE (GET_CODE (operands[0]),
10883                       operands[1], operands[2]) == CCFPmode
10884    && !TARGET_CMOVE"
10885   "#")
10886
10887 (define_split
10888   [(set (pc)
10889         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10890                         [(match_operand 1 "register_operand" "")
10891                          (match_operand 2 "nonimmediate_operand" "")])
10892           (match_operand 3 "" "")
10893           (match_operand 4 "" "")))
10894    (clobber (reg:CCFP FPSR_REG))
10895    (clobber (reg:CCFP FLAGS_REG))]
10896   "reload_completed"
10897   [(const_int 0)]
10898 {
10899   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10900                         operands[3], operands[4], NULL_RTX, NULL_RTX);
10901   DONE;
10902 })
10903
10904 (define_split
10905   [(set (pc)
10906         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10907                         [(match_operand 1 "register_operand" "")
10908                          (match_operand 2 "general_operand" "")])
10909           (match_operand 3 "" "")
10910           (match_operand 4 "" "")))
10911    (clobber (reg:CCFP FPSR_REG))
10912    (clobber (reg:CCFP FLAGS_REG))
10913    (clobber (match_scratch:HI 5 "=a"))]
10914   "reload_completed"
10915   [(const_int 0)]
10916 {
10917   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10918                         operands[3], operands[4], operands[5], NULL_RTX);
10919   DONE;
10920 })
10921
10922 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10923 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10924 ;; with a precedence over other operators and is always put in the first
10925 ;; place. Swap condition and operands to match ficom instruction.
10926
10927 (define_insn "*fp_jcc_4_<mode>_387"
10928   [(set (pc)
10929         (if_then_else
10930           (match_operator 0 "ix86_swapped_fp_comparison_operator"
10931             [(match_operator 1 "float_operator"
10932               [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
10933              (match_operand 3 "register_operand" "f,f")])
10934           (label_ref (match_operand 4 "" ""))
10935           (pc)))
10936    (clobber (reg:CCFP FPSR_REG))
10937    (clobber (reg:CCFP FLAGS_REG))
10938    (clobber (match_scratch:HI 5 "=a,a"))]
10939   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
10940    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
10941    && GET_MODE (operands[1]) == GET_MODE (operands[3])
10942    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
10943    && !TARGET_CMOVE"
10944   "#")
10945
10946 (define_split
10947   [(set (pc)
10948         (if_then_else
10949           (match_operator 0 "ix86_swapped_fp_comparison_operator"
10950             [(match_operator 1 "float_operator"
10951               [(match_operand:X87MODEI12 2 "memory_operand" "")])
10952              (match_operand 3 "register_operand" "")])
10953           (match_operand 4 "" "")
10954           (match_operand 5 "" "")))
10955    (clobber (reg:CCFP FPSR_REG))
10956    (clobber (reg:CCFP FLAGS_REG))
10957    (clobber (match_scratch:HI 6 "=a"))]
10958   "reload_completed"
10959   [(const_int 0)]
10960 {
10961   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
10962
10963   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10964                         operands[3], operands[7],
10965                         operands[4], operands[5], operands[6], NULL_RTX);
10966   DONE;
10967 })
10968
10969 ;; %%% Kill this when reload knows how to do it.
10970 (define_split
10971   [(set (pc)
10972         (if_then_else
10973           (match_operator 0 "ix86_swapped_fp_comparison_operator"
10974             [(match_operator 1 "float_operator"
10975               [(match_operand:X87MODEI12 2 "register_operand" "")])
10976              (match_operand 3 "register_operand" "")])
10977           (match_operand 4 "" "")
10978           (match_operand 5 "" "")))
10979    (clobber (reg:CCFP FPSR_REG))
10980    (clobber (reg:CCFP FLAGS_REG))
10981    (clobber (match_scratch:HI 6 "=a"))]
10982   "reload_completed"
10983   [(const_int 0)]
10984 {
10985   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10986   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
10987
10988   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10989                         operands[3], operands[7],
10990                         operands[4], operands[5], operands[6], operands[2]);
10991   DONE;
10992 })
10993 \f
10994 ;; Unconditional and other jump instructions
10995
10996 (define_insn "jump"
10997   [(set (pc)
10998         (label_ref (match_operand 0 "" "")))]
10999   ""
11000   "jmp\t%l0"
11001   [(set_attr "type" "ibr")
11002    (set (attr "length")
11003            (if_then_else (and (ge (minus (match_dup 0) (pc))
11004                                   (const_int -126))
11005                               (lt (minus (match_dup 0) (pc))
11006                                   (const_int 128)))
11007              (const_int 2)
11008              (const_int 5)))
11009    (set_attr "modrm" "0")])
11010
11011 (define_expand "indirect_jump"
11012   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11013   ""
11014   "")
11015
11016 (define_insn "*indirect_jump"
11017   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11018   ""
11019   "jmp\t%A0"
11020   [(set_attr "type" "ibr")
11021    (set_attr "length_immediate" "0")])
11022
11023 (define_expand "tablejump"
11024   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11025               (use (label_ref (match_operand 1 "" "")))])]
11026   ""
11027 {
11028   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11029      relative.  Convert the relative address to an absolute address.  */
11030   if (flag_pic)
11031     {
11032       rtx op0, op1;
11033       enum rtx_code code;
11034
11035       /* We can't use @GOTOFF for text labels on VxWorks;
11036          see gotoff_operand.  */
11037       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11038         {
11039           code = PLUS;
11040           op0 = operands[0];
11041           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11042         }
11043       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11044         {
11045           code = PLUS;
11046           op0 = operands[0];
11047           op1 = pic_offset_table_rtx;
11048         }
11049       else
11050         {
11051           code = MINUS;
11052           op0 = pic_offset_table_rtx;
11053           op1 = operands[0];
11054         }
11055
11056       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11057                                          OPTAB_DIRECT);
11058     }
11059 })
11060
11061 (define_insn "*tablejump_1"
11062   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11063    (use (label_ref (match_operand 1 "" "")))]
11064   ""
11065   "jmp\t%A0"
11066   [(set_attr "type" "ibr")
11067    (set_attr "length_immediate" "0")])
11068 \f
11069 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11070
11071 (define_peephole2
11072   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11073    (set (match_operand:QI 1 "register_operand" "")
11074         (match_operator:QI 2 "ix86_comparison_operator"
11075           [(reg FLAGS_REG) (const_int 0)]))
11076    (set (match_operand 3 "q_regs_operand" "")
11077         (zero_extend (match_dup 1)))]
11078   "(peep2_reg_dead_p (3, operands[1])
11079     || operands_match_p (operands[1], operands[3]))
11080    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11081   [(set (match_dup 4) (match_dup 0))
11082    (set (strict_low_part (match_dup 5))
11083         (match_dup 2))]
11084 {
11085   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11086   operands[5] = gen_lowpart (QImode, operands[3]);
11087   ix86_expand_clear (operands[3]);
11088 })
11089
11090 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11091
11092 (define_peephole2
11093   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11094    (set (match_operand:QI 1 "register_operand" "")
11095         (match_operator:QI 2 "ix86_comparison_operator"
11096           [(reg FLAGS_REG) (const_int 0)]))
11097    (parallel [(set (match_operand 3 "q_regs_operand" "")
11098                    (zero_extend (match_dup 1)))
11099               (clobber (reg:CC FLAGS_REG))])]
11100   "(peep2_reg_dead_p (3, operands[1])
11101     || operands_match_p (operands[1], operands[3]))
11102    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11103   [(set (match_dup 4) (match_dup 0))
11104    (set (strict_low_part (match_dup 5))
11105         (match_dup 2))]
11106 {
11107   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11108   operands[5] = gen_lowpart (QImode, operands[3]);
11109   ix86_expand_clear (operands[3]);
11110 })
11111 \f
11112 ;; Call instructions.
11113
11114 ;; The predicates normally associated with named expanders are not properly
11115 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11116 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11117
11118 ;; P6 processors will jump to the address after the decrement when %esp
11119 ;; is used as a call operand, so they will execute return address as a code.
11120 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11121  
11122 ;; Call subroutine returning no value.
11123
11124 (define_expand "call_pop"
11125   [(parallel [(call (match_operand:QI 0 "" "")
11126                     (match_operand:SI 1 "" ""))
11127               (set (reg:SI SP_REG)
11128                    (plus:SI (reg:SI SP_REG)
11129                             (match_operand:SI 3 "" "")))])]
11130   "!TARGET_64BIT"
11131 {
11132   ix86_expand_call (NULL, operands[0], operands[1],
11133                     operands[2], operands[3], 0);
11134   DONE;
11135 })
11136
11137 (define_insn "*call_pop_0"
11138   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11139          (match_operand:SI 1 "" ""))
11140    (set (reg:SI SP_REG)
11141         (plus:SI (reg:SI SP_REG)
11142                  (match_operand:SI 2 "immediate_operand" "")))]
11143   "!TARGET_64BIT"
11144 {
11145   if (SIBLING_CALL_P (insn))
11146     return "jmp\t%P0";
11147   else
11148     return "call\t%P0";
11149 }
11150   [(set_attr "type" "call")])
11151
11152 (define_insn "*call_pop_1"
11153   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11154          (match_operand:SI 1 "" ""))
11155    (set (reg:SI SP_REG)
11156         (plus:SI (reg:SI SP_REG)
11157                  (match_operand:SI 2 "immediate_operand" "i")))]
11158   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11159 {
11160   if (constant_call_address_operand (operands[0], Pmode))
11161     return "call\t%P0";
11162   return "call\t%A0";
11163 }
11164   [(set_attr "type" "call")])
11165
11166 (define_insn "*sibcall_pop_1"
11167   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11168          (match_operand:SI 1 "" ""))
11169    (set (reg:SI SP_REG)
11170         (plus:SI (reg:SI SP_REG)
11171                  (match_operand:SI 2 "immediate_operand" "i,i")))]
11172   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11173   "@
11174    jmp\t%P0
11175    jmp\t%A0"
11176   [(set_attr "type" "call")])
11177
11178 (define_expand "call"
11179   [(call (match_operand:QI 0 "" "")
11180          (match_operand 1 "" ""))
11181    (use (match_operand 2 "" ""))]
11182   ""
11183 {
11184   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11185   DONE;
11186 })
11187
11188 (define_expand "sibcall"
11189   [(call (match_operand:QI 0 "" "")
11190          (match_operand 1 "" ""))
11191    (use (match_operand 2 "" ""))]
11192   ""
11193 {
11194   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11195   DONE;
11196 })
11197
11198 (define_insn "*call_0"
11199   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11200          (match_operand 1 "" ""))]
11201   ""
11202 {
11203   if (SIBLING_CALL_P (insn))
11204     return "jmp\t%P0";
11205   else
11206     return "call\t%P0";
11207 }
11208   [(set_attr "type" "call")])
11209
11210 (define_insn "*call_1"
11211   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11212          (match_operand 1 "" ""))]
11213   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11214 {
11215   if (constant_call_address_operand (operands[0], Pmode))
11216     return "call\t%P0";
11217   return "call\t%A0";
11218 }
11219   [(set_attr "type" "call")])
11220
11221 (define_insn "*sibcall_1"
11222   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11223          (match_operand 1 "" ""))]
11224   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11225   "@
11226    jmp\t%P0
11227    jmp\t%A0"
11228   [(set_attr "type" "call")])
11229
11230 (define_insn "*call_1_rex64"
11231   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11232          (match_operand 1 "" ""))]
11233   "TARGET_64BIT && !SIBLING_CALL_P (insn)
11234    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11235 {
11236   if (constant_call_address_operand (operands[0], Pmode))
11237     return "call\t%P0";
11238   return "call\t%A0";
11239 }
11240   [(set_attr "type" "call")])
11241
11242 (define_insn "*call_1_rex64_ms_sysv"
11243   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11244          (match_operand 1 "" ""))
11245    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11246    (clobber (reg:TI XMM6_REG))
11247    (clobber (reg:TI XMM7_REG))
11248    (clobber (reg:TI XMM8_REG))
11249    (clobber (reg:TI XMM9_REG))
11250    (clobber (reg:TI XMM10_REG))
11251    (clobber (reg:TI XMM11_REG))
11252    (clobber (reg:TI XMM12_REG))
11253    (clobber (reg:TI XMM13_REG))
11254    (clobber (reg:TI XMM14_REG))
11255    (clobber (reg:TI XMM15_REG))
11256    (clobber (reg:DI SI_REG))
11257    (clobber (reg:DI DI_REG))]
11258   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11259 {
11260   if (constant_call_address_operand (operands[0], Pmode))
11261     return "call\t%P0";
11262   return "call\t%A0";
11263 }
11264   [(set_attr "type" "call")])
11265
11266 (define_insn "*call_1_rex64_large"
11267   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11268          (match_operand 1 "" ""))]
11269   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11270   "call\t%A0"
11271   [(set_attr "type" "call")])
11272
11273 (define_insn "*sibcall_1_rex64"
11274   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11275          (match_operand 1 "" ""))]
11276   "TARGET_64BIT && SIBLING_CALL_P (insn)"
11277   "@
11278    jmp\t%P0
11279    jmp\t%A0"
11280   [(set_attr "type" "call")])
11281
11282 ;; Call subroutine, returning value in operand 0
11283 (define_expand "call_value_pop"
11284   [(parallel [(set (match_operand 0 "" "")
11285                    (call (match_operand:QI 1 "" "")
11286                          (match_operand:SI 2 "" "")))
11287               (set (reg:SI SP_REG)
11288                    (plus:SI (reg:SI SP_REG)
11289                             (match_operand:SI 4 "" "")))])]
11290   "!TARGET_64BIT"
11291 {
11292   ix86_expand_call (operands[0], operands[1], operands[2],
11293                     operands[3], operands[4], 0);
11294   DONE;
11295 })
11296
11297 (define_expand "call_value"
11298   [(set (match_operand 0 "" "")
11299         (call (match_operand:QI 1 "" "")
11300               (match_operand:SI 2 "" "")))
11301    (use (match_operand:SI 3 "" ""))]
11302   ;; Operand 3 is not used on the i386.
11303   ""
11304 {
11305   ix86_expand_call (operands[0], operands[1], operands[2],
11306                     operands[3], NULL, 0);
11307   DONE;
11308 })
11309
11310 (define_expand "sibcall_value"
11311   [(set (match_operand 0 "" "")
11312         (call (match_operand:QI 1 "" "")
11313               (match_operand:SI 2 "" "")))
11314    (use (match_operand:SI 3 "" ""))]
11315   ;; Operand 3 is not used on the i386.
11316   ""
11317 {
11318   ix86_expand_call (operands[0], operands[1], operands[2],
11319                     operands[3], NULL, 1);
11320   DONE;
11321 })
11322
11323 ;; Call subroutine returning any type.
11324
11325 (define_expand "untyped_call"
11326   [(parallel [(call (match_operand 0 "" "")
11327                     (const_int 0))
11328               (match_operand 1 "" "")
11329               (match_operand 2 "" "")])]
11330   ""
11331 {
11332   int i;
11333
11334   /* In order to give reg-stack an easier job in validating two
11335      coprocessor registers as containing a possible return value,
11336      simply pretend the untyped call returns a complex long double
11337      value. 
11338
11339      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11340      and should have the default ABI.  */
11341
11342   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11343                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11344                     operands[0], const0_rtx,
11345                     GEN_INT ((TARGET_64BIT
11346                               ? (ix86_abi == SYSV_ABI
11347                                  ? X86_64_SSE_REGPARM_MAX
11348                                  : X86_64_MS_SSE_REGPARM_MAX)
11349                               : X86_32_SSE_REGPARM_MAX)
11350                              - 1),
11351                     NULL, 0);
11352
11353   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11354     {
11355       rtx set = XVECEXP (operands[2], 0, i);
11356       emit_move_insn (SET_DEST (set), SET_SRC (set));
11357     }
11358
11359   /* The optimizer does not know that the call sets the function value
11360      registers we stored in the result block.  We avoid problems by
11361      claiming that all hard registers are used and clobbered at this
11362      point.  */
11363   emit_insn (gen_blockage ());
11364
11365   DONE;
11366 })
11367 \f
11368 ;; Prologue and epilogue instructions
11369
11370 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11371 ;; all of memory.  This blocks insns from being moved across this point.
11372
11373 (define_insn "blockage"
11374   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11375   ""
11376   ""
11377   [(set_attr "length" "0")])
11378
11379 ;; Do not schedule instructions accessing memory across this point.
11380
11381 (define_expand "memory_blockage"
11382   [(set (match_dup 0)
11383         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11384   ""
11385 {
11386   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11387   MEM_VOLATILE_P (operands[0]) = 1;
11388 })
11389
11390 (define_insn "*memory_blockage"
11391   [(set (match_operand:BLK 0 "" "")
11392         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11393   ""
11394   ""
11395   [(set_attr "length" "0")])
11396
11397 ;; As USE insns aren't meaningful after reload, this is used instead
11398 ;; to prevent deleting instructions setting registers for PIC code
11399 (define_insn "prologue_use"
11400   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11401   ""
11402   ""
11403   [(set_attr "length" "0")])
11404
11405 ;; Insn emitted into the body of a function to return from a function.
11406 ;; This is only done if the function's epilogue is known to be simple.
11407 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11408
11409 (define_expand "return"
11410   [(return)]
11411   "ix86_can_use_return_insn_p ()"
11412 {
11413   if (crtl->args.pops_args)
11414     {
11415       rtx popc = GEN_INT (crtl->args.pops_args);
11416       emit_jump_insn (gen_return_pop_internal (popc));
11417       DONE;
11418     }
11419 })
11420
11421 (define_insn "return_internal"
11422   [(return)]
11423   "reload_completed"
11424   "ret"
11425   [(set_attr "length" "1")
11426    (set_attr "atom_unit" "jeu")
11427    (set_attr "length_immediate" "0")
11428    (set_attr "modrm" "0")])
11429
11430 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11431 ;; instruction Athlon and K8 have.
11432
11433 (define_insn "return_internal_long"
11434   [(return)
11435    (unspec [(const_int 0)] UNSPEC_REP)]
11436   "reload_completed"
11437   "rep\;ret"
11438   [(set_attr "length" "2")
11439    (set_attr "atom_unit" "jeu")
11440    (set_attr "length_immediate" "0")
11441    (set_attr "prefix_rep" "1")
11442    (set_attr "modrm" "0")])
11443
11444 (define_insn "return_pop_internal"
11445   [(return)
11446    (use (match_operand:SI 0 "const_int_operand" ""))]
11447   "reload_completed"
11448   "ret\t%0"
11449   [(set_attr "length" "3")
11450    (set_attr "atom_unit" "jeu")
11451    (set_attr "length_immediate" "2")
11452    (set_attr "modrm" "0")])
11453
11454 (define_insn "return_indirect_internal"
11455   [(return)
11456    (use (match_operand:SI 0 "register_operand" "r"))]
11457   "reload_completed"
11458   "jmp\t%A0"
11459   [(set_attr "type" "ibr")
11460    (set_attr "length_immediate" "0")])
11461
11462 (define_insn "nop"
11463   [(const_int 0)]
11464   ""
11465   "nop"
11466   [(set_attr "length" "1")
11467    (set_attr "length_immediate" "0")
11468    (set_attr "modrm" "0")])
11469
11470 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
11471 (define_insn "nops"
11472   [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11473                     UNSPECV_NOPS)]
11474   "reload_completed"
11475 {
11476   int num = INTVAL (operands[0]);
11477
11478   gcc_assert (num >= 1 && num <= 8);
11479
11480   while (num--)
11481     fputs ("\tnop\n", asm_out_file);
11482
11483   return "";
11484 }
11485   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11486    (set_attr "length_immediate" "0")
11487    (set_attr "modrm" "0")])
11488
11489 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11490 ;; branch prediction penalty for the third jump in a 16-byte
11491 ;; block on K8.
11492
11493 (define_insn "pad"
11494   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11495   ""
11496 {
11497 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11498   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11499 #else
11500   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11501      The align insn is used to avoid 3 jump instructions in the row to improve
11502      branch prediction and the benefits hardly outweigh the cost of extra 8
11503      nops on the average inserted by full alignment pseudo operation.  */
11504 #endif
11505   return "";
11506 }
11507   [(set_attr "length" "16")])
11508
11509 (define_expand "prologue"
11510   [(const_int 0)]
11511   ""
11512   "ix86_expand_prologue (); DONE;")
11513
11514 (define_insn "set_got"
11515   [(set (match_operand:SI 0 "register_operand" "=r")
11516         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11517    (clobber (reg:CC FLAGS_REG))]
11518   "!TARGET_64BIT"
11519   "* return output_set_got (operands[0], NULL_RTX);"
11520   [(set_attr "type" "multi")
11521    (set_attr "length" "12")])
11522
11523 (define_insn "set_got_labelled"
11524   [(set (match_operand:SI 0 "register_operand" "=r")
11525         (unspec:SI [(label_ref (match_operand 1 "" ""))]
11526          UNSPEC_SET_GOT))
11527    (clobber (reg:CC FLAGS_REG))]
11528   "!TARGET_64BIT"
11529   "* return output_set_got (operands[0], operands[1]);"
11530   [(set_attr "type" "multi")
11531    (set_attr "length" "12")])
11532
11533 (define_insn "set_got_rex64"
11534   [(set (match_operand:DI 0 "register_operand" "=r")
11535         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11536   "TARGET_64BIT"
11537   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11538   [(set_attr "type" "lea")
11539    (set_attr "length_address" "4")
11540    (set_attr "mode" "DI")])
11541
11542 (define_insn "set_rip_rex64"
11543   [(set (match_operand:DI 0 "register_operand" "=r")
11544         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11545   "TARGET_64BIT"
11546   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11547   [(set_attr "type" "lea")
11548    (set_attr "length_address" "4")
11549    (set_attr "mode" "DI")])
11550
11551 (define_insn "set_got_offset_rex64"
11552   [(set (match_operand:DI 0 "register_operand" "=r")
11553         (unspec:DI
11554           [(label_ref (match_operand 1 "" ""))]
11555           UNSPEC_SET_GOT_OFFSET))]
11556   "TARGET_64BIT"
11557   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11558   [(set_attr "type" "imov")
11559    (set_attr "length_immediate" "0")
11560    (set_attr "length_address" "8")
11561    (set_attr "mode" "DI")])
11562
11563 (define_expand "epilogue"
11564   [(const_int 0)]
11565   ""
11566   "ix86_expand_epilogue (1); DONE;")
11567
11568 (define_expand "sibcall_epilogue"
11569   [(const_int 0)]
11570   ""
11571   "ix86_expand_epilogue (0); DONE;")
11572
11573 (define_expand "eh_return"
11574   [(use (match_operand 0 "register_operand" ""))]
11575   ""
11576 {
11577   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11578
11579   /* Tricky bit: we write the address of the handler to which we will
11580      be returning into someone else's stack frame, one word below the
11581      stack address we wish to restore.  */
11582   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11583   tmp = plus_constant (tmp, -UNITS_PER_WORD);
11584   tmp = gen_rtx_MEM (Pmode, tmp);
11585   emit_move_insn (tmp, ra);
11586
11587   emit_jump_insn (gen_eh_return_internal ());
11588   emit_barrier ();
11589   DONE;
11590 })
11591
11592 (define_insn_and_split "eh_return_internal"
11593   [(eh_return)]
11594   ""
11595   "#"
11596   "epilogue_completed"
11597   [(const_int 0)]
11598   "ix86_expand_epilogue (2); DONE;")
11599
11600 (define_insn "leave"
11601   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11602    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11603    (clobber (mem:BLK (scratch)))]
11604   "!TARGET_64BIT"
11605   "leave"
11606   [(set_attr "type" "leave")])
11607
11608 (define_insn "leave_rex64"
11609   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11610    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11611    (clobber (mem:BLK (scratch)))]
11612   "TARGET_64BIT"
11613   "leave"
11614   [(set_attr "type" "leave")])
11615 \f
11616 ;; Handle -fsplit-stack.
11617
11618 (define_expand "split_stack_prologue"
11619   [(const_int 0)]
11620   ""
11621 {
11622   ix86_expand_split_stack_prologue ();
11623   DONE;
11624 })
11625
11626 ;; In order to support the call/return predictor, we use a return
11627 ;; instruction which the middle-end doesn't see.
11628 (define_insn "split_stack_return"
11629   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11630                     UNSPEC_STACK_CHECK)]
11631   ""
11632 {
11633   if (operands[0] == const0_rtx)
11634     return "ret";
11635   else
11636     return "ret\t%0";
11637 }
11638   [(set_attr "atom_unit" "jeu")
11639    (set_attr "modrm" "0")
11640    (set (attr "length")
11641         (if_then_else (match_operand:SI 0 "const0_operand" "")
11642                       (const_int 1)
11643                       (const_int 3)))
11644    (set (attr "length_immediate")
11645         (if_then_else (match_operand:SI 0 "const0_operand" "")
11646                       (const_int 0)
11647                       (const_int 2)))])
11648
11649 ;; If there are operand 0 bytes available on the stack, jump to
11650 ;; operand 1.
11651
11652 (define_expand "split_stack_space_check"
11653   [(set (pc) (if_then_else
11654               (ltu (minus (reg SP_REG)
11655                           (match_operand 0 "register_operand" ""))
11656                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11657               (label_ref (match_operand 1 "" ""))
11658               (pc)))]
11659   ""
11660 {
11661   rtx reg, size, limit;
11662
11663   reg = gen_reg_rtx (Pmode);
11664   size = force_reg (Pmode, operands[0]);
11665   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11666   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11667                           UNSPEC_STACK_CHECK);
11668   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11669   ix86_expand_branch (GEU, reg, limit, operands[1]);
11670
11671   DONE;
11672 })
11673 \f
11674 ;; Bit manipulation instructions.
11675
11676 (define_expand "ffs<mode>2"
11677   [(set (match_dup 2) (const_int -1))
11678    (parallel [(set (reg:CCZ FLAGS_REG)
11679                    (compare:CCZ
11680                      (match_operand:SWI48 1 "nonimmediate_operand" "")
11681                      (const_int 0)))
11682               (set (match_operand:SWI48 0 "register_operand" "")
11683                    (ctz:SWI48 (match_dup 1)))])
11684    (set (match_dup 0) (if_then_else:SWI48
11685                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
11686                         (match_dup 2)
11687                         (match_dup 0)))
11688    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11689               (clobber (reg:CC FLAGS_REG))])]
11690   ""
11691 {
11692   if (<MODE>mode == SImode && !TARGET_CMOVE)
11693     {
11694       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11695       DONE;
11696     }
11697   operands[2] = gen_reg_rtx (<MODE>mode);
11698 })
11699
11700 (define_insn_and_split "ffssi2_no_cmove"
11701   [(set (match_operand:SI 0 "register_operand" "=r")
11702         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11703    (clobber (match_scratch:SI 2 "=&q"))
11704    (clobber (reg:CC FLAGS_REG))]
11705   "!TARGET_CMOVE"
11706   "#"
11707   "&& reload_completed"
11708   [(parallel [(set (reg:CCZ FLAGS_REG)
11709                    (compare:CCZ (match_dup 1) (const_int 0)))
11710               (set (match_dup 0) (ctz:SI (match_dup 1)))])
11711    (set (strict_low_part (match_dup 3))
11712         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11713    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11714               (clobber (reg:CC FLAGS_REG))])
11715    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11716               (clobber (reg:CC FLAGS_REG))])
11717    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11718               (clobber (reg:CC FLAGS_REG))])]
11719 {
11720   operands[3] = gen_lowpart (QImode, operands[2]);
11721   ix86_expand_clear (operands[2]);
11722 })
11723
11724 (define_insn "*ffs<mode>_1"
11725   [(set (reg:CCZ FLAGS_REG)
11726         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11727                      (const_int 0)))
11728    (set (match_operand:SWI48 0 "register_operand" "=r")
11729         (ctz:SWI48 (match_dup 1)))]
11730   ""
11731   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11732   [(set_attr "type" "alu1")
11733    (set_attr "prefix_0f" "1")
11734    (set_attr "mode" "<MODE>")])
11735
11736 (define_insn "ctz<mode>2"
11737   [(set (match_operand:SWI48 0 "register_operand" "=r")
11738         (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
11739    (clobber (reg:CC FLAGS_REG))]
11740   ""
11741   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11742   [(set_attr "type" "alu1")
11743    (set_attr "prefix_0f" "1")
11744    (set_attr "mode" "<MODE>")])
11745
11746 (define_expand "clz<mode>2"
11747   [(parallel
11748      [(set (match_operand:SWI248 0 "register_operand" "")
11749            (minus:SWI248
11750              (match_dup 2)
11751              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11752       (clobber (reg:CC FLAGS_REG))])
11753    (parallel
11754      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11755       (clobber (reg:CC FLAGS_REG))])]
11756   ""
11757 {
11758   if (TARGET_ABM)
11759     {
11760       emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11761       DONE;
11762     }
11763   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11764 })
11765
11766 (define_insn "clz<mode>2_abm"
11767   [(set (match_operand:SWI248 0 "register_operand" "=r")
11768         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11769    (clobber (reg:CC FLAGS_REG))]
11770   "TARGET_ABM"
11771   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11772   [(set_attr "prefix_rep" "1")
11773    (set_attr "type" "bitmanip")
11774    (set_attr "mode" "<MODE>")])
11775
11776 (define_insn "bsr_rex64"
11777   [(set (match_operand:DI 0 "register_operand" "=r")
11778         (minus:DI (const_int 63)
11779                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
11780    (clobber (reg:CC FLAGS_REG))]
11781   "TARGET_64BIT"
11782   "bsr{q}\t{%1, %0|%0, %1}"
11783   [(set_attr "type" "alu1")
11784    (set_attr "prefix_0f" "1")
11785    (set_attr "mode" "DI")])
11786
11787 (define_insn "bsr"
11788   [(set (match_operand:SI 0 "register_operand" "=r")
11789         (minus:SI (const_int 31)
11790                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
11791    (clobber (reg:CC FLAGS_REG))]
11792   ""
11793   "bsr{l}\t{%1, %0|%0, %1}"
11794   [(set_attr "type" "alu1")
11795    (set_attr "prefix_0f" "1")
11796    (set_attr "mode" "SI")])
11797
11798 (define_insn "*bsrhi"
11799   [(set (match_operand:HI 0 "register_operand" "=r")
11800         (minus:HI (const_int 15)
11801                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
11802    (clobber (reg:CC FLAGS_REG))]
11803   ""
11804   "bsr{w}\t{%1, %0|%0, %1}"
11805   [(set_attr "type" "alu1")
11806    (set_attr "prefix_0f" "1")
11807    (set_attr "mode" "HI")])
11808
11809 (define_insn "popcount<mode>2"
11810   [(set (match_operand:SWI248 0 "register_operand" "=r")
11811         (popcount:SWI248
11812           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11813    (clobber (reg:CC FLAGS_REG))]
11814   "TARGET_POPCNT"
11815 {
11816 #if TARGET_MACHO
11817   return "popcnt\t{%1, %0|%0, %1}";
11818 #else
11819   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11820 #endif
11821 }
11822   [(set_attr "prefix_rep" "1")
11823    (set_attr "type" "bitmanip")
11824    (set_attr "mode" "<MODE>")])
11825
11826 (define_insn "*popcount<mode>2_cmp"
11827   [(set (reg FLAGS_REG)
11828         (compare
11829           (popcount:SWI248
11830             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
11831           (const_int 0)))
11832    (set (match_operand:SWI248 0 "register_operand" "=r")
11833         (popcount:SWI248 (match_dup 1)))]
11834   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11835 {
11836 #if TARGET_MACHO
11837   return "popcnt\t{%1, %0|%0, %1}";
11838 #else
11839   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11840 #endif
11841 }
11842   [(set_attr "prefix_rep" "1")
11843    (set_attr "type" "bitmanip")
11844    (set_attr "mode" "<MODE>")])
11845
11846 (define_insn "*popcountsi2_cmp_zext"
11847   [(set (reg FLAGS_REG)
11848         (compare
11849           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
11850           (const_int 0)))
11851    (set (match_operand:DI 0 "register_operand" "=r")
11852         (zero_extend:DI(popcount:SI (match_dup 1))))]
11853   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11854 {
11855 #if TARGET_MACHO
11856   return "popcnt\t{%1, %0|%0, %1}";
11857 #else
11858   return "popcnt{l}\t{%1, %0|%0, %1}";
11859 #endif
11860 }
11861   [(set_attr "prefix_rep" "1")
11862    (set_attr "type" "bitmanip")
11863    (set_attr "mode" "SI")])
11864
11865 (define_expand "bswap<mode>2"
11866   [(set (match_operand:SWI48 0 "register_operand" "")
11867         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
11868   ""
11869 {
11870   if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
11871     {
11872       rtx x = operands[0];
11873
11874       emit_move_insn (x, operands[1]);
11875       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11876       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
11877       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11878       DONE;
11879     }
11880 })
11881
11882 (define_insn "*bswap<mode>2_movbe"
11883   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
11884         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
11885   "TARGET_MOVBE
11886    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11887   "@
11888     bswap\t%0
11889     movbe\t{%1, %0|%0, %1}
11890     movbe\t{%1, %0|%0, %1}"
11891   [(set_attr "type" "bitmanip,imov,imov")
11892    (set_attr "modrm" "0,1,1")
11893    (set_attr "prefix_0f" "*,1,1")
11894    (set_attr "prefix_extra" "*,1,1")
11895    (set_attr "mode" "<MODE>")])
11896
11897 (define_insn "*bswap<mode>2_1"
11898   [(set (match_operand:SWI48 0 "register_operand" "=r")
11899         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
11900   "TARGET_BSWAP"
11901   "bswap\t%0"
11902   [(set_attr "type" "bitmanip")
11903    (set_attr "modrm" "0")
11904    (set_attr "mode" "<MODE>")])
11905
11906 (define_insn "*bswaphi_lowpart_1"
11907   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
11908         (bswap:HI (match_dup 0)))
11909    (clobber (reg:CC FLAGS_REG))]
11910   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
11911   "@
11912     xchg{b}\t{%h0, %b0|%b0, %h0}
11913     rol{w}\t{$8, %0|%0, 8}"
11914   [(set_attr "length" "2,4")
11915    (set_attr "mode" "QI,HI")])
11916
11917 (define_insn "bswaphi_lowpart"
11918   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
11919         (bswap:HI (match_dup 0)))
11920    (clobber (reg:CC FLAGS_REG))]
11921   ""
11922   "rol{w}\t{$8, %0|%0, 8}"
11923   [(set_attr "length" "4")
11924    (set_attr "mode" "HI")])
11925
11926 (define_expand "paritydi2"
11927   [(set (match_operand:DI 0 "register_operand" "")
11928         (parity:DI (match_operand:DI 1 "register_operand" "")))]
11929   "! TARGET_POPCNT"
11930 {
11931   rtx scratch = gen_reg_rtx (QImode);
11932   rtx cond;
11933
11934   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
11935                                 NULL_RTX, operands[1]));
11936
11937   cond = gen_rtx_fmt_ee (ORDERED, QImode,
11938                          gen_rtx_REG (CCmode, FLAGS_REG),
11939                          const0_rtx);
11940   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
11941
11942   if (TARGET_64BIT)
11943     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
11944   else
11945     {
11946       rtx tmp = gen_reg_rtx (SImode);
11947
11948       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
11949       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
11950     }
11951   DONE;
11952 })
11953
11954 (define_expand "paritysi2"
11955   [(set (match_operand:SI 0 "register_operand" "")
11956         (parity:SI (match_operand:SI 1 "register_operand" "")))]
11957   "! TARGET_POPCNT"
11958 {
11959   rtx scratch = gen_reg_rtx (QImode);
11960   rtx cond;
11961
11962   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
11963
11964   cond = gen_rtx_fmt_ee (ORDERED, QImode,
11965                          gen_rtx_REG (CCmode, FLAGS_REG),
11966                          const0_rtx);
11967   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
11968
11969   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
11970   DONE;
11971 })
11972
11973 (define_insn_and_split "paritydi2_cmp"
11974   [(set (reg:CC FLAGS_REG)
11975         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
11976                    UNSPEC_PARITY))
11977    (clobber (match_scratch:DI 0 "=r"))
11978    (clobber (match_scratch:SI 1 "=&r"))
11979    (clobber (match_scratch:HI 2 "=Q"))]
11980   "! TARGET_POPCNT"
11981   "#"
11982   "&& reload_completed"
11983   [(parallel
11984      [(set (match_dup 1)
11985            (xor:SI (match_dup 1) (match_dup 4)))
11986       (clobber (reg:CC FLAGS_REG))])
11987    (parallel
11988      [(set (reg:CC FLAGS_REG)
11989            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
11990       (clobber (match_dup 1))
11991       (clobber (match_dup 2))])]
11992 {
11993   operands[4] = gen_lowpart (SImode, operands[3]);
11994
11995   if (TARGET_64BIT)
11996     {
11997       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
11998       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
11999     }
12000   else
12001     operands[1] = gen_highpart (SImode, operands[3]);
12002 })
12003
12004 (define_insn_and_split "paritysi2_cmp"
12005   [(set (reg:CC FLAGS_REG)
12006         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12007                    UNSPEC_PARITY))
12008    (clobber (match_scratch:SI 0 "=r"))
12009    (clobber (match_scratch:HI 1 "=&Q"))]
12010   "! TARGET_POPCNT"
12011   "#"
12012   "&& reload_completed"
12013   [(parallel
12014      [(set (match_dup 1)
12015            (xor:HI (match_dup 1) (match_dup 3)))
12016       (clobber (reg:CC FLAGS_REG))])
12017    (parallel
12018      [(set (reg:CC FLAGS_REG)
12019            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12020       (clobber (match_dup 1))])]
12021 {
12022   operands[3] = gen_lowpart (HImode, operands[2]);
12023
12024   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12025   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12026 })
12027
12028 (define_insn "*parityhi2_cmp"
12029   [(set (reg:CC FLAGS_REG)
12030         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12031                    UNSPEC_PARITY))
12032    (clobber (match_scratch:HI 0 "=Q"))]
12033   "! TARGET_POPCNT"
12034   "xor{b}\t{%h0, %b0|%b0, %h0}"
12035   [(set_attr "length" "2")
12036    (set_attr "mode" "HI")])
12037 \f
12038 ;; Thread-local storage patterns for ELF.
12039 ;;
12040 ;; Note that these code sequences must appear exactly as shown
12041 ;; in order to allow linker relaxation.
12042
12043 (define_insn "*tls_global_dynamic_32_gnu"
12044   [(set (match_operand:SI 0 "register_operand" "=a")
12045         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12046                     (match_operand:SI 2 "tls_symbolic_operand" "")
12047                     (match_operand:SI 3 "call_insn_operand" "")]
12048                     UNSPEC_TLS_GD))
12049    (clobber (match_scratch:SI 4 "=d"))
12050    (clobber (match_scratch:SI 5 "=c"))
12051    (clobber (reg:CC FLAGS_REG))]
12052   "!TARGET_64BIT && TARGET_GNU_TLS"
12053   "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12054   [(set_attr "type" "multi")
12055    (set_attr "length" "12")])
12056
12057 (define_expand "tls_global_dynamic_32"
12058   [(parallel [(set (match_operand:SI 0 "register_operand" "")
12059                    (unspec:SI
12060                     [(match_dup 2)
12061                      (match_operand:SI 1 "tls_symbolic_operand" "")
12062                      (match_dup 3)]
12063                     UNSPEC_TLS_GD))
12064               (clobber (match_scratch:SI 4 ""))
12065               (clobber (match_scratch:SI 5 ""))
12066               (clobber (reg:CC FLAGS_REG))])]
12067   ""
12068 {
12069   if (flag_pic)
12070     operands[2] = pic_offset_table_rtx;
12071   else
12072     {
12073       operands[2] = gen_reg_rtx (Pmode);
12074       emit_insn (gen_set_got (operands[2]));
12075     }
12076   if (TARGET_GNU2_TLS)
12077     {
12078        emit_insn (gen_tls_dynamic_gnu2_32
12079                   (operands[0], operands[1], operands[2]));
12080        DONE;
12081     }
12082   operands[3] = ix86_tls_get_addr ();
12083 })
12084
12085 (define_insn "*tls_global_dynamic_64"
12086   [(set (match_operand:DI 0 "register_operand" "=a")
12087         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12088                  (match_operand:DI 3 "" "")))
12089    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12090               UNSPEC_TLS_GD)]
12091   "TARGET_64BIT"
12092   { return ASM_BYTE "0x66\n\tlea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}\n" ASM_SHORT "0x6666\n\trex64\n\tcall\t%P2"; }
12093   [(set_attr "type" "multi")
12094    (set_attr "length" "16")])
12095
12096 (define_expand "tls_global_dynamic_64"
12097   [(parallel [(set (match_operand:DI 0 "register_operand" "")
12098                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12099               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12100                          UNSPEC_TLS_GD)])]
12101   ""
12102 {
12103   if (TARGET_GNU2_TLS)
12104     {
12105        emit_insn (gen_tls_dynamic_gnu2_64
12106                   (operands[0], operands[1]));
12107        DONE;
12108     }
12109   operands[2] = ix86_tls_get_addr ();
12110 })
12111
12112 (define_insn "*tls_local_dynamic_base_32_gnu"
12113   [(set (match_operand:SI 0 "register_operand" "=a")
12114         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12115                     (match_operand:SI 2 "call_insn_operand" "")]
12116                    UNSPEC_TLS_LD_BASE))
12117    (clobber (match_scratch:SI 3 "=d"))
12118    (clobber (match_scratch:SI 4 "=c"))
12119    (clobber (reg:CC FLAGS_REG))]
12120   "!TARGET_64BIT && TARGET_GNU_TLS"
12121   "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12122   [(set_attr "type" "multi")
12123    (set_attr "length" "11")])
12124
12125 (define_expand "tls_local_dynamic_base_32"
12126   [(parallel [(set (match_operand:SI 0 "register_operand" "")
12127                    (unspec:SI [(match_dup 1) (match_dup 2)]
12128                               UNSPEC_TLS_LD_BASE))
12129               (clobber (match_scratch:SI 3 ""))
12130               (clobber (match_scratch:SI 4 ""))
12131               (clobber (reg:CC FLAGS_REG))])]
12132   ""
12133 {
12134   if (flag_pic)
12135     operands[1] = pic_offset_table_rtx;
12136   else
12137     {
12138       operands[1] = gen_reg_rtx (Pmode);
12139       emit_insn (gen_set_got (operands[1]));
12140     }
12141   if (TARGET_GNU2_TLS)
12142     {
12143        emit_insn (gen_tls_dynamic_gnu2_32
12144                   (operands[0], ix86_tls_module_base (), operands[1]));
12145        DONE;
12146     }
12147   operands[2] = ix86_tls_get_addr ();
12148 })
12149
12150 (define_insn "*tls_local_dynamic_base_64"
12151   [(set (match_operand:DI 0 "register_operand" "=a")
12152         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12153                  (match_operand:DI 2 "" "")))
12154    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12155   "TARGET_64BIT"
12156   "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12157   [(set_attr "type" "multi")
12158    (set_attr "length" "12")])
12159
12160 (define_expand "tls_local_dynamic_base_64"
12161   [(parallel [(set (match_operand:DI 0 "register_operand" "")
12162                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12163               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12164   ""
12165 {
12166   if (TARGET_GNU2_TLS)
12167     {
12168        emit_insn (gen_tls_dynamic_gnu2_64
12169                   (operands[0], ix86_tls_module_base ()));
12170        DONE;
12171     }
12172   operands[1] = ix86_tls_get_addr ();
12173 })
12174
12175 ;; Local dynamic of a single variable is a lose.  Show combine how
12176 ;; to convert that back to global dynamic.
12177
12178 (define_insn_and_split "*tls_local_dynamic_32_once"
12179   [(set (match_operand:SI 0 "register_operand" "=a")
12180         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12181                              (match_operand:SI 2 "call_insn_operand" "")]
12182                             UNSPEC_TLS_LD_BASE)
12183                  (const:SI (unspec:SI
12184                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
12185                             UNSPEC_DTPOFF))))
12186    (clobber (match_scratch:SI 4 "=d"))
12187    (clobber (match_scratch:SI 5 "=c"))
12188    (clobber (reg:CC FLAGS_REG))]
12189   ""
12190   "#"
12191   ""
12192   [(parallel [(set (match_dup 0)
12193                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12194                               UNSPEC_TLS_GD))
12195               (clobber (match_dup 4))
12196               (clobber (match_dup 5))
12197               (clobber (reg:CC FLAGS_REG))])])
12198
12199 ;; Segment register for the thread base ptr load
12200 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12201
12202 ;; Load and add the thread base pointer from %gs:0.
12203 (define_insn "*load_tp_<mode>"
12204   [(set (match_operand:P 0 "register_operand" "=r")
12205         (unspec:P [(const_int 0)] UNSPEC_TP))]
12206   ""
12207   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12208   [(set_attr "type" "imov")
12209    (set_attr "modrm" "0")
12210    (set_attr "length" "7")
12211    (set_attr "memory" "load")
12212    (set_attr "imm_disp" "false")])
12213
12214 (define_insn "*add_tp_<mode>"
12215   [(set (match_operand:P 0 "register_operand" "=r")
12216         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12217                 (match_operand:P 1 "register_operand" "0")))
12218    (clobber (reg:CC FLAGS_REG))]
12219   ""
12220   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12221   [(set_attr "type" "alu")
12222    (set_attr "modrm" "0")
12223    (set_attr "length" "7")
12224    (set_attr "memory" "load")
12225    (set_attr "imm_disp" "false")])
12226
12227 ;; GNU2 TLS patterns can be split.
12228
12229 (define_expand "tls_dynamic_gnu2_32"
12230   [(set (match_dup 3)
12231         (plus:SI (match_operand:SI 2 "register_operand" "")
12232                  (const:SI
12233                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12234                              UNSPEC_TLSDESC))))
12235    (parallel
12236     [(set (match_operand:SI 0 "register_operand" "")
12237           (unspec:SI [(match_dup 1) (match_dup 3)
12238                       (match_dup 2) (reg:SI SP_REG)]
12239                       UNSPEC_TLSDESC))
12240      (clobber (reg:CC FLAGS_REG))])]
12241   "!TARGET_64BIT && TARGET_GNU2_TLS"
12242 {
12243   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12244   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12245 })
12246
12247 (define_insn "*tls_dynamic_lea_32"
12248   [(set (match_operand:SI 0 "register_operand" "=r")
12249         (plus:SI (match_operand:SI 1 "register_operand" "b")
12250                  (const:SI
12251                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12252                               UNSPEC_TLSDESC))))]
12253   "!TARGET_64BIT && TARGET_GNU2_TLS"
12254   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12255   [(set_attr "type" "lea")
12256    (set_attr "mode" "SI")
12257    (set_attr "length" "6")
12258    (set_attr "length_address" "4")])
12259
12260 (define_insn "*tls_dynamic_call_32"
12261   [(set (match_operand:SI 0 "register_operand" "=a")
12262         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12263                     (match_operand:SI 2 "register_operand" "0")
12264                     ;; we have to make sure %ebx still points to the GOT
12265                     (match_operand:SI 3 "register_operand" "b")
12266                     (reg:SI SP_REG)]
12267                    UNSPEC_TLSDESC))
12268    (clobber (reg:CC FLAGS_REG))]
12269   "!TARGET_64BIT && TARGET_GNU2_TLS"
12270   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12271   [(set_attr "type" "call")
12272    (set_attr "length" "2")
12273    (set_attr "length_address" "0")])
12274
12275 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12276   [(set (match_operand:SI 0 "register_operand" "=&a")
12277         (plus:SI
12278          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12279                      (match_operand:SI 4 "" "")
12280                      (match_operand:SI 2 "register_operand" "b")
12281                      (reg:SI SP_REG)]
12282                     UNSPEC_TLSDESC)
12283          (const:SI (unspec:SI
12284                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
12285                     UNSPEC_DTPOFF))))
12286    (clobber (reg:CC FLAGS_REG))]
12287   "!TARGET_64BIT && TARGET_GNU2_TLS"
12288   "#"
12289   ""
12290   [(set (match_dup 0) (match_dup 5))]
12291 {
12292   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12293   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12294 })
12295
12296 (define_expand "tls_dynamic_gnu2_64"
12297   [(set (match_dup 2)
12298         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12299                    UNSPEC_TLSDESC))
12300    (parallel
12301     [(set (match_operand:DI 0 "register_operand" "")
12302           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12303                      UNSPEC_TLSDESC))
12304      (clobber (reg:CC FLAGS_REG))])]
12305   "TARGET_64BIT && TARGET_GNU2_TLS"
12306 {
12307   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12308   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12309 })
12310
12311 (define_insn "*tls_dynamic_lea_64"
12312   [(set (match_operand:DI 0 "register_operand" "=r")
12313         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12314                    UNSPEC_TLSDESC))]
12315   "TARGET_64BIT && TARGET_GNU2_TLS"
12316   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12317   [(set_attr "type" "lea")
12318    (set_attr "mode" "DI")
12319    (set_attr "length" "7")
12320    (set_attr "length_address" "4")])
12321
12322 (define_insn "*tls_dynamic_call_64"
12323   [(set (match_operand:DI 0 "register_operand" "=a")
12324         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12325                     (match_operand:DI 2 "register_operand" "0")
12326                     (reg:DI SP_REG)]
12327                    UNSPEC_TLSDESC))
12328    (clobber (reg:CC FLAGS_REG))]
12329   "TARGET_64BIT && TARGET_GNU2_TLS"
12330   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12331   [(set_attr "type" "call")
12332    (set_attr "length" "2")
12333    (set_attr "length_address" "0")])
12334
12335 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12336   [(set (match_operand:DI 0 "register_operand" "=&a")
12337         (plus:DI
12338          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12339                      (match_operand:DI 3 "" "")
12340                      (reg:DI SP_REG)]
12341                     UNSPEC_TLSDESC)
12342          (const:DI (unspec:DI
12343                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
12344                     UNSPEC_DTPOFF))))
12345    (clobber (reg:CC FLAGS_REG))]
12346   "TARGET_64BIT && TARGET_GNU2_TLS"
12347   "#"
12348   ""
12349   [(set (match_dup 0) (match_dup 4))]
12350 {
12351   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12352   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12353 })
12354 \f
12355 ;; These patterns match the binary 387 instructions for addM3, subM3,
12356 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
12357 ;; SFmode.  The first is the normal insn, the second the same insn but
12358 ;; with one operand a conversion, and the third the same insn but with
12359 ;; the other operand a conversion.  The conversion may be SFmode or
12360 ;; SImode if the target mode DFmode, but only SImode if the target mode
12361 ;; is SFmode.
12362
12363 ;; Gcc is slightly more smart about handling normal two address instructions
12364 ;; so use special patterns for add and mull.
12365
12366 (define_insn "*fop_<mode>_comm_mixed_avx"
12367   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12368         (match_operator:MODEF 3 "binary_fp_operator"
12369           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12370            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12371   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12372    && COMMUTATIVE_ARITH_P (operands[3])
12373    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12374   "* return output_387_binary_op (insn, operands);"
12375   [(set (attr "type")
12376         (if_then_else (eq_attr "alternative" "1")
12377            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12378               (const_string "ssemul")
12379               (const_string "sseadd"))
12380            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12381               (const_string "fmul")
12382               (const_string "fop"))))
12383    (set_attr "prefix" "orig,maybe_vex")
12384    (set_attr "mode" "<MODE>")])
12385
12386 (define_insn "*fop_<mode>_comm_mixed"
12387   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12388         (match_operator:MODEF 3 "binary_fp_operator"
12389           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12390            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12391   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12392    && COMMUTATIVE_ARITH_P (operands[3])
12393    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12394   "* return output_387_binary_op (insn, operands);"
12395   [(set (attr "type")
12396         (if_then_else (eq_attr "alternative" "1")
12397            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12398               (const_string "ssemul")
12399               (const_string "sseadd"))
12400            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12401               (const_string "fmul")
12402               (const_string "fop"))))
12403    (set_attr "mode" "<MODE>")])
12404
12405 (define_insn "*fop_<mode>_comm_avx"
12406   [(set (match_operand:MODEF 0 "register_operand" "=x")
12407         (match_operator:MODEF 3 "binary_fp_operator"
12408           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12409            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12410   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12411    && COMMUTATIVE_ARITH_P (operands[3])
12412    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12413   "* return output_387_binary_op (insn, operands);"
12414   [(set (attr "type")
12415         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12416            (const_string "ssemul")
12417            (const_string "sseadd")))
12418    (set_attr "prefix" "vex")
12419    (set_attr "mode" "<MODE>")])
12420
12421 (define_insn "*fop_<mode>_comm_sse"
12422   [(set (match_operand:MODEF 0 "register_operand" "=x")
12423         (match_operator:MODEF 3 "binary_fp_operator"
12424           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12425            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12426   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12427    && COMMUTATIVE_ARITH_P (operands[3])
12428    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12429   "* return output_387_binary_op (insn, operands);"
12430   [(set (attr "type")
12431         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12432            (const_string "ssemul")
12433            (const_string "sseadd")))
12434    (set_attr "mode" "<MODE>")])
12435
12436 (define_insn "*fop_<mode>_comm_i387"
12437   [(set (match_operand:MODEF 0 "register_operand" "=f")
12438         (match_operator:MODEF 3 "binary_fp_operator"
12439           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12440            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12441   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12442    && COMMUTATIVE_ARITH_P (operands[3])
12443    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12444   "* return output_387_binary_op (insn, operands);"
12445   [(set (attr "type")
12446         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12447            (const_string "fmul")
12448            (const_string "fop")))
12449    (set_attr "mode" "<MODE>")])
12450
12451 (define_insn "*fop_<mode>_1_mixed_avx"
12452   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12453         (match_operator:MODEF 3 "binary_fp_operator"
12454           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
12455            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12456   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12457    && !COMMUTATIVE_ARITH_P (operands[3])
12458    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12459   "* return output_387_binary_op (insn, operands);"
12460   [(set (attr "type")
12461         (cond [(and (eq_attr "alternative" "2")
12462                     (match_operand:MODEF 3 "mult_operator" ""))
12463                  (const_string "ssemul")
12464                (and (eq_attr "alternative" "2")
12465                     (match_operand:MODEF 3 "div_operator" ""))
12466                  (const_string "ssediv")
12467                (eq_attr "alternative" "2")
12468                  (const_string "sseadd")
12469                (match_operand:MODEF 3 "mult_operator" "")
12470                  (const_string "fmul")
12471                (match_operand:MODEF 3 "div_operator" "")
12472                  (const_string "fdiv")
12473               ]
12474               (const_string "fop")))
12475    (set_attr "prefix" "orig,orig,maybe_vex")
12476    (set_attr "mode" "<MODE>")])
12477
12478 (define_insn "*fop_<mode>_1_mixed"
12479   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12480         (match_operator:MODEF 3 "binary_fp_operator"
12481           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
12482            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12483   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12484    && !COMMUTATIVE_ARITH_P (operands[3])
12485    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12486   "* return output_387_binary_op (insn, operands);"
12487   [(set (attr "type")
12488         (cond [(and (eq_attr "alternative" "2")
12489                     (match_operand:MODEF 3 "mult_operator" ""))
12490                  (const_string "ssemul")
12491                (and (eq_attr "alternative" "2")
12492                     (match_operand:MODEF 3 "div_operator" ""))
12493                  (const_string "ssediv")
12494                (eq_attr "alternative" "2")
12495                  (const_string "sseadd")
12496                (match_operand:MODEF 3 "mult_operator" "")
12497                  (const_string "fmul")
12498                (match_operand:MODEF 3 "div_operator" "")
12499                  (const_string "fdiv")
12500               ]
12501               (const_string "fop")))
12502    (set_attr "mode" "<MODE>")])
12503
12504 (define_insn "*rcpsf2_sse"
12505   [(set (match_operand:SF 0 "register_operand" "=x")
12506         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12507                    UNSPEC_RCP))]
12508   "TARGET_SSE_MATH"
12509   "%vrcpss\t{%1, %d0|%d0, %1}"
12510   [(set_attr "type" "sse")
12511    (set_attr "atom_sse_attr" "rcp")
12512    (set_attr "prefix" "maybe_vex")
12513    (set_attr "mode" "SF")])
12514
12515 (define_insn "*fop_<mode>_1_avx"
12516   [(set (match_operand:MODEF 0 "register_operand" "=x")
12517         (match_operator:MODEF 3 "binary_fp_operator"
12518           [(match_operand:MODEF 1 "register_operand" "x")
12519            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12520   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12521    && !COMMUTATIVE_ARITH_P (operands[3])"
12522   "* return output_387_binary_op (insn, operands);"
12523   [(set (attr "type")
12524         (cond [(match_operand:MODEF 3 "mult_operator" "")
12525                  (const_string "ssemul")
12526                (match_operand:MODEF 3 "div_operator" "")
12527                  (const_string "ssediv")
12528               ]
12529               (const_string "sseadd")))
12530    (set_attr "prefix" "vex")
12531    (set_attr "mode" "<MODE>")])
12532
12533 (define_insn "*fop_<mode>_1_sse"
12534   [(set (match_operand:MODEF 0 "register_operand" "=x")
12535         (match_operator:MODEF 3 "binary_fp_operator"
12536           [(match_operand:MODEF 1 "register_operand" "0")
12537            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12538   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12539    && !COMMUTATIVE_ARITH_P (operands[3])"
12540   "* return output_387_binary_op (insn, operands);"
12541   [(set (attr "type")
12542         (cond [(match_operand:MODEF 3 "mult_operator" "")
12543                  (const_string "ssemul")
12544                (match_operand:MODEF 3 "div_operator" "")
12545                  (const_string "ssediv")
12546               ]
12547               (const_string "sseadd")))
12548    (set_attr "mode" "<MODE>")])
12549
12550 ;; This pattern is not fully shadowed by the pattern above.
12551 (define_insn "*fop_<mode>_1_i387"
12552   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12553         (match_operator:MODEF 3 "binary_fp_operator"
12554           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12555            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12556   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12557    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12558    && !COMMUTATIVE_ARITH_P (operands[3])
12559    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12560   "* return output_387_binary_op (insn, operands);"
12561   [(set (attr "type")
12562         (cond [(match_operand:MODEF 3 "mult_operator" "")
12563                  (const_string "fmul")
12564                (match_operand:MODEF 3 "div_operator" "")
12565                  (const_string "fdiv")
12566               ]
12567               (const_string "fop")))
12568    (set_attr "mode" "<MODE>")])
12569
12570 ;; ??? Add SSE splitters for these!
12571 (define_insn "*fop_<MODEF:mode>_2_i387"
12572   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12573         (match_operator:MODEF 3 "binary_fp_operator"
12574           [(float:MODEF
12575              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12576            (match_operand:MODEF 2 "register_operand" "0,0")]))]
12577   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12578    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12579    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12580   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12581   [(set (attr "type")
12582         (cond [(match_operand:MODEF 3 "mult_operator" "")
12583                  (const_string "fmul")
12584                (match_operand:MODEF 3 "div_operator" "")
12585                  (const_string "fdiv")
12586               ]
12587               (const_string "fop")))
12588    (set_attr "fp_int_src" "true")
12589    (set_attr "mode" "<X87MODEI12:MODE>")])
12590
12591 (define_insn "*fop_<MODEF:mode>_3_i387"
12592   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12593         (match_operator:MODEF 3 "binary_fp_operator"
12594           [(match_operand:MODEF 1 "register_operand" "0,0")
12595            (float:MODEF
12596              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12597   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12598    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12599    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12600   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12601   [(set (attr "type")
12602         (cond [(match_operand:MODEF 3 "mult_operator" "")
12603                  (const_string "fmul")
12604                (match_operand:MODEF 3 "div_operator" "")
12605                  (const_string "fdiv")
12606               ]
12607               (const_string "fop")))
12608    (set_attr "fp_int_src" "true")
12609    (set_attr "mode" "<MODE>")])
12610
12611 (define_insn "*fop_df_4_i387"
12612   [(set (match_operand:DF 0 "register_operand" "=f,f")
12613         (match_operator:DF 3 "binary_fp_operator"
12614            [(float_extend:DF
12615              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12616             (match_operand:DF 2 "register_operand" "0,f")]))]
12617   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12618    && !(TARGET_SSE2 && TARGET_SSE_MATH)
12619    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12620   "* return output_387_binary_op (insn, operands);"
12621   [(set (attr "type")
12622         (cond [(match_operand:DF 3 "mult_operator" "")
12623                  (const_string "fmul")
12624                (match_operand:DF 3 "div_operator" "")
12625                  (const_string "fdiv")
12626               ]
12627               (const_string "fop")))
12628    (set_attr "mode" "SF")])
12629
12630 (define_insn "*fop_df_5_i387"
12631   [(set (match_operand:DF 0 "register_operand" "=f,f")
12632         (match_operator:DF 3 "binary_fp_operator"
12633           [(match_operand:DF 1 "register_operand" "0,f")
12634            (float_extend:DF
12635             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12636   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12637    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12638   "* return output_387_binary_op (insn, operands);"
12639   [(set (attr "type")
12640         (cond [(match_operand:DF 3 "mult_operator" "")
12641                  (const_string "fmul")
12642                (match_operand:DF 3 "div_operator" "")
12643                  (const_string "fdiv")
12644               ]
12645               (const_string "fop")))
12646    (set_attr "mode" "SF")])
12647
12648 (define_insn "*fop_df_6_i387"
12649   [(set (match_operand:DF 0 "register_operand" "=f,f")
12650         (match_operator:DF 3 "binary_fp_operator"
12651           [(float_extend:DF
12652             (match_operand:SF 1 "register_operand" "0,f"))
12653            (float_extend:DF
12654             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12655   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12656    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12657   "* return output_387_binary_op (insn, operands);"
12658   [(set (attr "type")
12659         (cond [(match_operand:DF 3 "mult_operator" "")
12660                  (const_string "fmul")
12661                (match_operand:DF 3 "div_operator" "")
12662                  (const_string "fdiv")
12663               ]
12664               (const_string "fop")))
12665    (set_attr "mode" "SF")])
12666
12667 (define_insn "*fop_xf_comm_i387"
12668   [(set (match_operand:XF 0 "register_operand" "=f")
12669         (match_operator:XF 3 "binary_fp_operator"
12670                         [(match_operand:XF 1 "register_operand" "%0")
12671                          (match_operand:XF 2 "register_operand" "f")]))]
12672   "TARGET_80387
12673    && COMMUTATIVE_ARITH_P (operands[3])"
12674   "* return output_387_binary_op (insn, operands);"
12675   [(set (attr "type")
12676         (if_then_else (match_operand:XF 3 "mult_operator" "")
12677            (const_string "fmul")
12678            (const_string "fop")))
12679    (set_attr "mode" "XF")])
12680
12681 (define_insn "*fop_xf_1_i387"
12682   [(set (match_operand:XF 0 "register_operand" "=f,f")
12683         (match_operator:XF 3 "binary_fp_operator"
12684                         [(match_operand:XF 1 "register_operand" "0,f")
12685                          (match_operand:XF 2 "register_operand" "f,0")]))]
12686   "TARGET_80387
12687    && !COMMUTATIVE_ARITH_P (operands[3])"
12688   "* return output_387_binary_op (insn, operands);"
12689   [(set (attr "type")
12690         (cond [(match_operand:XF 3 "mult_operator" "")
12691                  (const_string "fmul")
12692                (match_operand:XF 3 "div_operator" "")
12693                  (const_string "fdiv")
12694               ]
12695               (const_string "fop")))
12696    (set_attr "mode" "XF")])
12697
12698 (define_insn "*fop_xf_2_i387"
12699   [(set (match_operand:XF 0 "register_operand" "=f,f")
12700         (match_operator:XF 3 "binary_fp_operator"
12701           [(float:XF
12702              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12703            (match_operand:XF 2 "register_operand" "0,0")]))]
12704   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12705   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12706   [(set (attr "type")
12707         (cond [(match_operand:XF 3 "mult_operator" "")
12708                  (const_string "fmul")
12709                (match_operand:XF 3 "div_operator" "")
12710                  (const_string "fdiv")
12711               ]
12712               (const_string "fop")))
12713    (set_attr "fp_int_src" "true")
12714    (set_attr "mode" "<MODE>")])
12715
12716 (define_insn "*fop_xf_3_i387"
12717   [(set (match_operand:XF 0 "register_operand" "=f,f")
12718         (match_operator:XF 3 "binary_fp_operator"
12719           [(match_operand:XF 1 "register_operand" "0,0")
12720            (float:XF
12721              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12722   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12723   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12724   [(set (attr "type")
12725         (cond [(match_operand:XF 3 "mult_operator" "")
12726                  (const_string "fmul")
12727                (match_operand:XF 3 "div_operator" "")
12728                  (const_string "fdiv")
12729               ]
12730               (const_string "fop")))
12731    (set_attr "fp_int_src" "true")
12732    (set_attr "mode" "<MODE>")])
12733
12734 (define_insn "*fop_xf_4_i387"
12735   [(set (match_operand:XF 0 "register_operand" "=f,f")
12736         (match_operator:XF 3 "binary_fp_operator"
12737            [(float_extend:XF
12738               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12739             (match_operand:XF 2 "register_operand" "0,f")]))]
12740   "TARGET_80387"
12741   "* return output_387_binary_op (insn, operands);"
12742   [(set (attr "type")
12743         (cond [(match_operand:XF 3 "mult_operator" "")
12744                  (const_string "fmul")
12745                (match_operand:XF 3 "div_operator" "")
12746                  (const_string "fdiv")
12747               ]
12748               (const_string "fop")))
12749    (set_attr "mode" "<MODE>")])
12750
12751 (define_insn "*fop_xf_5_i387"
12752   [(set (match_operand:XF 0 "register_operand" "=f,f")
12753         (match_operator:XF 3 "binary_fp_operator"
12754           [(match_operand:XF 1 "register_operand" "0,f")
12755            (float_extend:XF
12756              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12757   "TARGET_80387"
12758   "* return output_387_binary_op (insn, operands);"
12759   [(set (attr "type")
12760         (cond [(match_operand:XF 3 "mult_operator" "")
12761                  (const_string "fmul")
12762                (match_operand:XF 3 "div_operator" "")
12763                  (const_string "fdiv")
12764               ]
12765               (const_string "fop")))
12766    (set_attr "mode" "<MODE>")])
12767
12768 (define_insn "*fop_xf_6_i387"
12769   [(set (match_operand:XF 0 "register_operand" "=f,f")
12770         (match_operator:XF 3 "binary_fp_operator"
12771           [(float_extend:XF
12772              (match_operand:MODEF 1 "register_operand" "0,f"))
12773            (float_extend:XF
12774              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12775   "TARGET_80387"
12776   "* return output_387_binary_op (insn, operands);"
12777   [(set (attr "type")
12778         (cond [(match_operand:XF 3 "mult_operator" "")
12779                  (const_string "fmul")
12780                (match_operand:XF 3 "div_operator" "")
12781                  (const_string "fdiv")
12782               ]
12783               (const_string "fop")))
12784    (set_attr "mode" "<MODE>")])
12785
12786 (define_split
12787   [(set (match_operand 0 "register_operand" "")
12788         (match_operator 3 "binary_fp_operator"
12789            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
12790             (match_operand 2 "register_operand" "")]))]
12791   "reload_completed
12792    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12793    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
12794   [(const_int 0)]
12795 {
12796   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
12797   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12798   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12799                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
12800                                           GET_MODE (operands[3]),
12801                                           operands[4],
12802                                           operands[2])));
12803   ix86_free_from_memory (GET_MODE (operands[1]));
12804   DONE;
12805 })
12806
12807 (define_split
12808   [(set (match_operand 0 "register_operand" "")
12809         (match_operator 3 "binary_fp_operator"
12810            [(match_operand 1 "register_operand" "")
12811             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
12812   "reload_completed
12813    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12814    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
12815   [(const_int 0)]
12816 {
12817   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
12818   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12819   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12820                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
12821                                           GET_MODE (operands[3]),
12822                                           operands[1],
12823                                           operands[4])));
12824   ix86_free_from_memory (GET_MODE (operands[2]));
12825   DONE;
12826 })
12827 \f
12828 ;; FPU special functions.
12829
12830 ;; This pattern implements a no-op XFmode truncation for
12831 ;; all fancy i386 XFmode math functions.
12832
12833 (define_insn "truncxf<mode>2_i387_noop_unspec"
12834   [(set (match_operand:MODEF 0 "register_operand" "=f")
12835         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
12836         UNSPEC_TRUNC_NOOP))]
12837   "TARGET_USE_FANCY_MATH_387"
12838   "* return output_387_reg_move (insn, operands);"
12839   [(set_attr "type" "fmov")
12840    (set_attr "mode" "<MODE>")])
12841
12842 (define_insn "sqrtxf2"
12843   [(set (match_operand:XF 0 "register_operand" "=f")
12844         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
12845   "TARGET_USE_FANCY_MATH_387"
12846   "fsqrt"
12847   [(set_attr "type" "fpspc")
12848    (set_attr "mode" "XF")
12849    (set_attr "athlon_decode" "direct")
12850    (set_attr "amdfam10_decode" "direct")])
12851
12852 (define_insn "sqrt_extend<mode>xf2_i387"
12853   [(set (match_operand:XF 0 "register_operand" "=f")
12854         (sqrt:XF
12855           (float_extend:XF
12856             (match_operand:MODEF 1 "register_operand" "0"))))]
12857   "TARGET_USE_FANCY_MATH_387"
12858   "fsqrt"
12859   [(set_attr "type" "fpspc")
12860    (set_attr "mode" "XF")
12861    (set_attr "athlon_decode" "direct")
12862    (set_attr "amdfam10_decode" "direct")])
12863
12864 (define_insn "*rsqrtsf2_sse"
12865   [(set (match_operand:SF 0 "register_operand" "=x")
12866         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12867                    UNSPEC_RSQRT))]
12868   "TARGET_SSE_MATH"
12869   "%vrsqrtss\t{%1, %d0|%d0, %1}"
12870   [(set_attr "type" "sse")
12871    (set_attr "atom_sse_attr" "rcp")
12872    (set_attr "prefix" "maybe_vex")
12873    (set_attr "mode" "SF")])
12874
12875 (define_expand "rsqrtsf2"
12876   [(set (match_operand:SF 0 "register_operand" "")
12877         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
12878                    UNSPEC_RSQRT))]
12879   "TARGET_SSE_MATH"
12880 {
12881   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
12882   DONE;
12883 })
12884
12885 (define_insn "*sqrt<mode>2_sse"
12886   [(set (match_operand:MODEF 0 "register_operand" "=x")
12887         (sqrt:MODEF
12888           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
12889   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
12890   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
12891   [(set_attr "type" "sse")
12892    (set_attr "atom_sse_attr" "sqrt")
12893    (set_attr "prefix" "maybe_vex")
12894    (set_attr "mode" "<MODE>")
12895    (set_attr "athlon_decode" "*")
12896    (set_attr "amdfam10_decode" "*")])
12897
12898 (define_expand "sqrt<mode>2"
12899   [(set (match_operand:MODEF 0 "register_operand" "")
12900         (sqrt:MODEF
12901           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
12902   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
12903    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
12904 {
12905   if (<MODE>mode == SFmode
12906       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
12907       && flag_finite_math_only && !flag_trapping_math
12908       && flag_unsafe_math_optimizations)
12909     {
12910       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
12911       DONE;
12912     }
12913
12914   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
12915     {
12916       rtx op0 = gen_reg_rtx (XFmode);
12917       rtx op1 = force_reg (<MODE>mode, operands[1]);
12918
12919       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
12920       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
12921       DONE;
12922    }
12923 })
12924
12925 (define_insn "fpremxf4_i387"
12926   [(set (match_operand:XF 0 "register_operand" "=f")
12927         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
12928                     (match_operand:XF 3 "register_operand" "1")]
12929                    UNSPEC_FPREM_F))
12930    (set (match_operand:XF 1 "register_operand" "=u")
12931         (unspec:XF [(match_dup 2) (match_dup 3)]
12932                    UNSPEC_FPREM_U))
12933    (set (reg:CCFP FPSR_REG)
12934         (unspec:CCFP [(match_dup 2) (match_dup 3)]
12935                      UNSPEC_C2_FLAG))]
12936   "TARGET_USE_FANCY_MATH_387"
12937   "fprem"
12938   [(set_attr "type" "fpspc")
12939    (set_attr "mode" "XF")])
12940
12941 (define_expand "fmodxf3"
12942   [(use (match_operand:XF 0 "register_operand" ""))
12943    (use (match_operand:XF 1 "general_operand" ""))
12944    (use (match_operand:XF 2 "general_operand" ""))]
12945   "TARGET_USE_FANCY_MATH_387"
12946 {
12947   rtx label = gen_label_rtx ();
12948
12949   rtx op1 = gen_reg_rtx (XFmode);
12950   rtx op2 = gen_reg_rtx (XFmode);
12951
12952   emit_move_insn (op2, operands[2]);
12953   emit_move_insn (op1, operands[1]);
12954
12955   emit_label (label);
12956   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
12957   ix86_emit_fp_unordered_jump (label);
12958   LABEL_NUSES (label) = 1;
12959
12960   emit_move_insn (operands[0], op1);
12961   DONE;
12962 })
12963
12964 (define_expand "fmod<mode>3"
12965   [(use (match_operand:MODEF 0 "register_operand" ""))
12966    (use (match_operand:MODEF 1 "general_operand" ""))
12967    (use (match_operand:MODEF 2 "general_operand" ""))]
12968   "TARGET_USE_FANCY_MATH_387"
12969 {
12970   rtx (*gen_truncxf) (rtx, rtx);
12971
12972   rtx label = gen_label_rtx ();
12973
12974   rtx op1 = gen_reg_rtx (XFmode);
12975   rtx op2 = gen_reg_rtx (XFmode);
12976
12977   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
12978   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
12979
12980   emit_label (label);
12981   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
12982   ix86_emit_fp_unordered_jump (label);
12983   LABEL_NUSES (label) = 1;
12984
12985   /* Truncate the result properly for strict SSE math.  */
12986   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12987       && !TARGET_MIX_SSE_I387)
12988     gen_truncxf = gen_truncxf<mode>2;
12989   else
12990     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
12991
12992   emit_insn (gen_truncxf (operands[0], op1));
12993   DONE;
12994 })
12995
12996 (define_insn "fprem1xf4_i387"
12997   [(set (match_operand:XF 0 "register_operand" "=f")
12998         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
12999                     (match_operand:XF 3 "register_operand" "1")]
13000                    UNSPEC_FPREM1_F))
13001    (set (match_operand:XF 1 "register_operand" "=u")
13002         (unspec:XF [(match_dup 2) (match_dup 3)]
13003                    UNSPEC_FPREM1_U))
13004    (set (reg:CCFP FPSR_REG)
13005         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13006                      UNSPEC_C2_FLAG))]
13007   "TARGET_USE_FANCY_MATH_387"
13008   "fprem1"
13009   [(set_attr "type" "fpspc")
13010    (set_attr "mode" "XF")])
13011
13012 (define_expand "remainderxf3"
13013   [(use (match_operand:XF 0 "register_operand" ""))
13014    (use (match_operand:XF 1 "general_operand" ""))
13015    (use (match_operand:XF 2 "general_operand" ""))]
13016   "TARGET_USE_FANCY_MATH_387"
13017 {
13018   rtx label = gen_label_rtx ();
13019
13020   rtx op1 = gen_reg_rtx (XFmode);
13021   rtx op2 = gen_reg_rtx (XFmode);
13022
13023   emit_move_insn (op2, operands[2]);
13024   emit_move_insn (op1, operands[1]);
13025
13026   emit_label (label);
13027   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13028   ix86_emit_fp_unordered_jump (label);
13029   LABEL_NUSES (label) = 1;
13030
13031   emit_move_insn (operands[0], op1);
13032   DONE;
13033 })
13034
13035 (define_expand "remainder<mode>3"
13036   [(use (match_operand:MODEF 0 "register_operand" ""))
13037    (use (match_operand:MODEF 1 "general_operand" ""))
13038    (use (match_operand:MODEF 2 "general_operand" ""))]
13039   "TARGET_USE_FANCY_MATH_387"
13040 {
13041   rtx (*gen_truncxf) (rtx, rtx);
13042
13043   rtx label = gen_label_rtx ();
13044
13045   rtx op1 = gen_reg_rtx (XFmode);
13046   rtx op2 = gen_reg_rtx (XFmode);
13047
13048   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13049   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13050
13051   emit_label (label);
13052
13053   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13054   ix86_emit_fp_unordered_jump (label);
13055   LABEL_NUSES (label) = 1;
13056
13057   /* Truncate the result properly for strict SSE math.  */
13058   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13059       && !TARGET_MIX_SSE_I387)
13060     gen_truncxf = gen_truncxf<mode>2;
13061   else
13062     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13063
13064   emit_insn (gen_truncxf (operands[0], op1));
13065   DONE;
13066 })
13067
13068 (define_insn "*sinxf2_i387"
13069   [(set (match_operand:XF 0 "register_operand" "=f")
13070         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13071   "TARGET_USE_FANCY_MATH_387
13072    && flag_unsafe_math_optimizations"
13073   "fsin"
13074   [(set_attr "type" "fpspc")
13075    (set_attr "mode" "XF")])
13076
13077 (define_insn "*sin_extend<mode>xf2_i387"
13078   [(set (match_operand:XF 0 "register_operand" "=f")
13079         (unspec:XF [(float_extend:XF
13080                       (match_operand:MODEF 1 "register_operand" "0"))]
13081                    UNSPEC_SIN))]
13082   "TARGET_USE_FANCY_MATH_387
13083    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13084        || TARGET_MIX_SSE_I387)
13085    && flag_unsafe_math_optimizations"
13086   "fsin"
13087   [(set_attr "type" "fpspc")
13088    (set_attr "mode" "XF")])
13089
13090 (define_insn "*cosxf2_i387"
13091   [(set (match_operand:XF 0 "register_operand" "=f")
13092         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13093   "TARGET_USE_FANCY_MATH_387
13094    && flag_unsafe_math_optimizations"
13095   "fcos"
13096   [(set_attr "type" "fpspc")
13097    (set_attr "mode" "XF")])
13098
13099 (define_insn "*cos_extend<mode>xf2_i387"
13100   [(set (match_operand:XF 0 "register_operand" "=f")
13101         (unspec:XF [(float_extend:XF
13102                       (match_operand:MODEF 1 "register_operand" "0"))]
13103                    UNSPEC_COS))]
13104   "TARGET_USE_FANCY_MATH_387
13105    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13106        || TARGET_MIX_SSE_I387)
13107    && flag_unsafe_math_optimizations"
13108   "fcos"
13109   [(set_attr "type" "fpspc")
13110    (set_attr "mode" "XF")])
13111
13112 ;; When sincos pattern is defined, sin and cos builtin functions will be
13113 ;; expanded to sincos pattern with one of its outputs left unused.
13114 ;; CSE pass will figure out if two sincos patterns can be combined,
13115 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13116 ;; depending on the unused output.
13117
13118 (define_insn "sincosxf3"
13119   [(set (match_operand:XF 0 "register_operand" "=f")
13120         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13121                    UNSPEC_SINCOS_COS))
13122    (set (match_operand:XF 1 "register_operand" "=u")
13123         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13124   "TARGET_USE_FANCY_MATH_387
13125    && flag_unsafe_math_optimizations"
13126   "fsincos"
13127   [(set_attr "type" "fpspc")
13128    (set_attr "mode" "XF")])
13129
13130 (define_split
13131   [(set (match_operand:XF 0 "register_operand" "")
13132         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13133                    UNSPEC_SINCOS_COS))
13134    (set (match_operand:XF 1 "register_operand" "")
13135         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13136   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13137    && !(reload_completed || reload_in_progress)"
13138   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13139
13140 (define_split
13141   [(set (match_operand:XF 0 "register_operand" "")
13142         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13143                    UNSPEC_SINCOS_COS))
13144    (set (match_operand:XF 1 "register_operand" "")
13145         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13146   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13147    && !(reload_completed || reload_in_progress)"
13148   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13149
13150 (define_insn "sincos_extend<mode>xf3_i387"
13151   [(set (match_operand:XF 0 "register_operand" "=f")
13152         (unspec:XF [(float_extend:XF
13153                       (match_operand:MODEF 2 "register_operand" "0"))]
13154                    UNSPEC_SINCOS_COS))
13155    (set (match_operand:XF 1 "register_operand" "=u")
13156         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13157   "TARGET_USE_FANCY_MATH_387
13158    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13159        || TARGET_MIX_SSE_I387)
13160    && flag_unsafe_math_optimizations"
13161   "fsincos"
13162   [(set_attr "type" "fpspc")
13163    (set_attr "mode" "XF")])
13164
13165 (define_split
13166   [(set (match_operand:XF 0 "register_operand" "")
13167         (unspec:XF [(float_extend:XF
13168                       (match_operand:MODEF 2 "register_operand" ""))]
13169                    UNSPEC_SINCOS_COS))
13170    (set (match_operand:XF 1 "register_operand" "")
13171         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13172   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13173    && !(reload_completed || reload_in_progress)"
13174   [(set (match_dup 1)
13175         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13176
13177 (define_split
13178   [(set (match_operand:XF 0 "register_operand" "")
13179         (unspec:XF [(float_extend:XF
13180                       (match_operand:MODEF 2 "register_operand" ""))]
13181                    UNSPEC_SINCOS_COS))
13182    (set (match_operand:XF 1 "register_operand" "")
13183         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13184   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13185    && !(reload_completed || reload_in_progress)"
13186   [(set (match_dup 0)
13187         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13188
13189 (define_expand "sincos<mode>3"
13190   [(use (match_operand:MODEF 0 "register_operand" ""))
13191    (use (match_operand:MODEF 1 "register_operand" ""))
13192    (use (match_operand:MODEF 2 "register_operand" ""))]
13193   "TARGET_USE_FANCY_MATH_387
13194    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13195        || TARGET_MIX_SSE_I387)
13196    && flag_unsafe_math_optimizations"
13197 {
13198   rtx op0 = gen_reg_rtx (XFmode);
13199   rtx op1 = gen_reg_rtx (XFmode);
13200
13201   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13202   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13203   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13204   DONE;
13205 })
13206
13207 (define_insn "fptanxf4_i387"
13208   [(set (match_operand:XF 0 "register_operand" "=f")
13209         (match_operand:XF 3 "const_double_operand" "F"))
13210    (set (match_operand:XF 1 "register_operand" "=u")
13211         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13212                    UNSPEC_TAN))]
13213   "TARGET_USE_FANCY_MATH_387
13214    && flag_unsafe_math_optimizations
13215    && standard_80387_constant_p (operands[3]) == 2"
13216   "fptan"
13217   [(set_attr "type" "fpspc")
13218    (set_attr "mode" "XF")])
13219
13220 (define_insn "fptan_extend<mode>xf4_i387"
13221   [(set (match_operand:MODEF 0 "register_operand" "=f")
13222         (match_operand:MODEF 3 "const_double_operand" "F"))
13223    (set (match_operand:XF 1 "register_operand" "=u")
13224         (unspec:XF [(float_extend:XF
13225                       (match_operand:MODEF 2 "register_operand" "0"))]
13226                    UNSPEC_TAN))]
13227   "TARGET_USE_FANCY_MATH_387
13228    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13229        || TARGET_MIX_SSE_I387)
13230    && flag_unsafe_math_optimizations
13231    && standard_80387_constant_p (operands[3]) == 2"
13232   "fptan"
13233   [(set_attr "type" "fpspc")
13234    (set_attr "mode" "XF")])
13235
13236 (define_expand "tanxf2"
13237   [(use (match_operand:XF 0 "register_operand" ""))
13238    (use (match_operand:XF 1 "register_operand" ""))]
13239   "TARGET_USE_FANCY_MATH_387
13240    && flag_unsafe_math_optimizations"
13241 {
13242   rtx one = gen_reg_rtx (XFmode);
13243   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13244
13245   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13246   DONE;
13247 })
13248
13249 (define_expand "tan<mode>2"
13250   [(use (match_operand:MODEF 0 "register_operand" ""))
13251    (use (match_operand:MODEF 1 "register_operand" ""))]
13252   "TARGET_USE_FANCY_MATH_387
13253    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13254        || TARGET_MIX_SSE_I387)
13255    && flag_unsafe_math_optimizations"
13256 {
13257   rtx op0 = gen_reg_rtx (XFmode);
13258
13259   rtx one = gen_reg_rtx (<MODE>mode);
13260   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13261
13262   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13263                                              operands[1], op2));
13264   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13265   DONE;
13266 })
13267
13268 (define_insn "*fpatanxf3_i387"
13269   [(set (match_operand:XF 0 "register_operand" "=f")
13270         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13271                     (match_operand:XF 2 "register_operand" "u")]
13272                    UNSPEC_FPATAN))
13273    (clobber (match_scratch:XF 3 "=2"))]
13274   "TARGET_USE_FANCY_MATH_387
13275    && flag_unsafe_math_optimizations"
13276   "fpatan"
13277   [(set_attr "type" "fpspc")
13278    (set_attr "mode" "XF")])
13279
13280 (define_insn "fpatan_extend<mode>xf3_i387"
13281   [(set (match_operand:XF 0 "register_operand" "=f")
13282         (unspec:XF [(float_extend:XF
13283                       (match_operand:MODEF 1 "register_operand" "0"))
13284                     (float_extend:XF
13285                       (match_operand:MODEF 2 "register_operand" "u"))]
13286                    UNSPEC_FPATAN))
13287    (clobber (match_scratch:XF 3 "=2"))]
13288   "TARGET_USE_FANCY_MATH_387
13289    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13290        || TARGET_MIX_SSE_I387)
13291    && flag_unsafe_math_optimizations"
13292   "fpatan"
13293   [(set_attr "type" "fpspc")
13294    (set_attr "mode" "XF")])
13295
13296 (define_expand "atan2xf3"
13297   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13298                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
13299                                (match_operand:XF 1 "register_operand" "")]
13300                               UNSPEC_FPATAN))
13301               (clobber (match_scratch:XF 3 ""))])]
13302   "TARGET_USE_FANCY_MATH_387
13303    && flag_unsafe_math_optimizations")
13304
13305 (define_expand "atan2<mode>3"
13306   [(use (match_operand:MODEF 0 "register_operand" ""))
13307    (use (match_operand:MODEF 1 "register_operand" ""))
13308    (use (match_operand:MODEF 2 "register_operand" ""))]
13309   "TARGET_USE_FANCY_MATH_387
13310    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13311        || TARGET_MIX_SSE_I387)
13312    && flag_unsafe_math_optimizations"
13313 {
13314   rtx op0 = gen_reg_rtx (XFmode);
13315
13316   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13317   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13318   DONE;
13319 })
13320
13321 (define_expand "atanxf2"
13322   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13323                    (unspec:XF [(match_dup 2)
13324                                (match_operand:XF 1 "register_operand" "")]
13325                               UNSPEC_FPATAN))
13326               (clobber (match_scratch:XF 3 ""))])]
13327   "TARGET_USE_FANCY_MATH_387
13328    && flag_unsafe_math_optimizations"
13329 {
13330   operands[2] = gen_reg_rtx (XFmode);
13331   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13332 })
13333
13334 (define_expand "atan<mode>2"
13335   [(use (match_operand:MODEF 0 "register_operand" ""))
13336    (use (match_operand:MODEF 1 "register_operand" ""))]
13337   "TARGET_USE_FANCY_MATH_387
13338    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13339        || TARGET_MIX_SSE_I387)
13340    && flag_unsafe_math_optimizations"
13341 {
13342   rtx op0 = gen_reg_rtx (XFmode);
13343
13344   rtx op2 = gen_reg_rtx (<MODE>mode);
13345   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13346
13347   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13348   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13349   DONE;
13350 })
13351
13352 (define_expand "asinxf2"
13353   [(set (match_dup 2)
13354         (mult:XF (match_operand:XF 1 "register_operand" "")
13355                  (match_dup 1)))
13356    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13357    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13358    (parallel [(set (match_operand:XF 0 "register_operand" "")
13359                    (unspec:XF [(match_dup 5) (match_dup 1)]
13360                               UNSPEC_FPATAN))
13361               (clobber (match_scratch:XF 6 ""))])]
13362   "TARGET_USE_FANCY_MATH_387
13363    && flag_unsafe_math_optimizations"
13364 {
13365   int i;
13366
13367   if (optimize_insn_for_size_p ())
13368     FAIL;
13369
13370   for (i = 2; i < 6; i++)
13371     operands[i] = gen_reg_rtx (XFmode);
13372
13373   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13374 })
13375
13376 (define_expand "asin<mode>2"
13377   [(use (match_operand:MODEF 0 "register_operand" ""))
13378    (use (match_operand:MODEF 1 "general_operand" ""))]
13379  "TARGET_USE_FANCY_MATH_387
13380    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13381        || TARGET_MIX_SSE_I387)
13382    && flag_unsafe_math_optimizations"
13383 {
13384   rtx op0 = gen_reg_rtx (XFmode);
13385   rtx op1 = gen_reg_rtx (XFmode);
13386
13387   if (optimize_insn_for_size_p ())
13388     FAIL;
13389
13390   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13391   emit_insn (gen_asinxf2 (op0, op1));
13392   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13393   DONE;
13394 })
13395
13396 (define_expand "acosxf2"
13397   [(set (match_dup 2)
13398         (mult:XF (match_operand:XF 1 "register_operand" "")
13399                  (match_dup 1)))
13400    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13401    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13402    (parallel [(set (match_operand:XF 0 "register_operand" "")
13403                    (unspec:XF [(match_dup 1) (match_dup 5)]
13404                               UNSPEC_FPATAN))
13405               (clobber (match_scratch:XF 6 ""))])]
13406   "TARGET_USE_FANCY_MATH_387
13407    && flag_unsafe_math_optimizations"
13408 {
13409   int i;
13410
13411   if (optimize_insn_for_size_p ())
13412     FAIL;
13413
13414   for (i = 2; i < 6; i++)
13415     operands[i] = gen_reg_rtx (XFmode);
13416
13417   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13418 })
13419
13420 (define_expand "acos<mode>2"
13421   [(use (match_operand:MODEF 0 "register_operand" ""))
13422    (use (match_operand:MODEF 1 "general_operand" ""))]
13423  "TARGET_USE_FANCY_MATH_387
13424    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13425        || TARGET_MIX_SSE_I387)
13426    && flag_unsafe_math_optimizations"
13427 {
13428   rtx op0 = gen_reg_rtx (XFmode);
13429   rtx op1 = gen_reg_rtx (XFmode);
13430
13431   if (optimize_insn_for_size_p ())
13432     FAIL;
13433
13434   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13435   emit_insn (gen_acosxf2 (op0, op1));
13436   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13437   DONE;
13438 })
13439
13440 (define_insn "fyl2xxf3_i387"
13441   [(set (match_operand:XF 0 "register_operand" "=f")
13442         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13443                     (match_operand:XF 2 "register_operand" "u")]
13444                    UNSPEC_FYL2X))
13445    (clobber (match_scratch:XF 3 "=2"))]
13446   "TARGET_USE_FANCY_MATH_387
13447    && flag_unsafe_math_optimizations"
13448   "fyl2x"
13449   [(set_attr "type" "fpspc")
13450    (set_attr "mode" "XF")])
13451
13452 (define_insn "fyl2x_extend<mode>xf3_i387"
13453   [(set (match_operand:XF 0 "register_operand" "=f")
13454         (unspec:XF [(float_extend:XF
13455                       (match_operand:MODEF 1 "register_operand" "0"))
13456                     (match_operand:XF 2 "register_operand" "u")]
13457                    UNSPEC_FYL2X))
13458    (clobber (match_scratch:XF 3 "=2"))]
13459   "TARGET_USE_FANCY_MATH_387
13460    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13461        || TARGET_MIX_SSE_I387)
13462    && flag_unsafe_math_optimizations"
13463   "fyl2x"
13464   [(set_attr "type" "fpspc")
13465    (set_attr "mode" "XF")])
13466
13467 (define_expand "logxf2"
13468   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13469                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13470                                (match_dup 2)] UNSPEC_FYL2X))
13471               (clobber (match_scratch:XF 3 ""))])]
13472   "TARGET_USE_FANCY_MATH_387
13473    && flag_unsafe_math_optimizations"
13474 {
13475   operands[2] = gen_reg_rtx (XFmode);
13476   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13477 })
13478
13479 (define_expand "log<mode>2"
13480   [(use (match_operand:MODEF 0 "register_operand" ""))
13481    (use (match_operand:MODEF 1 "register_operand" ""))]
13482   "TARGET_USE_FANCY_MATH_387
13483    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13484        || TARGET_MIX_SSE_I387)
13485    && flag_unsafe_math_optimizations"
13486 {
13487   rtx op0 = gen_reg_rtx (XFmode);
13488
13489   rtx op2 = gen_reg_rtx (XFmode);
13490   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13491
13492   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13493   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13494   DONE;
13495 })
13496
13497 (define_expand "log10xf2"
13498   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13499                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13500                                (match_dup 2)] UNSPEC_FYL2X))
13501               (clobber (match_scratch:XF 3 ""))])]
13502   "TARGET_USE_FANCY_MATH_387
13503    && flag_unsafe_math_optimizations"
13504 {
13505   operands[2] = gen_reg_rtx (XFmode);
13506   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13507 })
13508
13509 (define_expand "log10<mode>2"
13510   [(use (match_operand:MODEF 0 "register_operand" ""))
13511    (use (match_operand:MODEF 1 "register_operand" ""))]
13512   "TARGET_USE_FANCY_MATH_387
13513    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13514        || TARGET_MIX_SSE_I387)
13515    && flag_unsafe_math_optimizations"
13516 {
13517   rtx op0 = gen_reg_rtx (XFmode);
13518
13519   rtx op2 = gen_reg_rtx (XFmode);
13520   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13521
13522   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13523   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13524   DONE;
13525 })
13526
13527 (define_expand "log2xf2"
13528   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13529                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13530                                (match_dup 2)] UNSPEC_FYL2X))
13531               (clobber (match_scratch:XF 3 ""))])]
13532   "TARGET_USE_FANCY_MATH_387
13533    && flag_unsafe_math_optimizations"
13534 {
13535   operands[2] = gen_reg_rtx (XFmode);
13536   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13537 })
13538
13539 (define_expand "log2<mode>2"
13540   [(use (match_operand:MODEF 0 "register_operand" ""))
13541    (use (match_operand:MODEF 1 "register_operand" ""))]
13542   "TARGET_USE_FANCY_MATH_387
13543    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13544        || TARGET_MIX_SSE_I387)
13545    && flag_unsafe_math_optimizations"
13546 {
13547   rtx op0 = gen_reg_rtx (XFmode);
13548
13549   rtx op2 = gen_reg_rtx (XFmode);
13550   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13551
13552   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13553   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13554   DONE;
13555 })
13556
13557 (define_insn "fyl2xp1xf3_i387"
13558   [(set (match_operand:XF 0 "register_operand" "=f")
13559         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13560                     (match_operand:XF 2 "register_operand" "u")]
13561                    UNSPEC_FYL2XP1))
13562    (clobber (match_scratch:XF 3 "=2"))]
13563   "TARGET_USE_FANCY_MATH_387
13564    && flag_unsafe_math_optimizations"
13565   "fyl2xp1"
13566   [(set_attr "type" "fpspc")
13567    (set_attr "mode" "XF")])
13568
13569 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13570   [(set (match_operand:XF 0 "register_operand" "=f")
13571         (unspec:XF [(float_extend:XF
13572                       (match_operand:MODEF 1 "register_operand" "0"))
13573                     (match_operand:XF 2 "register_operand" "u")]
13574                    UNSPEC_FYL2XP1))
13575    (clobber (match_scratch:XF 3 "=2"))]
13576   "TARGET_USE_FANCY_MATH_387
13577    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13578        || TARGET_MIX_SSE_I387)
13579    && flag_unsafe_math_optimizations"
13580   "fyl2xp1"
13581   [(set_attr "type" "fpspc")
13582    (set_attr "mode" "XF")])
13583
13584 (define_expand "log1pxf2"
13585   [(use (match_operand:XF 0 "register_operand" ""))
13586    (use (match_operand:XF 1 "register_operand" ""))]
13587   "TARGET_USE_FANCY_MATH_387
13588    && flag_unsafe_math_optimizations"
13589 {
13590   if (optimize_insn_for_size_p ())
13591     FAIL;
13592
13593   ix86_emit_i387_log1p (operands[0], operands[1]);
13594   DONE;
13595 })
13596
13597 (define_expand "log1p<mode>2"
13598   [(use (match_operand:MODEF 0 "register_operand" ""))
13599    (use (match_operand:MODEF 1 "register_operand" ""))]
13600   "TARGET_USE_FANCY_MATH_387
13601    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13602        || TARGET_MIX_SSE_I387)
13603    && flag_unsafe_math_optimizations"
13604 {
13605   rtx op0;
13606
13607   if (optimize_insn_for_size_p ())
13608     FAIL;
13609
13610   op0 = gen_reg_rtx (XFmode);
13611
13612   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13613
13614   ix86_emit_i387_log1p (op0, operands[1]);
13615   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13616   DONE;
13617 })
13618
13619 (define_insn "fxtractxf3_i387"
13620   [(set (match_operand:XF 0 "register_operand" "=f")
13621         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13622                    UNSPEC_XTRACT_FRACT))
13623    (set (match_operand:XF 1 "register_operand" "=u")
13624         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13625   "TARGET_USE_FANCY_MATH_387
13626    && flag_unsafe_math_optimizations"
13627   "fxtract"
13628   [(set_attr "type" "fpspc")
13629    (set_attr "mode" "XF")])
13630
13631 (define_insn "fxtract_extend<mode>xf3_i387"
13632   [(set (match_operand:XF 0 "register_operand" "=f")
13633         (unspec:XF [(float_extend:XF
13634                       (match_operand:MODEF 2 "register_operand" "0"))]
13635                    UNSPEC_XTRACT_FRACT))
13636    (set (match_operand:XF 1 "register_operand" "=u")
13637         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13638   "TARGET_USE_FANCY_MATH_387
13639    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13640        || TARGET_MIX_SSE_I387)
13641    && flag_unsafe_math_optimizations"
13642   "fxtract"
13643   [(set_attr "type" "fpspc")
13644    (set_attr "mode" "XF")])
13645
13646 (define_expand "logbxf2"
13647   [(parallel [(set (match_dup 2)
13648                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13649                               UNSPEC_XTRACT_FRACT))
13650               (set (match_operand:XF 0 "register_operand" "")
13651                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13652   "TARGET_USE_FANCY_MATH_387
13653    && flag_unsafe_math_optimizations"
13654   "operands[2] = gen_reg_rtx (XFmode);")
13655
13656 (define_expand "logb<mode>2"
13657   [(use (match_operand:MODEF 0 "register_operand" ""))
13658    (use (match_operand:MODEF 1 "register_operand" ""))]
13659   "TARGET_USE_FANCY_MATH_387
13660    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13661        || TARGET_MIX_SSE_I387)
13662    && flag_unsafe_math_optimizations"
13663 {
13664   rtx op0 = gen_reg_rtx (XFmode);
13665   rtx op1 = gen_reg_rtx (XFmode);
13666
13667   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13668   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13669   DONE;
13670 })
13671
13672 (define_expand "ilogbxf2"
13673   [(use (match_operand:SI 0 "register_operand" ""))
13674    (use (match_operand:XF 1 "register_operand" ""))]
13675   "TARGET_USE_FANCY_MATH_387
13676    && flag_unsafe_math_optimizations"
13677 {
13678   rtx op0, op1;
13679
13680   if (optimize_insn_for_size_p ())
13681     FAIL;
13682
13683   op0 = gen_reg_rtx (XFmode);
13684   op1 = gen_reg_rtx (XFmode);
13685
13686   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13687   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13688   DONE;
13689 })
13690
13691 (define_expand "ilogb<mode>2"
13692   [(use (match_operand:SI 0 "register_operand" ""))
13693    (use (match_operand:MODEF 1 "register_operand" ""))]
13694   "TARGET_USE_FANCY_MATH_387
13695    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13696        || TARGET_MIX_SSE_I387)
13697    && flag_unsafe_math_optimizations"
13698 {
13699   rtx op0, op1;
13700
13701   if (optimize_insn_for_size_p ())
13702     FAIL;
13703
13704   op0 = gen_reg_rtx (XFmode);
13705   op1 = gen_reg_rtx (XFmode);
13706
13707   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13708   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13709   DONE;
13710 })
13711
13712 (define_insn "*f2xm1xf2_i387"
13713   [(set (match_operand:XF 0 "register_operand" "=f")
13714         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13715                    UNSPEC_F2XM1))]
13716   "TARGET_USE_FANCY_MATH_387
13717    && flag_unsafe_math_optimizations"
13718   "f2xm1"
13719   [(set_attr "type" "fpspc")
13720    (set_attr "mode" "XF")])
13721
13722 (define_insn "*fscalexf4_i387"
13723   [(set (match_operand:XF 0 "register_operand" "=f")
13724         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13725                     (match_operand:XF 3 "register_operand" "1")]
13726                    UNSPEC_FSCALE_FRACT))
13727    (set (match_operand:XF 1 "register_operand" "=u")
13728         (unspec:XF [(match_dup 2) (match_dup 3)]
13729                    UNSPEC_FSCALE_EXP))]
13730   "TARGET_USE_FANCY_MATH_387
13731    && flag_unsafe_math_optimizations"
13732   "fscale"
13733   [(set_attr "type" "fpspc")
13734    (set_attr "mode" "XF")])
13735
13736 (define_expand "expNcorexf3"
13737   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13738                                (match_operand:XF 2 "register_operand" "")))
13739    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13740    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13741    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13742    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13743    (parallel [(set (match_operand:XF 0 "register_operand" "")
13744                    (unspec:XF [(match_dup 8) (match_dup 4)]
13745                               UNSPEC_FSCALE_FRACT))
13746               (set (match_dup 9)
13747                    (unspec:XF [(match_dup 8) (match_dup 4)]
13748                               UNSPEC_FSCALE_EXP))])]
13749   "TARGET_USE_FANCY_MATH_387
13750    && flag_unsafe_math_optimizations"
13751 {
13752   int i;
13753
13754   if (optimize_insn_for_size_p ())
13755     FAIL;
13756
13757   for (i = 3; i < 10; i++)
13758     operands[i] = gen_reg_rtx (XFmode);
13759
13760   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
13761 })
13762
13763 (define_expand "expxf2"
13764   [(use (match_operand:XF 0 "register_operand" ""))
13765    (use (match_operand:XF 1 "register_operand" ""))]
13766   "TARGET_USE_FANCY_MATH_387
13767    && flag_unsafe_math_optimizations"
13768 {
13769   rtx op2;
13770
13771   if (optimize_insn_for_size_p ())
13772     FAIL;
13773
13774   op2 = gen_reg_rtx (XFmode);
13775   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
13776
13777   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13778   DONE;
13779 })
13780
13781 (define_expand "exp<mode>2"
13782   [(use (match_operand:MODEF 0 "register_operand" ""))
13783    (use (match_operand:MODEF 1 "general_operand" ""))]
13784  "TARGET_USE_FANCY_MATH_387
13785    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13786        || TARGET_MIX_SSE_I387)
13787    && flag_unsafe_math_optimizations"
13788 {
13789   rtx op0, op1;
13790
13791   if (optimize_insn_for_size_p ())
13792     FAIL;
13793
13794   op0 = gen_reg_rtx (XFmode);
13795   op1 = gen_reg_rtx (XFmode);
13796
13797   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13798   emit_insn (gen_expxf2 (op0, op1));
13799   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13800   DONE;
13801 })
13802
13803 (define_expand "exp10xf2"
13804   [(use (match_operand:XF 0 "register_operand" ""))
13805    (use (match_operand:XF 1 "register_operand" ""))]
13806   "TARGET_USE_FANCY_MATH_387
13807    && flag_unsafe_math_optimizations"
13808 {
13809   rtx op2;
13810
13811   if (optimize_insn_for_size_p ())
13812     FAIL;
13813
13814   op2 = gen_reg_rtx (XFmode);
13815   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
13816
13817   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13818   DONE;
13819 })
13820
13821 (define_expand "exp10<mode>2"
13822   [(use (match_operand:MODEF 0 "register_operand" ""))
13823    (use (match_operand:MODEF 1 "general_operand" ""))]
13824  "TARGET_USE_FANCY_MATH_387
13825    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13826        || TARGET_MIX_SSE_I387)
13827    && flag_unsafe_math_optimizations"
13828 {
13829   rtx op0, op1;
13830
13831   if (optimize_insn_for_size_p ())
13832     FAIL;
13833
13834   op0 = gen_reg_rtx (XFmode);
13835   op1 = gen_reg_rtx (XFmode);
13836
13837   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13838   emit_insn (gen_exp10xf2 (op0, op1));
13839   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13840   DONE;
13841 })
13842
13843 (define_expand "exp2xf2"
13844   [(use (match_operand:XF 0 "register_operand" ""))
13845    (use (match_operand:XF 1 "register_operand" ""))]
13846   "TARGET_USE_FANCY_MATH_387
13847    && flag_unsafe_math_optimizations"
13848 {
13849   rtx op2;
13850
13851   if (optimize_insn_for_size_p ())
13852     FAIL;
13853
13854   op2 = gen_reg_rtx (XFmode);
13855   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
13856
13857   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13858   DONE;
13859 })
13860
13861 (define_expand "exp2<mode>2"
13862   [(use (match_operand:MODEF 0 "register_operand" ""))
13863    (use (match_operand:MODEF 1 "general_operand" ""))]
13864  "TARGET_USE_FANCY_MATH_387
13865    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13866        || TARGET_MIX_SSE_I387)
13867    && flag_unsafe_math_optimizations"
13868 {
13869   rtx op0, op1;
13870
13871   if (optimize_insn_for_size_p ())
13872     FAIL;
13873
13874   op0 = gen_reg_rtx (XFmode);
13875   op1 = gen_reg_rtx (XFmode);
13876
13877   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13878   emit_insn (gen_exp2xf2 (op0, op1));
13879   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13880   DONE;
13881 })
13882
13883 (define_expand "expm1xf2"
13884   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13885                                (match_dup 2)))
13886    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13887    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13888    (set (match_dup 9) (float_extend:XF (match_dup 13)))
13889    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13890    (parallel [(set (match_dup 7)
13891                    (unspec:XF [(match_dup 6) (match_dup 4)]
13892                               UNSPEC_FSCALE_FRACT))
13893               (set (match_dup 8)
13894                    (unspec:XF [(match_dup 6) (match_dup 4)]
13895                               UNSPEC_FSCALE_EXP))])
13896    (parallel [(set (match_dup 10)
13897                    (unspec:XF [(match_dup 9) (match_dup 8)]
13898                               UNSPEC_FSCALE_FRACT))
13899               (set (match_dup 11)
13900                    (unspec:XF [(match_dup 9) (match_dup 8)]
13901                               UNSPEC_FSCALE_EXP))])
13902    (set (match_dup 12) (minus:XF (match_dup 10)
13903                                  (float_extend:XF (match_dup 13))))
13904    (set (match_operand:XF 0 "register_operand" "")
13905         (plus:XF (match_dup 12) (match_dup 7)))]
13906   "TARGET_USE_FANCY_MATH_387
13907    && flag_unsafe_math_optimizations"
13908 {
13909   int i;
13910
13911   if (optimize_insn_for_size_p ())
13912     FAIL;
13913
13914   for (i = 2; i < 13; i++)
13915     operands[i] = gen_reg_rtx (XFmode);
13916
13917   operands[13]
13918     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
13919
13920   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
13921 })
13922
13923 (define_expand "expm1<mode>2"
13924   [(use (match_operand:MODEF 0 "register_operand" ""))
13925    (use (match_operand:MODEF 1 "general_operand" ""))]
13926  "TARGET_USE_FANCY_MATH_387
13927    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13928        || TARGET_MIX_SSE_I387)
13929    && flag_unsafe_math_optimizations"
13930 {
13931   rtx op0, op1;
13932
13933   if (optimize_insn_for_size_p ())
13934     FAIL;
13935
13936   op0 = gen_reg_rtx (XFmode);
13937   op1 = gen_reg_rtx (XFmode);
13938
13939   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13940   emit_insn (gen_expm1xf2 (op0, op1));
13941   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13942   DONE;
13943 })
13944
13945 (define_expand "ldexpxf3"
13946   [(set (match_dup 3)
13947         (float:XF (match_operand:SI 2 "register_operand" "")))
13948    (parallel [(set (match_operand:XF 0 " register_operand" "")
13949                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13950                                (match_dup 3)]
13951                               UNSPEC_FSCALE_FRACT))
13952               (set (match_dup 4)
13953                    (unspec:XF [(match_dup 1) (match_dup 3)]
13954                               UNSPEC_FSCALE_EXP))])]
13955   "TARGET_USE_FANCY_MATH_387
13956    && flag_unsafe_math_optimizations"
13957 {
13958   if (optimize_insn_for_size_p ())
13959     FAIL;
13960
13961   operands[3] = gen_reg_rtx (XFmode);
13962   operands[4] = gen_reg_rtx (XFmode);
13963 })
13964
13965 (define_expand "ldexp<mode>3"
13966   [(use (match_operand:MODEF 0 "register_operand" ""))
13967    (use (match_operand:MODEF 1 "general_operand" ""))
13968    (use (match_operand:SI 2 "register_operand" ""))]
13969  "TARGET_USE_FANCY_MATH_387
13970    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13971        || TARGET_MIX_SSE_I387)
13972    && flag_unsafe_math_optimizations"
13973 {
13974   rtx op0, op1;
13975
13976   if (optimize_insn_for_size_p ())
13977     FAIL;
13978
13979   op0 = gen_reg_rtx (XFmode);
13980   op1 = gen_reg_rtx (XFmode);
13981
13982   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13983   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
13984   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13985   DONE;
13986 })
13987
13988 (define_expand "scalbxf3"
13989   [(parallel [(set (match_operand:XF 0 " register_operand" "")
13990                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13991                                (match_operand:XF 2 "register_operand" "")]
13992                               UNSPEC_FSCALE_FRACT))
13993               (set (match_dup 3)
13994                    (unspec:XF [(match_dup 1) (match_dup 2)]
13995                               UNSPEC_FSCALE_EXP))])]
13996   "TARGET_USE_FANCY_MATH_387
13997    && flag_unsafe_math_optimizations"
13998 {
13999   if (optimize_insn_for_size_p ())
14000     FAIL;
14001
14002   operands[3] = gen_reg_rtx (XFmode);
14003 })
14004
14005 (define_expand "scalb<mode>3"
14006   [(use (match_operand:MODEF 0 "register_operand" ""))
14007    (use (match_operand:MODEF 1 "general_operand" ""))
14008    (use (match_operand:MODEF 2 "general_operand" ""))]
14009  "TARGET_USE_FANCY_MATH_387
14010    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14011        || TARGET_MIX_SSE_I387)
14012    && flag_unsafe_math_optimizations"
14013 {
14014   rtx op0, op1, op2;
14015
14016   if (optimize_insn_for_size_p ())
14017     FAIL;
14018
14019   op0 = gen_reg_rtx (XFmode);
14020   op1 = gen_reg_rtx (XFmode);
14021   op2 = gen_reg_rtx (XFmode);
14022
14023   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14024   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14025   emit_insn (gen_scalbxf3 (op0, op1, op2));
14026   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14027   DONE;
14028 })
14029
14030 (define_expand "significandxf2"
14031   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14032                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14033                               UNSPEC_XTRACT_FRACT))
14034               (set (match_dup 2)
14035                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14036   "TARGET_USE_FANCY_MATH_387
14037    && flag_unsafe_math_optimizations"
14038   "operands[2] = gen_reg_rtx (XFmode);")
14039
14040 (define_expand "significand<mode>2"
14041   [(use (match_operand:MODEF 0 "register_operand" ""))
14042    (use (match_operand:MODEF 1 "register_operand" ""))]
14043   "TARGET_USE_FANCY_MATH_387
14044    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14045        || TARGET_MIX_SSE_I387)
14046    && flag_unsafe_math_optimizations"
14047 {
14048   rtx op0 = gen_reg_rtx (XFmode);
14049   rtx op1 = gen_reg_rtx (XFmode);
14050
14051   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14052   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14053   DONE;
14054 })
14055 \f
14056
14057 (define_insn "sse4_1_round<mode>2"
14058   [(set (match_operand:MODEF 0 "register_operand" "=x")
14059         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14060                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14061                       UNSPEC_ROUND))]
14062   "TARGET_ROUND"
14063   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14064   [(set_attr "type" "ssecvt")
14065    (set_attr "prefix_extra" "1")
14066    (set_attr "prefix" "maybe_vex")
14067    (set_attr "mode" "<MODE>")])
14068
14069 (define_insn "rintxf2"
14070   [(set (match_operand:XF 0 "register_operand" "=f")
14071         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14072                    UNSPEC_FRNDINT))]
14073   "TARGET_USE_FANCY_MATH_387
14074    && flag_unsafe_math_optimizations"
14075   "frndint"
14076   [(set_attr "type" "fpspc")
14077    (set_attr "mode" "XF")])
14078
14079 (define_expand "rint<mode>2"
14080   [(use (match_operand:MODEF 0 "register_operand" ""))
14081    (use (match_operand:MODEF 1 "register_operand" ""))]
14082   "(TARGET_USE_FANCY_MATH_387
14083     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14084         || TARGET_MIX_SSE_I387)
14085     && flag_unsafe_math_optimizations)
14086    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14087        && !flag_trapping_math)"
14088 {
14089   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14090       && !flag_trapping_math)
14091     {
14092       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14093         FAIL;
14094       if (TARGET_ROUND)
14095         emit_insn (gen_sse4_1_round<mode>2
14096                    (operands[0], operands[1], GEN_INT (0x04)));
14097       else
14098         ix86_expand_rint (operand0, operand1);
14099     }
14100   else
14101     {
14102       rtx op0 = gen_reg_rtx (XFmode);
14103       rtx op1 = gen_reg_rtx (XFmode);
14104
14105       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14106       emit_insn (gen_rintxf2 (op0, op1));
14107
14108       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14109     }
14110   DONE;
14111 })
14112
14113 (define_expand "round<mode>2"
14114   [(match_operand:MODEF 0 "register_operand" "")
14115    (match_operand:MODEF 1 "nonimmediate_operand" "")]
14116   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14117    && !flag_trapping_math && !flag_rounding_math"
14118 {
14119   if (optimize_insn_for_size_p ())
14120     FAIL;
14121   if (TARGET_64BIT || (<MODE>mode != DFmode))
14122     ix86_expand_round (operand0, operand1);
14123   else
14124     ix86_expand_rounddf_32 (operand0, operand1);
14125   DONE;
14126 })
14127
14128 (define_insn_and_split "*fistdi2_1"
14129   [(set (match_operand:DI 0 "nonimmediate_operand" "")
14130         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14131                    UNSPEC_FIST))]
14132   "TARGET_USE_FANCY_MATH_387
14133    && can_create_pseudo_p ()"
14134   "#"
14135   "&& 1"
14136   [(const_int 0)]
14137 {
14138   if (memory_operand (operands[0], VOIDmode))
14139     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14140   else
14141     {
14142       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14143       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14144                                          operands[2]));
14145     }
14146   DONE;
14147 }
14148   [(set_attr "type" "fpspc")
14149    (set_attr "mode" "DI")])
14150
14151 (define_insn "fistdi2"
14152   [(set (match_operand:DI 0 "memory_operand" "=m")
14153         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14154                    UNSPEC_FIST))
14155    (clobber (match_scratch:XF 2 "=&1f"))]
14156   "TARGET_USE_FANCY_MATH_387"
14157   "* return output_fix_trunc (insn, operands, 0);"
14158   [(set_attr "type" "fpspc")
14159    (set_attr "mode" "DI")])
14160
14161 (define_insn "fistdi2_with_temp"
14162   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14163         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14164                    UNSPEC_FIST))
14165    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14166    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14167   "TARGET_USE_FANCY_MATH_387"
14168   "#"
14169   [(set_attr "type" "fpspc")
14170    (set_attr "mode" "DI")])
14171
14172 (define_split
14173   [(set (match_operand:DI 0 "register_operand" "")
14174         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14175                    UNSPEC_FIST))
14176    (clobber (match_operand:DI 2 "memory_operand" ""))
14177    (clobber (match_scratch 3 ""))]
14178   "reload_completed"
14179   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14180               (clobber (match_dup 3))])
14181    (set (match_dup 0) (match_dup 2))])
14182
14183 (define_split
14184   [(set (match_operand:DI 0 "memory_operand" "")
14185         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14186                    UNSPEC_FIST))
14187    (clobber (match_operand:DI 2 "memory_operand" ""))
14188    (clobber (match_scratch 3 ""))]
14189   "reload_completed"
14190   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14191               (clobber (match_dup 3))])])
14192
14193 (define_insn_and_split "*fist<mode>2_1"
14194   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14195         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14196                            UNSPEC_FIST))]
14197   "TARGET_USE_FANCY_MATH_387
14198    && can_create_pseudo_p ()"
14199   "#"
14200   "&& 1"
14201   [(const_int 0)]
14202 {
14203   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14204   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14205                                         operands[2]));
14206   DONE;
14207 }
14208   [(set_attr "type" "fpspc")
14209    (set_attr "mode" "<MODE>")])
14210
14211 (define_insn "fist<mode>2"
14212   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14213         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14214                            UNSPEC_FIST))]
14215   "TARGET_USE_FANCY_MATH_387"
14216   "* return output_fix_trunc (insn, operands, 0);"
14217   [(set_attr "type" "fpspc")
14218    (set_attr "mode" "<MODE>")])
14219
14220 (define_insn "fist<mode>2_with_temp"
14221   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14222         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14223                            UNSPEC_FIST))
14224    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14225   "TARGET_USE_FANCY_MATH_387"
14226   "#"
14227   [(set_attr "type" "fpspc")
14228    (set_attr "mode" "<MODE>")])
14229
14230 (define_split
14231   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14232         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14233                            UNSPEC_FIST))
14234    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14235   "reload_completed"
14236   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14237    (set (match_dup 0) (match_dup 2))])
14238
14239 (define_split
14240   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14241         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14242                            UNSPEC_FIST))
14243    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14244   "reload_completed"
14245   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14246
14247 (define_expand "lrintxf<mode>2"
14248   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14249      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14250                       UNSPEC_FIST))]
14251   "TARGET_USE_FANCY_MATH_387")
14252
14253 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14254   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14255      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14256                         UNSPEC_FIX_NOTRUNC))]
14257   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14258    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)")
14259
14260 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14261   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14262    (match_operand:MODEF 1 "register_operand" "")]
14263   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14264    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14265    && !flag_trapping_math && !flag_rounding_math"
14266 {
14267   if (optimize_insn_for_size_p ())
14268     FAIL;
14269   ix86_expand_lround (operand0, operand1);
14270   DONE;
14271 })
14272
14273 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14274 (define_insn_and_split "frndintxf2_floor"
14275   [(set (match_operand:XF 0 "register_operand" "")
14276         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14277          UNSPEC_FRNDINT_FLOOR))
14278    (clobber (reg:CC FLAGS_REG))]
14279   "TARGET_USE_FANCY_MATH_387
14280    && flag_unsafe_math_optimizations
14281    && can_create_pseudo_p ()"
14282   "#"
14283   "&& 1"
14284   [(const_int 0)]
14285 {
14286   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14287
14288   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14289   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14290
14291   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14292                                         operands[2], operands[3]));
14293   DONE;
14294 }
14295   [(set_attr "type" "frndint")
14296    (set_attr "i387_cw" "floor")
14297    (set_attr "mode" "XF")])
14298
14299 (define_insn "frndintxf2_floor_i387"
14300   [(set (match_operand:XF 0 "register_operand" "=f")
14301         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14302          UNSPEC_FRNDINT_FLOOR))
14303    (use (match_operand:HI 2 "memory_operand" "m"))
14304    (use (match_operand:HI 3 "memory_operand" "m"))]
14305   "TARGET_USE_FANCY_MATH_387
14306    && flag_unsafe_math_optimizations"
14307   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14308   [(set_attr "type" "frndint")
14309    (set_attr "i387_cw" "floor")
14310    (set_attr "mode" "XF")])
14311
14312 (define_expand "floorxf2"
14313   [(use (match_operand:XF 0 "register_operand" ""))
14314    (use (match_operand:XF 1 "register_operand" ""))]
14315   "TARGET_USE_FANCY_MATH_387
14316    && flag_unsafe_math_optimizations"
14317 {
14318   if (optimize_insn_for_size_p ())
14319     FAIL;
14320   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14321   DONE;
14322 })
14323
14324 (define_expand "floor<mode>2"
14325   [(use (match_operand:MODEF 0 "register_operand" ""))
14326    (use (match_operand:MODEF 1 "register_operand" ""))]
14327   "(TARGET_USE_FANCY_MATH_387
14328     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14329         || TARGET_MIX_SSE_I387)
14330     && flag_unsafe_math_optimizations)
14331    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14332        && !flag_trapping_math)"
14333 {
14334   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14335       && !flag_trapping_math
14336       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14337     {
14338       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14339         FAIL;
14340       if (TARGET_ROUND)
14341         emit_insn (gen_sse4_1_round<mode>2
14342                    (operands[0], operands[1], GEN_INT (0x01)));
14343       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14344         ix86_expand_floorceil (operand0, operand1, true);
14345       else
14346         ix86_expand_floorceildf_32 (operand0, operand1, true);
14347     }
14348   else
14349     {
14350       rtx op0, op1;
14351
14352       if (optimize_insn_for_size_p ())
14353         FAIL;
14354
14355       op0 = gen_reg_rtx (XFmode);
14356       op1 = gen_reg_rtx (XFmode);
14357       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14358       emit_insn (gen_frndintxf2_floor (op0, op1));
14359
14360       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14361     }
14362   DONE;
14363 })
14364
14365 (define_insn_and_split "*fist<mode>2_floor_1"
14366   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14367         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14368          UNSPEC_FIST_FLOOR))
14369    (clobber (reg:CC FLAGS_REG))]
14370   "TARGET_USE_FANCY_MATH_387
14371    && flag_unsafe_math_optimizations
14372    && can_create_pseudo_p ()"
14373   "#"
14374   "&& 1"
14375   [(const_int 0)]
14376 {
14377   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14378
14379   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14380   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14381   if (memory_operand (operands[0], VOIDmode))
14382     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14383                                       operands[2], operands[3]));
14384   else
14385     {
14386       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14387       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14388                                                   operands[2], operands[3],
14389                                                   operands[4]));
14390     }
14391   DONE;
14392 }
14393   [(set_attr "type" "fistp")
14394    (set_attr "i387_cw" "floor")
14395    (set_attr "mode" "<MODE>")])
14396
14397 (define_insn "fistdi2_floor"
14398   [(set (match_operand:DI 0 "memory_operand" "=m")
14399         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14400          UNSPEC_FIST_FLOOR))
14401    (use (match_operand:HI 2 "memory_operand" "m"))
14402    (use (match_operand:HI 3 "memory_operand" "m"))
14403    (clobber (match_scratch:XF 4 "=&1f"))]
14404   "TARGET_USE_FANCY_MATH_387
14405    && flag_unsafe_math_optimizations"
14406   "* return output_fix_trunc (insn, operands, 0);"
14407   [(set_attr "type" "fistp")
14408    (set_attr "i387_cw" "floor")
14409    (set_attr "mode" "DI")])
14410
14411 (define_insn "fistdi2_floor_with_temp"
14412   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14413         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14414          UNSPEC_FIST_FLOOR))
14415    (use (match_operand:HI 2 "memory_operand" "m,m"))
14416    (use (match_operand:HI 3 "memory_operand" "m,m"))
14417    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14418    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14419   "TARGET_USE_FANCY_MATH_387
14420    && flag_unsafe_math_optimizations"
14421   "#"
14422   [(set_attr "type" "fistp")
14423    (set_attr "i387_cw" "floor")
14424    (set_attr "mode" "DI")])
14425
14426 (define_split
14427   [(set (match_operand:DI 0 "register_operand" "")
14428         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14429          UNSPEC_FIST_FLOOR))
14430    (use (match_operand:HI 2 "memory_operand" ""))
14431    (use (match_operand:HI 3 "memory_operand" ""))
14432    (clobber (match_operand:DI 4 "memory_operand" ""))
14433    (clobber (match_scratch 5 ""))]
14434   "reload_completed"
14435   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14436               (use (match_dup 2))
14437               (use (match_dup 3))
14438               (clobber (match_dup 5))])
14439    (set (match_dup 0) (match_dup 4))])
14440
14441 (define_split
14442   [(set (match_operand:DI 0 "memory_operand" "")
14443         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14444          UNSPEC_FIST_FLOOR))
14445    (use (match_operand:HI 2 "memory_operand" ""))
14446    (use (match_operand:HI 3 "memory_operand" ""))
14447    (clobber (match_operand:DI 4 "memory_operand" ""))
14448    (clobber (match_scratch 5 ""))]
14449   "reload_completed"
14450   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14451               (use (match_dup 2))
14452               (use (match_dup 3))
14453               (clobber (match_dup 5))])])
14454
14455 (define_insn "fist<mode>2_floor"
14456   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14457         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14458          UNSPEC_FIST_FLOOR))
14459    (use (match_operand:HI 2 "memory_operand" "m"))
14460    (use (match_operand:HI 3 "memory_operand" "m"))]
14461   "TARGET_USE_FANCY_MATH_387
14462    && flag_unsafe_math_optimizations"
14463   "* return output_fix_trunc (insn, operands, 0);"
14464   [(set_attr "type" "fistp")
14465    (set_attr "i387_cw" "floor")
14466    (set_attr "mode" "<MODE>")])
14467
14468 (define_insn "fist<mode>2_floor_with_temp"
14469   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14470         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14471          UNSPEC_FIST_FLOOR))
14472    (use (match_operand:HI 2 "memory_operand" "m,m"))
14473    (use (match_operand:HI 3 "memory_operand" "m,m"))
14474    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14475   "TARGET_USE_FANCY_MATH_387
14476    && flag_unsafe_math_optimizations"
14477   "#"
14478   [(set_attr "type" "fistp")
14479    (set_attr "i387_cw" "floor")
14480    (set_attr "mode" "<MODE>")])
14481
14482 (define_split
14483   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14484         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14485          UNSPEC_FIST_FLOOR))
14486    (use (match_operand:HI 2 "memory_operand" ""))
14487    (use (match_operand:HI 3 "memory_operand" ""))
14488    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14489   "reload_completed"
14490   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14491                                   UNSPEC_FIST_FLOOR))
14492               (use (match_dup 2))
14493               (use (match_dup 3))])
14494    (set (match_dup 0) (match_dup 4))])
14495
14496 (define_split
14497   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14498         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14499          UNSPEC_FIST_FLOOR))
14500    (use (match_operand:HI 2 "memory_operand" ""))
14501    (use (match_operand:HI 3 "memory_operand" ""))
14502    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14503   "reload_completed"
14504   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14505                                   UNSPEC_FIST_FLOOR))
14506               (use (match_dup 2))
14507               (use (match_dup 3))])])
14508
14509 (define_expand "lfloorxf<mode>2"
14510   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14511                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14512                     UNSPEC_FIST_FLOOR))
14513               (clobber (reg:CC FLAGS_REG))])]
14514   "TARGET_USE_FANCY_MATH_387
14515    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14516    && flag_unsafe_math_optimizations")
14517
14518 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14519   [(match_operand:SWI48 0 "nonimmediate_operand" "")
14520    (match_operand:MODEF 1 "register_operand" "")]
14521   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14522    && !flag_trapping_math"
14523 {
14524   if (TARGET_64BIT && optimize_insn_for_size_p ())
14525     FAIL;
14526   ix86_expand_lfloorceil (operand0, operand1, true);
14527   DONE;
14528 })
14529
14530 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14531 (define_insn_and_split "frndintxf2_ceil"
14532   [(set (match_operand:XF 0 "register_operand" "")
14533         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14534          UNSPEC_FRNDINT_CEIL))
14535    (clobber (reg:CC FLAGS_REG))]
14536   "TARGET_USE_FANCY_MATH_387
14537    && flag_unsafe_math_optimizations
14538    && can_create_pseudo_p ()"
14539   "#"
14540   "&& 1"
14541   [(const_int 0)]
14542 {
14543   ix86_optimize_mode_switching[I387_CEIL] = 1;
14544
14545   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14546   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14547
14548   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14549                                        operands[2], operands[3]));
14550   DONE;
14551 }
14552   [(set_attr "type" "frndint")
14553    (set_attr "i387_cw" "ceil")
14554    (set_attr "mode" "XF")])
14555
14556 (define_insn "frndintxf2_ceil_i387"
14557   [(set (match_operand:XF 0 "register_operand" "=f")
14558         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14559          UNSPEC_FRNDINT_CEIL))
14560    (use (match_operand:HI 2 "memory_operand" "m"))
14561    (use (match_operand:HI 3 "memory_operand" "m"))]
14562   "TARGET_USE_FANCY_MATH_387
14563    && flag_unsafe_math_optimizations"
14564   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14565   [(set_attr "type" "frndint")
14566    (set_attr "i387_cw" "ceil")
14567    (set_attr "mode" "XF")])
14568
14569 (define_expand "ceilxf2"
14570   [(use (match_operand:XF 0 "register_operand" ""))
14571    (use (match_operand:XF 1 "register_operand" ""))]
14572   "TARGET_USE_FANCY_MATH_387
14573    && flag_unsafe_math_optimizations"
14574 {
14575   if (optimize_insn_for_size_p ())
14576     FAIL;
14577   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14578   DONE;
14579 })
14580
14581 (define_expand "ceil<mode>2"
14582   [(use (match_operand:MODEF 0 "register_operand" ""))
14583    (use (match_operand:MODEF 1 "register_operand" ""))]
14584   "(TARGET_USE_FANCY_MATH_387
14585     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14586         || TARGET_MIX_SSE_I387)
14587     && flag_unsafe_math_optimizations)
14588    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14589        && !flag_trapping_math)"
14590 {
14591   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14592       && !flag_trapping_math
14593       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14594     {
14595       if (TARGET_ROUND)
14596         emit_insn (gen_sse4_1_round<mode>2
14597                    (operands[0], operands[1], GEN_INT (0x02)));
14598       else if (optimize_insn_for_size_p ())
14599         FAIL;
14600       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14601         ix86_expand_floorceil (operand0, operand1, false);
14602       else
14603         ix86_expand_floorceildf_32 (operand0, operand1, false);
14604     }
14605   else
14606     {
14607       rtx op0, op1;
14608
14609       if (optimize_insn_for_size_p ())
14610         FAIL;
14611
14612       op0 = gen_reg_rtx (XFmode);
14613       op1 = gen_reg_rtx (XFmode);
14614       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14615       emit_insn (gen_frndintxf2_ceil (op0, op1));
14616
14617       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14618     }
14619   DONE;
14620 })
14621
14622 (define_insn_and_split "*fist<mode>2_ceil_1"
14623   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14624         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14625          UNSPEC_FIST_CEIL))
14626    (clobber (reg:CC FLAGS_REG))]
14627   "TARGET_USE_FANCY_MATH_387
14628    && flag_unsafe_math_optimizations
14629    && can_create_pseudo_p ()"
14630   "#"
14631   "&& 1"
14632   [(const_int 0)]
14633 {
14634   ix86_optimize_mode_switching[I387_CEIL] = 1;
14635
14636   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14637   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14638   if (memory_operand (operands[0], VOIDmode))
14639     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14640                                      operands[2], operands[3]));
14641   else
14642     {
14643       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14644       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14645                                                  operands[2], operands[3],
14646                                                  operands[4]));
14647     }
14648   DONE;
14649 }
14650   [(set_attr "type" "fistp")
14651    (set_attr "i387_cw" "ceil")
14652    (set_attr "mode" "<MODE>")])
14653
14654 (define_insn "fistdi2_ceil"
14655   [(set (match_operand:DI 0 "memory_operand" "=m")
14656         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14657          UNSPEC_FIST_CEIL))
14658    (use (match_operand:HI 2 "memory_operand" "m"))
14659    (use (match_operand:HI 3 "memory_operand" "m"))
14660    (clobber (match_scratch:XF 4 "=&1f"))]
14661   "TARGET_USE_FANCY_MATH_387
14662    && flag_unsafe_math_optimizations"
14663   "* return output_fix_trunc (insn, operands, 0);"
14664   [(set_attr "type" "fistp")
14665    (set_attr "i387_cw" "ceil")
14666    (set_attr "mode" "DI")])
14667
14668 (define_insn "fistdi2_ceil_with_temp"
14669   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14670         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14671          UNSPEC_FIST_CEIL))
14672    (use (match_operand:HI 2 "memory_operand" "m,m"))
14673    (use (match_operand:HI 3 "memory_operand" "m,m"))
14674    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14675    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14676   "TARGET_USE_FANCY_MATH_387
14677    && flag_unsafe_math_optimizations"
14678   "#"
14679   [(set_attr "type" "fistp")
14680    (set_attr "i387_cw" "ceil")
14681    (set_attr "mode" "DI")])
14682
14683 (define_split
14684   [(set (match_operand:DI 0 "register_operand" "")
14685         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14686          UNSPEC_FIST_CEIL))
14687    (use (match_operand:HI 2 "memory_operand" ""))
14688    (use (match_operand:HI 3 "memory_operand" ""))
14689    (clobber (match_operand:DI 4 "memory_operand" ""))
14690    (clobber (match_scratch 5 ""))]
14691   "reload_completed"
14692   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14693               (use (match_dup 2))
14694               (use (match_dup 3))
14695               (clobber (match_dup 5))])
14696    (set (match_dup 0) (match_dup 4))])
14697
14698 (define_split
14699   [(set (match_operand:DI 0 "memory_operand" "")
14700         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14701          UNSPEC_FIST_CEIL))
14702    (use (match_operand:HI 2 "memory_operand" ""))
14703    (use (match_operand:HI 3 "memory_operand" ""))
14704    (clobber (match_operand:DI 4 "memory_operand" ""))
14705    (clobber (match_scratch 5 ""))]
14706   "reload_completed"
14707   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14708               (use (match_dup 2))
14709               (use (match_dup 3))
14710               (clobber (match_dup 5))])])
14711
14712 (define_insn "fist<mode>2_ceil"
14713   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14714         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14715          UNSPEC_FIST_CEIL))
14716    (use (match_operand:HI 2 "memory_operand" "m"))
14717    (use (match_operand:HI 3 "memory_operand" "m"))]
14718   "TARGET_USE_FANCY_MATH_387
14719    && flag_unsafe_math_optimizations"
14720   "* return output_fix_trunc (insn, operands, 0);"
14721   [(set_attr "type" "fistp")
14722    (set_attr "i387_cw" "ceil")
14723    (set_attr "mode" "<MODE>")])
14724
14725 (define_insn "fist<mode>2_ceil_with_temp"
14726   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14727         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14728          UNSPEC_FIST_CEIL))
14729    (use (match_operand:HI 2 "memory_operand" "m,m"))
14730    (use (match_operand:HI 3 "memory_operand" "m,m"))
14731    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14732   "TARGET_USE_FANCY_MATH_387
14733    && flag_unsafe_math_optimizations"
14734   "#"
14735   [(set_attr "type" "fistp")
14736    (set_attr "i387_cw" "ceil")
14737    (set_attr "mode" "<MODE>")])
14738
14739 (define_split
14740   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14741         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14742          UNSPEC_FIST_CEIL))
14743    (use (match_operand:HI 2 "memory_operand" ""))
14744    (use (match_operand:HI 3 "memory_operand" ""))
14745    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14746   "reload_completed"
14747   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14748                                   UNSPEC_FIST_CEIL))
14749               (use (match_dup 2))
14750               (use (match_dup 3))])
14751    (set (match_dup 0) (match_dup 4))])
14752
14753 (define_split
14754   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14755         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14756          UNSPEC_FIST_CEIL))
14757    (use (match_operand:HI 2 "memory_operand" ""))
14758    (use (match_operand:HI 3 "memory_operand" ""))
14759    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14760   "reload_completed"
14761   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14762                                   UNSPEC_FIST_CEIL))
14763               (use (match_dup 2))
14764               (use (match_dup 3))])])
14765
14766 (define_expand "lceilxf<mode>2"
14767   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14768                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14769                     UNSPEC_FIST_CEIL))
14770               (clobber (reg:CC FLAGS_REG))])]
14771   "TARGET_USE_FANCY_MATH_387
14772    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14773    && flag_unsafe_math_optimizations")
14774
14775 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
14776   [(match_operand:SWI48 0 "nonimmediate_operand" "")
14777    (match_operand:MODEF 1 "register_operand" "")]
14778   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14779    && !flag_trapping_math"
14780 {
14781   ix86_expand_lfloorceil (operand0, operand1, false);
14782   DONE;
14783 })
14784
14785 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14786 (define_insn_and_split "frndintxf2_trunc"
14787   [(set (match_operand:XF 0 "register_operand" "")
14788         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14789          UNSPEC_FRNDINT_TRUNC))
14790    (clobber (reg:CC FLAGS_REG))]
14791   "TARGET_USE_FANCY_MATH_387
14792    && flag_unsafe_math_optimizations
14793    && can_create_pseudo_p ()"
14794   "#"
14795   "&& 1"
14796   [(const_int 0)]
14797 {
14798   ix86_optimize_mode_switching[I387_TRUNC] = 1;
14799
14800   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14801   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
14802
14803   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
14804                                         operands[2], operands[3]));
14805   DONE;
14806 }
14807   [(set_attr "type" "frndint")
14808    (set_attr "i387_cw" "trunc")
14809    (set_attr "mode" "XF")])
14810
14811 (define_insn "frndintxf2_trunc_i387"
14812   [(set (match_operand:XF 0 "register_operand" "=f")
14813         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14814          UNSPEC_FRNDINT_TRUNC))
14815    (use (match_operand:HI 2 "memory_operand" "m"))
14816    (use (match_operand:HI 3 "memory_operand" "m"))]
14817   "TARGET_USE_FANCY_MATH_387
14818    && flag_unsafe_math_optimizations"
14819   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14820   [(set_attr "type" "frndint")
14821    (set_attr "i387_cw" "trunc")
14822    (set_attr "mode" "XF")])
14823
14824 (define_expand "btruncxf2"
14825   [(use (match_operand:XF 0 "register_operand" ""))
14826    (use (match_operand:XF 1 "register_operand" ""))]
14827   "TARGET_USE_FANCY_MATH_387
14828    && flag_unsafe_math_optimizations"
14829 {
14830   if (optimize_insn_for_size_p ())
14831     FAIL;
14832   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
14833   DONE;
14834 })
14835
14836 (define_expand "btrunc<mode>2"
14837   [(use (match_operand:MODEF 0 "register_operand" ""))
14838    (use (match_operand:MODEF 1 "register_operand" ""))]
14839   "(TARGET_USE_FANCY_MATH_387
14840     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14841         || TARGET_MIX_SSE_I387)
14842     && flag_unsafe_math_optimizations)
14843    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14844        && !flag_trapping_math)"
14845 {
14846   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14847       && !flag_trapping_math
14848       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14849     {
14850       if (TARGET_ROUND)
14851         emit_insn (gen_sse4_1_round<mode>2
14852                    (operands[0], operands[1], GEN_INT (0x03)));
14853       else if (optimize_insn_for_size_p ())
14854         FAIL;
14855       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14856         ix86_expand_trunc (operand0, operand1);
14857       else
14858         ix86_expand_truncdf_32 (operand0, operand1);
14859     }
14860   else
14861     {
14862       rtx op0, op1;
14863
14864       if (optimize_insn_for_size_p ())
14865         FAIL;
14866
14867       op0 = gen_reg_rtx (XFmode);
14868       op1 = gen_reg_rtx (XFmode);
14869       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14870       emit_insn (gen_frndintxf2_trunc (op0, op1));
14871
14872       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14873     }
14874   DONE;
14875 })
14876
14877 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14878 (define_insn_and_split "frndintxf2_mask_pm"
14879   [(set (match_operand:XF 0 "register_operand" "")
14880         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14881          UNSPEC_FRNDINT_MASK_PM))
14882    (clobber (reg:CC FLAGS_REG))]
14883   "TARGET_USE_FANCY_MATH_387
14884    && flag_unsafe_math_optimizations
14885    && can_create_pseudo_p ()"
14886   "#"
14887   "&& 1"
14888   [(const_int 0)]
14889 {
14890   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
14891
14892   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14893   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
14894
14895   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
14896                                           operands[2], operands[3]));
14897   DONE;
14898 }
14899   [(set_attr "type" "frndint")
14900    (set_attr "i387_cw" "mask_pm")
14901    (set_attr "mode" "XF")])
14902
14903 (define_insn "frndintxf2_mask_pm_i387"
14904   [(set (match_operand:XF 0 "register_operand" "=f")
14905         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14906          UNSPEC_FRNDINT_MASK_PM))
14907    (use (match_operand:HI 2 "memory_operand" "m"))
14908    (use (match_operand:HI 3 "memory_operand" "m"))]
14909   "TARGET_USE_FANCY_MATH_387
14910    && flag_unsafe_math_optimizations"
14911   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
14912   [(set_attr "type" "frndint")
14913    (set_attr "i387_cw" "mask_pm")
14914    (set_attr "mode" "XF")])
14915
14916 (define_expand "nearbyintxf2"
14917   [(use (match_operand:XF 0 "register_operand" ""))
14918    (use (match_operand:XF 1 "register_operand" ""))]
14919   "TARGET_USE_FANCY_MATH_387
14920    && flag_unsafe_math_optimizations"
14921 {
14922   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
14923   DONE;
14924 })
14925
14926 (define_expand "nearbyint<mode>2"
14927   [(use (match_operand:MODEF 0 "register_operand" ""))
14928    (use (match_operand:MODEF 1 "register_operand" ""))]
14929   "TARGET_USE_FANCY_MATH_387
14930    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14931        || TARGET_MIX_SSE_I387)
14932    && flag_unsafe_math_optimizations"
14933 {
14934   rtx op0 = gen_reg_rtx (XFmode);
14935   rtx op1 = gen_reg_rtx (XFmode);
14936
14937   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14938   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
14939
14940   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14941   DONE;
14942 })
14943
14944 (define_insn "fxam<mode>2_i387"
14945   [(set (match_operand:HI 0 "register_operand" "=a")
14946         (unspec:HI
14947           [(match_operand:X87MODEF 1 "register_operand" "f")]
14948           UNSPEC_FXAM))]
14949   "TARGET_USE_FANCY_MATH_387"
14950   "fxam\n\tfnstsw\t%0"
14951   [(set_attr "type" "multi")
14952    (set_attr "length" "4")
14953    (set_attr "unit" "i387")
14954    (set_attr "mode" "<MODE>")])
14955
14956 (define_insn_and_split "fxam<mode>2_i387_with_temp"
14957   [(set (match_operand:HI 0 "register_operand" "")
14958         (unspec:HI
14959           [(match_operand:MODEF 1 "memory_operand" "")]
14960           UNSPEC_FXAM_MEM))]
14961   "TARGET_USE_FANCY_MATH_387
14962    && can_create_pseudo_p ()"
14963   "#"
14964   "&& 1"
14965   [(set (match_dup 2)(match_dup 1))
14966    (set (match_dup 0)
14967         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
14968 {
14969   operands[2] = gen_reg_rtx (<MODE>mode);
14970
14971   MEM_VOLATILE_P (operands[1]) = 1;
14972 }
14973   [(set_attr "type" "multi")
14974    (set_attr "unit" "i387")
14975    (set_attr "mode" "<MODE>")])
14976
14977 (define_expand "isinfxf2"
14978   [(use (match_operand:SI 0 "register_operand" ""))
14979    (use (match_operand:XF 1 "register_operand" ""))]
14980   "TARGET_USE_FANCY_MATH_387
14981    && TARGET_C99_FUNCTIONS"
14982 {
14983   rtx mask = GEN_INT (0x45);
14984   rtx val = GEN_INT (0x05);
14985
14986   rtx cond;
14987
14988   rtx scratch = gen_reg_rtx (HImode);
14989   rtx res = gen_reg_rtx (QImode);
14990
14991   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
14992
14993   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
14994   emit_insn (gen_cmpqi_ext_3 (scratch, val));
14995   cond = gen_rtx_fmt_ee (EQ, QImode,
14996                          gen_rtx_REG (CCmode, FLAGS_REG),
14997                          const0_rtx);
14998   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
14999   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15000   DONE;
15001 })
15002
15003 (define_expand "isinf<mode>2"
15004   [(use (match_operand:SI 0 "register_operand" ""))
15005    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15006   "TARGET_USE_FANCY_MATH_387
15007    && TARGET_C99_FUNCTIONS
15008    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15009 {
15010   rtx mask = GEN_INT (0x45);
15011   rtx val = GEN_INT (0x05);
15012
15013   rtx cond;
15014
15015   rtx scratch = gen_reg_rtx (HImode);
15016   rtx res = gen_reg_rtx (QImode);
15017
15018   /* Remove excess precision by forcing value through memory. */
15019   if (memory_operand (operands[1], VOIDmode))
15020     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15021   else
15022     {
15023       enum ix86_stack_slot slot = (virtuals_instantiated
15024                                    ? SLOT_TEMP
15025                                    : SLOT_VIRTUAL);
15026       rtx temp = assign_386_stack_local (<MODE>mode, slot);
15027
15028       emit_move_insn (temp, operands[1]);
15029       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15030     }
15031
15032   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15033   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15034   cond = gen_rtx_fmt_ee (EQ, QImode,
15035                          gen_rtx_REG (CCmode, FLAGS_REG),
15036                          const0_rtx);
15037   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15038   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15039   DONE;
15040 })
15041
15042 (define_expand "signbitxf2"
15043   [(use (match_operand:SI 0 "register_operand" ""))
15044    (use (match_operand:XF 1 "register_operand" ""))]
15045   "TARGET_USE_FANCY_MATH_387"
15046 {
15047   rtx scratch = gen_reg_rtx (HImode);
15048
15049   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15050   emit_insn (gen_andsi3 (operands[0],
15051              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15052   DONE;
15053 })
15054
15055 (define_insn "movmsk_df"
15056   [(set (match_operand:SI 0 "register_operand" "=r")
15057         (unspec:SI
15058           [(match_operand:DF 1 "register_operand" "x")]
15059           UNSPEC_MOVMSK))]
15060   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15061   "%vmovmskpd\t{%1, %0|%0, %1}"
15062   [(set_attr "type" "ssemov")
15063    (set_attr "prefix" "maybe_vex")
15064    (set_attr "mode" "DF")])
15065
15066 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15067 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15068 (define_expand "signbitdf2"
15069   [(use (match_operand:SI 0 "register_operand" ""))
15070    (use (match_operand:DF 1 "register_operand" ""))]
15071   "TARGET_USE_FANCY_MATH_387
15072    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15073 {
15074   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15075     {
15076       emit_insn (gen_movmsk_df (operands[0], operands[1]));
15077       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15078     }
15079   else
15080     {
15081       rtx scratch = gen_reg_rtx (HImode);
15082
15083       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15084       emit_insn (gen_andsi3 (operands[0],
15085                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15086     }
15087   DONE;
15088 })
15089
15090 (define_expand "signbitsf2"
15091   [(use (match_operand:SI 0 "register_operand" ""))
15092    (use (match_operand:SF 1 "register_operand" ""))]
15093   "TARGET_USE_FANCY_MATH_387
15094    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15095 {
15096   rtx scratch = gen_reg_rtx (HImode);
15097
15098   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15099   emit_insn (gen_andsi3 (operands[0],
15100              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15101   DONE;
15102 })
15103 \f
15104 ;; Block operation instructions
15105
15106 (define_insn "cld"
15107   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15108   ""
15109   "cld"
15110   [(set_attr "length" "1")
15111    (set_attr "length_immediate" "0")
15112    (set_attr "modrm" "0")])
15113
15114 (define_expand "movmemsi"
15115   [(use (match_operand:BLK 0 "memory_operand" ""))
15116    (use (match_operand:BLK 1 "memory_operand" ""))
15117    (use (match_operand:SI 2 "nonmemory_operand" ""))
15118    (use (match_operand:SI 3 "const_int_operand" ""))
15119    (use (match_operand:SI 4 "const_int_operand" ""))
15120    (use (match_operand:SI 5 "const_int_operand" ""))]
15121   ""
15122 {
15123  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15124                          operands[4], operands[5]))
15125    DONE;
15126  else
15127    FAIL;
15128 })
15129
15130 (define_expand "movmemdi"
15131   [(use (match_operand:BLK 0 "memory_operand" ""))
15132    (use (match_operand:BLK 1 "memory_operand" ""))
15133    (use (match_operand:DI 2 "nonmemory_operand" ""))
15134    (use (match_operand:DI 3 "const_int_operand" ""))
15135    (use (match_operand:SI 4 "const_int_operand" ""))
15136    (use (match_operand:SI 5 "const_int_operand" ""))]
15137   "TARGET_64BIT"
15138 {
15139  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15140                          operands[4], operands[5]))
15141    DONE;
15142  else
15143    FAIL;
15144 })
15145
15146 ;; Most CPUs don't like single string operations
15147 ;; Handle this case here to simplify previous expander.
15148
15149 (define_expand "strmov"
15150   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15151    (set (match_operand 1 "memory_operand" "") (match_dup 4))
15152    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15153               (clobber (reg:CC FLAGS_REG))])
15154    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15155               (clobber (reg:CC FLAGS_REG))])]
15156   ""
15157 {
15158   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15159
15160   /* If .md ever supports :P for Pmode, these can be directly
15161      in the pattern above.  */
15162   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15163   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15164
15165   /* Can't use this if the user has appropriated esi or edi.  */
15166   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15167       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15168     {
15169       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15170                                       operands[2], operands[3],
15171                                       operands[5], operands[6]));
15172       DONE;
15173     }
15174
15175   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15176 })
15177
15178 (define_expand "strmov_singleop"
15179   [(parallel [(set (match_operand 1 "memory_operand" "")
15180                    (match_operand 3 "memory_operand" ""))
15181               (set (match_operand 0 "register_operand" "")
15182                    (match_operand 4 "" ""))
15183               (set (match_operand 2 "register_operand" "")
15184                    (match_operand 5 "" ""))])]
15185   ""
15186   "ix86_current_function_needs_cld = 1;")
15187
15188 (define_insn "*strmovdi_rex_1"
15189   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15190         (mem:DI (match_operand:DI 3 "register_operand" "1")))
15191    (set (match_operand:DI 0 "register_operand" "=D")
15192         (plus:DI (match_dup 2)
15193                  (const_int 8)))
15194    (set (match_operand:DI 1 "register_operand" "=S")
15195         (plus:DI (match_dup 3)
15196                  (const_int 8)))]
15197   "TARGET_64BIT"
15198   "movsq"
15199   [(set_attr "type" "str")
15200    (set_attr "mode" "DI")
15201    (set_attr "memory" "both")])
15202
15203 (define_insn "*strmovsi_1"
15204   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15205         (mem:SI (match_operand:SI 3 "register_operand" "1")))
15206    (set (match_operand:SI 0 "register_operand" "=D")
15207         (plus:SI (match_dup 2)
15208                  (const_int 4)))
15209    (set (match_operand:SI 1 "register_operand" "=S")
15210         (plus:SI (match_dup 3)
15211                  (const_int 4)))]
15212   "!TARGET_64BIT"
15213   "movs{l|d}"
15214   [(set_attr "type" "str")
15215    (set_attr "mode" "SI")
15216    (set_attr "memory" "both")])
15217
15218 (define_insn "*strmovsi_rex_1"
15219   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15220         (mem:SI (match_operand:DI 3 "register_operand" "1")))
15221    (set (match_operand:DI 0 "register_operand" "=D")
15222         (plus:DI (match_dup 2)
15223                  (const_int 4)))
15224    (set (match_operand:DI 1 "register_operand" "=S")
15225         (plus:DI (match_dup 3)
15226                  (const_int 4)))]
15227   "TARGET_64BIT"
15228   "movs{l|d}"
15229   [(set_attr "type" "str")
15230    (set_attr "mode" "SI")
15231    (set_attr "memory" "both")])
15232
15233 (define_insn "*strmovhi_1"
15234   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15235         (mem:HI (match_operand:SI 3 "register_operand" "1")))
15236    (set (match_operand:SI 0 "register_operand" "=D")
15237         (plus:SI (match_dup 2)
15238                  (const_int 2)))
15239    (set (match_operand:SI 1 "register_operand" "=S")
15240         (plus:SI (match_dup 3)
15241                  (const_int 2)))]
15242   "!TARGET_64BIT"
15243   "movsw"
15244   [(set_attr "type" "str")
15245    (set_attr "memory" "both")
15246    (set_attr "mode" "HI")])
15247
15248 (define_insn "*strmovhi_rex_1"
15249   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15250         (mem:HI (match_operand:DI 3 "register_operand" "1")))
15251    (set (match_operand:DI 0 "register_operand" "=D")
15252         (plus:DI (match_dup 2)
15253                  (const_int 2)))
15254    (set (match_operand:DI 1 "register_operand" "=S")
15255         (plus:DI (match_dup 3)
15256                  (const_int 2)))]
15257   "TARGET_64BIT"
15258   "movsw"
15259   [(set_attr "type" "str")
15260    (set_attr "memory" "both")
15261    (set_attr "mode" "HI")])
15262
15263 (define_insn "*strmovqi_1"
15264   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15265         (mem:QI (match_operand:SI 3 "register_operand" "1")))
15266    (set (match_operand:SI 0 "register_operand" "=D")
15267         (plus:SI (match_dup 2)
15268                  (const_int 1)))
15269    (set (match_operand:SI 1 "register_operand" "=S")
15270         (plus:SI (match_dup 3)
15271                  (const_int 1)))]
15272   "!TARGET_64BIT"
15273   "movsb"
15274   [(set_attr "type" "str")
15275    (set_attr "memory" "both")
15276    (set_attr "mode" "QI")])
15277
15278 (define_insn "*strmovqi_rex_1"
15279   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15280         (mem:QI (match_operand:DI 3 "register_operand" "1")))
15281    (set (match_operand:DI 0 "register_operand" "=D")
15282         (plus:DI (match_dup 2)
15283                  (const_int 1)))
15284    (set (match_operand:DI 1 "register_operand" "=S")
15285         (plus:DI (match_dup 3)
15286                  (const_int 1)))]
15287   "TARGET_64BIT"
15288   "movsb"
15289   [(set_attr "type" "str")
15290    (set_attr "memory" "both")
15291    (set_attr "prefix_rex" "0")
15292    (set_attr "mode" "QI")])
15293
15294 (define_expand "rep_mov"
15295   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15296               (set (match_operand 0 "register_operand" "")
15297                    (match_operand 5 "" ""))
15298               (set (match_operand 2 "register_operand" "")
15299                    (match_operand 6 "" ""))
15300               (set (match_operand 1 "memory_operand" "")
15301                    (match_operand 3 "memory_operand" ""))
15302               (use (match_dup 4))])]
15303   ""
15304   "ix86_current_function_needs_cld = 1;")
15305
15306 (define_insn "*rep_movdi_rex64"
15307   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15308    (set (match_operand:DI 0 "register_operand" "=D")
15309         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15310                             (const_int 3))
15311                  (match_operand:DI 3 "register_operand" "0")))
15312    (set (match_operand:DI 1 "register_operand" "=S")
15313         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15314                  (match_operand:DI 4 "register_operand" "1")))
15315    (set (mem:BLK (match_dup 3))
15316         (mem:BLK (match_dup 4)))
15317    (use (match_dup 5))]
15318   "TARGET_64BIT"
15319   "rep{%;} movsq"
15320   [(set_attr "type" "str")
15321    (set_attr "prefix_rep" "1")
15322    (set_attr "memory" "both")
15323    (set_attr "mode" "DI")])
15324
15325 (define_insn "*rep_movsi"
15326   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15327    (set (match_operand:SI 0 "register_operand" "=D")
15328         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15329                             (const_int 2))
15330                  (match_operand:SI 3 "register_operand" "0")))
15331    (set (match_operand:SI 1 "register_operand" "=S")
15332         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15333                  (match_operand:SI 4 "register_operand" "1")))
15334    (set (mem:BLK (match_dup 3))
15335         (mem:BLK (match_dup 4)))
15336    (use (match_dup 5))]
15337   "!TARGET_64BIT"
15338   "rep{%;} movs{l|d}"
15339   [(set_attr "type" "str")
15340    (set_attr "prefix_rep" "1")
15341    (set_attr "memory" "both")
15342    (set_attr "mode" "SI")])
15343
15344 (define_insn "*rep_movsi_rex64"
15345   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15346    (set (match_operand:DI 0 "register_operand" "=D")
15347         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15348                             (const_int 2))
15349                  (match_operand:DI 3 "register_operand" "0")))
15350    (set (match_operand:DI 1 "register_operand" "=S")
15351         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15352                  (match_operand:DI 4 "register_operand" "1")))
15353    (set (mem:BLK (match_dup 3))
15354         (mem:BLK (match_dup 4)))
15355    (use (match_dup 5))]
15356   "TARGET_64BIT"
15357   "rep{%;} movs{l|d}"
15358   [(set_attr "type" "str")
15359    (set_attr "prefix_rep" "1")
15360    (set_attr "memory" "both")
15361    (set_attr "mode" "SI")])
15362
15363 (define_insn "*rep_movqi"
15364   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15365    (set (match_operand:SI 0 "register_operand" "=D")
15366         (plus:SI (match_operand:SI 3 "register_operand" "0")
15367                  (match_operand:SI 5 "register_operand" "2")))
15368    (set (match_operand:SI 1 "register_operand" "=S")
15369         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15370    (set (mem:BLK (match_dup 3))
15371         (mem:BLK (match_dup 4)))
15372    (use (match_dup 5))]
15373   "!TARGET_64BIT"
15374   "rep{%;} movsb"
15375   [(set_attr "type" "str")
15376    (set_attr "prefix_rep" "1")
15377    (set_attr "memory" "both")
15378    (set_attr "mode" "SI")])
15379
15380 (define_insn "*rep_movqi_rex64"
15381   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15382    (set (match_operand:DI 0 "register_operand" "=D")
15383         (plus:DI (match_operand:DI 3 "register_operand" "0")
15384                  (match_operand:DI 5 "register_operand" "2")))
15385    (set (match_operand:DI 1 "register_operand" "=S")
15386         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15387    (set (mem:BLK (match_dup 3))
15388         (mem:BLK (match_dup 4)))
15389    (use (match_dup 5))]
15390   "TARGET_64BIT"
15391   "rep{%;} movsb"
15392   [(set_attr "type" "str")
15393    (set_attr "prefix_rep" "1")
15394    (set_attr "memory" "both")
15395    (set_attr "mode" "SI")])
15396
15397 (define_expand "setmemsi"
15398    [(use (match_operand:BLK 0 "memory_operand" ""))
15399     (use (match_operand:SI 1 "nonmemory_operand" ""))
15400     (use (match_operand 2 "const_int_operand" ""))
15401     (use (match_operand 3 "const_int_operand" ""))
15402     (use (match_operand:SI 4 "const_int_operand" ""))
15403     (use (match_operand:SI 5 "const_int_operand" ""))]
15404   ""
15405 {
15406  if (ix86_expand_setmem (operands[0], operands[1],
15407                          operands[2], operands[3],
15408                          operands[4], operands[5]))
15409    DONE;
15410  else
15411    FAIL;
15412 })
15413
15414 (define_expand "setmemdi"
15415    [(use (match_operand:BLK 0 "memory_operand" ""))
15416     (use (match_operand:DI 1 "nonmemory_operand" ""))
15417     (use (match_operand 2 "const_int_operand" ""))
15418     (use (match_operand 3 "const_int_operand" ""))
15419     (use (match_operand 4 "const_int_operand" ""))
15420     (use (match_operand 5 "const_int_operand" ""))]
15421   "TARGET_64BIT"
15422 {
15423  if (ix86_expand_setmem (operands[0], operands[1],
15424                          operands[2], operands[3],
15425                          operands[4], operands[5]))
15426    DONE;
15427  else
15428    FAIL;
15429 })
15430
15431 ;; Most CPUs don't like single string operations
15432 ;; Handle this case here to simplify previous expander.
15433
15434 (define_expand "strset"
15435   [(set (match_operand 1 "memory_operand" "")
15436         (match_operand 2 "register_operand" ""))
15437    (parallel [(set (match_operand 0 "register_operand" "")
15438                    (match_dup 3))
15439               (clobber (reg:CC FLAGS_REG))])]
15440   ""
15441 {
15442   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15443     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15444
15445   /* If .md ever supports :P for Pmode, this can be directly
15446      in the pattern above.  */
15447   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15448                               GEN_INT (GET_MODE_SIZE (GET_MODE
15449                                                       (operands[2]))));
15450   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15451     {
15452       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15453                                       operands[3]));
15454       DONE;
15455     }
15456 })
15457
15458 (define_expand "strset_singleop"
15459   [(parallel [(set (match_operand 1 "memory_operand" "")
15460                    (match_operand 2 "register_operand" ""))
15461               (set (match_operand 0 "register_operand" "")
15462                    (match_operand 3 "" ""))])]
15463   ""
15464   "ix86_current_function_needs_cld = 1;")
15465
15466 (define_insn "*strsetdi_rex_1"
15467   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15468         (match_operand:DI 2 "register_operand" "a"))
15469    (set (match_operand:DI 0 "register_operand" "=D")
15470         (plus:DI (match_dup 1)
15471                  (const_int 8)))]
15472   "TARGET_64BIT"
15473   "stosq"
15474   [(set_attr "type" "str")
15475    (set_attr "memory" "store")
15476    (set_attr "mode" "DI")])
15477
15478 (define_insn "*strsetsi_1"
15479   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15480         (match_operand:SI 2 "register_operand" "a"))
15481    (set (match_operand:SI 0 "register_operand" "=D")
15482         (plus:SI (match_dup 1)
15483                  (const_int 4)))]
15484   "!TARGET_64BIT"
15485   "stos{l|d}"
15486   [(set_attr "type" "str")
15487    (set_attr "memory" "store")
15488    (set_attr "mode" "SI")])
15489
15490 (define_insn "*strsetsi_rex_1"
15491   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15492         (match_operand:SI 2 "register_operand" "a"))
15493    (set (match_operand:DI 0 "register_operand" "=D")
15494         (plus:DI (match_dup 1)
15495                  (const_int 4)))]
15496   "TARGET_64BIT"
15497   "stos{l|d}"
15498   [(set_attr "type" "str")
15499    (set_attr "memory" "store")
15500    (set_attr "mode" "SI")])
15501
15502 (define_insn "*strsethi_1"
15503   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15504         (match_operand:HI 2 "register_operand" "a"))
15505    (set (match_operand:SI 0 "register_operand" "=D")
15506         (plus:SI (match_dup 1)
15507                  (const_int 2)))]
15508   "!TARGET_64BIT"
15509   "stosw"
15510   [(set_attr "type" "str")
15511    (set_attr "memory" "store")
15512    (set_attr "mode" "HI")])
15513
15514 (define_insn "*strsethi_rex_1"
15515   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15516         (match_operand:HI 2 "register_operand" "a"))
15517    (set (match_operand:DI 0 "register_operand" "=D")
15518         (plus:DI (match_dup 1)
15519                  (const_int 2)))]
15520   "TARGET_64BIT"
15521   "stosw"
15522   [(set_attr "type" "str")
15523    (set_attr "memory" "store")
15524    (set_attr "mode" "HI")])
15525
15526 (define_insn "*strsetqi_1"
15527   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15528         (match_operand:QI 2 "register_operand" "a"))
15529    (set (match_operand:SI 0 "register_operand" "=D")
15530         (plus:SI (match_dup 1)
15531                  (const_int 1)))]
15532   "!TARGET_64BIT"
15533   "stosb"
15534   [(set_attr "type" "str")
15535    (set_attr "memory" "store")
15536    (set_attr "mode" "QI")])
15537
15538 (define_insn "*strsetqi_rex_1"
15539   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15540         (match_operand:QI 2 "register_operand" "a"))
15541    (set (match_operand:DI 0 "register_operand" "=D")
15542         (plus:DI (match_dup 1)
15543                  (const_int 1)))]
15544   "TARGET_64BIT"
15545   "stosb"
15546   [(set_attr "type" "str")
15547    (set_attr "memory" "store")
15548    (set_attr "prefix_rex" "0")
15549    (set_attr "mode" "QI")])
15550
15551 (define_expand "rep_stos"
15552   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15553               (set (match_operand 0 "register_operand" "")
15554                    (match_operand 4 "" ""))
15555               (set (match_operand 2 "memory_operand" "") (const_int 0))
15556               (use (match_operand 3 "register_operand" ""))
15557               (use (match_dup 1))])]
15558   ""
15559   "ix86_current_function_needs_cld = 1;")
15560
15561 (define_insn "*rep_stosdi_rex64"
15562   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15563    (set (match_operand:DI 0 "register_operand" "=D")
15564         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15565                             (const_int 3))
15566                  (match_operand:DI 3 "register_operand" "0")))
15567    (set (mem:BLK (match_dup 3))
15568         (const_int 0))
15569    (use (match_operand:DI 2 "register_operand" "a"))
15570    (use (match_dup 4))]
15571   "TARGET_64BIT"
15572   "rep{%;} stosq"
15573   [(set_attr "type" "str")
15574    (set_attr "prefix_rep" "1")
15575    (set_attr "memory" "store")
15576    (set_attr "mode" "DI")])
15577
15578 (define_insn "*rep_stossi"
15579   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15580    (set (match_operand:SI 0 "register_operand" "=D")
15581         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15582                             (const_int 2))
15583                  (match_operand:SI 3 "register_operand" "0")))
15584    (set (mem:BLK (match_dup 3))
15585         (const_int 0))
15586    (use (match_operand:SI 2 "register_operand" "a"))
15587    (use (match_dup 4))]
15588   "!TARGET_64BIT"
15589   "rep{%;} stos{l|d}"
15590   [(set_attr "type" "str")
15591    (set_attr "prefix_rep" "1")
15592    (set_attr "memory" "store")
15593    (set_attr "mode" "SI")])
15594
15595 (define_insn "*rep_stossi_rex64"
15596   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15597    (set (match_operand:DI 0 "register_operand" "=D")
15598         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15599                             (const_int 2))
15600                  (match_operand:DI 3 "register_operand" "0")))
15601    (set (mem:BLK (match_dup 3))
15602         (const_int 0))
15603    (use (match_operand:SI 2 "register_operand" "a"))
15604    (use (match_dup 4))]
15605   "TARGET_64BIT"
15606   "rep{%;} stos{l|d}"
15607   [(set_attr "type" "str")
15608    (set_attr "prefix_rep" "1")
15609    (set_attr "memory" "store")
15610    (set_attr "mode" "SI")])
15611
15612 (define_insn "*rep_stosqi"
15613   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15614    (set (match_operand:SI 0 "register_operand" "=D")
15615         (plus:SI (match_operand:SI 3 "register_operand" "0")
15616                  (match_operand:SI 4 "register_operand" "1")))
15617    (set (mem:BLK (match_dup 3))
15618         (const_int 0))
15619    (use (match_operand:QI 2 "register_operand" "a"))
15620    (use (match_dup 4))]
15621   "!TARGET_64BIT"
15622   "rep{%;} stosb"
15623   [(set_attr "type" "str")
15624    (set_attr "prefix_rep" "1")
15625    (set_attr "memory" "store")
15626    (set_attr "mode" "QI")])
15627
15628 (define_insn "*rep_stosqi_rex64"
15629   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15630    (set (match_operand:DI 0 "register_operand" "=D")
15631         (plus:DI (match_operand:DI 3 "register_operand" "0")
15632                  (match_operand:DI 4 "register_operand" "1")))
15633    (set (mem:BLK (match_dup 3))
15634         (const_int 0))
15635    (use (match_operand:QI 2 "register_operand" "a"))
15636    (use (match_dup 4))]
15637   "TARGET_64BIT"
15638   "rep{%;} stosb"
15639   [(set_attr "type" "str")
15640    (set_attr "prefix_rep" "1")
15641    (set_attr "memory" "store")
15642    (set_attr "prefix_rex" "0")
15643    (set_attr "mode" "QI")])
15644
15645 (define_expand "cmpstrnsi"
15646   [(set (match_operand:SI 0 "register_operand" "")
15647         (compare:SI (match_operand:BLK 1 "general_operand" "")
15648                     (match_operand:BLK 2 "general_operand" "")))
15649    (use (match_operand 3 "general_operand" ""))
15650    (use (match_operand 4 "immediate_operand" ""))]
15651   ""
15652 {
15653   rtx addr1, addr2, out, outlow, count, countreg, align;
15654
15655   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15656     FAIL;
15657
15658   /* Can't use this if the user has appropriated esi or edi.  */
15659   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15660     FAIL;
15661
15662   out = operands[0];
15663   if (!REG_P (out))
15664     out = gen_reg_rtx (SImode);
15665
15666   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15667   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15668   if (addr1 != XEXP (operands[1], 0))
15669     operands[1] = replace_equiv_address_nv (operands[1], addr1);
15670   if (addr2 != XEXP (operands[2], 0))
15671     operands[2] = replace_equiv_address_nv (operands[2], addr2);
15672
15673   count = operands[3];
15674   countreg = ix86_zero_extend_to_Pmode (count);
15675
15676   /* %%% Iff we are testing strict equality, we can use known alignment
15677      to good advantage.  This may be possible with combine, particularly
15678      once cc0 is dead.  */
15679   align = operands[4];
15680
15681   if (CONST_INT_P (count))
15682     {
15683       if (INTVAL (count) == 0)
15684         {
15685           emit_move_insn (operands[0], const0_rtx);
15686           DONE;
15687         }
15688       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15689                                      operands[1], operands[2]));
15690     }
15691   else
15692     {
15693       rtx (*gen_cmp) (rtx, rtx);
15694
15695       gen_cmp = (TARGET_64BIT
15696                  ? gen_cmpdi_1 : gen_cmpsi_1);
15697
15698       emit_insn (gen_cmp (countreg, countreg));
15699       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15700                                   operands[1], operands[2]));
15701     }
15702
15703   outlow = gen_lowpart (QImode, out);
15704   emit_insn (gen_cmpintqi (outlow));
15705   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15706
15707   if (operands[0] != out)
15708     emit_move_insn (operands[0], out);
15709
15710   DONE;
15711 })
15712
15713 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15714
15715 (define_expand "cmpintqi"
15716   [(set (match_dup 1)
15717         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15718    (set (match_dup 2)
15719         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15720    (parallel [(set (match_operand:QI 0 "register_operand" "")
15721                    (minus:QI (match_dup 1)
15722                              (match_dup 2)))
15723               (clobber (reg:CC FLAGS_REG))])]
15724   ""
15725   "operands[1] = gen_reg_rtx (QImode);
15726    operands[2] = gen_reg_rtx (QImode);")
15727
15728 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
15729 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
15730
15731 (define_expand "cmpstrnqi_nz_1"
15732   [(parallel [(set (reg:CC FLAGS_REG)
15733                    (compare:CC (match_operand 4 "memory_operand" "")
15734                                (match_operand 5 "memory_operand" "")))
15735               (use (match_operand 2 "register_operand" ""))
15736               (use (match_operand:SI 3 "immediate_operand" ""))
15737               (clobber (match_operand 0 "register_operand" ""))
15738               (clobber (match_operand 1 "register_operand" ""))
15739               (clobber (match_dup 2))])]
15740   ""
15741   "ix86_current_function_needs_cld = 1;")
15742
15743 (define_insn "*cmpstrnqi_nz_1"
15744   [(set (reg:CC FLAGS_REG)
15745         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15746                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
15747    (use (match_operand:SI 6 "register_operand" "2"))
15748    (use (match_operand:SI 3 "immediate_operand" "i"))
15749    (clobber (match_operand:SI 0 "register_operand" "=S"))
15750    (clobber (match_operand:SI 1 "register_operand" "=D"))
15751    (clobber (match_operand:SI 2 "register_operand" "=c"))]
15752   "!TARGET_64BIT"
15753   "repz{%;} cmpsb"
15754   [(set_attr "type" "str")
15755    (set_attr "mode" "QI")
15756    (set_attr "prefix_rep" "1")])
15757
15758 (define_insn "*cmpstrnqi_nz_rex_1"
15759   [(set (reg:CC FLAGS_REG)
15760         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15761                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
15762    (use (match_operand:DI 6 "register_operand" "2"))
15763    (use (match_operand:SI 3 "immediate_operand" "i"))
15764    (clobber (match_operand:DI 0 "register_operand" "=S"))
15765    (clobber (match_operand:DI 1 "register_operand" "=D"))
15766    (clobber (match_operand:DI 2 "register_operand" "=c"))]
15767   "TARGET_64BIT"
15768   "repz{%;} cmpsb"
15769   [(set_attr "type" "str")
15770    (set_attr "mode" "QI")
15771    (set_attr "prefix_rex" "0")
15772    (set_attr "prefix_rep" "1")])
15773
15774 ;; The same, but the count is not known to not be zero.
15775
15776 (define_expand "cmpstrnqi_1"
15777   [(parallel [(set (reg:CC FLAGS_REG)
15778                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15779                                      (const_int 0))
15780                   (compare:CC (match_operand 4 "memory_operand" "")
15781                               (match_operand 5 "memory_operand" ""))
15782                   (const_int 0)))
15783               (use (match_operand:SI 3 "immediate_operand" ""))
15784               (use (reg:CC FLAGS_REG))
15785               (clobber (match_operand 0 "register_operand" ""))
15786               (clobber (match_operand 1 "register_operand" ""))
15787               (clobber (match_dup 2))])]
15788   ""
15789   "ix86_current_function_needs_cld = 1;")
15790
15791 (define_insn "*cmpstrnqi_1"
15792   [(set (reg:CC FLAGS_REG)
15793         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
15794                              (const_int 0))
15795           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15796                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
15797           (const_int 0)))
15798    (use (match_operand:SI 3 "immediate_operand" "i"))
15799    (use (reg:CC FLAGS_REG))
15800    (clobber (match_operand:SI 0 "register_operand" "=S"))
15801    (clobber (match_operand:SI 1 "register_operand" "=D"))
15802    (clobber (match_operand:SI 2 "register_operand" "=c"))]
15803   "!TARGET_64BIT"
15804   "repz{%;} cmpsb"
15805   [(set_attr "type" "str")
15806    (set_attr "mode" "QI")
15807    (set_attr "prefix_rep" "1")])
15808
15809 (define_insn "*cmpstrnqi_rex_1"
15810   [(set (reg:CC FLAGS_REG)
15811         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
15812                              (const_int 0))
15813           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15814                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
15815           (const_int 0)))
15816    (use (match_operand:SI 3 "immediate_operand" "i"))
15817    (use (reg:CC FLAGS_REG))
15818    (clobber (match_operand:DI 0 "register_operand" "=S"))
15819    (clobber (match_operand:DI 1 "register_operand" "=D"))
15820    (clobber (match_operand:DI 2 "register_operand" "=c"))]
15821   "TARGET_64BIT"
15822   "repz{%;} cmpsb"
15823   [(set_attr "type" "str")
15824    (set_attr "mode" "QI")
15825    (set_attr "prefix_rex" "0")
15826    (set_attr "prefix_rep" "1")])
15827
15828 (define_expand "strlensi"
15829   [(set (match_operand:SI 0 "register_operand" "")
15830         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
15831                     (match_operand:QI 2 "immediate_operand" "")
15832                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15833   ""
15834 {
15835  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15836    DONE;
15837  else
15838    FAIL;
15839 })
15840
15841 (define_expand "strlendi"
15842   [(set (match_operand:DI 0 "register_operand" "")
15843         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
15844                     (match_operand:QI 2 "immediate_operand" "")
15845                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15846   ""
15847 {
15848  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15849    DONE;
15850  else
15851    FAIL;
15852 })
15853
15854 (define_expand "strlenqi_1"
15855   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
15856               (clobber (match_operand 1 "register_operand" ""))
15857               (clobber (reg:CC FLAGS_REG))])]
15858   ""
15859   "ix86_current_function_needs_cld = 1;")
15860
15861 (define_insn "*strlenqi_1"
15862   [(set (match_operand:SI 0 "register_operand" "=&c")
15863         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
15864                     (match_operand:QI 2 "register_operand" "a")
15865                     (match_operand:SI 3 "immediate_operand" "i")
15866                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
15867    (clobber (match_operand:SI 1 "register_operand" "=D"))
15868    (clobber (reg:CC FLAGS_REG))]
15869   "!TARGET_64BIT"
15870   "repnz{%;} scasb"
15871   [(set_attr "type" "str")
15872    (set_attr "mode" "QI")
15873    (set_attr "prefix_rep" "1")])
15874
15875 (define_insn "*strlenqi_rex_1"
15876   [(set (match_operand:DI 0 "register_operand" "=&c")
15877         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
15878                     (match_operand:QI 2 "register_operand" "a")
15879                     (match_operand:DI 3 "immediate_operand" "i")
15880                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
15881    (clobber (match_operand:DI 1 "register_operand" "=D"))
15882    (clobber (reg:CC FLAGS_REG))]
15883   "TARGET_64BIT"
15884   "repnz{%;} scasb"
15885   [(set_attr "type" "str")
15886    (set_attr "mode" "QI")
15887    (set_attr "prefix_rex" "0")
15888    (set_attr "prefix_rep" "1")])
15889
15890 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
15891 ;; handled in combine, but it is not currently up to the task.
15892 ;; When used for their truth value, the cmpstrn* expanders generate
15893 ;; code like this:
15894 ;;
15895 ;;   repz cmpsb
15896 ;;   seta       %al
15897 ;;   setb       %dl
15898 ;;   cmpb       %al, %dl
15899 ;;   jcc        label
15900 ;;
15901 ;; The intermediate three instructions are unnecessary.
15902
15903 ;; This one handles cmpstrn*_nz_1...
15904 (define_peephole2
15905   [(parallel[
15906      (set (reg:CC FLAGS_REG)
15907           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15908                       (mem:BLK (match_operand 5 "register_operand" ""))))
15909      (use (match_operand 6 "register_operand" ""))
15910      (use (match_operand:SI 3 "immediate_operand" ""))
15911      (clobber (match_operand 0 "register_operand" ""))
15912      (clobber (match_operand 1 "register_operand" ""))
15913      (clobber (match_operand 2 "register_operand" ""))])
15914    (set (match_operand:QI 7 "register_operand" "")
15915         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15916    (set (match_operand:QI 8 "register_operand" "")
15917         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15918    (set (reg FLAGS_REG)
15919         (compare (match_dup 7) (match_dup 8)))
15920   ]
15921   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15922   [(parallel[
15923      (set (reg:CC FLAGS_REG)
15924           (compare:CC (mem:BLK (match_dup 4))
15925                       (mem:BLK (match_dup 5))))
15926      (use (match_dup 6))
15927      (use (match_dup 3))
15928      (clobber (match_dup 0))
15929      (clobber (match_dup 1))
15930      (clobber (match_dup 2))])])
15931
15932 ;; ...and this one handles cmpstrn*_1.
15933 (define_peephole2
15934   [(parallel[
15935      (set (reg:CC FLAGS_REG)
15936           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15937                                (const_int 0))
15938             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15939                         (mem:BLK (match_operand 5 "register_operand" "")))
15940             (const_int 0)))
15941      (use (match_operand:SI 3 "immediate_operand" ""))
15942      (use (reg:CC FLAGS_REG))
15943      (clobber (match_operand 0 "register_operand" ""))
15944      (clobber (match_operand 1 "register_operand" ""))
15945      (clobber (match_operand 2 "register_operand" ""))])
15946    (set (match_operand:QI 7 "register_operand" "")
15947         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15948    (set (match_operand:QI 8 "register_operand" "")
15949         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15950    (set (reg FLAGS_REG)
15951         (compare (match_dup 7) (match_dup 8)))
15952   ]
15953   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15954   [(parallel[
15955      (set (reg:CC FLAGS_REG)
15956           (if_then_else:CC (ne (match_dup 6)
15957                                (const_int 0))
15958             (compare:CC (mem:BLK (match_dup 4))
15959                         (mem:BLK (match_dup 5)))
15960             (const_int 0)))
15961      (use (match_dup 3))
15962      (use (reg:CC FLAGS_REG))
15963      (clobber (match_dup 0))
15964      (clobber (match_dup 1))
15965      (clobber (match_dup 2))])])
15966 \f
15967 ;; Conditional move instructions.
15968
15969 (define_expand "mov<mode>cc"
15970   [(set (match_operand:SWIM 0 "register_operand" "")
15971         (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
15972                            (match_operand:SWIM 2 "general_operand" "")
15973                            (match_operand:SWIM 3 "general_operand" "")))]
15974   ""
15975   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
15976
15977 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15978 ;; the register first winds up with `sbbl $0,reg', which is also weird.
15979 ;; So just document what we're doing explicitly.
15980
15981 (define_expand "x86_mov<mode>cc_0_m1"
15982   [(parallel
15983     [(set (match_operand:SWI48 0 "register_operand" "")
15984           (if_then_else:SWI48
15985             (match_operator:SWI48 2 "ix86_carry_flag_operator"
15986              [(match_operand 1 "flags_reg_operand" "")
15987               (const_int 0)])
15988             (const_int -1)
15989             (const_int 0)))
15990      (clobber (reg:CC FLAGS_REG))])])
15991
15992 (define_insn "*x86_mov<mode>cc_0_m1"
15993   [(set (match_operand:SWI48 0 "register_operand" "=r")
15994         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15995                              [(reg FLAGS_REG) (const_int 0)])
15996           (const_int -1)
15997           (const_int 0)))
15998    (clobber (reg:CC FLAGS_REG))]
15999   ""
16000   "sbb{<imodesuffix>}\t%0, %0"
16001   ; Since we don't have the proper number of operands for an alu insn,
16002   ; fill in all the blanks.
16003   [(set_attr "type" "alu")
16004    (set_attr "use_carry" "1")
16005    (set_attr "pent_pair" "pu")
16006    (set_attr "memory" "none")
16007    (set_attr "imm_disp" "false")
16008    (set_attr "mode" "<MODE>")
16009    (set_attr "length_immediate" "0")])
16010
16011 (define_insn "*x86_mov<mode>cc_0_m1_se"
16012   [(set (match_operand:SWI48 0 "register_operand" "=r")
16013         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16014                              [(reg FLAGS_REG) (const_int 0)])
16015                             (const_int 1)
16016                             (const_int 0)))
16017    (clobber (reg:CC FLAGS_REG))]
16018   ""
16019   "sbb{<imodesuffix>}\t%0, %0"
16020   [(set_attr "type" "alu")
16021    (set_attr "use_carry" "1")
16022    (set_attr "pent_pair" "pu")
16023    (set_attr "memory" "none")
16024    (set_attr "imm_disp" "false")
16025    (set_attr "mode" "<MODE>")
16026    (set_attr "length_immediate" "0")])
16027
16028 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16029   [(set (match_operand:SWI48 0 "register_operand" "=r")
16030         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16031                     [(reg FLAGS_REG) (const_int 0)])))]
16032   ""
16033   "sbb{<imodesuffix>}\t%0, %0"
16034   [(set_attr "type" "alu")
16035    (set_attr "use_carry" "1")
16036    (set_attr "pent_pair" "pu")
16037    (set_attr "memory" "none")
16038    (set_attr "imm_disp" "false")
16039    (set_attr "mode" "<MODE>")
16040    (set_attr "length_immediate" "0")])
16041
16042 (define_insn "*mov<mode>cc_noc"
16043   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16044         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16045                                [(reg FLAGS_REG) (const_int 0)])
16046           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16047           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16048   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16049   "@
16050    cmov%O2%C1\t{%2, %0|%0, %2}
16051    cmov%O2%c1\t{%3, %0|%0, %3}"
16052   [(set_attr "type" "icmov")
16053    (set_attr "mode" "<MODE>")])
16054
16055 (define_insn_and_split "*movqicc_noc"
16056   [(set (match_operand:QI 0 "register_operand" "=r,r")
16057         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16058                            [(match_operand 4 "flags_reg_operand" "")
16059                             (const_int 0)])
16060                       (match_operand:QI 2 "register_operand" "r,0")
16061                       (match_operand:QI 3 "register_operand" "0,r")))]
16062   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16063   "#"
16064   "&& reload_completed"
16065   [(set (match_dup 0)
16066         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16067                       (match_dup 2)
16068                       (match_dup 3)))]
16069   "operands[0] = gen_lowpart (SImode, operands[0]);
16070    operands[2] = gen_lowpart (SImode, operands[2]);
16071    operands[3] = gen_lowpart (SImode, operands[3]);"
16072   [(set_attr "type" "icmov")
16073    (set_attr "mode" "SI")])
16074
16075 (define_expand "mov<mode>cc"
16076   [(set (match_operand:X87MODEF 0 "register_operand" "")
16077         (if_then_else:X87MODEF
16078           (match_operand 1 "ix86_fp_comparison_operator" "")
16079           (match_operand:X87MODEF 2 "register_operand" "")
16080           (match_operand:X87MODEF 3 "register_operand" "")))]
16081   "(TARGET_80387 && TARGET_CMOVE)
16082    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16083   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16084
16085 (define_insn "*movsfcc_1_387"
16086   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16087         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16088                                 [(reg FLAGS_REG) (const_int 0)])
16089                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16090                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16091   "TARGET_80387 && TARGET_CMOVE
16092    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16093   "@
16094    fcmov%F1\t{%2, %0|%0, %2}
16095    fcmov%f1\t{%3, %0|%0, %3}
16096    cmov%O2%C1\t{%2, %0|%0, %2}
16097    cmov%O2%c1\t{%3, %0|%0, %3}"
16098   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16099    (set_attr "mode" "SF,SF,SI,SI")])
16100
16101 (define_insn "*movdfcc_1"
16102   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16103         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16104                                 [(reg FLAGS_REG) (const_int 0)])
16105                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16106                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16107   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16108    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16109   "@
16110    fcmov%F1\t{%2, %0|%0, %2}
16111    fcmov%f1\t{%3, %0|%0, %3}
16112    #
16113    #"
16114   [(set_attr "type" "fcmov,fcmov,multi,multi")
16115    (set_attr "mode" "DF")])
16116
16117 (define_insn "*movdfcc_1_rex64"
16118   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16119         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16120                                 [(reg FLAGS_REG) (const_int 0)])
16121                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16122                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16123   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16124    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16125   "@
16126    fcmov%F1\t{%2, %0|%0, %2}
16127    fcmov%f1\t{%3, %0|%0, %3}
16128    cmov%O2%C1\t{%2, %0|%0, %2}
16129    cmov%O2%c1\t{%3, %0|%0, %3}"
16130   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16131    (set_attr "mode" "DF")])
16132
16133 (define_split
16134   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16135         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16136                                 [(match_operand 4 "flags_reg_operand" "")
16137                                  (const_int 0)])
16138                       (match_operand:DF 2 "nonimmediate_operand" "")
16139                       (match_operand:DF 3 "nonimmediate_operand" "")))]
16140   "!TARGET_64BIT && reload_completed"
16141   [(set (match_dup 2)
16142         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16143                       (match_dup 5)
16144                       (match_dup 6)))
16145    (set (match_dup 3)
16146         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16147                       (match_dup 7)
16148                       (match_dup 8)))]
16149 {
16150   split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16151   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16152 })
16153
16154 (define_insn "*movxfcc_1"
16155   [(set (match_operand:XF 0 "register_operand" "=f,f")
16156         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16157                                 [(reg FLAGS_REG) (const_int 0)])
16158                       (match_operand:XF 2 "register_operand" "f,0")
16159                       (match_operand:XF 3 "register_operand" "0,f")))]
16160   "TARGET_80387 && TARGET_CMOVE"
16161   "@
16162    fcmov%F1\t{%2, %0|%0, %2}
16163    fcmov%f1\t{%3, %0|%0, %3}"
16164   [(set_attr "type" "fcmov")
16165    (set_attr "mode" "XF")])
16166
16167 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16168 ;; the scalar versions to have only XMM registers as operands.
16169
16170 ;; XOP conditional move
16171 (define_insn "*xop_pcmov_<mode>"
16172   [(set (match_operand:MODEF 0 "register_operand" "=x")
16173         (if_then_else:MODEF
16174           (match_operand:MODEF 1 "register_operand" "x")
16175           (match_operand:MODEF 2 "register_operand" "x")
16176           (match_operand:MODEF 3 "register_operand" "x")))]
16177   "TARGET_XOP"
16178   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16179   [(set_attr "type" "sse4arg")])
16180
16181 ;; These versions of the min/max patterns are intentionally ignorant of
16182 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16183 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16184 ;; are undefined in this condition, we're certain this is correct.
16185
16186 (define_insn "*avx_<code><mode>3"
16187   [(set (match_operand:MODEF 0 "register_operand" "=x")
16188         (smaxmin:MODEF
16189           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16190           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16191   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16192   "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16193   [(set_attr "type" "sseadd")
16194    (set_attr "prefix" "vex")
16195    (set_attr "mode" "<MODE>")])
16196
16197 (define_insn "<code><mode>3"
16198   [(set (match_operand:MODEF 0 "register_operand" "=x")
16199         (smaxmin:MODEF
16200           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16201           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16202   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16203   "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16204   [(set_attr "type" "sseadd")
16205    (set_attr "mode" "<MODE>")])
16206
16207 ;; These versions of the min/max patterns implement exactly the operations
16208 ;;   min = (op1 < op2 ? op1 : op2)
16209 ;;   max = (!(op1 < op2) ? op1 : op2)
16210 ;; Their operands are not commutative, and thus they may be used in the
16211 ;; presence of -0.0 and NaN.
16212
16213 (define_insn "*avx_ieee_smin<mode>3"
16214   [(set (match_operand:MODEF 0 "register_operand" "=x")
16215         (unspec:MODEF
16216           [(match_operand:MODEF 1 "register_operand" "x")
16217            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16218          UNSPEC_IEEE_MIN))]
16219   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16220   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16221   [(set_attr "type" "sseadd")
16222    (set_attr "prefix" "vex")
16223    (set_attr "mode" "<MODE>")])
16224
16225 (define_insn "*ieee_smin<mode>3"
16226   [(set (match_operand:MODEF 0 "register_operand" "=x")
16227         (unspec:MODEF
16228           [(match_operand:MODEF 1 "register_operand" "0")
16229            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16230          UNSPEC_IEEE_MIN))]
16231   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16232   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16233   [(set_attr "type" "sseadd")
16234    (set_attr "mode" "<MODE>")])
16235
16236 (define_insn "*avx_ieee_smax<mode>3"
16237   [(set (match_operand:MODEF 0 "register_operand" "=x")
16238         (unspec:MODEF
16239           [(match_operand:MODEF 1 "register_operand" "0")
16240            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16241          UNSPEC_IEEE_MAX))]
16242   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16243   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16244   [(set_attr "type" "sseadd")
16245    (set_attr "prefix" "vex")
16246    (set_attr "mode" "<MODE>")])
16247
16248 (define_insn "*ieee_smax<mode>3"
16249   [(set (match_operand:MODEF 0 "register_operand" "=x")
16250         (unspec:MODEF
16251           [(match_operand:MODEF 1 "register_operand" "0")
16252            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16253          UNSPEC_IEEE_MAX))]
16254   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16255   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16256   [(set_attr "type" "sseadd")
16257    (set_attr "mode" "<MODE>")])
16258
16259 ;; Make two stack loads independent:
16260 ;;   fld aa              fld aa
16261 ;;   fld %st(0)     ->   fld bb
16262 ;;   fmul bb             fmul %st(1), %st
16263 ;;
16264 ;; Actually we only match the last two instructions for simplicity.
16265 (define_peephole2
16266   [(set (match_operand 0 "fp_register_operand" "")
16267         (match_operand 1 "fp_register_operand" ""))
16268    (set (match_dup 0)
16269         (match_operator 2 "binary_fp_operator"
16270            [(match_dup 0)
16271             (match_operand 3 "memory_operand" "")]))]
16272   "REGNO (operands[0]) != REGNO (operands[1])"
16273   [(set (match_dup 0) (match_dup 3))
16274    (set (match_dup 0) (match_dup 4))]
16275
16276   ;; The % modifier is not operational anymore in peephole2's, so we have to
16277   ;; swap the operands manually in the case of addition and multiplication.
16278   "if (COMMUTATIVE_ARITH_P (operands[2]))
16279      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16280                                    GET_MODE (operands[2]),
16281                                    operands[0], operands[1]);
16282    else
16283      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16284                                    GET_MODE (operands[2]),
16285                                    operands[1], operands[0]);")
16286
16287 ;; Conditional addition patterns
16288 (define_expand "add<mode>cc"
16289   [(match_operand:SWI 0 "register_operand" "")
16290    (match_operand 1 "ordered_comparison_operator" "")
16291    (match_operand:SWI 2 "register_operand" "")
16292    (match_operand:SWI 3 "const_int_operand" "")]
16293   ""
16294   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16295 \f
16296 ;; Misc patterns (?)
16297
16298 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16299 ;; Otherwise there will be nothing to keep
16300 ;;
16301 ;; [(set (reg ebp) (reg esp))]
16302 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16303 ;;  (clobber (eflags)]
16304 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16305 ;;
16306 ;; in proper program order.
16307
16308 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16309   [(set (match_operand:P 0 "register_operand" "=r,r")
16310         (plus:P (match_operand:P 1 "register_operand" "0,r")
16311                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16312    (clobber (reg:CC FLAGS_REG))
16313    (clobber (mem:BLK (scratch)))]
16314   ""
16315 {
16316   switch (get_attr_type (insn))
16317     {
16318     case TYPE_IMOV:
16319       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16320
16321     case TYPE_ALU:
16322       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16323       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16324         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16325
16326       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16327
16328     default:
16329       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16330       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16331     }
16332 }
16333   [(set (attr "type")
16334         (cond [(and (eq_attr "alternative" "0")
16335                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16336                  (const_string "alu")
16337                (match_operand:<MODE> 2 "const0_operand" "")
16338                  (const_string "imov")
16339               ]
16340               (const_string "lea")))
16341    (set (attr "length_immediate")
16342         (cond [(eq_attr "type" "imov")
16343                  (const_string "0")
16344                (and (eq_attr "type" "alu")
16345                     (match_operand 2 "const128_operand" ""))
16346                  (const_string "1")
16347               ]
16348               (const_string "*")))
16349    (set_attr "mode" "<MODE>")])
16350
16351 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16352   [(set (match_operand:P 0 "register_operand" "=r")
16353         (minus:P (match_operand:P 1 "register_operand" "0")
16354                  (match_operand:P 2 "register_operand" "r")))
16355    (clobber (reg:CC FLAGS_REG))
16356    (clobber (mem:BLK (scratch)))]
16357   ""
16358   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16359   [(set_attr "type" "alu")
16360    (set_attr "mode" "<MODE>")])
16361
16362 (define_insn "allocate_stack_worker_probe_<mode>"
16363   [(set (match_operand:P 0 "register_operand" "=a")
16364         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16365                             UNSPECV_STACK_PROBE))
16366    (clobber (reg:CC FLAGS_REG))]
16367   "ix86_target_stack_probe ()"
16368   "call\t___chkstk_ms"
16369   [(set_attr "type" "multi")
16370    (set_attr "length" "5")])
16371
16372 (define_expand "allocate_stack"
16373   [(match_operand 0 "register_operand" "")
16374    (match_operand 1 "general_operand" "")]
16375   "ix86_target_stack_probe ()"
16376 {
16377   rtx x;
16378
16379 #ifndef CHECK_STACK_LIMIT
16380 #define CHECK_STACK_LIMIT 0
16381 #endif
16382
16383   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16384       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16385     {
16386       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16387                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16388       if (x != stack_pointer_rtx)
16389         emit_move_insn (stack_pointer_rtx, x);
16390     }
16391   else
16392     {
16393       x = copy_to_mode_reg (Pmode, operands[1]);
16394       if (TARGET_64BIT)
16395         emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16396       else
16397         emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16398       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16399                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16400       if (x != stack_pointer_rtx)
16401         emit_move_insn (stack_pointer_rtx, x);
16402     }
16403
16404   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16405   DONE;
16406 })
16407
16408 ;; Use IOR for stack probes, this is shorter.
16409 (define_expand "probe_stack"
16410   [(match_operand 0 "memory_operand" "")]
16411   ""
16412 {
16413   rtx (*gen_ior3) (rtx, rtx, rtx);
16414
16415   gen_ior3 = (GET_MODE (operands[0]) == DImode
16416               ? gen_iordi3 : gen_iorsi3);
16417
16418   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16419   DONE;
16420 })
16421
16422 (define_insn "adjust_stack_and_probe<mode>"
16423   [(set (match_operand:P 0 "register_operand" "=r")
16424         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16425                             UNSPECV_PROBE_STACK_RANGE))
16426    (set (reg:P SP_REG)
16427         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16428    (clobber (reg:CC FLAGS_REG))
16429    (clobber (mem:BLK (scratch)))]
16430   ""
16431   "* return output_adjust_stack_and_probe (operands[0]);"
16432   [(set_attr "type" "multi")])
16433
16434 (define_insn "probe_stack_range<mode>"
16435   [(set (match_operand:P 0 "register_operand" "=r")
16436         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16437                             (match_operand:P 2 "const_int_operand" "n")]
16438                             UNSPECV_PROBE_STACK_RANGE))
16439    (clobber (reg:CC FLAGS_REG))]
16440   ""
16441   "* return output_probe_stack_range (operands[0], operands[2]);"
16442   [(set_attr "type" "multi")])
16443
16444 (define_expand "builtin_setjmp_receiver"
16445   [(label_ref (match_operand 0 "" ""))]
16446   "!TARGET_64BIT && flag_pic"
16447 {
16448 #if TARGET_MACHO
16449   if (TARGET_MACHO)
16450     {
16451       rtx xops[3];
16452       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16453       rtx label_rtx = gen_label_rtx ();
16454       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16455       xops[0] = xops[1] = picreg;
16456       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16457       ix86_expand_binary_operator (MINUS, SImode, xops);
16458     }
16459   else
16460 #endif
16461     emit_insn (gen_set_got (pic_offset_table_rtx));
16462   DONE;
16463 })
16464 \f
16465 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16466
16467 (define_split
16468   [(set (match_operand 0 "register_operand" "")
16469         (match_operator 3 "promotable_binary_operator"
16470            [(match_operand 1 "register_operand" "")
16471             (match_operand 2 "aligned_operand" "")]))
16472    (clobber (reg:CC FLAGS_REG))]
16473   "! TARGET_PARTIAL_REG_STALL && reload_completed
16474    && ((GET_MODE (operands[0]) == HImode
16475         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16476             /* ??? next two lines just !satisfies_constraint_K (...) */
16477             || !CONST_INT_P (operands[2])
16478             || satisfies_constraint_K (operands[2])))
16479        || (GET_MODE (operands[0]) == QImode
16480            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16481   [(parallel [(set (match_dup 0)
16482                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16483               (clobber (reg:CC FLAGS_REG))])]
16484   "operands[0] = gen_lowpart (SImode, operands[0]);
16485    operands[1] = gen_lowpart (SImode, operands[1]);
16486    if (GET_CODE (operands[3]) != ASHIFT)
16487      operands[2] = gen_lowpart (SImode, operands[2]);
16488    PUT_MODE (operands[3], SImode);")
16489
16490 ; Promote the QImode tests, as i386 has encoding of the AND
16491 ; instruction with 32-bit sign-extended immediate and thus the
16492 ; instruction size is unchanged, except in the %eax case for
16493 ; which it is increased by one byte, hence the ! optimize_size.
16494 (define_split
16495   [(set (match_operand 0 "flags_reg_operand" "")
16496         (match_operator 2 "compare_operator"
16497           [(and (match_operand 3 "aligned_operand" "")
16498                 (match_operand 4 "const_int_operand" ""))
16499            (const_int 0)]))
16500    (set (match_operand 1 "register_operand" "")
16501         (and (match_dup 3) (match_dup 4)))]
16502   "! TARGET_PARTIAL_REG_STALL && reload_completed
16503    && optimize_insn_for_speed_p ()
16504    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16505        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16506    /* Ensure that the operand will remain sign-extended immediate.  */
16507    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16508   [(parallel [(set (match_dup 0)
16509                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16510                                     (const_int 0)]))
16511               (set (match_dup 1)
16512                    (and:SI (match_dup 3) (match_dup 4)))])]
16513 {
16514   operands[4]
16515     = gen_int_mode (INTVAL (operands[4])
16516                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16517   operands[1] = gen_lowpart (SImode, operands[1]);
16518   operands[3] = gen_lowpart (SImode, operands[3]);
16519 })
16520
16521 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16522 ; the TEST instruction with 32-bit sign-extended immediate and thus
16523 ; the instruction size would at least double, which is not what we
16524 ; want even with ! optimize_size.
16525 (define_split
16526   [(set (match_operand 0 "flags_reg_operand" "")
16527         (match_operator 1 "compare_operator"
16528           [(and (match_operand:HI 2 "aligned_operand" "")
16529                 (match_operand:HI 3 "const_int_operand" ""))
16530            (const_int 0)]))]
16531   "! TARGET_PARTIAL_REG_STALL && reload_completed
16532    && ! TARGET_FAST_PREFIX
16533    && optimize_insn_for_speed_p ()
16534    /* Ensure that the operand will remain sign-extended immediate.  */
16535    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16536   [(set (match_dup 0)
16537         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16538                          (const_int 0)]))]
16539 {
16540   operands[3]
16541     = gen_int_mode (INTVAL (operands[3])
16542                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16543   operands[2] = gen_lowpart (SImode, operands[2]);
16544 })
16545
16546 (define_split
16547   [(set (match_operand 0 "register_operand" "")
16548         (neg (match_operand 1 "register_operand" "")))
16549    (clobber (reg:CC FLAGS_REG))]
16550   "! TARGET_PARTIAL_REG_STALL && reload_completed
16551    && (GET_MODE (operands[0]) == HImode
16552        || (GET_MODE (operands[0]) == QImode
16553            && (TARGET_PROMOTE_QImode
16554                || optimize_insn_for_size_p ())))"
16555   [(parallel [(set (match_dup 0)
16556                    (neg:SI (match_dup 1)))
16557               (clobber (reg:CC FLAGS_REG))])]
16558   "operands[0] = gen_lowpart (SImode, operands[0]);
16559    operands[1] = gen_lowpart (SImode, operands[1]);")
16560
16561 (define_split
16562   [(set (match_operand 0 "register_operand" "")
16563         (not (match_operand 1 "register_operand" "")))]
16564   "! TARGET_PARTIAL_REG_STALL && reload_completed
16565    && (GET_MODE (operands[0]) == HImode
16566        || (GET_MODE (operands[0]) == QImode
16567            && (TARGET_PROMOTE_QImode
16568                || optimize_insn_for_size_p ())))"
16569   [(set (match_dup 0)
16570         (not:SI (match_dup 1)))]
16571   "operands[0] = gen_lowpart (SImode, operands[0]);
16572    operands[1] = gen_lowpart (SImode, operands[1]);")
16573
16574 (define_split
16575   [(set (match_operand 0 "register_operand" "")
16576         (if_then_else (match_operator 1 "ordered_comparison_operator"
16577                                 [(reg FLAGS_REG) (const_int 0)])
16578                       (match_operand 2 "register_operand" "")
16579                       (match_operand 3 "register_operand" "")))]
16580   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16581    && (GET_MODE (operands[0]) == HImode
16582        || (GET_MODE (operands[0]) == QImode
16583            && (TARGET_PROMOTE_QImode
16584                || optimize_insn_for_size_p ())))"
16585   [(set (match_dup 0)
16586         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16587   "operands[0] = gen_lowpart (SImode, operands[0]);
16588    operands[2] = gen_lowpart (SImode, operands[2]);
16589    operands[3] = gen_lowpart (SImode, operands[3]);")
16590 \f
16591 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
16592 ;; transform a complex memory operation into two memory to register operations.
16593
16594 ;; Don't push memory operands
16595 (define_peephole2
16596   [(set (match_operand:SWI 0 "push_operand" "")
16597         (match_operand:SWI 1 "memory_operand" ""))
16598    (match_scratch:SWI 2 "<r>")]
16599   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16600    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16601   [(set (match_dup 2) (match_dup 1))
16602    (set (match_dup 0) (match_dup 2))])
16603
16604 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16605 ;; SImode pushes.
16606 (define_peephole2
16607   [(set (match_operand:SF 0 "push_operand" "")
16608         (match_operand:SF 1 "memory_operand" ""))
16609    (match_scratch:SF 2 "r")]
16610   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16611    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16612   [(set (match_dup 2) (match_dup 1))
16613    (set (match_dup 0) (match_dup 2))])
16614
16615 ;; Don't move an immediate directly to memory when the instruction
16616 ;; gets too big.
16617 (define_peephole2
16618   [(match_scratch:SWI124 1 "<r>")
16619    (set (match_operand:SWI124 0 "memory_operand" "")
16620         (const_int 0))]
16621   "optimize_insn_for_speed_p ()
16622    && !TARGET_USE_MOV0
16623    && TARGET_SPLIT_LONG_MOVES
16624    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16625    && peep2_regno_dead_p (0, FLAGS_REG)"
16626   [(parallel [(set (match_dup 2) (const_int 0))
16627               (clobber (reg:CC FLAGS_REG))])
16628    (set (match_dup 0) (match_dup 1))]
16629   "operands[2] = gen_lowpart (SImode, operands[1]);")
16630
16631 (define_peephole2
16632   [(match_scratch:SWI124 2 "<r>")
16633    (set (match_operand:SWI124 0 "memory_operand" "")
16634         (match_operand:SWI124 1 "immediate_operand" ""))]
16635   "optimize_insn_for_speed_p ()
16636    && TARGET_SPLIT_LONG_MOVES
16637    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16638   [(set (match_dup 2) (match_dup 1))
16639    (set (match_dup 0) (match_dup 2))])
16640
16641 ;; Don't compare memory with zero, load and use a test instead.
16642 (define_peephole2
16643   [(set (match_operand 0 "flags_reg_operand" "")
16644         (match_operator 1 "compare_operator"
16645           [(match_operand:SI 2 "memory_operand" "")
16646            (const_int 0)]))
16647    (match_scratch:SI 3 "r")]
16648   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16649   [(set (match_dup 3) (match_dup 2))
16650    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16651
16652 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16653 ;; Don't split NOTs with a displacement operand, because resulting XOR
16654 ;; will not be pairable anyway.
16655 ;;
16656 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16657 ;; represented using a modRM byte.  The XOR replacement is long decoded,
16658 ;; so this split helps here as well.
16659 ;;
16660 ;; Note: Can't do this as a regular split because we can't get proper
16661 ;; lifetime information then.
16662
16663 (define_peephole2
16664   [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16665         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16666   "optimize_insn_for_speed_p ()
16667    && ((TARGET_NOT_UNPAIRABLE
16668         && (!MEM_P (operands[0])
16669             || !memory_displacement_operand (operands[0], <MODE>mode)))
16670        || (TARGET_NOT_VECTORMODE
16671            && long_memory_operand (operands[0], <MODE>mode)))
16672    && peep2_regno_dead_p (0, FLAGS_REG)"
16673   [(parallel [(set (match_dup 0)
16674                    (xor:SWI124 (match_dup 1) (const_int -1)))
16675               (clobber (reg:CC FLAGS_REG))])])
16676
16677 ;; Non pairable "test imm, reg" instructions can be translated to
16678 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
16679 ;; byte opcode instead of two, have a short form for byte operands),
16680 ;; so do it for other CPUs as well.  Given that the value was dead,
16681 ;; this should not create any new dependencies.  Pass on the sub-word
16682 ;; versions if we're concerned about partial register stalls.
16683
16684 (define_peephole2
16685   [(set (match_operand 0 "flags_reg_operand" "")
16686         (match_operator 1 "compare_operator"
16687           [(and:SI (match_operand:SI 2 "register_operand" "")
16688                    (match_operand:SI 3 "immediate_operand" ""))
16689            (const_int 0)]))]
16690   "ix86_match_ccmode (insn, CCNOmode)
16691    && (true_regnum (operands[2]) != AX_REG
16692        || satisfies_constraint_K (operands[3]))
16693    && peep2_reg_dead_p (1, operands[2])"
16694   [(parallel
16695      [(set (match_dup 0)
16696            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16697                             (const_int 0)]))
16698       (set (match_dup 2)
16699            (and:SI (match_dup 2) (match_dup 3)))])])
16700
16701 ;; We don't need to handle HImode case, because it will be promoted to SImode
16702 ;; on ! TARGET_PARTIAL_REG_STALL
16703
16704 (define_peephole2
16705   [(set (match_operand 0 "flags_reg_operand" "")
16706         (match_operator 1 "compare_operator"
16707           [(and:QI (match_operand:QI 2 "register_operand" "")
16708                    (match_operand:QI 3 "immediate_operand" ""))
16709            (const_int 0)]))]
16710   "! TARGET_PARTIAL_REG_STALL
16711    && ix86_match_ccmode (insn, CCNOmode)
16712    && true_regnum (operands[2]) != AX_REG
16713    && peep2_reg_dead_p (1, operands[2])"
16714   [(parallel
16715      [(set (match_dup 0)
16716            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16717                             (const_int 0)]))
16718       (set (match_dup 2)
16719            (and:QI (match_dup 2) (match_dup 3)))])])
16720
16721 (define_peephole2
16722   [(set (match_operand 0 "flags_reg_operand" "")
16723         (match_operator 1 "compare_operator"
16724           [(and:SI
16725              (zero_extract:SI
16726                (match_operand 2 "ext_register_operand" "")
16727                (const_int 8)
16728                (const_int 8))
16729              (match_operand 3 "const_int_operand" ""))
16730            (const_int 0)]))]
16731   "! TARGET_PARTIAL_REG_STALL
16732    && ix86_match_ccmode (insn, CCNOmode)
16733    && true_regnum (operands[2]) != AX_REG
16734    && peep2_reg_dead_p (1, operands[2])"
16735   [(parallel [(set (match_dup 0)
16736                    (match_op_dup 1
16737                      [(and:SI
16738                         (zero_extract:SI
16739                           (match_dup 2)
16740                           (const_int 8)
16741                           (const_int 8))
16742                         (match_dup 3))
16743                       (const_int 0)]))
16744               (set (zero_extract:SI (match_dup 2)
16745                                     (const_int 8)
16746                                     (const_int 8))
16747                    (and:SI
16748                      (zero_extract:SI
16749                        (match_dup 2)
16750                        (const_int 8)
16751                        (const_int 8))
16752                      (match_dup 3)))])])
16753
16754 ;; Don't do logical operations with memory inputs.
16755 (define_peephole2
16756   [(match_scratch:SI 2 "r")
16757    (parallel [(set (match_operand:SI 0 "register_operand" "")
16758                    (match_operator:SI 3 "arith_or_logical_operator"
16759                      [(match_dup 0)
16760                       (match_operand:SI 1 "memory_operand" "")]))
16761               (clobber (reg:CC FLAGS_REG))])]
16762   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16763   [(set (match_dup 2) (match_dup 1))
16764    (parallel [(set (match_dup 0)
16765                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16766               (clobber (reg:CC FLAGS_REG))])])
16767
16768 (define_peephole2
16769   [(match_scratch:SI 2 "r")
16770    (parallel [(set (match_operand:SI 0 "register_operand" "")
16771                    (match_operator:SI 3 "arith_or_logical_operator"
16772                      [(match_operand:SI 1 "memory_operand" "")
16773                       (match_dup 0)]))
16774               (clobber (reg:CC FLAGS_REG))])]
16775   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16776   [(set (match_dup 2) (match_dup 1))
16777    (parallel [(set (match_dup 0)
16778                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16779               (clobber (reg:CC FLAGS_REG))])])
16780
16781 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
16782 ;; refers to the destination of the load!
16783
16784 (define_peephole2
16785   [(set (match_operand:SI 0 "register_operand" "")
16786         (match_operand:SI 1 "register_operand" ""))
16787    (parallel [(set (match_dup 0)
16788                    (match_operator:SI 3 "commutative_operator"
16789                      [(match_dup 0)
16790                       (match_operand:SI 2 "memory_operand" "")]))
16791               (clobber (reg:CC FLAGS_REG))])]
16792   "REGNO (operands[0]) != REGNO (operands[1])
16793    && GENERAL_REGNO_P (REGNO (operands[0]))
16794    && GENERAL_REGNO_P (REGNO (operands[1]))"
16795   [(set (match_dup 0) (match_dup 4))
16796    (parallel [(set (match_dup 0)
16797                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16798               (clobber (reg:CC FLAGS_REG))])]
16799   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16800
16801 (define_peephole2
16802   [(set (match_operand 0 "register_operand" "")
16803         (match_operand 1 "register_operand" ""))
16804    (set (match_dup 0)
16805                    (match_operator 3 "commutative_operator"
16806                      [(match_dup 0)
16807                       (match_operand 2 "memory_operand" "")]))]
16808   "REGNO (operands[0]) != REGNO (operands[1])
16809    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
16810        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16811   [(set (match_dup 0) (match_dup 2))
16812    (set (match_dup 0)
16813         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16814
16815 ; Don't do logical operations with memory outputs
16816 ;
16817 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16818 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
16819 ; the same decoder scheduling characteristics as the original.
16820
16821 (define_peephole2
16822   [(match_scratch:SI 2 "r")
16823    (parallel [(set (match_operand:SI 0 "memory_operand" "")
16824                    (match_operator:SI 3 "arith_or_logical_operator"
16825                      [(match_dup 0)
16826                       (match_operand:SI 1 "nonmemory_operand" "")]))
16827               (clobber (reg:CC FLAGS_REG))])]
16828   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16829    /* Do not split stack checking probes.  */
16830    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16831   [(set (match_dup 2) (match_dup 0))
16832    (parallel [(set (match_dup 2)
16833                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16834               (clobber (reg:CC FLAGS_REG))])
16835    (set (match_dup 0) (match_dup 2))])
16836
16837 (define_peephole2
16838   [(match_scratch:SI 2 "r")
16839    (parallel [(set (match_operand:SI 0 "memory_operand" "")
16840                    (match_operator:SI 3 "arith_or_logical_operator"
16841                      [(match_operand:SI 1 "nonmemory_operand" "")
16842                       (match_dup 0)]))
16843               (clobber (reg:CC FLAGS_REG))])]
16844   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16845    /* Do not split stack checking probes.  */
16846    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16847   [(set (match_dup 2) (match_dup 0))
16848    (parallel [(set (match_dup 2)
16849                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16850               (clobber (reg:CC FLAGS_REG))])
16851    (set (match_dup 0) (match_dup 2))])
16852
16853 ;; Attempt to always use XOR for zeroing registers.
16854 (define_peephole2
16855   [(set (match_operand 0 "register_operand" "")
16856         (match_operand 1 "const0_operand" ""))]
16857   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16858    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16859    && GENERAL_REG_P (operands[0])
16860    && peep2_regno_dead_p (0, FLAGS_REG)"
16861   [(parallel [(set (match_dup 0) (const_int 0))
16862               (clobber (reg:CC FLAGS_REG))])]
16863   "operands[0] = gen_lowpart (word_mode, operands[0]);")
16864
16865 (define_peephole2
16866   [(set (strict_low_part (match_operand 0 "register_operand" ""))
16867         (const_int 0))]
16868   "(GET_MODE (operands[0]) == QImode
16869     || GET_MODE (operands[0]) == HImode)
16870    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16871    && peep2_regno_dead_p (0, FLAGS_REG)"
16872   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16873               (clobber (reg:CC FLAGS_REG))])])
16874
16875 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16876 (define_peephole2
16877   [(set (match_operand:SWI248 0 "register_operand" "")
16878         (const_int -1))]
16879   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16880    && peep2_regno_dead_p (0, FLAGS_REG)"
16881   [(parallel [(set (match_dup 0) (const_int -1))
16882               (clobber (reg:CC FLAGS_REG))])]
16883 {
16884   if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16885     operands[0] = gen_lowpart (SImode, operands[0]);
16886 })
16887
16888 ;; Attempt to convert simple lea to add/shift.
16889 ;; These can be created by move expanders.
16890
16891 (define_peephole2
16892   [(set (match_operand:SWI48 0 "register_operand" "")
16893         (plus:SWI48 (match_dup 0)
16894                     (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
16895   "peep2_regno_dead_p (0, FLAGS_REG)"
16896   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16897               (clobber (reg:CC FLAGS_REG))])])
16898
16899 (define_peephole2
16900   [(set (match_operand:SI 0 "register_operand" "")
16901         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
16902                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
16903   "TARGET_64BIT
16904    && peep2_regno_dead_p (0, FLAGS_REG)
16905    && REGNO (operands[0]) == REGNO (operands[1])"
16906   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
16907               (clobber (reg:CC FLAGS_REG))])]
16908   "operands[2] = gen_lowpart (SImode, operands[2]);")
16909
16910 (define_peephole2
16911   [(set (match_operand:SWI48 0 "register_operand" "")
16912         (mult:SWI48 (match_dup 0)
16913                     (match_operand:SWI48 1 "const_int_operand" "")))]
16914   "exact_log2 (INTVAL (operands[1])) >= 0
16915    && peep2_regno_dead_p (0, FLAGS_REG)"
16916   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
16917               (clobber (reg:CC FLAGS_REG))])]
16918   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16919
16920 (define_peephole2
16921   [(set (match_operand:SI 0 "register_operand" "")
16922         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
16923                    (match_operand:DI 2 "const_int_operand" "")) 0))]
16924   "TARGET_64BIT
16925    && exact_log2 (INTVAL (operands[2])) >= 0
16926    && REGNO (operands[0]) == REGNO (operands[1])
16927    && peep2_regno_dead_p (0, FLAGS_REG)"
16928   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
16929               (clobber (reg:CC FLAGS_REG))])]
16930   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16931
16932 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
16933 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
16934 ;; On many CPUs it is also faster, since special hardware to avoid esp
16935 ;; dependencies is present.
16936
16937 ;; While some of these conversions may be done using splitters, we use
16938 ;; peepholes in order to allow combine_stack_adjustments pass to see
16939 ;; nonobfuscated RTL.
16940
16941 ;; Convert prologue esp subtractions to push.
16942 ;; We need register to push.  In order to keep verify_flow_info happy we have
16943 ;; two choices
16944 ;; - use scratch and clobber it in order to avoid dependencies
16945 ;; - use already live register
16946 ;; We can't use the second way right now, since there is no reliable way how to
16947 ;; verify that given register is live.  First choice will also most likely in
16948 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
16949 ;; call clobbered registers are dead.  We may want to use base pointer as an
16950 ;; alternative when no register is available later.
16951
16952 (define_peephole2
16953   [(match_scratch:P 1 "r")
16954    (parallel [(set (reg:P SP_REG)
16955                    (plus:P (reg:P SP_REG)
16956                            (match_operand:P 0 "const_int_operand" "")))
16957               (clobber (reg:CC FLAGS_REG))
16958               (clobber (mem:BLK (scratch)))])]
16959   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16960    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16961   [(clobber (match_dup 1))
16962    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16963               (clobber (mem:BLK (scratch)))])])
16964
16965 (define_peephole2
16966   [(match_scratch:P 1 "r")
16967    (parallel [(set (reg:P SP_REG)
16968                    (plus:P (reg:P SP_REG)
16969                            (match_operand:P 0 "const_int_operand" "")))
16970               (clobber (reg:CC FLAGS_REG))
16971               (clobber (mem:BLK (scratch)))])]
16972   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16973    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16974   [(clobber (match_dup 1))
16975    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16976    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16977               (clobber (mem:BLK (scratch)))])])
16978
16979 ;; Convert esp subtractions to push.
16980 (define_peephole2
16981   [(match_scratch:P 1 "r")
16982    (parallel [(set (reg:P SP_REG)
16983                    (plus:P (reg:P SP_REG)
16984                            (match_operand:P 0 "const_int_operand" "")))
16985               (clobber (reg:CC FLAGS_REG))])]
16986   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16987    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16988   [(clobber (match_dup 1))
16989    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16990
16991 (define_peephole2
16992   [(match_scratch:P 1 "r")
16993    (parallel [(set (reg:P SP_REG)
16994                    (plus:P (reg:P SP_REG)
16995                            (match_operand:P 0 "const_int_operand" "")))
16996               (clobber (reg:CC FLAGS_REG))])]
16997   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16998    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16999   [(clobber (match_dup 1))
17000    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17001    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17002
17003 ;; Convert epilogue deallocator to pop.
17004 (define_peephole2
17005   [(match_scratch:P 1 "r")
17006    (parallel [(set (reg:P SP_REG)
17007                    (plus:P (reg:P SP_REG)
17008                            (match_operand:P 0 "const_int_operand" "")))
17009               (clobber (reg:CC FLAGS_REG))
17010               (clobber (mem:BLK (scratch)))])]
17011   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17012    && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17013   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17014               (clobber (mem:BLK (scratch)))])])
17015
17016 ;; Two pops case is tricky, since pop causes dependency
17017 ;; on destination register.  We use two registers if available.
17018 (define_peephole2
17019   [(match_scratch:P 1 "r")
17020    (match_scratch:P 2 "r")
17021    (parallel [(set (reg:P SP_REG)
17022                    (plus:P (reg:P SP_REG)
17023                            (match_operand:P 0 "const_int_operand" "")))
17024               (clobber (reg:CC FLAGS_REG))
17025               (clobber (mem:BLK (scratch)))])]
17026   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17027    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17028   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17029               (clobber (mem:BLK (scratch)))])
17030    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17031
17032 (define_peephole2
17033   [(match_scratch:P 1 "r")
17034    (parallel [(set (reg:P SP_REG)
17035                    (plus:P (reg:P SP_REG)
17036                            (match_operand:P 0 "const_int_operand" "")))
17037               (clobber (reg:CC FLAGS_REG))
17038               (clobber (mem:BLK (scratch)))])]
17039   "optimize_insn_for_size_p ()
17040    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17041   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17042               (clobber (mem:BLK (scratch)))])
17043    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17044
17045 ;; Convert esp additions to pop.
17046 (define_peephole2
17047   [(match_scratch:P 1 "r")
17048    (parallel [(set (reg:P SP_REG)
17049                    (plus:P (reg:P SP_REG)
17050                            (match_operand:P 0 "const_int_operand" "")))
17051               (clobber (reg:CC FLAGS_REG))])]
17052   "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17053   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17054
17055 ;; Two pops case is tricky, since pop causes dependency
17056 ;; on destination register.  We use two registers if available.
17057 (define_peephole2
17058   [(match_scratch:P 1 "r")
17059    (match_scratch:P 2 "r")
17060    (parallel [(set (reg:P SP_REG)
17061                    (plus:P (reg:P SP_REG)
17062                            (match_operand:P 0 "const_int_operand" "")))
17063               (clobber (reg:CC FLAGS_REG))])]
17064   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17065   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17066    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17067
17068 (define_peephole2
17069   [(match_scratch:P 1 "r")
17070    (parallel [(set (reg:P SP_REG)
17071                    (plus:P (reg:P SP_REG)
17072                            (match_operand:P 0 "const_int_operand" "")))
17073               (clobber (reg:CC FLAGS_REG))])]
17074   "optimize_insn_for_size_p ()
17075    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17076   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17077    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17078 \f
17079 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17080 ;; required and register dies.  Similarly for 128 to -128.
17081 (define_peephole2
17082   [(set (match_operand 0 "flags_reg_operand" "")
17083         (match_operator 1 "compare_operator"
17084           [(match_operand 2 "register_operand" "")
17085            (match_operand 3 "const_int_operand" "")]))]
17086   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17087      && incdec_operand (operands[3], GET_MODE (operands[3])))
17088     || (!TARGET_FUSE_CMP_AND_BRANCH
17089         && INTVAL (operands[3]) == 128))
17090    && ix86_match_ccmode (insn, CCGCmode)
17091    && peep2_reg_dead_p (1, operands[2])"
17092   [(parallel [(set (match_dup 0)
17093                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17094               (clobber (match_dup 2))])])
17095 \f
17096 ;; Convert imul by three, five and nine into lea
17097 (define_peephole2
17098   [(parallel
17099     [(set (match_operand:SWI48 0 "register_operand" "")
17100           (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17101                       (match_operand:SWI48 2 "const_int_operand" "")))
17102      (clobber (reg:CC FLAGS_REG))])]
17103   "INTVAL (operands[2]) == 3
17104    || INTVAL (operands[2]) == 5
17105    || INTVAL (operands[2]) == 9"
17106   [(set (match_dup 0)
17107         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17108                     (match_dup 1)))]
17109   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17110
17111 (define_peephole2
17112   [(parallel
17113     [(set (match_operand:SWI48 0 "register_operand" "")
17114           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17115                       (match_operand:SWI48 2 "const_int_operand" "")))
17116      (clobber (reg:CC FLAGS_REG))])]
17117   "optimize_insn_for_speed_p ()
17118    && (INTVAL (operands[2]) == 3
17119        || INTVAL (operands[2]) == 5
17120        || INTVAL (operands[2]) == 9)"
17121   [(set (match_dup 0) (match_dup 1))
17122    (set (match_dup 0)
17123         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17124                     (match_dup 0)))]
17125   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17126
17127 ;; imul $32bit_imm, mem, reg is vector decoded, while
17128 ;; imul $32bit_imm, reg, reg is direct decoded.
17129 (define_peephole2
17130   [(match_scratch:SWI48 3 "r")
17131    (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17132                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17133                                (match_operand:SWI48 2 "immediate_operand" "")))
17134               (clobber (reg:CC FLAGS_REG))])]
17135   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17136    && !satisfies_constraint_K (operands[2])"
17137   [(set (match_dup 3) (match_dup 1))
17138    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17139               (clobber (reg:CC FLAGS_REG))])])
17140
17141 (define_peephole2
17142   [(match_scratch:SI 3 "r")
17143    (parallel [(set (match_operand:DI 0 "register_operand" "")
17144                    (zero_extend:DI
17145                      (mult:SI (match_operand:SI 1 "memory_operand" "")
17146                               (match_operand:SI 2 "immediate_operand" ""))))
17147               (clobber (reg:CC FLAGS_REG))])]
17148   "TARGET_64BIT
17149    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17150    && !satisfies_constraint_K (operands[2])"
17151   [(set (match_dup 3) (match_dup 1))
17152    (parallel [(set (match_dup 0)
17153                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17154               (clobber (reg:CC FLAGS_REG))])])
17155
17156 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17157 ;; Convert it into imul reg, reg
17158 ;; It would be better to force assembler to encode instruction using long
17159 ;; immediate, but there is apparently no way to do so.
17160 (define_peephole2
17161   [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17162                    (mult:SWI248
17163                     (match_operand:SWI248 1 "nonimmediate_operand" "")
17164                     (match_operand:SWI248 2 "const_int_operand" "")))
17165               (clobber (reg:CC FLAGS_REG))])
17166    (match_scratch:SWI248 3 "r")]
17167   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17168    && satisfies_constraint_K (operands[2])"
17169   [(set (match_dup 3) (match_dup 2))
17170    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17171               (clobber (reg:CC FLAGS_REG))])]
17172 {
17173   if (!rtx_equal_p (operands[0], operands[1]))
17174     emit_move_insn (operands[0], operands[1]);
17175 })
17176
17177 ;; After splitting up read-modify operations, array accesses with memory
17178 ;; operands might end up in form:
17179 ;;  sall    $2, %eax
17180 ;;  movl    4(%esp), %edx
17181 ;;  addl    %edx, %eax
17182 ;; instead of pre-splitting:
17183 ;;  sall    $2, %eax
17184 ;;  addl    4(%esp), %eax
17185 ;; Turn it into:
17186 ;;  movl    4(%esp), %edx
17187 ;;  leal    (%edx,%eax,4), %eax
17188
17189 (define_peephole2
17190   [(match_scratch:P 5 "r")
17191    (parallel [(set (match_operand 0 "register_operand" "")
17192                    (ashift (match_operand 1 "register_operand" "")
17193                            (match_operand 2 "const_int_operand" "")))
17194                (clobber (reg:CC FLAGS_REG))])
17195    (parallel [(set (match_operand 3 "register_operand" "")
17196                    (plus (match_dup 0)
17197                          (match_operand 4 "x86_64_general_operand" "")))
17198                    (clobber (reg:CC FLAGS_REG))])]
17199   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
17200    /* Validate MODE for lea.  */
17201    && ((!TARGET_PARTIAL_REG_STALL
17202         && (GET_MODE (operands[0]) == QImode
17203             || GET_MODE (operands[0]) == HImode))
17204        || GET_MODE (operands[0]) == SImode
17205        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17206    && (rtx_equal_p (operands[0], operands[3])
17207        || peep2_reg_dead_p (2, operands[0]))
17208    /* We reorder load and the shift.  */
17209    && !reg_overlap_mentioned_p (operands[0], operands[4])"
17210   [(set (match_dup 5) (match_dup 4))
17211    (set (match_dup 0) (match_dup 1))]
17212 {
17213   enum machine_mode mode = GET_MODE (operands[1]) == DImode ? DImode : SImode;
17214   int scale = 1 << INTVAL (operands[2]);
17215   rtx index = gen_lowpart (Pmode, operands[1]);
17216   rtx base = gen_lowpart (Pmode, operands[5]);
17217   rtx dest = gen_lowpart (mode, operands[3]);
17218
17219   operands[1] = gen_rtx_PLUS (Pmode, base,
17220                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17221   operands[5] = base;
17222   if (mode != Pmode)
17223     {
17224       operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17225       operands[5] = gen_rtx_SUBREG (mode, operands[5], 0);
17226     }
17227   operands[0] = dest;
17228 })
17229 \f
17230 ;; Call-value patterns last so that the wildcard operand does not
17231 ;; disrupt insn-recog's switch tables.
17232
17233 (define_insn "*call_value_pop_0"
17234   [(set (match_operand 0 "" "")
17235         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17236               (match_operand:SI 2 "" "")))
17237    (set (reg:SI SP_REG)
17238         (plus:SI (reg:SI SP_REG)
17239                  (match_operand:SI 3 "immediate_operand" "")))]
17240   "!TARGET_64BIT"
17241 {
17242   if (SIBLING_CALL_P (insn))
17243     return "jmp\t%P1";
17244   else
17245     return "call\t%P1";
17246 }
17247   [(set_attr "type" "callv")])
17248
17249 (define_insn "*call_value_pop_1"
17250   [(set (match_operand 0 "" "")
17251         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17252               (match_operand:SI 2 "" "")))
17253    (set (reg:SI SP_REG)
17254         (plus:SI (reg:SI SP_REG)
17255                  (match_operand:SI 3 "immediate_operand" "i")))]
17256   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17257 {
17258   if (constant_call_address_operand (operands[1], Pmode))
17259     return "call\t%P1";
17260   return "call\t%A1";
17261 }
17262   [(set_attr "type" "callv")])
17263
17264 (define_insn "*sibcall_value_pop_1"
17265   [(set (match_operand 0 "" "")
17266         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17267               (match_operand:SI 2 "" "")))
17268    (set (reg:SI SP_REG)
17269         (plus:SI (reg:SI SP_REG)
17270                  (match_operand:SI 3 "immediate_operand" "i,i")))]
17271   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17272   "@
17273    jmp\t%P1
17274    jmp\t%A1"
17275   [(set_attr "type" "callv")])
17276
17277 (define_insn "*call_value_0"
17278   [(set (match_operand 0 "" "")
17279         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17280               (match_operand:SI 2 "" "")))]
17281   "!TARGET_64BIT"
17282 {
17283   if (SIBLING_CALL_P (insn))
17284     return "jmp\t%P1";
17285   else
17286     return "call\t%P1";
17287 }
17288   [(set_attr "type" "callv")])
17289
17290 (define_insn "*call_value_0_rex64"
17291   [(set (match_operand 0 "" "")
17292         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17293               (match_operand:DI 2 "const_int_operand" "")))]
17294   "TARGET_64BIT"
17295 {
17296   if (SIBLING_CALL_P (insn))
17297     return "jmp\t%P1";
17298   else
17299     return "call\t%P1";
17300 }
17301   [(set_attr "type" "callv")])
17302
17303 (define_insn "*call_value_0_rex64_ms_sysv"
17304   [(set (match_operand 0 "" "")
17305         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17306               (match_operand:DI 2 "const_int_operand" "")))
17307    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17308    (clobber (reg:TI XMM6_REG))
17309    (clobber (reg:TI XMM7_REG))
17310    (clobber (reg:TI XMM8_REG))
17311    (clobber (reg:TI XMM9_REG))
17312    (clobber (reg:TI XMM10_REG))
17313    (clobber (reg:TI XMM11_REG))
17314    (clobber (reg:TI XMM12_REG))
17315    (clobber (reg:TI XMM13_REG))
17316    (clobber (reg:TI XMM14_REG))
17317    (clobber (reg:TI XMM15_REG))
17318    (clobber (reg:DI SI_REG))
17319    (clobber (reg:DI DI_REG))]
17320   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17321 {
17322   if (SIBLING_CALL_P (insn))
17323     return "jmp\t%P1";
17324   else
17325     return "call\t%P1";
17326 }
17327   [(set_attr "type" "callv")])
17328
17329 (define_insn "*call_value_1"
17330   [(set (match_operand 0 "" "")
17331         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17332               (match_operand:SI 2 "" "")))]
17333   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17334 {
17335   if (constant_call_address_operand (operands[1], Pmode))
17336     return "call\t%P1";
17337   return "call\t%A1";
17338 }
17339   [(set_attr "type" "callv")])
17340
17341 (define_insn "*sibcall_value_1"
17342   [(set (match_operand 0 "" "")
17343         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17344               (match_operand:SI 2 "" "")))]
17345   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17346   "@
17347    jmp\t%P1
17348    jmp\t%A1"
17349   [(set_attr "type" "callv")])
17350
17351 (define_insn "*call_value_1_rex64"
17352   [(set (match_operand 0 "" "")
17353         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17354               (match_operand:DI 2 "" "")))]
17355   "TARGET_64BIT && !SIBLING_CALL_P (insn)
17356    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17357 {
17358   if (constant_call_address_operand (operands[1], Pmode))
17359     return "call\t%P1";
17360   return "call\t%A1";
17361 }
17362   [(set_attr "type" "callv")])
17363
17364 (define_insn "*call_value_1_rex64_ms_sysv"
17365   [(set (match_operand 0 "" "")
17366         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17367               (match_operand:DI 2 "" "")))
17368    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17369    (clobber (reg:TI XMM6_REG))
17370    (clobber (reg:TI XMM7_REG))
17371    (clobber (reg:TI XMM8_REG))
17372    (clobber (reg:TI XMM9_REG))
17373    (clobber (reg:TI XMM10_REG))
17374    (clobber (reg:TI XMM11_REG))
17375    (clobber (reg:TI XMM12_REG))
17376    (clobber (reg:TI XMM13_REG))
17377    (clobber (reg:TI XMM14_REG))
17378    (clobber (reg:TI XMM15_REG))
17379    (clobber (reg:DI SI_REG))
17380    (clobber (reg:DI DI_REG))]
17381   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17382 {
17383   if (constant_call_address_operand (operands[1], Pmode))
17384     return "call\t%P1";
17385   return "call\t%A1";
17386 }
17387   [(set_attr "type" "callv")])
17388
17389 (define_insn "*call_value_1_rex64_large"
17390   [(set (match_operand 0 "" "")
17391         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17392               (match_operand:DI 2 "" "")))]
17393   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17394   "call\t%A1"
17395   [(set_attr "type" "callv")])
17396
17397 (define_insn "*sibcall_value_1_rex64"
17398   [(set (match_operand 0 "" "")
17399         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17400               (match_operand:DI 2 "" "")))]
17401   "TARGET_64BIT && SIBLING_CALL_P (insn)"
17402   "@
17403    jmp\t%P1
17404    jmp\t%A1"
17405   [(set_attr "type" "callv")])
17406 \f
17407 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17408 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17409 ;; caught for use by garbage collectors and the like.  Using an insn that
17410 ;; maps to SIGILL makes it more likely the program will rightfully die.
17411 ;; Keeping with tradition, "6" is in honor of #UD.
17412 (define_insn "trap"
17413   [(trap_if (const_int 1) (const_int 6))]
17414   ""
17415   { return ASM_SHORT "0x0b0f"; }
17416   [(set_attr "length" "2")])
17417
17418 (define_expand "prefetch"
17419   [(prefetch (match_operand 0 "address_operand" "")
17420              (match_operand:SI 1 "const_int_operand" "")
17421              (match_operand:SI 2 "const_int_operand" ""))]
17422   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17423 {
17424   int rw = INTVAL (operands[1]);
17425   int locality = INTVAL (operands[2]);
17426
17427   gcc_assert (rw == 0 || rw == 1);
17428   gcc_assert (locality >= 0 && locality <= 3);
17429   gcc_assert (GET_MODE (operands[0]) == Pmode
17430               || GET_MODE (operands[0]) == VOIDmode);
17431
17432   /* Use 3dNOW prefetch in case we are asking for write prefetch not
17433      supported by SSE counterpart or the SSE prefetch is not available
17434      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17435      of locality.  */
17436   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17437     operands[2] = GEN_INT (3);
17438   else
17439     operands[1] = const0_rtx;
17440 })
17441
17442 (define_insn "*prefetch_sse_<mode>"
17443   [(prefetch (match_operand:P 0 "address_operand" "p")
17444              (const_int 0)
17445              (match_operand:SI 1 "const_int_operand" ""))]
17446   "TARGET_PREFETCH_SSE"
17447 {
17448   static const char * const patterns[4] = {
17449    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17450   };
17451
17452   int locality = INTVAL (operands[1]);
17453   gcc_assert (locality >= 0 && locality <= 3);
17454
17455   return patterns[locality];
17456 }
17457   [(set_attr "type" "sse")
17458    (set_attr "atom_sse_attr" "prefetch")
17459    (set (attr "length_address")
17460         (symbol_ref "memory_address_length (operands[0])"))
17461    (set_attr "memory" "none")])
17462
17463 (define_insn "*prefetch_3dnow_<mode>"
17464   [(prefetch (match_operand:P 0 "address_operand" "p")
17465              (match_operand:SI 1 "const_int_operand" "n")
17466              (const_int 3))]
17467   "TARGET_3DNOW"
17468 {
17469   if (INTVAL (operands[1]) == 0)
17470     return "prefetch\t%a0";
17471   else
17472     return "prefetchw\t%a0";
17473 }
17474   [(set_attr "type" "mmx")
17475    (set (attr "length_address")
17476         (symbol_ref "memory_address_length (operands[0])"))
17477    (set_attr "memory" "none")])
17478
17479 (define_expand "stack_protect_set"
17480   [(match_operand 0 "memory_operand" "")
17481    (match_operand 1 "memory_operand" "")]
17482   ""
17483 {
17484   rtx (*insn)(rtx, rtx);
17485
17486 #ifdef TARGET_THREAD_SSP_OFFSET
17487   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17488   insn = (TARGET_64BIT
17489           ? gen_stack_tls_protect_set_di
17490           : gen_stack_tls_protect_set_si);
17491 #else
17492   insn = (TARGET_64BIT
17493           ? gen_stack_protect_set_di
17494           : gen_stack_protect_set_si);
17495 #endif
17496
17497   emit_insn (insn (operands[0], operands[1]));
17498   DONE;
17499 })
17500
17501 (define_insn "stack_protect_set_<mode>"
17502   [(set (match_operand:P 0 "memory_operand" "=m")
17503         (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17504    (set (match_scratch:P 2 "=&r") (const_int 0))
17505    (clobber (reg:CC FLAGS_REG))]
17506   ""
17507   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17508   [(set_attr "type" "multi")])
17509
17510 (define_insn "stack_tls_protect_set_<mode>"
17511   [(set (match_operand:P 0 "memory_operand" "=m")
17512         (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17513                   UNSPEC_SP_TLS_SET))
17514    (set (match_scratch:P 2 "=&r") (const_int 0))
17515    (clobber (reg:CC FLAGS_REG))]
17516   ""
17517   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17518   [(set_attr "type" "multi")])
17519
17520 (define_expand "stack_protect_test"
17521   [(match_operand 0 "memory_operand" "")
17522    (match_operand 1 "memory_operand" "")
17523    (match_operand 2 "" "")]
17524   ""
17525 {
17526   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17527
17528   rtx (*insn)(rtx, rtx, rtx);
17529
17530 #ifdef TARGET_THREAD_SSP_OFFSET
17531   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17532   insn = (TARGET_64BIT
17533           ? gen_stack_tls_protect_test_di
17534           : gen_stack_tls_protect_test_si);
17535 #else
17536   insn = (TARGET_64BIT
17537           ? gen_stack_protect_test_di
17538           : gen_stack_protect_test_si);
17539 #endif
17540
17541   emit_insn (insn (flags, operands[0], operands[1]));
17542
17543   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17544                                   flags, const0_rtx, operands[2]));
17545   DONE;
17546 })
17547
17548 (define_insn "stack_protect_test_<mode>"
17549   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17550         (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17551                      (match_operand:P 2 "memory_operand" "m")]
17552                     UNSPEC_SP_TEST))
17553    (clobber (match_scratch:P 3 "=&r"))]
17554   ""
17555   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17556   [(set_attr "type" "multi")])
17557
17558 (define_insn "stack_tls_protect_test_<mode>"
17559   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17560         (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17561                      (match_operand:P 2 "const_int_operand" "i")]
17562                     UNSPEC_SP_TLS_TEST))
17563    (clobber (match_scratch:P 3 "=r"))]
17564   ""
17565   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17566   [(set_attr "type" "multi")])
17567
17568 (define_insn "sse4_2_crc32<mode>"
17569   [(set (match_operand:SI 0 "register_operand" "=r")
17570         (unspec:SI
17571           [(match_operand:SI 1 "register_operand" "0")
17572            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17573           UNSPEC_CRC32))]
17574   "TARGET_SSE4_2 || TARGET_CRC32"
17575   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17576   [(set_attr "type" "sselog1")
17577    (set_attr "prefix_rep" "1")
17578    (set_attr "prefix_extra" "1")
17579    (set (attr "prefix_data16")
17580      (if_then_else (match_operand:HI 2 "" "")
17581        (const_string "1")
17582        (const_string "*")))
17583    (set (attr "prefix_rex")
17584      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17585        (const_string "1")
17586        (const_string "*")))
17587    (set_attr "mode" "SI")])
17588
17589 (define_insn "sse4_2_crc32di"
17590   [(set (match_operand:DI 0 "register_operand" "=r")
17591         (unspec:DI
17592           [(match_operand:DI 1 "register_operand" "0")
17593            (match_operand:DI 2 "nonimmediate_operand" "rm")]
17594           UNSPEC_CRC32))]
17595   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17596   "crc32{q}\t{%2, %0|%0, %2}"
17597   [(set_attr "type" "sselog1")
17598    (set_attr "prefix_rep" "1")
17599    (set_attr "prefix_extra" "1")
17600    (set_attr "mode" "DI")])
17601
17602 (define_expand "rdpmc"
17603   [(match_operand:DI 0 "register_operand" "")
17604    (match_operand:SI 1 "register_operand" "")]
17605   ""
17606 {
17607   rtx reg = gen_reg_rtx (DImode);
17608   rtx si;
17609
17610   /* Force operand 1 into ECX.  */
17611   rtx ecx = gen_rtx_REG (SImode, CX_REG);
17612   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17613   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17614                                 UNSPECV_RDPMC);
17615
17616   if (TARGET_64BIT)
17617     {
17618       rtvec vec = rtvec_alloc (2);
17619       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17620       rtx upper = gen_reg_rtx (DImode);
17621       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17622                                         gen_rtvec (1, const0_rtx),
17623                                         UNSPECV_RDPMC);
17624       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17625       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17626       emit_insn (load);
17627       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17628                                    NULL, 1, OPTAB_DIRECT);
17629       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17630                                  OPTAB_DIRECT);
17631     }
17632   else
17633     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17634   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17635   DONE;
17636 })
17637
17638 (define_insn "*rdpmc"
17639   [(set (match_operand:DI 0 "register_operand" "=A")
17640         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17641                             UNSPECV_RDPMC))]
17642   "!TARGET_64BIT"
17643   "rdpmc"
17644   [(set_attr "type" "other")
17645    (set_attr "length" "2")])
17646
17647 (define_insn "*rdpmc_rex64"
17648   [(set (match_operand:DI 0 "register_operand" "=a")
17649         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17650                             UNSPECV_RDPMC))
17651   (set (match_operand:DI 1 "register_operand" "=d")
17652        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17653   "TARGET_64BIT"
17654   "rdpmc"
17655   [(set_attr "type" "other")
17656    (set_attr "length" "2")])
17657
17658 (define_expand "rdtsc"
17659   [(set (match_operand:DI 0 "register_operand" "")
17660         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17661   ""
17662 {
17663   if (TARGET_64BIT)
17664     {
17665       rtvec vec = rtvec_alloc (2);
17666       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17667       rtx upper = gen_reg_rtx (DImode);
17668       rtx lower = gen_reg_rtx (DImode);
17669       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17670                                          gen_rtvec (1, const0_rtx),
17671                                          UNSPECV_RDTSC);
17672       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17673       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17674       emit_insn (load);
17675       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17676                                    NULL, 1, OPTAB_DIRECT);
17677       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17678                                    OPTAB_DIRECT);
17679       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17680       DONE;
17681     }
17682 })
17683
17684 (define_insn "*rdtsc"
17685   [(set (match_operand:DI 0 "register_operand" "=A")
17686         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17687   "!TARGET_64BIT"
17688   "rdtsc"
17689   [(set_attr "type" "other")
17690    (set_attr "length" "2")])
17691
17692 (define_insn "*rdtsc_rex64"
17693   [(set (match_operand:DI 0 "register_operand" "=a")
17694         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17695    (set (match_operand:DI 1 "register_operand" "=d")
17696         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17697   "TARGET_64BIT"
17698   "rdtsc"
17699   [(set_attr "type" "other")
17700    (set_attr "length" "2")])
17701
17702 (define_expand "rdtscp"
17703   [(match_operand:DI 0 "register_operand" "")
17704    (match_operand:SI 1 "memory_operand" "")]
17705   ""
17706 {
17707   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17708                                     gen_rtvec (1, const0_rtx),
17709                                     UNSPECV_RDTSCP);
17710   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17711                                     gen_rtvec (1, const0_rtx),
17712                                     UNSPECV_RDTSCP);
17713   rtx reg = gen_reg_rtx (DImode);
17714   rtx tmp = gen_reg_rtx (SImode);
17715
17716   if (TARGET_64BIT)
17717     {
17718       rtvec vec = rtvec_alloc (3);
17719       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17720       rtx upper = gen_reg_rtx (DImode);
17721       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17722       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17723       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17724       emit_insn (load);
17725       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17726                                    NULL, 1, OPTAB_DIRECT);
17727       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17728                                  OPTAB_DIRECT);
17729     }
17730   else
17731     {
17732       rtvec vec = rtvec_alloc (2);
17733       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17734       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17735       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17736       emit_insn (load);
17737     }
17738   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17739   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17740   DONE;
17741 })
17742
17743 (define_insn "*rdtscp"
17744   [(set (match_operand:DI 0 "register_operand" "=A")
17745         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17746    (set (match_operand:SI 1 "register_operand" "=c")
17747         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17748   "!TARGET_64BIT"
17749   "rdtscp"
17750   [(set_attr "type" "other")
17751    (set_attr "length" "3")])
17752
17753 (define_insn "*rdtscp_rex64"
17754   [(set (match_operand:DI 0 "register_operand" "=a")
17755         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17756    (set (match_operand:DI 1 "register_operand" "=d")
17757         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17758    (set (match_operand:SI 2 "register_operand" "=c")
17759         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17760   "TARGET_64BIT"
17761   "rdtscp"
17762   [(set_attr "type" "other")
17763    (set_attr "length" "3")])
17764
17765 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17766 ;;
17767 ;; LWP instructions
17768 ;;
17769 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17770
17771 (define_expand "lwp_llwpcb"
17772   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17773                     UNSPECV_LLWP_INTRINSIC)]
17774   "TARGET_LWP")
17775
17776 (define_insn "*lwp_llwpcb<mode>1"
17777   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17778                     UNSPECV_LLWP_INTRINSIC)]
17779   "TARGET_LWP"
17780   "llwpcb\t%0"
17781   [(set_attr "type" "lwp")
17782    (set_attr "mode" "<MODE>")
17783    (set_attr "length" "5")])
17784
17785 (define_expand "lwp_slwpcb"
17786   [(set (match_operand 0 "register_operand" "=r")
17787         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17788   "TARGET_LWP"
17789 {
17790   if (TARGET_64BIT)
17791     emit_insn (gen_lwp_slwpcbdi (operands[0]));
17792   else
17793     emit_insn (gen_lwp_slwpcbsi (operands[0]));
17794   DONE;
17795 })
17796
17797 (define_insn "lwp_slwpcb<mode>"
17798   [(set (match_operand:P 0 "register_operand" "=r")
17799         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17800   "TARGET_LWP"
17801   "slwpcb\t%0"
17802   [(set_attr "type" "lwp")
17803    (set_attr "mode" "<MODE>")
17804    (set_attr "length" "5")])
17805
17806 (define_expand "lwp_lwpval<mode>3"
17807   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17808                      (match_operand:SI 2 "nonimmediate_operand" "rm")
17809                      (match_operand:SI 3 "const_int_operand" "i")]
17810                     UNSPECV_LWPVAL_INTRINSIC)]
17811   "TARGET_LWP"
17812   "/* Avoid unused variable warning.  */
17813    (void) operand0;")
17814
17815 (define_insn "*lwp_lwpval<mode>3_1"
17816   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17817                      (match_operand:SI 1 "nonimmediate_operand" "rm")
17818                      (match_operand:SI 2 "const_int_operand" "i")]
17819                     UNSPECV_LWPVAL_INTRINSIC)]
17820   "TARGET_LWP"
17821   "lwpval\t{%2, %1, %0|%0, %1, %2}"
17822   [(set_attr "type" "lwp")
17823    (set_attr "mode" "<MODE>")
17824    (set (attr "length")
17825         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17826
17827 (define_expand "lwp_lwpins<mode>3"
17828   [(set (reg:CCC FLAGS_REG)
17829         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17830                               (match_operand:SI 2 "nonimmediate_operand" "rm")
17831                               (match_operand:SI 3 "const_int_operand" "i")]
17832                              UNSPECV_LWPINS_INTRINSIC))
17833    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17834         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17835   "TARGET_LWP")
17836
17837 (define_insn "*lwp_lwpins<mode>3_1"
17838   [(set (reg:CCC FLAGS_REG)
17839         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17840                               (match_operand:SI 1 "nonimmediate_operand" "rm")
17841                               (match_operand:SI 2 "const_int_operand" "i")]
17842                              UNSPECV_LWPINS_INTRINSIC))]
17843   "TARGET_LWP"
17844   "lwpins\t{%2, %1, %0|%0, %1, %2}"
17845   [(set_attr "type" "lwp")
17846    (set_attr "mode" "<MODE>")
17847    (set (attr "length")
17848         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17849
17850 (define_insn "rdfsbase<mode>"
17851   [(set (match_operand:SWI48 0 "register_operand" "=r")
17852         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
17853   "TARGET_64BIT && TARGET_FSGSBASE"
17854   "rdfsbase %0"
17855   [(set_attr "type" "other")
17856    (set_attr "prefix_extra" "2")])
17857
17858 (define_insn "rdgsbase<mode>"
17859   [(set (match_operand:SWI48 0 "register_operand" "=r")
17860         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
17861   "TARGET_64BIT && TARGET_FSGSBASE"
17862   "rdgsbase %0"
17863   [(set_attr "type" "other")
17864    (set_attr "prefix_extra" "2")])
17865
17866 (define_insn "wrfsbase<mode>"
17867   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17868                     UNSPECV_WRFSBASE)]
17869   "TARGET_64BIT && TARGET_FSGSBASE"
17870   "wrfsbase %0"
17871   [(set_attr "type" "other")
17872    (set_attr "prefix_extra" "2")])
17873
17874 (define_insn "wrgsbase<mode>"
17875   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17876                     UNSPECV_WRGSBASE)]
17877   "TARGET_64BIT && TARGET_FSGSBASE"
17878   "wrgsbase %0"
17879   [(set_attr "type" "other")
17880    (set_attr "prefix_extra" "2")])
17881
17882 (define_expand "rdrand<mode>"
17883   [(set (match_operand:SWI248 0 "register_operand" "=r")
17884         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
17885   "TARGET_RDRND"
17886 {
17887   rtx retry_label, insn, ccc;
17888
17889   retry_label = gen_label_rtx ();
17890
17891   emit_label (retry_label);
17892
17893   /* Generate rdrand.  */
17894   emit_insn (gen_rdrand<mode>_1 (operands[0]));
17895
17896   /* Retry if the carry flag isn't valid.  */
17897   ccc = gen_rtx_REG (CCCmode, FLAGS_REG);
17898   ccc = gen_rtx_EQ (VOIDmode, ccc, const0_rtx);
17899   ccc = gen_rtx_IF_THEN_ELSE (VOIDmode, ccc, pc_rtx,
17900                               gen_rtx_LABEL_REF (VOIDmode, retry_label));
17901   insn = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, ccc));
17902   JUMP_LABEL (insn) = retry_label;
17903
17904   DONE;
17905 })
17906
17907 (define_insn "rdrand<mode>_1"
17908   [(set (match_operand:SWI248 0 "register_operand" "=r")
17909         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
17910   "TARGET_RDRND"
17911   "rdrand %0"
17912   [(set_attr "type" "other")
17913    (set_attr "prefix_extra" "1")])
17914
17915 (include "mmx.md")
17916 (include "sse.md")
17917 (include "sync.md")